Sub Hunter game assignment, need help guys!!!

Hi everyone,

Thanks for taking the time to read my thread; I'm taking a C++ class in college and the last assignment for the semester is to write a sub hunter game that's worth 25% of my grade so needless to say I have to do a very good job on it. The due date is in less than 5 days so I hope I have enough time. This is what my professor wants:

Your final project is to create a game called Sub Hunter.

BOARD:
Is a 10 x 10 grid of cells

Destroyer:
Represented by the @ symbol
Has properties consisting of
Direction facing (N,S,E,W)
Depth charges - a count of remaining depth charges
Strength - How much damage it can take before sinking
Damage taken - how much damage it has taken from the sub

Has three action points to spend each round - to be input by the player
Possible Actions:

Move Forward - move one square in the direction facing
Turn Left - make a 90 degree turn to the left in the same square
Turn Right - make a 90 degree turn to the right in the same square
Ping - look for a sub. Ping allows the destroyer to "see" if the sub is within two squares of its current location. If the sub is within two squares, the destroyer only knows the direction from its position (not the distance)
Depth charge - drop a depth charge
Sub:
Represented by the ┴ symbol
Has properties consisting of
Direction facing (N,S,E,W)
Torpedos - a count of remaining torpedos
Strength - How much damage it can take before sinking
Damage taken - how much damage it has taken from the destroyer

Has two action points to spend each round - to be determined by the computer
Possible Actions:

Move Forward - move one square in the direction facing
Turn Left - make a 90 degree turn to the left in the same square
Turn Right - make a 90 degree turn to the right in the same square
Scope- look for a destroyer. Scope allows the sub to "see" if the destroyer is within two squares of its current location. If the destroyer is within two squares, the sub knows the direction and distance from its position
Torpedo - shoot a torpedo at the ship (only the direction it is facing)
Game Play:

The user inputs their actions as one turn (e.g. Forward, forward, ping).
The computer determines the subs actions (Scope, torpedo)
The program the runs the turns, sub first then destroyer based on the users actions and the computers actions and gives appropriate messages to the user based what happens.

When the destroyer runs out of depth charges it is considered to be sunk by the sub
If the sub runs out of torpedos, it can run away (head for the boarder of the map) if it successfully runs away the game is a draw

Depth charges - When dropped they explode in the square they are in causing full damage to that square and half damage to all the squares around it.

Torpedos - run straight in the direction the sub is facing for 2 squares. They hit for full damage if the sub is on that line within two square of the launch point - otherwise they miss.

You should determine damage - limits for the ships and amount caused by the weapons, that make the game playable.

Extra Credit ideas - implement more!

Levels to the game (Easy, Hard etc)
Directional pings - only work in one direction but give exact information
Launchable depth charges can go X squares away before exploding
Homing torpedos
Smarter sub tactics (run quiet ie. harder to find)
Depth to the grid (3d array, meaning you also need depth for the charges to explode, minimum depth for scoping etc etc)
Sound and more. Be creative.




And this is what I have so far, I've been reading a lot online about the battleship game which is similar and I have already created a 10x10 array that's gonna represent the game board; I also managed to place the destroyer and sub in the game board even though they're not really doing anything yet.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>

const int ROWS = 10; //rows for the board
const int COLS = 10; //Columns for the board

enum attackGrid { SEA_NOT_HIT, SEA_HIT, BOAT_HIT, BOAT_NOT_HIT, SUB_HIT,
                 SUB_NOT_HIT};

const char board[] = {'~', '`', '*', '@', '┴','x'};
//2D game board array.
attackGrid gameBoard[ROWS][COLS];

void displayBoard();
void placeShip();
void playerMove(char);
void attack(int , int);
bool gameOver();


using namespace std;

/*
 * 
 */
int main(int argc, char** argv)
{
    
    
    char input; 
    
    srand(time(0)); // random number generator
    
    do
    {
        placeShip();
        displayBoard();
       // playerMove();
    char moveOption;
    
    // Gets user input.
    cout << " Please select an option: \n";
    cout << " Enter A to attack your opponent: \n";
    cout << " Enter M to move the ship: \n";
    cout << " Enter P to ping the map for sub: \n";
    cout << " Enter D to drop depth charge: \n";
    cout << " Enter Q to quit. \n";
    cin >> moveOption;
    
    
        while(cin >> moveOption)
        {
            playerMove(moveOption);
            
            if (gameOver())
            {
                cout << "Victory is yours!!\n";
                break;
            }
        }
    cout << "Would you like to play another round? (y/n)";
    input = 'n';
    cin >> input;
    } while (input == 'y');
    
      return 0;
}

void placeShip()
{
    for (int x = 0; x < ROWS; x++)
    {
        for (int y = 0; y < COLS; y++)
        {
           gameBoard[x][y] = SEA_NOT_HIT;       
        }
    }
    //Places destroyer on the map.
    int xPoint = rand() % (ROWS - 1);
    int yPoint = rand() % (COLS - 5);
    
    gameBoard[xPoint][yPoint + 0] = BOAT_NOT_HIT;
    gameBoard[xPoint][yPoint + 1] = BOAT_NOT_HIT;
    gameBoard[xPoint][yPoint + 2] = BOAT_NOT_HIT;
    gameBoard[xPoint][yPoint + 3] = BOAT_NOT_HIT;
    
    //Places submarine on the map.
    int subXpoint = rand() % (ROWS - 1);
    int subYpoint = rand() % (COLS - 4);
    
    gameBoard[subXpoint][subYpoint+8] = SUB_NOT_HIT;
    gameBoard[subXpoint][subYpoint+9] = SUB_NOT_HIT;
    gameBoard[subXpoint][subYpoint+10] = SUB_NOT_HIT;
    
}


void displayBoard()
{
    
   cout << "welcome to the sub hunter game!!!\n\n";
   cout << "This is your game board.\n\n";
    
   cout << setw(2) << " ";
   
   for (int coord = 0; coord < ROWS; coord++)
   {
       cout << setw(2) << coord;
   }
    
   cout << endl;
   
   for (int x = 0; x < ROWS; x++)
   {
       cout << setw(2) << x;
       for (int y = 0; y < COLS; y++)
       {
           cout << " " << board[gameBoard[x][y]];
       }
       cout << endl;
   }
   cout << endl << endl;
}
void playerMove(char move)
{
    switch (move)
    {
        int xPt, yPt;
       
        case 'A': cin >> xPt;
                  cin >> yPt;
             
                  if(xPt >= 0 && xPt < ROWS)
                    {
                        cout << "Attacking now (" << xPt << "," << yPt <<")\n";
                        attack(xPt , yPt);
                    }
                  
                  else
                      {
                        cout <<" Please enter valid coordinates between 0 and" 
                                                               << ROWS-1 <<"\n";
                      }
       
            displayBoard();
            cout << "Please make your move:";
            break;
            
         case 'Q': cout << "Goodbye!! \n";
                   exit(0);
                   break;   
                  
              
       /* default:
            cout << "Wrong input" << move << endl;
            break;
       */
    }
    cin.get();
   
}

void attack(int xLoc, int yLoc)
{
    switch (gameBoard[xLoc][yLoc])
    {
        case SEA_NOT_HIT:
            gameBoard[xLoc][yLoc] = SEA_HIT;
            break;
            
        case BOAT_NOT_HIT:
            gameBoard[xLoc][yLoc] = BOAT_HIT;
    
    }

}

bool gameOver()
{
    for (int x = 0; x < ROWS; x++)
    {
        for (int y = 0; y < COLS; y++)
        {
            if(gameBoard[x][y] == BOAT_NOT_HIT)
            {
                return false;
            }
        }

    }
}


I've been working on this for about 8 hours straight today and I'm very frustrated because I'm not sure how to do everything the professor wants me to do on this assignment. Any help, ideas, constructive criticism would be greatly appreciated , I'm starting to get desperate because I cannot afford to fail this class.

Thanks in advance,

Alex

I would strongly recommend restructuring your program to be object oriented. You could reuse a lot of your code by plugging it into the correct places.

I'll get you started:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const int BOARD_LENGTH = 10;

class Ship;

class Board
{
	Ship*** buf; //2d array of ship pointers
public:
	//I'm not 100% sure this constructor is correct; check it yourself
	Board()
	: buf(new Ship*[10])
	{
		for(int i = 0; i < BOARD_LENGTH; ++i)
		{
			buf[i] = new Ship[BOARD_LENGTH];
		}
	}

	~Board()
	{
		//...
	}

	//these functions could be replaced with operator overloading if you want
	Ship* getTile(int x, int y)
	{
		if(x < 0 || y < 0 || x >= BOARD_LENGTH || y >= BOARD_LENGTH)
			return NULL;
		return buf[x][y];
	}

	void setTile(int x, int y, Ship* ship)
	{
		if(x < 0 || y < 0 || x >= BOARD_LENGTH || y >= BOARD_LENGTH)
			throw 0; //you could replace this with a real exception
		buf[x][y] = ship;
	}
};

enum AttackType{ /* list each type of attack (torpedo, depth charge, etc.) */ };

//base class with all the behaviors of ships
class Ship
{
public:
	Ship();
	virtual ~Ship();

	virtual void attack(AttackType type);
	virtual void turnLeft();
	virtual void turnRight();
	virtual void move();
	virtual void search(); //ping and scope
	//any other behaviors I missed
};

class Destroyer
{

//needed so the destroyer can move itself in the board
Board* board;

//data members such as torpedos remaining
//you may or may not want to store its position here, as it is already implicitly stored in the Board

public:
	Destroyer(Board*);
	~Destroyer();

	//implement the Destroyer version of all the Ship functions
};

class Submarine
{
//same as Destroyer, but with the submarine versions of the Ship functions
};

int main()
{
	int destroyerX = /*...*/;
	int destroyerY = /*...*/;
	int submarineX = /*...*/;
	int submarineY = /*...*/;

	Board board;
	board.setTile(destroyerX, destroyerY, new Destroyer(&board));
	board.setTile(submarineX, submarineY, new Submarine(&board));

	//game loop
	while(true)
	{
		//ask the player for a move and do it by calling the appropriate Destroyer function
		//for example, board.getTile(x, y)->move();

		if(/* submarine is dead */) break;

		//make a move for the computer and call the Submarine function

		if(/* destroyer is dead or submarine left */) break;
	}

	//post-game stuff like announcing the winner
}


By structuring a ship's behaviors in this way, the program becomes a lot easier to manage. I probably missed quite a bit, and I haven't tried compiling any of this, so you're on your own from here. You could also make this a bit cleaner by separating it into multiple files.
I agree with Telion.

I think you should implement some OOP in your code... Does this project have to be done in a console? If not, I think you should make your game using SFML or SDL... it would be a whole lot better in terms of graphics, and maybe, game-play.
Last edited on
@Telion, thanks a lot man. The code I posted was full of errors; so last night I went to bed at 2 am correcting some mistakes but you just helped me figure out one of the areas I was stuck in. I'm gonna mix your code with what I have done so far and hopefully between today and tomorrow I should get it done; you just saved me at least a day of work.

@Code Assassin, this one is supposed to be run on a console so no graphics necessary thanks god. I have my hands full without graphics so adding graphics libs and all that would make it even more difficult. Keep in mind that even though I have worked with switches, loops, arrays, structures and functions on previous assignments this semester; I have only worked on less complicated programs like calculators, record keeping programs but never on games. To make things worse this is an online class, so access to the professor and classmates for ideas is rather limited.

But once again thank you guys for taking the time to look over my code and help me figure this out, it means a lot to me.
Can I do structures instead of classes? We haven't worked with class yet, I'm going over it on the book right now because even though class seems easier to use and more organized; I haven't really used them.
You can use either one, but I think classes would be better for what you're doing. It's really up to you.
I also emailed my professor to ask him if I could use classes even though we didn't really covered it this semester and he said that he would rather not have me use them but if I did I would have to go to his office and explain every bit of code and maybe even write some in front of him to prove it was my work; because apparently some people have been caught cheating recently. So it looks like the only easy way with this guy is the hard way, I'm gonna have to go back to the arrays, loops, and about a million if/else statements and switches in order to get this done. Frustrating to say the least.
Lol, good luck.
Topic archived. No new replies allowed.