Help in Battleship game

I don't know what I am doing wrong. I can't make the ships to be displayed. Any suggestions please? And also after I choose the coordinates the first elements from the one-sized arrays coordinate_1 and coordinate_2 changes. I need this as quick and possible, please.
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
void createBoardH(int height, int width)
 {
 	 for(int i=0; i<width; ++i)
	 {
	   for(int j=0; j<height; ++j)
	   {
              boardH[i][j] = cell;
       }
	 }
  }
void showBoardH()//original board
 {
	     cout <<"   ";
	     showwcoord();
			 for(int i=0;i<width; i++)
			 {
			 cout<<coordinate_2[i]<<"  ";
 	         for(int j=0; j<height; j++)
				 {
				 
                 cout<< boardC[i][j]<<" ";
	           }
			 cout<<endl;
			 }
 }
void ManualPlace(int x, int y, int Ship, int ShipOrientation)
  {
	 if (placementfinished())
	 {
		 game();
	 }
	 int i = 0;
	 int j = 0;
	 char cell1 = cell;
    cout << "Choose your first coordinate from where you want your ship to start:" <<endl;
    cin >> coordinate_1[i];
       switch (coordinate_1[i])
	   {
	    case 'A':
			x = 1;
			showBoardH();
			break;
		case 'B':
			x = 2;
			showBoardH();
			break;
		case 'C':
			x = 3;
			showBoardH();
			break;
		case 'D':
			x = 4;
			showBoardH();
			break;
		case 'E':
			x = 5;
			showBoardH();
			break;
		case 'F':
			x = 6;
			showBoardH();
			break;
		case 'G':
			x = 7;
			showBoardH();
			break;
		case 'H':
			x = 8;
			showBoardH();
			break;
		case 'I':
			x = 9;
			showBoardH();
			break;
		case 'J':
			x = 10;
			showBoardH();
			break;
		default:
			cout<<"coordinate error, try again!"<<endl;
			ManualPlace(x,y,Ship, ShipOrientation);
			break;
	   }
    cout << "Choose your second coordinate from where you want your ship to start:" <<endl;
    cin >> coordinate_2[j];
	  switch(coordinate_2[j])
	  {
		  case 1:
			  y = 1;
			  showBoardH();
			  break;
		  case 2:
			  y = 2;
			  showBoardH();
			  break;
			case 3:
			  y = 3;
			  showBoardH();
			  break;
			case 4:
			  y = 4;
			  showBoardH();
			  break;
			case 5:
			  y = 5;
			  showBoardH();
			  break;
			case 6:
			  y = 6;
			  showBoardH();
			  break;
			case 7:
			  y = 7;
			  showBoardH();
			  break;
			case 8:
			  y = 8;
			  showBoardH();
			  break;
			case 9:
			  y = 9;
			  showBoardH();
			  break;
			case 0:
			  y = 10;
			  showBoardH();
			  break;
			default:
               cout <<"coordinate error, try again" <<endl;
               ManualPlace(x,y,Ship, ShipOrientation);
	  }
    cout << "Choose your ship type (one of the above) :" <<endl;
    cout << "1- aircraft carrier"<<endl;
    cout << "2- battleship"<<endl;
    cout << "3- cruiser"<<endl;
    cout << "4- submarine"<<endl<<endl<<endl;
    cin >> Ship;
	numberofA = 0;
	numberofB = 0;
	numberofC = 0;
	numberofS = 0;

       switch (Ship)
   {
      case 1:
          ShipType = 'A';
          ShipSize = 5;
          numberofA ++;//number of aircrafts on board
          cell1 = 'A';
          break;
       case 2:
          ShipType = 'B';
          ShipSize = 4;
          numberofB ++;//number of the battleships on board
          cell1 = 'B';
          break;
	   case 3:
          ShipType = 'C';
          ShipSize = 3;
          numberofC ++;//number of cruisers on board
          cell1 = 'C';
          break;
	   case 4:
          ShipType = 'S';
          ShipSize = 2;
          numberofS ++;//number of submarines on board
          cell1 = 'S';
          break;
	    default:        // mistypes by the user
           cout << "Error in chosen option" <<endl;
           cout << "Check your chooose and try again" <<endl;
           ManualPlace(x,y,Ship, ShipOrientation);
		   break;
   }

      cout << "Choose your ship orientation from the options above:" <<endl;
      cout <<"1- right" <<endl;
      cout <<"2- left "<<endl;
      cout <<"3- up "<<endl;
      cout <<"4- down "<<endl<<endl<<endl;
      cin >> ShipOrientation;
      numberofships = 0;
      switch (ShipOrientation)
	  {
          case 1:
			            putshipright(x,y,Ship,ShipOrientation);
			            showBoardH();
                        numberofships ++;
                        cout <<"You still have ships to place..." ;
						ManualPlace(x,y,Ship, ShipOrientation);
						cout <<endl;
                        break;
          case 2:
			            putshipleft(x,y,Ship,ShipOrientation);
                        showBoardH();
                        numberofships ++;
                        cout <<"You still have ships to place..." <<endl;
						ManualPlace(x,y,Ship, ShipOrientation);
				        break;
		  case 3:
			            putshipup(x,y,Ship,ShipOrientation);
                        showBoardH();
                        numberofships ++;
                        cout <<"You still have ships to place..." <<endl;
						ManualPlace(x,y,Ship, ShipOrientation);
				        break;
          case 4:
			            putshipdown(x,y,Ship,ShipOrientation);
                        showBoardH();
                        numberofships ++;
                        cout <<"You still have ships to place..." <<endl;
						ManualPlace(x,y,Ship, ShipOrientation);
				        break;
                
          default ://misstyping by user
             cout <<"Errors in typing the orientation" <<endl;
             cout <<"Check spelling and try again" <<endl<<endl;
			 ManualPlace(x,y,ShipType, ShipOrientation);
			 break;
        }
bool placementfinished()
{
	numberofships = numberofA + numberofB + numberofC + numberofS;
	bool fin = true;
	if (numberofships = 6)
	{
		fin = true;
	}
	else 
	{
		fin = false;
	}
	if (fin)
	{
		 return true;
	}
	else 
	{
		return false;
	}

}
void putshipright(int x, int y, int Ship, int Shiporientation)
{
	int i = 0;
	for (i = 0;i < ShipSize;i++)
	{
		boardH[x+i][y]= 'A';
	}
}
void putshipleft(int x, int y, int Ship, int Shiporientation)
{
	int i = 0;
	for (i = 0;i < ShipSize;i++)
	{
		boardH[x-i][y]= cell1;
	}
}
void putshipup(int x, int y, int Ship, int Shiporientation)
{
	int j = 0;
	for (j = 0;j < ShipSize;j++)
	{
		boardH[x][y-j]= cell1;
	}
}
void putshipdown(int x, int y, int Ship, int Shiporientation)
{
	int j = 0;
	for (j = 0;j < ShipSize;j++)
	{
		boardH[x][y+j]= cell1;
	}
}
	  }
Hmm. For consistency shouldn't you rather do:
1
2
3
4
5
6
7
8
9
10
void createBoardH(int height, int width)
{
    for(int i=0; i<width; i++)
    {
        for(int j=0; j<height; j++)
        {
              boardH[i][j] = cell;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bool placementfinished()
{
	numberofships = numberofA + numberofB + numberofC + numberofS;
	bool fin = true;
	if (numberofships = 6)
	{
		fin = true;
	}
	else 
	{
		fin = false;
	}
	if (fin)
	{
		 return true;
	}
	else 
	{
		return false;
	}

}


This is a horribly inefficient function. Rather do something like this:
1
2
3
4
5
6
7
8
bool placementfinished()
{
	numberofships = numberofA + numberofB + numberofC + numberofS;
        if(numberofships == 6)
            return true;
        else
            return false;
}
Also, I don't think the OP realises/understands how to return values properly.

That function should return a bool. You have a bool called fin. This means you can return fin. So checking if it is true/false is pointless anyway.
OP? I also see you are using recursion to setup your board. I think you should add an 'else' after your if (placementfinished()) otherwise you going to finish you game and redo another one.


Last edited on
@GodPyro I'll try that. but the main problem is that I can't change the cells in the array to get an 'A' or 'B' value (the values for the ships A for aircrafts and so on). placementfinished() is the function that will stop the repetitions.
@vladootz69 where do you declare boardH ? Is it in the same scope as these functions?

This is a logic error because it will output "You still have ships to place..." even though it will hit the recursion and placementfinished() will return true. This will mislead the user.
1
2
3
4
showBoardH();
numberofships ++;
cout <<"You still have ships to place..." <<endl;
ManualPlace(x,y,Ship, ShipOrientation);


Rather remove the cout and move the ManualPlace to after the switch statement. This is all encapsulated in the else after the placementfinished() call.

Also what is the point of numberofships in:
1
2
3
4
5
6
7
8
9
10
numberofships = 0;
      switch (ShipOrientation)
	  {
          case 1:
			            putshipright(x,y,Ship,ShipOrientation);
			            showBoardH();
                        numberofships ++;
                        cout <<"You still have ships to place..." ;
						ManualPlace(x,y,Ship, ShipOrientation);
						cout <<endl;


when you are setting it in placementFinished()
numberofships = numberofA + numberofB + numberofC + numberofS;
Last edited on
Lines 81, 132 and 172 are your problem.
ManualPlace(x,y,Ship, ShipOrientation);

Remove this so you can continue to place that specific recursion call's ship in the array.
Last edited on
coordinate_1 and coordinate_2 should just be x and y. I also don't know why you are passing those parameters (x, y, Ship, ShipOrientation) in the recursion call.
ManualPlace(x,y,Ship, ShipOrientation);

The only thing you need to worry about is boardH being modified to cater for the changes you are making to it.

Line 21:
cout<< boardC[i][j]
What is boardC ? Surely that should be boardH from showBoardH()
Last edited on
showBoardH is supposed to display the 10 by 10 array. and x and y it should take the values from coordinate_1 and 2 as inputs from the user.
//yea but I tried to make coordinate_1[10] as an array that holds a,b, c and so on...when the user inputs a the x it would take the value 1. this is what i was trying to do
Last edited on
Oh. I get it. I didn't see the default in the switch. But at the same time I don't think its a good idea to call another recursion step here because if you make a mistake in y you have to reenter x again etc.
Last edited on
I removed the recursion calls, but still nothing happen with the board. It does not put the ships on the board. I'm out of ideas right now
Line 34 is your problem:
char cell1 = cell;

You are trying to access this variable which doesn't exist in the scope of putshipright(), putshipleft(), putshipup() and putshipdown();

Declare cell1 as a global variable i.e. outside of your functions in the body of your program.
Last edited on
I had some time so decided to rehash your work:

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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
// Variables
int numberofA = 0;
int numberofB = 0;
int numberofC = 0;
int numberofS = 0;
int ShipSize;
char ShipType;
int numberofships = 0;
const int height = 10;
const int width = 10;
char boardH[height][width];
char emptyCell = 'x';
char cell1;
char coordinate_1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',};
int x, y, Ship, ShipOrientation;

void createBoardH()
{
    for(int i=0; i < width; ++i)
    {
        for(int j=0; j < height; ++j)
	{
	    boardH[i][j] = emptyCell;
        }
    }
}
void showBoardH()//original board
{	
    //showwcoord();
    cout << "   1 2 3 4 5 6 7 8 9 10" << endl;
    for(int i=0; i < height; i++)
    {
	cout<< coordinate_1[i] << "  ";
 	for(int j=0; j < width; j++)
	{
		cout<< boardH[i][j] <<" ";
	}
	cout<<endl;
    }
    cout << endl;
}
bool placementfinished()
{
	numberofships = numberofA + numberofB + numberofC + numberofS;

	if (numberofships == 6)
	{
		return true;
	}
	else 
	{
		return false;
	}
}
void putshipright(int x, int y)
{
	for (int i = 0;i < ShipSize;i++)
	{
		if((x+i) < width)
			boardH[y][x+i]= cell1;
		else
			break;
	}
}
void putshipleft(int x, int y)
{
	for (int i = 0;i < ShipSize;i++)
	{
		if((x-i) >= 0)
			boardH[y][x-i]= cell1;
		else
			break;
	}
}
void putshipup(int x, int y)
{
	for (int j = 0; j < ShipSize; j++)
	{
		if((y-j) >= 0)
			boardH[y-j][x]= cell1;
		else
			break;
	}
}
void putshipdown(int x, int y)
{
	for (int j = 0;j < ShipSize;j++)
	{
		if((y+j) < height)
			boardH[y+j][x]= cell1;
		else
			break;
	}
}
void ManualPlace()
{
    if (placementfinished())
    {
	 cout << "No on second thought you don't have ships to place. :P" << endl;
	 cout << "PLAY GAME!" << endl;
    }
    else 
    {
    x = 0;	
    while(x <= 0 || x > 10)
    {
	cout << "Choose your first coordinate from where you want your ship to start:" <<endl;
	cin >> x;
	if(x <= 0 || x > 10)
	{			
		cout << "coordinate error, try again!" << endl;
	}
    }
    // Decrement x by 1 because array is from 0-9 and user entered range 1-10
    x--;

    y = 0;
    while(y <= 0 || y > 10)
    {
        cout << "Choose your second coordinate from where you want your ship to start: "<<endl;
	cin >> y;
	if(y <= 0 || y > 10)
	{			
		cout << "coordinate error, try again!" << endl;
	}
    }
    // Decrement y by 1 because array is from 0-9 and user entered range 1-10
    y--;

    Ship = 0;
    while(Ship <= 0 || Ship > 4)
    {
	cout << "Choose your ship type (one of the above) :" <<endl;
	cout << "1- aircraft carrier"<<endl;
	cout << "2- battleship"<<endl;
	cout << "3- cruiser"<<endl;
	cout << "4- submarine"<<endl<<endl<<endl;
	cin >> Ship;
	
	switch (Ship)
	{
	    case 1:
		  ShipType = 'A';
		  ShipSize = 5;
		  numberofA ++;//number of aircrafts on board
		  cell1 = 'A';
		  break;
	   case 2:
		  ShipType = 'B';
		  ShipSize = 4;
		  numberofB ++;//number of the battleships on board
		  cell1 = 'B';
		  break;
	   case 3:
		  ShipType = 'C';
		  ShipSize = 3;
		  numberofC ++;//number of cruisers on board
		  cell1 = 'C';
		  break;
	   case 4:
		  ShipType = 'S';
		  ShipSize = 2;
		  numberofS ++;//number of submarines on board
		  cell1 = 'S';
		  break;
	default:        // mistypes by the user
		   cout << "Error in chosen option" <<endl;
		   cout << "Check your chooose and try again" <<endl;
		   break;
	}
    }

    ShipOrientation = 0;
    while(ShipOrientation <= 0 || ShipOrientation > 4 )
    {
          cout << "Choose your ship orientation from the options above:" <<endl;
          cout <<"1- right" <<endl;
          cout <<"2- left "<<endl;
          cout <<"3- up "<<endl;
          cout <<"4- down "<<endl<<endl<<endl;
          cin >> ShipOrientation;
          switch (ShipOrientation)
	  {
              case 1:
	           putshipright(x,y);
   	           showBoardH();
                   cout <<"You still have ships to place..." <<endl;
	  	   ManualPlace();
                   break;
             case 2:
		   putshipleft(x,y);
                   showBoardH();
                   cout <<"You still have ships to place..." <<endl;
		   ManualPlace();
		   break;
	    case 3:
		   putshipup(x,y);
                   showBoardH();
                   cout <<"You still have ships to place..." <<endl;
		   ManualPlace();
		   break;
            case 4:
		   putshipdown(x,y);
                   showBoardH();
                   cout <<"You still have ships to place..." <<endl;
		   ManualPlace();
		   break;
                
          default ://misstyping by user
                   cout <<"Errors in typing the orientation" <<endl;
                   cout <<"Check spelling and try again" <<endl<<endl;
	           break;
        }
    }
    }
}
Last edited on
Hope this work...I'll try it and come back with feedback. thankyou
//
After this...
1
2
cout << "No on second thought you don't have ships to place. :P" << endl;
	 cout << "PLAY GAME!" << endl;
can I put like the call of a function playgame();?
at this point after those two couts it run again the placement of ships.
and one more problem. for me it would be ideal to place 1 A, 1B, 2 C's, and 2 S's. I'll try to create some bool functions to limit the number of ships to those numbers.
////
And also if you input one wrong coordinate it repeat the cout <<"coordinate error" forever. I think there could be placed a recursive call to ManualPlace().
Last edited on
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
bool up(int ShipSize,int x, int y )
{
	bool ok = true;
	int j;
	if (y - ShipSize<1) 
	{
		ok = false;
	}
	else 
	{
		for (j = 0; j <= y- ShipSize+1;j++)
		 {
			if (boardH[x][y-j] = 'A') 
			{
				if (boardH[x][y-j] = 'B')
				{
					if (boardH[x][y-j] = 'C')
					{
						if (boardH[x][y-j] = 'S')
						{
							ok = false;
						}
						ok = false;
					}
					ok = false;
				}
				ok = false;
			}
		 }
	if (ok) 
	{
		return true;
	}
	else 
	{
		return false; 
	}
	}

}

Is this piece of code ok to check if you can place your ships up?
You can replace the couts with a function call. The reason why I put those there is because of the fact that I didn't have your game() function.

I made a mistake in my code and should of placed an else statement after the conditional and the beginning of ManualPlace(). I've fixed my code above.

DO NOT place recursive calls to ManualPlace() the way it has been written. The reason for this is that if you make a mistake in one of the inputs you will have to repeat the entire process. This will become quite aggravating for the user. The way I have written it is correct. While the user has not input the correct input it will prompt him to place input. This is true for all inputs i.e. if you put wrong coordinate for x it will prompt you to input x again. If you put wrong coordinate for y it will prompt you to input y again.

I see your code above is trying to check to see if the space that you want to place your ship is not occupied. This is correct logic but your execution and naming is slightly incorrect. You do need to have a boolean ok you can just use a return e.g.

1
2
3
4
if (boardH[x][y-j] == 'S')
{
    return false;
}


Also extend the function. Instead of just checking for up, check for all orientations. Another thing is that you don't need to make checks for every ship type i.e. have 4 conditionals (if statements) you can just have one that checks to see if the space is unoccupied:

1
2
3
4
if(boardH[y-j][x] != 'x')
{
    return false;
}


I've rewritten your function to include ShipOrientation checks.

Note: This is the last time I am rehashing your work because I feel like I'm doing the work for you.

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
bool isLegalPosition(int x, int y, int ShipSize, int ShipOrientation )
{
    switch(ShipOrientation)
    {
        // To the Right
        case 1:
            if(x+ShipSize >= width)
                return false;
            for(int i = 0; i < ShipSize; i++)
            {
                if(boardH[y][x+i] != 'x')
                    return false;
            }
        break;

        // To the Left
        case 2:
            if(x-ShipSize < 0 )
                return false;
            for(int i = 0; i < ShipSize; i++)
            {
                if(boardH[y][x-i] != 'x')
                    return false;
            }
        break;

        // Going Up
        case 3:
            if(y+ShipSize >= height )
                return false;
            for(int i = 0; i < ShipSize; i++)
            {
                if(boardH[y+i][x] != 'x')
                    return false;
            }
        break;

        // Goin Down
        case 4:
            if(y-ShipSize < 0 )
                return false;
            for(int i = 0; i < ShipSize; i++)
            {
                if(boardH[y-i][x] != 'x')
                    return false;
            }
        break;
    }
    // Everything has checked out and the position is legal
    return true;
}
Last edited on
Thank you very much for everything. For now, everything seems to work fine.
//I've rewritten on my own before you posted on one of my infinite triesand apparently it work fine. It looks like this....
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
bool up(int ShipSize,int x, int y )
{
	bool ok = true;
	int j;
	if (y - ShipSize < 1) 
	{
		ok = false;
	}
	else 
	{
		for (j = 0; j <= y- ShipSize+1;j++)
		 {
			 switch (boardH[x][y-j])
			 {
			 case 'A':
				 ok = false;
			     break;
			 case 'B':
				 ok = false;
				 break;
			 case 'C':
				  ok = false;
				  break;
			 case 'S':
				 ok = false;
				 break;
			 }
		}
	}
	if (ok){return true;}
	else{return false;}
}

Last edited on
You're welcome. :) Thats what we are here for.

Your code above is better but there is no reason why you have to create a boolean 'ok'. You can just use the 'return' command in its place because you don't want to waste time by going through the remaining iterations when you know already that a position is currently occupied. You want to exit out of the function and carry on with your program which is more efficient.
Topic archived. No new replies allowed.