13 Replies - 2302 Views - Last Post: 17 March 2013 - 08:03 PM Rate Topic: -----

#1 sports09  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 26-February 13

Battleship game question.

Posted 26 February 2013 - 12:45 PM

Hello, I am a beginner in C++ programming. I am have a problem with a Battleship game I have to do for a project. My code is below and I have to do is enhance the game to reject spots that have already been used. My question is how do I do that?
#ifndef __PROJECT1_H_
#define __PROJECT1_H_


#include <iostream>
#include <iomanip>
#include <string>
#include <ctime>    // For time()
#include <cstdlib>  // For srand() and rand()



#endif


using namespace std;

//========================================= global declarations
// Damage enum defines possible values at each grid point.
enum Damage {WATER_UNBOMBED, WATER_BOMBED, 
             SHIP_UNBOMBED , SHIP_BOMBED};

// The display array defines what to display for
//     each of the Damage enum values.  Changes to the
//     Damage enum require this to be changed also.
const char display[] = {'-', 'O', '-', 'X'};

const  int WIDTH = 5;   // Width of the grid.
const  int HEIGHT= 5;
Damage grid[WIDTH][HEIGHT];      // Records status of every grid cell.

//================================================== prototypes
void dropBomb(int xcoord, int ycoord);
void executeCommand(char cmd);
void initGrid();
bool isGameOver();
void print();
//bool oldGuess();


//======================================================== main
int main() {

    srand(time(0));  // Initialize random number generator
    
    char ans;
    do {
        initGrid();  // Randomly place ships on the grid.
        print();

		cout << "Please enter your orders sir: ";
        
        char commandCode;
        while (cin >> commandCode) {
        
            executeCommand(commandCode);
            
            if (isGameOver()) {
                cout << "Congratuations, you win" << endl;
                break;
            }
        }
        cout << "Do you want to play again? (y/n) ";
        ans = 'n';
        cin >> ans;
    } while (ans == 'y');
    
    return 0;
}//end main

//======================================================= executeCommand
void executeCommand(char cmd) {
    switch (cmd) {
        
        case 'q':           // quit
		    cout << "Yes sir, now quitting. It's been an honour sir." << endl;
            exit(0);
            break;
            
        case 'b':           // bomb
            int xloc, yloc;
            cin >> xloc;
			cin >> yloc;
            if (xloc>=0 && xloc<WIDTH){
				if(yloc >= 0 && yloc < HEIGHT){
				    cout << "Yes sir. Dropping ordinance at (x,y):(/>" << xloc << "," << yloc << ")" << endl;
					dropBomb(xloc, yloc);
				}else{
                  cout << "Error: Y Bombing coordinate must be between 0 and " << HEIGHT-1 << endl;
				}
            } else {
                cout << "Error: X Bombing coordinate must be between 0 and " << WIDTH-1 << endl;
            }
            print();
			cout << "Please enter your orders sir: ";
            break;
            
        default:            // error
            cerr << "Bad input " << cmd << endl;
            break;
    }
}

//======================================================= dropBomb
void dropBomb(int xcoord, int ycoord) {
    switch (grid[xcoord][ycoord])
	{
    
    case WATER_UNBOMBED: 
          grid[xcoord][ycoord] = WATER_BOMBED;
          break;
          
    case SHIP_UNBOMBED: 
          grid[xcoord][ycoord] = SHIP_BOMBED;
          break;
    }
    return;
}

//======================================================= initGrid
// initGrid() places random ships on the grid.
void initGrid() {
    for (int i=0; i<WIDTH; i++) {  // clear grid
		for(int j = 0; j < HEIGHT; j++){
			grid[i][j] = WATER_UNBOMBED;
		}
    }

	
    int startx = rand() % (WIDTH-2); // Place a 3-cell ship in grid.
	int starty = rand() % (HEIGHT-2);
    grid[startx+0][starty+0] = SHIP_UNBOMBED;
    grid[startx+1][starty+1] = SHIP_UNBOMBED;
    grid[startx+2][starty+2] = SHIP_UNBOMBED;
}

//========================================================== print
void print() {
    cout << endl;

	cout << setw(2) << " ";
    
    //-- Print coordinates.
    for (int coord=0; coord<WIDTH; coord++) {
        cout << setw(2) << coord;
    }

	cout << endl;

    for (int i=0; i<WIDTH; i++) {
	    cout << setw(2) << i;
		for(int j = 0; j < HEIGHT; j++){
			cout << " " << display[grid[i][j]];
		}
		cout << endl;
    }
    
    cout << endl << endl;
}

//====================================================== isGameOver
bool isGameOver() {
    for (int i=0; i<WIDTH; i++) {
		for(int j = 0; j < HEIGHT; j++){
			if (grid[i][j] == SHIP_UNBOMBED) {
				return false;
			}
        }
    }
    return true;
}


Is This A Good Question/Topic? 0
  • +

Replies To: Battleship game question.

#2 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Battleship game question.

Posted 26 February 2013 - 01:02 PM

The simplest way is to use a do ...while loop to generate where the next "strike" will be made. Each strike is given a specific value on the game grid (array).

It's like the ships on the game grid - each type of ship has a different value, and positive values indicate one side's ships, and negative values indicate the other side's ships. Now you have a common value that indicates when a grid has already been "hit". This works because the ships can't be moved after the game starts.

so if 22 is that unique value indicating the cell has been hit, then:
do {
   //get a random cell.x for the computers next strike
   //get a random cell.y for the computers next strike

}while(cell.x == 22 && cell.y == 22);




If you had a large number of cells, this wouldn't be ideal, since it will repeat trying to hit cells that have already been hit - but in a small game board like battleship, it's perfect.
Was This Post Helpful? 0
  • +
  • -

#3 sports09  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 26-February 13

Re: Battleship game question.

Posted 26 February 2013 - 01:17 PM

I forgot to say that this is a 1 player game. The board is 5x5 and the user tries to find the computers ship. I think there is only one.
Was This Post Helpful? 0
  • +
  • -

#4 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Battleship game question.

Posted 26 February 2013 - 01:21 PM

I knew it was a one player game - otherwise the computer program wouldn't be generating "strikes" against a ship.

One ship or ten ships or ten ships of ten types of ships - it's all the same as far as this advice goes. You keep generating "strikes" in a loop, until the program generates a unique cell to strike, that hasn't been struck before.

For a large grid, you'd change the algorithm for this, but not for a small one.
Was This Post Helpful? 0
  • +
  • -

#5 baavgai  Icon User is online

  • Dreaming Coder
  • member icon

Reputation: 5848
  • View blog
  • Posts: 12,707
  • Joined: 16-October 07

Re: Battleship game question.

Posted 26 February 2013 - 01:28 PM

You have the code dropBomb. What if you return a result from that?
bool dropBomb(int xcoord, int ycoord) {
	bool dropped = true;
	switch (grid[xcoord][ycoord]) {
		case WATER_UNBOMBED: 
			grid[xcoord][ycoord] = WATER_BOMBED;
			break;
		case SHIP_UNBOMBED: 
			grid[xcoord][ycoord] = SHIP_BOMBED;
			break;
		default:
			dropped = false;
	}
	return dropped;
}



You'd want to look at the result before you gave your "Dropping ordinance" feedback.

Though, honestly, you could move most of your 'b' code into a function to clean things up. And switches aren't always a good choice ( rarely are, actually ). Functions, almost always a good choice.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3589
  • View blog
  • Posts: 11,165
  • Joined: 05-May 12

Re: Battleship game question.

Posted 26 February 2013 - 01:32 PM

Look at your dropBomb() function. It looks at acceptable locations before marking the location as bombed. Create a similar function to return true if a spot can be bombed, and false if it can't. Then you when take the proposed coordinates, you can pass it to the function. If it returns false, then reject that proposed coordinate.
Was This Post Helpful? 0
  • +
  • -

#7 sports09  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 26-February 13

Re: Battleship game question.

Posted 26 February 2013 - 03:11 PM

Would something like this work?
if (grid[x][y] == WATER_BOMBED || grid[x][y] == SHIP_BOMBED) 
{  cout << "That location has already been bombed" << endl;
    cout << "Try again" << endl;
    return;  // exit and prompt for anoth command
}

Was This Post Helpful? 0
  • +
  • -

#8 Skydiver  Icon User is offline

  • Code herder
  • member icon

Reputation: 3589
  • View blog
  • Posts: 11,165
  • Joined: 05-May 12

Re: Battleship game question.

Posted 26 February 2013 - 03:15 PM

Your if statement is a direct hit, but you'll have to think a bit more about the return statement. How will the caller know the difference between a valid versus invalid coordinate, and therefore know whether it should ask for new coordinates or not.
Was This Post Helpful? 0
  • +
  • -

#9 sports09  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 26-February 13

Re: Battleship game question.

Posted 26 February 2013 - 06:18 PM

View PostSkydiver, on 26 February 2013 - 03:15 PM, said:

Your if statement is a direct hit, but you'll have to think a bit more about the return statement. How will the caller know the difference between a valid versus invalid coordinate, and therefore know whether it should ask for new coordinates or not.


So I need to have another statement asking the user to enter new coordinates?
Was This Post Helpful? 0
  • +
  • -

#10 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: Battleship game question.

Posted 26 February 2013 - 09:24 PM

IMO, the computer should always pick an empty cell to bomb. The human has a board, and has markers for every cell that has been bombed so far (with little markers).

If the human didn't think to use the markers, let him or her waste his move. Playing a smart game is up to him/her, not the computer.
Was This Post Helpful? 0
  • +
  • -

#11 adgjlsfhk  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 89
  • Joined: 08-February 13

Re: Battleship game question.

Posted 03 March 2013 - 08:12 AM

I probably would create a 2d array of boolians to track that. Then, use a for loop to look for a 0 value
Was This Post Helpful? 0
  • +
  • -

#12 sports09  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 26-February 13

Re: Battleship game question.

Posted 12 March 2013 - 08:13 AM

View PostSkydiver, on 26 February 2013 - 03:15 PM, said:

Your if statement is a direct hit, but you'll have to think a bit more about the return statement. How will the caller know the difference between a valid versus invalid coordinate, and therefore know whether it should ask for new coordinates or not.


I've been busy lately and have not worked on this for a while but I still can't figure out the return statement. I am really confused about all this stuff.
Was This Post Helpful? 0
  • +
  • -

#13 sports09  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 8
  • Joined: 26-February 13

Re: Battleship game question.

Posted 17 March 2013 - 01:32 PM

Sorry to keep bothering you guys with this but could someone please help me out with my last post?
Was This Post Helpful? 0
  • +
  • -

#14 adgjlsfhk  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 89
  • Joined: 08-February 13

Re: Battleship game question.

Posted 17 March 2013 - 08:03 PM

What's wrong with the return?
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1