Reputation: 2211
So I'm working on simple console battleships in C++. I have a class Ship like this:
class Ship {
public:
virtual void draw(int x, int y){}
virtual void shoot(int x, int y){}
virtual bool isDead(){};
};
and two classes (horizontal and vertical ship) which inherit from it. So a sample vertical one is:
class VertShip : public Ship{
private:
int x, y, shipSize;
char deck[4];
public:
VertShip(int x, int y, int shipSize) : x(x), y(y), shipSize(shipSize) {
for(int i=0; i<shipSize; ++i)
{
deck[i] = '_';
}
}
virtual void draw(int x, int y){
cout << deck[y - this->y];
}
virtual void shoot(int x, int y){
deck[y - this->y] = 'T';
--shipSize;
}
virtual bool isDead()
{
if(this->shipSize) return 0;
return 1;
}
};
so just each of the cells of my deck is represented inside the object. Shoot() runs when someone invokes the fire() method on the Board class and successfully hits the ship and draw() gives the drawBoard() method information about a given cell of the ship's deck. Also, ships[] is an array of pointers to the ships objects. So up to this point everything works fine - the problem is with the Board::fire():
void Board::fire(int w, int k){
if(mapOfCells[w][k]>=0)
ships[mapOfCells[w][k]]->shoot(w,k);
//if(ships[mapOfCells[w][k]]->isDead()) cout<<"The ship has drown.\n";
else
mapOfCells[w][k]=-2;
}
As soon as I uncomment the if, the weird behaviour starts. It gives me improper information (claiming that cells with ship in them are empty and the other way around too) and the game crashes after three shots. If I comment it, however, it works perfectly - just doesn't let you know if you sunk a ship completely.
What's wrong with it? Am I doing something malicious in this one if? Regretfully, I'm unable to provide a short, compilable source as this game simply won't run without most of the classes and methods and there's quite a few of them.
Upvotes: 0
Views: 82
Reputation: 4601
Try putting curly braces around your if
clause. Your else
clause is binding to the second if
statement rather than the first, and your second if
statement is being executed unconditionally.
Upvotes: 4
Reputation: 22094
If you simply uncomment this then the semantics changes:
Currently it is:
void Board::fire(int w, int k)
{
if(mapOfCells[w][k]>=0)
ships[mapOfCells[w][k]]->traf(w,k);
else
mapOfCells[w][k]=-2;
}
if you uncomment, it becomes:
void Board::fire(int w, int k)
{
if(mapOfCells[w][k]>=0)
ships[mapOfCells[w][k]]->traf(w,k);
if(ships[mapOfCells[w][k]]->isDead())
cout<<"The ship has drown.\n";
else
mapOfCells[w][k]=-2;
}
not sure if this is intended. Your unexpected behaviour could come from this though, because your indentation looks like you intended something else. As noted above, your default implementation also lacks a return value which should give you a compiler warning and undefined results.
Upvotes: 5