Battleships Computer science project Loop problem

As the title says, I am making a battleships game for my computing science poject at A level.

I've been having some trouble with a loop, as for some reason when the code runs through, if the bool IntChecker is false, the code just coninuously outputs "Please enter a number between 0 and 9" indefinitely.

This section of code, I use to take an input to use in other subroutines for placing the ships in the game.

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
void Getshipcoord(int &Xshipcoord, int &Yshipcoord)
{
	
		cout << "Please enter the X and Y coordinates of the back of the ship." << endl;
		while(IntCheck == false)
		{
			cout << "X: ";
			cin >> Xshipcoord;
			if(!cin.good())
			{
				IntCheck = false;
				cout << "Please enter a number between 0 and 9" << endl;
				cin >> Xshipcoord;
			}
			else
			{
				IntCheck = true;
			}
		}
		while(IntCheck == false)
		{
			cout << endl << "Y: ";
			cin >> Yshipcoord;
			if(!cin.good())
			{
				IntCheck = false;
				cout << "Please enter a number between 0 and 9" << endl;
				cin >> Yshipcoord;
			}
			else
			{
				IntCheck = true;
			}
		}
}


If the input stream fails you must first clear() the error flags, then clear the input buffer before you try to retrieve your new entry.

And how would i do that? like... cin.clear()? sorry, ive never had this problem before and only with searching the net, i found how to check cin with the cin.good() bit....

Thank you for the quick reply!
The first step would be to find the documentation for cin which is an istream. Here is a good starting point:
http://www.cplusplus.com/reference/istream/istream/

To clear the error flags you need to use the clear() method function. Then to clear the input buffer you can use the ignore() member function with the optional parameters, the number of characters to ignore and the delimiting character '\n'.

http://www.cplusplus.com/reference/ios/ios/clear/
http://www.cplusplus.com/reference/istream/istream/ignore/
Again, thank you for the super quick reply! will look over now! thank you very much! :)

here is the updated version i have so far**

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
void Getshipcoord(int &Xshipcoord, int &Yshipcoord)
{
	
	while(IntCheck == false)
	{
		cout << "X: ";
		cin >> Xshipcoord;
		if(cin.fail())
		{
			cin.clear();
			cin.ignore();
			cout << "Please enter a valid numer (0 to 9)" << endl;
			IntCheck = false;
		}
		else
		{
			cout << "Y: ";
			cin >> Yshipcoord;
			if(cin.fail())
			{
				cin.clear();
				cin.ignore();
				cout << cout << "Please enter a valid numer (0 to 9)" << endl;
				IntCheck = false;
			}
			else
			{
				IntCheck = true;
			}
		}
		
	}
}
Last edited on
Ok, so i have reached a point where by the GetShipCoord function is working fine an dandy, however in fixing it ive created YET ANOTHER problem!

This section of code here is just 1 of the 4 cases used, however they are almost identical anyway..


The issue I am now having is that when it calls the GetShipCoord, it works fine first time around, however if any invalid input is given, the GetShipCoord (line 19) function is either... skipped... or idk, it doesnt re run the function when called, and just skips it, continuing with the rest of the code...

See above for the updated GetShipCoord.

If you would like the full shipplacement function let me know, but as i said, either case is pretty much the same as the one before.

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
int shipplacement(int &Xshipcoord, int &Yshipcoord)//Algorithm 5
{
	int undo=1;
	int a=4;
    ShipsToPlace=5;
    NotValid=false;
    char direction;
    while(ShipsToPlace !=0)
    {
		Getshipcoord(Xcoord, Ycoord);     
		if(!NotValid)
		{
		--ShipsToPlace;
		Displayshipboard(shipboard);
		}
		NotValid=false;
		undo=0;
		cout << "You have " << ShipsToPlace+1 << " Ships to place." << endl; 
		Getshipcoord(Xcoord, Ycoord);     
		cout << "Which direction would you like your ship to point?" << endl;
			cout << "Up (U), Down (D), Left (L) or Right (R)." << endl;
            cin >> direction;
        
            switch (direction)
            {
                case 'L':
                {
					cout << "You chose to point your ship Left" << endl;
					    for(a=4; a!=0; a--)
						{
							++undo;
							
							while (shipboard[Xcoord][Ycoord] =='s')
							{
								cout << "You cannot place a ship here as a ship is already in this location: " << Xcoord << ", " << Ycoord << endl;
								--undo;
								NotValid=true;
								break;
							}	
							while(Xcoord<0 || Ycoord<0)
							{
									cout << "Your ship must be within the borders of the battle zone. Ships are 4 coordinates long. " << Xcoord << ", " << Ycoord <<  endl;
									NotValid=true;
									break;
							}	
							while(Xcoord>=10 || Ycoord>=10)
							{
									cout << "Your ship must be within the borders of the battle zone. Ships are 4 coordinates long. " << Xcoord << ", " << Ycoord <<  endl;
									NotValid=true;
									break;
							}
								
							if(!NotValid)
							{
								shipboard[Xcoord][Ycoord]='s';
								--Xcoord;
								cout << "Xcoord: " << Xcoord << " a: " << a << endl;
							}
							else
							{
								while(undo!=0)
								{
									++Xcoord;
									
									shipboard[Xcoord][Ycoord]=' ';
									cout << "Xcoord: " << Xcoord << " Undo: "  << undo << endl;
									--undo;
								}
							}
						}
						
                    break;
                }




Also sorry about the line spacing, it looks neater on my Visual studio, for some reason loads of spaces were added...
Last edited on
Part of the problem is this snippet:
1
2
3
4
5
6
7
		if(cin.fail())
		{
			cin.clear();
			cin.ignore();
			cout << "Please enter a valid numer (0 to 9)" << endl;
			IntCheck = false;
		}

Your ignore must totally clear the input buffer, your code only ignores 1 character. Normally you would use something like

std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
To use this method you need to include the <limits> header to use the numeric_limits class. This will ignore all the characters in the input buffer until it either reaches the end of the buffer or finds a new line character.

Topic archived. No new replies allowed.