Hi im doing little project tomy school and keep getting weird for me error.
While calling one of methods in my object this pointer is set to 0xcdcdcdcd. i googled it and found some info about erasing memory or destroing objects before calling, but i make sure no destructors are called before.
World.h
class Organism;
class Human;
class World
{
private:
vector <Organism*> organisms;
vector <Organism*> organismsToAdd;
vector <string> logs;
int turn_;
void initializeWorld();
void drawInterface();
void drawInfo();
void drawOrganisms();
void nextTurn();
bool isPositionTaken(int x, int y);
Organism* getOrganism(int x, int y);
void queueOrganismToAdd(Organism* newOrganism);
void addQueuedOrganisms();
void generateStartOrganisms();
bool isPlayerAlive();
public:
void executeMove(Organism* moving, int toX, int toY); //here's the problem
bool isPositionValid(int x, int y);
World(int x, int y);
struct
{
int x_, y_;
} worldSize;
void startGame();
~World();
};
executeMove
void World::executeMove(Organism* moving, int toX, int toY)
{
cout << moving->getSign();
getch();
if (!isPositionTaken(toX, toY)) // <- here it brake
{
moving->setPosition(toX, toY);
}
else if (moving->getSign() == getOrganism(toX, toY)->getSign())
{
//multiply
//make log
}
else {
if (!moving->specialCollision((getOrganism(toX, toY)))) return;
if (!getOrganism(toX, toY)->specialCollision(moving)) return;
if (moving->getPower() >= getOrganism(toX, toY)->getPower())
{
//log
//delete losser
}
else
{
//log
//delete losser
}
moving->setPosition(toX, toY);
}
}
isPositioinTaken
bool World::isPositionTaken(int x, int y)
{
for (int i = 0; i < this->organisms.size(); ++i) // here this is set to 0xcdcdcdcd
{
if (organisms[i]->getPositionX() == x && organisms[i]->getPositionY() == y) return true;
}
return false;
}
Method isPositionTaken is worlking well in other parts of project so im totally lost if finding whats wrong, i aprreciate any help
Since the organisms member has a default constructor, the only way to see this behavior at the line you indicated is if the call to executeMove() was using a pointer which was uninitialized.
Something like:
World *ptr; // not initialized on stack
...
ptr->executeMove();
Or this method was called from another method with the same problem.
Related
I have a sample of code for some framework that I am using. For ease of reading I have separated blocks of code from different files.
Tile.h
class Tile
{
public:
Tile(int row, int column);
~Tile();
void Draw();
void Update(double delta);
void SetValue(int value);
int GetValue();
private:
//Member variables
Label* m_ValueLabel;
int m_Value = 0;
int m_Row;
int m_Column;
float duration = 0.0f;
float xScale = 0;
float yScale = 0;
};
Tile.cpp
void Tile::SetValue(int value)
{
//Set the Tile's value
m_Value = value;
//if (m_Value != EMPTY_TILE)
{
//Update the Tile's Label
m_ValueLabel->SetText(to_string(m_Value));
}
/*else
{
m_ValueLabel->SetText("");
}*/
}
Game.h
class Game
{
public:
Game(); //Constructor
~Game(); //Destructor
void Update(double delta);
void Draw();
void HandleLeftMouseClick(float mouseX, float mouseY);
void HandleRightMouseClick(float mouseX, float mouseY);
void HandleKeyPress(Keyboard::Key key);
bool isBoardFull();
int GetEmptyTileIndex();
void SpawnTile();
void RandomizeSeed();
int RandomRange(int min, int max);
private:
//Member variables should go here
Tile* m_Tiles[NUM_TILES];
bool isTileFull[16] = {};
int TileValueArray[5] = { 2,2,2,4,4 };
};
Game.cpp
void Game::SpawnTile()
{
RandomizeSeed();
int meaningfulVariableName = GetEmptyTileIndex();
if (meaningfulVariableName != -1)
{
int RandomNumber = RandomRange(0,4);
int TileValue = TileValueArray[RandomNumber];
}
else if (meaningfulVariableName == -1)
{
//Does nothing
}
}
What I need to do with this is make it so that the TileValue created in Game.cpp can be passed to the SetValue function in Tile.cpp because the value created is required for m_Value in SetValue.
The majority of code present can probably be ignored, and anything commented out should not effect how I need the code to function at the moment. There is nothing wrong with the framework outside of these files, as I have used it several times before.
I know there are easier ways to do this, but this is how I am required to do it. I would really appreciate if someone could help me with this because anything that I have found online has not helped. If you think that you may need more code for clarification on something, please do not hesitate to ask. Also, in case it helps I am using this to create a 2048 clone.
You have a function Game::GetEmptyTileIndex which will return an index. You can use that index to set Game::m_Tiles by changing the Game::SpawnTile function like so:
// Game.cpp
void Game::SpawnTile()
{
RandomizeSeed();
// Returns a tile index.
int meaningfulVariableName = GetEmptyTileIndex();
if (meaningfulVariableName != -1)
{
int RandomNumber = RandomRange(0,4);
int TileValue = TileValueArray[RandomNumber];
// Set the value for the tile at the required index.
m_Tiles[meaningfulVariableName]->SetValue(TileValue);
}
else if (meaningfulVariableName == -1)
{
//Does nothing
}
}
I'd like to access to a double pointer which is located in another class "Board".
class Board
{
public:
Board(void);
Board(unsigned int xSize, unsigned int ySize);
~Board(void);
void SetObjectManager(ObjectManager* pObm);
void SetBlock(Block* block);
void LoadBoard(void);
void InitBoard(void);
//Other Functions...
private:
ObjectManager* m_obm;
Block* m_block;
//pointer to pointer to a int. (for 2 dimensional-array)
int **m_board;
};
First, the Board class. at the last line of class, you can see m_board.
I want to change this value in outside of this class.
Like this,
void Block::InitBlock(void)
{
int randPiece = Random::GIRand().RandInt(0, 1);
int randPos = Random::GIRand().RandInt(0, 10);
switch (randPiece)
{
case 0:
m_piece[2][1] = 1;
m_piece[2][2] = 1;
m_piece[2][3] = 1;
m_piece[3][3] = 1;
break;
//Other cases are here...
}
std::cout << "RandPos : " << randPos << std::endl;
std::cout << "RandPiece : " << randPiece << std::endl;
for (int y = 0; y < m_ySize; ++y)
{
for (int x = 0, pX = randPos; x < m_xSize; ++x, ++randPos)
{
if (m_piece[x][y] != 0)
m_board->SetBoardStatus(randPos, y, 1);
}
}
}
But, When I run this program, It blows up at SetBoardStatus(int, int, int)
SetBoardStatus looks like this,
void Board::SetBoardStatus(int x, int y, int value)
{
m_board[x][y] = value; //Visual Studio breaks the program here.
}
I allocate the double pointer properly.
And I set the board at the outside of this classes.
void Block::SetBoard(Board* board)
{
m_board = board;
}
And this is my block class.
class Block
{
public:
Block(void);
~Block(void);
void SetObjectManager(ObjectManager* pObm);
void LoadBlock (void);
void InitBlock (void);
void UpdateBlock (void);
void ReleaseBlock (void);
void SetBoard(Board* board);
private:
ObjectManager* m_obm;
Board* m_board;
int **m_piece;
int m_xSize;
int m_ySize;
};
Consider inheriting Block in Board; This will eliminate any possible de-referencing errors or bugs, as you can access the pointer right away.
Hey I am trying to make this space game. Now I have developed my ship, and am able to display it. However I would like to be able to use the class for more than one object. I can do this with a constructor but have no clue how to get a constructor working, what changes would I need to make to my code to make the object take an int value as a constructor and allow me to make multiple ships with the code by calling the object.
Here is my header file.
//
// Ship.hpp
// Zerg_Invasion
//
// Created by Flik Wolf on 11/9/15.
//
//
#ifndef Ship_h
#define Ship_h
#include <stdio.h>
#include "ofMain.h"
class Ship {
public:
// Constructor
Ship();
// Methods
void moveLeft();
void moveRight();
void load();
void draw();
void fire();
void keyPressed();
// Properties
int x;
int y;
ofColor color;
ofImage cat;
};
#endif
and here is my CPP file.
//
// Ship.cpp
// Zerg_Invasion
//
// Created by Flik Wolf on 11/9/15.
//
//
#include "Ship.h"
Ship::Ship() {
// Set the initial color
//color.set( ofRandom(255), ofRandom(255), ofRandom(255));
// Initial x position of the ball
x = 450;
// Initial y position of the ball
y = 200;
}
void Ship::moveLeft() {
x -= 10;
}
void Ship::moveRight() {
x += 10;
}
void Ship::load() {
cat.load("spaceShip.png");
}
void Ship::draw() {
cat.draw(x, y);
// ofCircle(x, y, 30);
}
void Ship::fire() {
ofSetColor(255, 255, 255);
ofCircle(x, 200, 2);
}
Also here is the .h and .cpp files for Openframeworks which I am using for graphics.
#pragma once
#include "ofMain.h"
#include "Ship.h"
class ofApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void keyPressed(int key);
void keyReleased(int key);
void mouseMoved(int x, int y);
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void mouseEntered(int x, int y);
void mouseExited(int x, int y);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
Ship theShip;
};
#include "ofApp.h"
//--------------------------------------------------------------
void ofApp::setup() {
// Smooth edges
ofEnableSmoothing();
// Fixed framerate
ofSetFrameRate(120);
theShip.load();
// No need to define the initial position of the ball
// because the Ball constructor does it for you
}
//--------------------------------------------------------------
void ofApp::update() {
// theShip.move();
}
//--------------------------------------------------------------
void ofApp::draw() {
ofBackground(0);
std::vector <int> nums;
nums.push_back(0);
nums.push_back(1);
nums.push_back(3);
nums.push_back(4);
nums.push_back(5);
nums.push_back(6);
nums.push_back(7);
nums.push_back(8);
cout << nums[0] << endl;
cout << nums[1] << endl;
theShip.draw();
}
//--------------------------------------------------------------
void ofApp::keyPressed(int key) {
if (key == 'a')
{
theShip.moveLeft();
}
if (key == 'd')
{
theShip.moveRight();
}
}
//--------------------------------------------------------------
void ofApp::keyReleased(int key) {
}
//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button) {
theShip.fire();
}
//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button) {
}
//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y) {
}
//--------------------------------------------------------------
void ofApp::windowResized(int w, int h) {
}
//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg) {
}
//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo) {
}
As mentioned, the constructor in your case should only produce one ship, and this should be the case with all object constructors.
However, it's still easy enough to create and maintain multiple ships (as you've implemented them) if you use a container like std::vector.
Containing multiple ships:
To create a container for your ships, you can use a vector like so:
std::vector<Ship> Ships;
Adding new ships:
To add additional ships to it, you can use std::vector::push_back():
Ships.push_back(Ship()); //Adds a new ship to 'Ships'
Updating the ships:
There are a couple of ways to cycle through your ships:
for (auto& i : Ships)
i.Update(); //Some updating function for each ship
Or, if you need to keep track of the specific position of each ship inside the vector:
for (unsigned int i = 0; i < Ships.size(); ++i)
Ships[i].Update() //The same updating function
How about to get the x and y as constructor argument?
in the .h file:
struct Ship {
// Constructor
Ship(int _x = 450, int _y = 200);
// ...
in the cpp file:
Ship::Ship(int _x, int _y) : x{_x}, y{_y} {
// Set the initial color
//color.set( ofRandom(255), ofRandom(255), ofRandom(255));
}
I'm trying to swap to objects of class. It's a puzzle game something like http://www.neos-guide.org/sites/default/files/Fifteen_puzzle.png. I'm using std::swap but it doesn't work. Here's code:
if (puzzle[i-1][j].getNum() == 16) {
std::swap(puzzle[i][j], puzzle[i-1][j]);
}
else if (puzzle[i+1][j].getNum() == 16) {
std::swap(puzzle[i+1][j], puzzle[i][j]);
}
else if (puzzle[i][j+1].getNum() == 16 && j != 3) {
std::swap(puzzle[i][j+1], puzzle[i][j]);
}
else if (puzzle[i][j-1].getNum() == 16 && j != 0) {
std::swap(puzzle[i][j-1], puzzle[i][j]);
}
And here's my puzzle class:
class Puzzle {
private:
int x;
int y;
int num;
ALLEGRO_FONT *font;
public:
Puzzle();
~Puzzle();
void init(int posx, int posy, ALLEGRO_FONT *font);
void setNum(int num);
void draw();
void setXY(int x, int y);
int getX();
int getY();
int getNum();
bool click(int mx, int my);
};
I have tried std::swap on 2D array of integers, on two objects of same class, on 1D object array and 2D object array. It worked. It just doesn't work in this implementation. I also tried to comment out ALLEGRO_FONT as I thought that there is the problem. But nothing has changed. cplusplus.com says that I need to include <algorithm> or <utility>. I tried both (not at the same time) but it didn't work. Any suggestions? Thank you :)
I have created a code in C++ that is supposed to display an O and an X, and you can move the O with w/a/s/d, and the X moves randomly. It compiles fine, but when I run it, there is an O, but no X. I put the source code here:
#include <iostream>
using namespace std;
//program class: defines player, enemies and powerups
#include<stdlib.h>
#include<time.h>
class prgm
{
friend void set_pos(prgm*const nprgm,int px,int py){nprgm->x=px;nprgm->y=py;}
friend void set_pos(prgm*const nprgm,int px,int py,int php){nprgm->x=px;nprgm->y=py;nprgm->hp=php;}
friend void set_pos(prgm*const nprgm,int px,int py,int php,char psym){nprgm->x=px;nprgm->y=py;nprgm->hp=php;nprgm->sym=psym;}
protected:
int x; //x-position
int y; //y-position
int hp; //health
char sym; //single-character representation
public:
prgm(){sym=' ';}
prgm(int px,int py,int php,char psym):x(px),y(py),hp(php),sym(psym){};
const int xpos(){return x;}
const int ypos(){return y;}
const char rsym(){return sym;}
void up(int n){y-=n;} //move program up
void left(int n){x-=n;} //move program left
void down(int n){y+=n;} //move program down
void right(int n){x+=n;} //move program right
void mutate(char nsym){sym=nsym;} //change program's symbol
void harm(int dam){hp-=dam;}
void heal(int dam){hp+=dam;}
prgm &prgm::operator=(const prgm&nprgm){x=nprgm.x;y=nprgm.y;hp=nprgm.hp;sym=nprgm.sym;}
};
//null program
prgm null();
//abstract enemy class for individual ai of each enemy
class enemy:public prgm
{
public:
void move(){}; //what enemy will do during its move
};
prgm player(0,0,0,'O');
void pmove()
{
char move;
cin>>move;
switch(move)
{
case 'w':
player.up(1);
break;
case 'a':
player.left(1);
break;
case 's':
player.down(1);
break;
case 'd':
player.right(1);
break;
case 'q':
exit(0);
break;
}
return;
}
//the X1 Virus Component, the simplest version of Virus X: moves in random directions, harms on contact.
class X1:public enemy
{
static const char sym='X';
public:
X1(){}
X1(int px,int py){x=px;y=py;}
void move();
};
void X1::move()
{
srand(time(0));
int dir=(rand()%2);
int dis=(rand()%3)-1;
while(dis=0)
{
dis=(rand()%3)-1;
}
if(dir=0)
{
y+=dis;
}
if(dir=1)
{
x+=dis;
}
return;
}
//sector 1
const int maxx=10; //length of sector
const int maxy=10; //height of sector
char sector[maxx][maxy]; //sector declaration
const int rsize=4;
prgm reactive_items[rsize];//array of powerups
X1 a(4,4); //enemy(ies)
const int vsize=1;
X1 viruses[vsize]={a}; //array of enemies
int px=0,py=0,php=1; //players position and hp
//function zeros-out the sector
void clear_sect()
{
for(int i=0;i<maxy;i++)
{
for(int j=0;j<maxx;j++)
{
sector[j][i]=' ';
}
}
}
//function sets all the enemies/powerups/player in the sector
void set_sect()
{
for(int i=0;i<rsize;i++)
{
int*tx=new int(reactive_items[i].xpos());
int*ty=new int(reactive_items[i].ypos());
char*ts=new char(reactive_items[i].rsym());
sector[*tx][*ty]=*ts;
delete tx;
delete ty;
delete ts;
}
for(int j=0;j<vsize;j++)
{
int*tx=new int(viruses[j].xpos());
int*ty=new int(viruses[j].ypos());
char*ts=new char(viruses[j].rsym());
sector[*tx][*ty]=*ts;
delete tx;
delete ty;
delete ts;
}
int*tx=new int(player.xpos());
int*ty=new int(player.ypos());
char*ts=new char(player.rsym());
sector[*tx][*ty]=*ts;
delete tx;
delete ty;
delete ts;
}
//function displays sector
void display_sect()
{
for(int i=0;i<maxy;i++)
{
for(int j=0;j<maxx;j++)
{
cout<<sector[j][i];
}
cout<<endl;
}
return;
}
void vmove()
{
for(int i=0;i<vsize;i++)
{
viruses[i].move();
}
return;
}
int main()
{
//load the sector # from the .txt, load the sector
set_pos(&player,px,py,php); //set the players x and y values
while(true){//while the player is on this sector
clear_sect();//clear the sector map
set_sect();//use the set function
display_sect();//use the display function
pmove();//players move
vmove();//enemy-ai move
//check board; relocate whats needed, initiate powerups, etc.
}//end of while
//when player wins sector
//write current sector to a .txt
//load program: restart this/story program/APHQ
return 0;
}
I know its long and pretty convoluted, (they were originally seperate .h files, but i put them together so that I could see all the code at once) but I really need an answer. Thanks
Your default constructor to prgm() sets the sym member to ' '. The static const char field does not override the base sym member, so the character used is probably the ' '.
Your enemy constructor should actually call the (int,int,int,char) base constructor to set the sym member.
Check your X1 class. It declares a static const char sym while it inherits a protected char sym member variable from class pgrm. Your display_sect function uses prgm's rsym() method, which returns the member variable, not the static member.