I know there are a few programmers here, so I was thinking I could get some help for a problem I'm having with my project. (Below is the code).
My current problem is with removing units. Presently, the behaviour is like this:
I cannot remove units in places where no units exist.
I can place units.
I can only remove the first unit I place. <- Main problem.
Can anyone help me fix this problem? My logic "feels" correct, but I have no idea what is actually wrong.
Functions of interest:
removeUnit
CUnit.removeSelf
Other information:
Programmed for/tested with Windows
Use ESC to access the menu
Use arrow keys to move the cursor (*)
Code
#include <cstdlib>
#include <conio.h>
#include <iostream>
#include <string>
#define WIDTH 45
#define HEIGHT 15
#define AREA WIDTH * HEIGHT
using namespace std;
struct SMapInfo
{
int tileType;
int unitType;
bool cursor;
};
SMapInfo GMap[WIDTH][HEIGHT];
class CUnit
{
int coordX, coordY; // coordinMainAtes
int HP; // HP
int wType; // weapon type: 1 = sword, 2 = axe, 3 = pike
public:
bool exists;
void addAtLoc(int x, int y, int iniHP, int iniWType) // Adds a unit at the location
{
coordX = x; // change coordinMainAtes
coordY = y;
wType = iniWType; // set weapon
HP = iniHP; // alive
GMap[coordX][coordY].unitType = wType; // add self to map
exists = 1; // now exists
}
bool isAtLoc(int x, int y) // Returns true if unit is at a location
{
if(x == coordX && y == coordY)
{
return 1;
}
else
{
return 0;
}
}
bool moveToLoc(int x, int y) // Returns true if unit is moved successfully
{
if(GMap[x][y].unitType == 0)
{
GMap[coordX][coordY].unitType = 0; // remove self from map
coordX = x; // change coordinMainAtes
coordY = y;
GMap[coordX][coordY].unitType = wType; // add self to map
return 1;
}
else
{
return 0;
}
}
void removeSelf() // Removes self.
{
GMap[coordX][coordY].unitType = 0; // remove self from map
exists = 0;
}
};
CUnit GUnitArray[AREA];
int GCursorX = 0;
int GCursorY = 0;
void resetGMap()
{
for(int y = 0; y < HEIGHT; y++)
{
for(int x = 0; x < WIDTH; x++)
{
GMap[x][y].tileType = 0;
GMap[x][y].unitType = 0;
GMap[x][y].cursor = 0;
}
}
}
void drawGMap()
{
for(int y = 0; y < HEIGHT; y++)
{
int xsum = 0;
for(int x = 0; x < WIDTH; x++)
{
xsum += GMap[x][y].unitType;
xsum += GMap[x][y].tileType;
xsum += GMap[x][y].cursor;
}
string emptyLine = "";
if(xsum == 0)
{
for(int i = 0; i < WIDTH; i++)
{
emptyLine += ".";
}
cout << emptyLine;
}
else
{
for(int x = 0; x < WIDTH; x++)
{
int xsum = 0;
if(GMap[x][y].cursor == 1) // draw cursor
{
cout << "*";
}
else if(GMap[x][y].unitType != 0) // draw unit
{
switch(GMap[x][y].unitType) // units
{
case 1: // swordsman
cout << "s";
break;
case 2: // axeman
cout << "a";
break;
case 3: // pikeman
cout << "p";
break;
default:
cout << "!";
break;
}
}
else
{
switch(GMap[x][y].tileType) // tiles
{
case 0: // open
cout << ".";
break;
case 1: // void
cout << " ";
break;
case 2: // high ground
cout << ":";
break;
default:
cout << "?";
break;
}
}
}
}
cout << endl;
}
}
string tileInfo(int T)
{
string tile;
switch (T)
{
case 0:
tile = "Ground";
break;
case 1:
tile = "Void";
break;
case 2:
tile = "High Ground";
break;
}
return tile;
}
string unitInfo(int U)
{
// 1 sword > 2 axe > 3 lance > 1 sword...
string unit;
switch (U)
{
case 0:
unit = "None";
break;
case 1:
unit = "Swordsman";
break;
case 2:
unit = "Axeman";
break;
case 3:
unit = "Pikeman";
break;
}
return unit;
}
void clrScrn()
{
system("CLS");
}
void placeCursor()
{
GMap[GCursorX][GCursorY].cursor = 1;
}
void removeCursor()
{
GMap[GCursorX][GCursorY].cursor = 0;
}
bool addUnit(int x, int y, int iniHP, int iniWType)
{
if(GMap[GCursorX][GCursorY].unitType == 0) // no unit presently occupies space
{
GMap[GCursorX][GCursorY].unitType = iniWType;
for(int i = 0; i < AREA; i++)
{
if(GUnitArray[i].exists != 1)
{
GUnitArray[i].addAtLoc(x, y, iniHP, iniWType);
}
}
return 1;
}
else
{
cout << "Failed to add unit." << endl;
system("PAUSE");
return 0;
}
}
bool removeUnit(int x, int y)
{
for(int i = 0; i < AREA; i++)
{
if(GUnitArray[i].exists == 1)
{
if(GUnitArray[i].isAtLoc(x, y) == 1)
{
GUnitArray[i].removeSelf();
cout << "Removed unit." << endl;
system("PAUSE");
return 1;
}
else
{
cout << "Failed to remove unit." << endl;
system("PAUSE");
return 0;
}
}
}
}
int main()
{
resetGMap();
int inMainA, inMainB;
bool gameOn = 1;
while(gameOn)
{
clrScrn();
placeCursor();
drawGMap();
cout << "Tile: " << tileInfo(GMap[GCursorX][GCursorY].tileType) << endl;
cout << "Unit: " << unitInfo(GMap[GCursorX][GCursorY].unitType) << endl;
cout << ">> ";
inMainA = getch();
cout << inMainA << endl; // return input
switch(inMainA)
{
case 224: // special key
inMainB = getch();
switch(inMainB)
{
case 72: // up
if (GCursorY > 0)
{
removeCursor();
GCursorY--;
}
break;
case 80: // down
if (GCursorY < HEIGHT - 1)
{
removeCursor();
GCursorY++;
}
break;
case 75: // left
if (GCursorX > 0)
{
removeCursor();
GCursorX--;
}
break;
case 77: // right
if (GCursorX < WIDTH - 1)
{
removeCursor();
GCursorX++;
}
break;
}
break;
case 27: // ESC menu
int inMenu;
bool menuOn;
menuOn = 1;
while(menuOn)
{
cout << "\n MENU" << endl;
cout << "ESC - Return" << endl;
cout << "1 - Place Tile" << endl;
cout << "2 - Place Unit" << endl;
cout << "3 - Remove Unit" << endl;
cout << "0 - Exit" << endl;
inMenu = getch();
switch(inMenu)
{
case 27: // ESC return
menuOn = 0;
break;
case 49: // 1 Tile Input
int inTile;
bool tileOn;
tileOn = 1;
while(tileOn)
{
cout << "\n TILE" << endl;
cout << "ESC - Return" << endl;
cout << "1 - Ground" << endl;
cout << "2 - Void" << endl;
cout << "3 - High Ground" << endl;
inTile = getch();
switch(inTile)
{
case 49: // 1 ground
tileOn = 0;
menuOn = 0;
GMap[GCursorX][GCursorY].tileType = 0;
break;
case 50: // 2 void
tileOn = 0;
menuOn = 0;
GMap[GCursorX][GCursorY].tileType = 1;
break;
case 51: // 3 high ground
tileOn = 0;
menuOn = 0;
GMap[GCursorX][GCursorY].tileType = 2;
break;
case 27: // ESC return
tileOn = 0;
break;
default:
break;
}
}
break;
case 50: // 2 Unit Input
int inUnit;
bool unitOn;
unitOn = 1;
while(unitOn)
{
cout << "\n UNIT" << endl;
cout << "ESC - Return" << endl;
cout << "1 - Swordsman" << endl;
cout << "2 - Axeman" << endl;
cout << "3 - Pikeman" << endl;
inUnit = getch();
switch(inUnit)
{
case 49: // 1 swordsman
unitOn = 0;
menuOn = 0;
addUnit(GCursorX, GCursorY, 3, 1);
break;
case 50: // 2 swordsman
unitOn = 0;
menuOn = 0;
addUnit(GCursorX, GCursorY, 3, 2);
break;
case 51: // 3 swordsman
unitOn = 0;
menuOn = 0;
addUnit(GCursorX, GCursorY, 3, 3);
break;
case 27: // ESC return
unitOn = 0;
break;
default:
break;
}
}
break;
case 51: // 3 remove unit
menuOn = 0;
removeUnit(GCursorX, GCursorY);
break;
case 48: // 0 exit
gameOn = 0;
menuOn = 0;
break;
default:
break;
}
}
default:
break;
}
}
return 0;
}
#include <conio.h>
#include <iostream>
#include <string>
#define WIDTH 45
#define HEIGHT 15
#define AREA WIDTH * HEIGHT
using namespace std;
struct SMapInfo
{
int tileType;
int unitType;
bool cursor;
};
SMapInfo GMap[WIDTH][HEIGHT];
class CUnit
{
int coordX, coordY; // coordinMainAtes
int HP; // HP
int wType; // weapon type: 1 = sword, 2 = axe, 3 = pike
public:
bool exists;
void addAtLoc(int x, int y, int iniHP, int iniWType) // Adds a unit at the location
{
coordX = x; // change coordinMainAtes
coordY = y;
wType = iniWType; // set weapon
HP = iniHP; // alive
GMap[coordX][coordY].unitType = wType; // add self to map
exists = 1; // now exists
}
bool isAtLoc(int x, int y) // Returns true if unit is at a location
{
if(x == coordX && y == coordY)
{
return 1;
}
else
{
return 0;
}
}
bool moveToLoc(int x, int y) // Returns true if unit is moved successfully
{
if(GMap[x][y].unitType == 0)
{
GMap[coordX][coordY].unitType = 0; // remove self from map
coordX = x; // change coordinMainAtes
coordY = y;
GMap[coordX][coordY].unitType = wType; // add self to map
return 1;
}
else
{
return 0;
}
}
void removeSelf() // Removes self.
{
GMap[coordX][coordY].unitType = 0; // remove self from map
exists = 0;
}
};
CUnit GUnitArray[AREA];
int GCursorX = 0;
int GCursorY = 0;
void resetGMap()
{
for(int y = 0; y < HEIGHT; y++)
{
for(int x = 0; x < WIDTH; x++)
{
GMap[x][y].tileType = 0;
GMap[x][y].unitType = 0;
GMap[x][y].cursor = 0;
}
}
}
void drawGMap()
{
for(int y = 0; y < HEIGHT; y++)
{
int xsum = 0;
for(int x = 0; x < WIDTH; x++)
{
xsum += GMap[x][y].unitType;
xsum += GMap[x][y].tileType;
xsum += GMap[x][y].cursor;
}
string emptyLine = "";
if(xsum == 0)
{
for(int i = 0; i < WIDTH; i++)
{
emptyLine += ".";
}
cout << emptyLine;
}
else
{
for(int x = 0; x < WIDTH; x++)
{
int xsum = 0;
if(GMap[x][y].cursor == 1) // draw cursor
{
cout << "*";
}
else if(GMap[x][y].unitType != 0) // draw unit
{
switch(GMap[x][y].unitType) // units
{
case 1: // swordsman
cout << "s";
break;
case 2: // axeman
cout << "a";
break;
case 3: // pikeman
cout << "p";
break;
default:
cout << "!";
break;
}
}
else
{
switch(GMap[x][y].tileType) // tiles
{
case 0: // open
cout << ".";
break;
case 1: // void
cout << " ";
break;
case 2: // high ground
cout << ":";
break;
default:
cout << "?";
break;
}
}
}
}
cout << endl;
}
}
string tileInfo(int T)
{
string tile;
switch (T)
{
case 0:
tile = "Ground";
break;
case 1:
tile = "Void";
break;
case 2:
tile = "High Ground";
break;
}
return tile;
}
string unitInfo(int U)
{
// 1 sword > 2 axe > 3 lance > 1 sword...
string unit;
switch (U)
{
case 0:
unit = "None";
break;
case 1:
unit = "Swordsman";
break;
case 2:
unit = "Axeman";
break;
case 3:
unit = "Pikeman";
break;
}
return unit;
}
void clrScrn()
{
system("CLS");
}
void placeCursor()
{
GMap[GCursorX][GCursorY].cursor = 1;
}
void removeCursor()
{
GMap[GCursorX][GCursorY].cursor = 0;
}
bool addUnit(int x, int y, int iniHP, int iniWType)
{
if(GMap[GCursorX][GCursorY].unitType == 0) // no unit presently occupies space
{
GMap[GCursorX][GCursorY].unitType = iniWType;
for(int i = 0; i < AREA; i++)
{
if(GUnitArray[i].exists != 1)
{
GUnitArray[i].addAtLoc(x, y, iniHP, iniWType);
}
}
return 1;
}
else
{
cout << "Failed to add unit." << endl;
system("PAUSE");
return 0;
}
}
bool removeUnit(int x, int y)
{
for(int i = 0; i < AREA; i++)
{
if(GUnitArray[i].exists == 1)
{
if(GUnitArray[i].isAtLoc(x, y) == 1)
{
GUnitArray[i].removeSelf();
cout << "Removed unit." << endl;
system("PAUSE");
return 1;
}
else
{
cout << "Failed to remove unit." << endl;
system("PAUSE");
return 0;
}
}
}
}
int main()
{
resetGMap();
int inMainA, inMainB;
bool gameOn = 1;
while(gameOn)
{
clrScrn();
placeCursor();
drawGMap();
cout << "Tile: " << tileInfo(GMap[GCursorX][GCursorY].tileType) << endl;
cout << "Unit: " << unitInfo(GMap[GCursorX][GCursorY].unitType) << endl;
cout << ">> ";
inMainA = getch();
cout << inMainA << endl; // return input
switch(inMainA)
{
case 224: // special key
inMainB = getch();
switch(inMainB)
{
case 72: // up
if (GCursorY > 0)
{
removeCursor();
GCursorY--;
}
break;
case 80: // down
if (GCursorY < HEIGHT - 1)
{
removeCursor();
GCursorY++;
}
break;
case 75: // left
if (GCursorX > 0)
{
removeCursor();
GCursorX--;
}
break;
case 77: // right
if (GCursorX < WIDTH - 1)
{
removeCursor();
GCursorX++;
}
break;
}
break;
case 27: // ESC menu
int inMenu;
bool menuOn;
menuOn = 1;
while(menuOn)
{
cout << "\n MENU" << endl;
cout << "ESC - Return" << endl;
cout << "1 - Place Tile" << endl;
cout << "2 - Place Unit" << endl;
cout << "3 - Remove Unit" << endl;
cout << "0 - Exit" << endl;
inMenu = getch();
switch(inMenu)
{
case 27: // ESC return
menuOn = 0;
break;
case 49: // 1 Tile Input
int inTile;
bool tileOn;
tileOn = 1;
while(tileOn)
{
cout << "\n TILE" << endl;
cout << "ESC - Return" << endl;
cout << "1 - Ground" << endl;
cout << "2 - Void" << endl;
cout << "3 - High Ground" << endl;
inTile = getch();
switch(inTile)
{
case 49: // 1 ground
tileOn = 0;
menuOn = 0;
GMap[GCursorX][GCursorY].tileType = 0;
break;
case 50: // 2 void
tileOn = 0;
menuOn = 0;
GMap[GCursorX][GCursorY].tileType = 1;
break;
case 51: // 3 high ground
tileOn = 0;
menuOn = 0;
GMap[GCursorX][GCursorY].tileType = 2;
break;
case 27: // ESC return
tileOn = 0;
break;
default:
break;
}
}
break;
case 50: // 2 Unit Input
int inUnit;
bool unitOn;
unitOn = 1;
while(unitOn)
{
cout << "\n UNIT" << endl;
cout << "ESC - Return" << endl;
cout << "1 - Swordsman" << endl;
cout << "2 - Axeman" << endl;
cout << "3 - Pikeman" << endl;
inUnit = getch();
switch(inUnit)
{
case 49: // 1 swordsman
unitOn = 0;
menuOn = 0;
addUnit(GCursorX, GCursorY, 3, 1);
break;
case 50: // 2 swordsman
unitOn = 0;
menuOn = 0;
addUnit(GCursorX, GCursorY, 3, 2);
break;
case 51: // 3 swordsman
unitOn = 0;
menuOn = 0;
addUnit(GCursorX, GCursorY, 3, 3);
break;
case 27: // ESC return
unitOn = 0;
break;
default:
break;
}
}
break;
case 51: // 3 remove unit
menuOn = 0;
removeUnit(GCursorX, GCursorY);
break;
case 48: // 0 exit
gameOn = 0;
menuOn = 0;
break;
default:
break;
}
}
default:
break;
}
}
return 0;
}