Click here to Skip to main content
15,879,474 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello I'm pretty new to C++ and am trying to simulate natural selection, similar to this video - https://www.youtube.com/watch?v=0ZGbIKd0XrM . I'm trying to add random movement in my game through random angles and moving speed amount of distance to that angle. However in the case of the code given below made using C++ and OpenGL, you will see that I console log the x and the y, however they end up defaulting to 300 after changing once(300 being both of their original value). Is there a fix for this and if so, what was I doing wrong? Thanks.
C++
#include <iostream>
#include <vector>
#include <random>
#include <cmath>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <cmath>

int width  = 600;
int height = 600;

/*class V2D
{
  public:
    V2D(){}
    V2D(float _x, float _y)
    {
      x = _x;
      y = _y;
    }
    float x;
    float y;
};
*/
class Survivor
{
  public:
    float x;
    float y;
    float energy;
    int foodInPossession;
    float speed;
    //float size;
    float sense;
    float angleOfSense = -1;
    Survivor();
    Survivor(float _x, float _y, float _speed, float _sense)
    {
      x = _x;
      y = _y;
      speed             = _speed;
      energy            = 100;
      foodInPossession  = 0;
      //size              = _size;
      sense             = _sense;
    }
    void update()
    {
      float LO = 0;
      float HI = 360;
      float aom;
      if(angleOfSense==-1)
        aom = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));
      else
        aom = angleOfSense;
      std::cout<<x<<" "<<y<<std::endl;
      x+= speed * sin(aom);
      y+= speed * cos(aom);
      std::cout<<x<<" "<<y<<std::endl;
    }
    bool onBorder()
    {
      return x == 0 || x == width || y == 0 || y == height;
    }
};
int main()
{
  std::vector<Survivor> survivors;
  survivors.push_back(Survivor(300, 300, 10, 1));
  GLFWwindow* window;
  if (!glfwInit())
    return 1;
  window = glfwCreateWindow(width, height, "Window", NULL, NULL);
  if (!window) {
    glfwTerminate();
    return 1;
  }
  glfwMakeContextCurrent(window);
  if(glewInit()!=GLEW_OK)
    std::cout<<"Error"<<std::endl;
  glEnable(GL_DEPTH_TEST);
  glMatrixMode(GL_PROJECTION);
  glfwGetFramebufferSize(window, &width, &height);
  glOrtho(0, width*(width/height), height, 0, -2, 2);
  while(!glfwWindowShouldClose(window)) {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glClearColor(0.11, 0.14, 0.17, 1);
    
    for(Survivor i : survivors)
    {
      if(!i.onBorder())
      {
        i.update();
      }
      glBegin(GL_QUADS);
      glColor3f(1, 1, 1);
      glVertex2f(i.x, i.y);
      glVertex2f(i.x + 1, i.y);
      glVertex2f(i.x + 1, i.y + 1);
      glVertex2f(i.x, i.y + 1);
      glEnd();
    }

    glfwSwapBuffers(window);
    glfwPollEvents();
  }
  glfwTerminate();
}


What I have tried:

I have tried nothing as of now, as I could not even find the root of the problem.
Posted
Updated 1-Jul-19 22:06pm

The root of the problem is this piece of code:
Quote:
if(angleOfSense==-1)
aom = LO + static_cast <float> (rand()) /( static_cast <float> (RAND_MAX/(HI-LO)));
else
aom = angleOfSense;
It computes a random angle only the first time it executes (when angleOfSense is equal to its initialization value, that is -1).

Moreover, please note sin and cos functions takes angles in radians, while your are passing degrees.
 
Share this answer
 
On top of what Carlo said in solution 1, there are two more issues:
Quote:
C++
return x == 0 || x == width || y == 0 || y == height;

Never compare floating point variables using == or != . These values are prone to subtle variations due to rounding effects, and therefore a direct comparison will almost always fail, even when, mathematically, it should succeed.

That said, since you are adding random values to x and y, you will probably never end exactly on the border - instead you'll move right past it! Therefore, rather than checking whether you are on the border, you should check whether you are outside! Alternately you should fix the update method to stop at the border.

Secondly:
C++
for(Survivor i : survivors)

This code will create a copy of the vector element. Therefore the update will not change any vector element, only it's copy. You might want to try
C++
for(Survivor& i : survivors)
instead, or simply
C++
for(auto& i : survivors)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900