CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 2 of 2
  1. #1
    Join Date
    Sep 2013
    Posts
    4

    BattleShip Game Help (Urgent)

    I'm doing a project and wanted to see if anyone could help me (correct or better yet solve the answer), this is what I got so far.

    Code:
    /*
    Simple Battleship.cpp
    */
    
    
    #include "stdafx.h"
    #include <iostream>
    #include <tchar.h>
    #include <time.h>
    #include <string>
    #include <math.h>
    
    using namespace std;
    
    #define MAXSQUARES 9
    #define MAXSHIPS 4
    #define SPACE ' '
    #define MARK 'S'
    #define WINNER true
    #define LOSER false
    
    
    
    class PatternMemory{
    private:
    	PatternMemory *next;
    	char moves[MAXSHIPS+1];
    	int readIndex, writeIndex;
    	int last;
    
    	bool moveExists(char move){
    		for(int i=0;i<MAXSHIPS;i++){
    			if(moves[i] == move){
    				return(true);
    			}
    		}
    		return(false);
    	}
    
    
    	void insertMove(char value, int ptr){
    		for(int i=MAXSHIPS-1;i > ptr;i--){
    			moves[i] = moves[i-1];
    		}
    		moves[ptr] = value;
    	}
    
    public:
    	PatternMemory():next(NULL){
    		readIndex = MAXSHIPS;
    		writeIndex = last = 0;
    		for(int i=0;i<=MAXSHIPS;i++)
    			moves[i] = MAXSQUARES;
    	}
    
    	void reset(){
    		readIndex = 0;
    	}
    
    
    	bool isFull(){
    		return(writeIndex == MAXSHIPS);
    	}
    
    	bool isEmpty(){
    		return(writeIndex == 0);
    	}
    
    	void copy(PatternMemory *src, int goodMatches){
    		for(int i=0;i<goodMatches;i++){
    			moves[i] = src->moves[i];
    		}
    		writeIndex = goodMatches;
    		readIndex = MAXSHIPS;
    	}
    
    	void put(char value){
    		if(moveExists(value) || writeIndex >= MAXSHIPS)
    			return;
    
    		if(writeIndex == 0)
    			moves[writeIndex++] = value;
    		else{
    			for(int i=0;i<writeIndex;i++){
    				if(value < moves[i]){
    					insertMove(value, i);
    					writeIndex++;
    					return;
    				}
    			}
    			moves[writeIndex++] = value;
    		}
    	}
    
    	int getNextMove(){
    		int move = moves[readIndex++];
    		readIndex %= (MAXSHIPS+1);
    		return(move);
    	}
    
    	PatternMemory *nextPattern(){
    		return(this->next);
    	}
    
    	bool hasData(){
    		bool retValue = (readIndex < writeIndex && writeIndex > 0) || isFull();
    		return(retValue);
    	}
    
    	PatternMemory *link(PatternMemory *n){
    		next = n;
    		return(n);
    	}
    
    	void show(){
    		for(int i=0;i< MAXSHIPS;i++){
    			cout << (int)moves[i] << " ";	
    		}
    		cout << endl;
    	}
    };
    
    
    
    
    
    class Scorer{
    private:
    /******************QUESTION 6. (6 Points)**********************
    1. Declare a floating point variable named points
    2. Declare a floating point variable named penalties
    *************************************************************/
    //Place Code Here
    		float points;
    		float penalties;
    
    public:
    
    	Scorer(){
    		reset();
    	}
    /************************QUESTION 7. (6 Points)**********************
    Declare a method named reset that does the following:
    1. It sets the value of the variable points to zero (0).
    2. It sets the value of the variable penalties to zero (0).
    3. It does not return a value.
    
    ******************************************************************/
    //Place Code Here
    	void reset(){
    		points = 0;
    		penalties = 0;
    	}
    	
    
    
    
    	float awardPoints(float value){
    		points += value;
    		return(points);
    	}
    
    
    
    /************************QUESTION 8. (6 Points)**************************
    Declare a method named PenaltyPoints that does the following:
    1. It has a single argument named value that is a floating point number.
    2. It adds the value of the argument value to the variable penalties.
    3. It returns the value of the variable penalties.
    
    **********************************************************************/
    //Place Code Here
    	float PenaltyPoints(float value){
    		value + penalties;
    		return (penalties);
    		
    	}
    
    
    
    
    
    
    
    
    
    /************************QUESTION 9. (6 Points)**********************
    Declare a method named getTotalPoints that does the following:
    1. It has no arguments.
    2. It calculates totalPoints by using the following formula:
    		totalPoints = points - penalties.
    3. It returns the floating point value totalPoints.
    
    ******************************************************************/
    //Place Code Here
    	getTotalPoints(float totalPoints){
    		
    		totalPoints = points - penalties;
    		return (totalPoints);
    
    	}
    
    	
    	float getPoints(){
    		return(points);
    	}
    
    	float getPenalties(){
    		return(penalties);
    	}
    
    /*************************QUESTION 10. (6 Points)**************************
    Declare a method named displayPoints that does the following:
    1. It has a single argument named pName that is a string.
    2. It outputs a text string to the console that displays name’s total points. 
    3. It uses the getTotalPoints() method to get the player’s total points.
    4. It does not return a value.
    
    Example:
    If pName has the value “The Player” and getTotalPoints() returns the value 20, then the following will be displayed:
    The Player has 20 points!
    ************************************************************************/
    //Place Code Here
    	displayPoints(string pName){
    		cout << pName << "You have " << getTotalPoints() << " Points" << endl;
    	}
    	
    };
    
    class BATTLEBOARD{
    private:
    /************************QUESTION 11. (6 Points)*************************
    1. Declare a character array variable named board whose number of elements is MAXSQUARES.
    2. Declare a boolean variable named HitFlag.
    **********************************************************************/
    
    //Place Code Here
     int board[MAX_SQUARES = 9];
    
    bool HitFlag;
    
    public:
    
    	BATTLEBOARD(){}
    
    	void PlaceShips(int moves[MAXSHIPS]){
    		for(int i = 0; i < MAXSHIPS; i++){
    			board[moves[i]]=MARK;
    		}
    	}
    
    /************************QUESTION 12. (6 Points)**************************
    Create a method named Reset() that does the following:
    1. It has no arguments.
    2. It initializes each element of the array variable board to equal the value SPACE.
    3. It returns nothing.
    
    ************************************************************************/
    //Place Code Here
    	void Reset(string EMPTY = ' '){
    		MAX_SQUARES = EMPTY;
    	}
    	
    
    
    
    /************************QUESTION 13. (6 Points)**********************
    Declare a method named Display that does the following:
    1. It has a no arguments.
    2. It displays the array board on the console.
    3. Specifically, it displays the contents of every cell of the game board on the console.
    4. It returns no value.
    
    Example:
    	
    | X |   | X |
    |---|---|---|
    |   | X |   |
    |---|---|---|
    | X |   |   | 
    *********************************************************************/
    //Place Code Here
    	void Display(){
    		cout << "\n\t" << board[0][0] << " | " << board[0][1] << " | " << board[0][2];
    		cout << "\n\t" << "---------";
    		cout << "\n\t" << board[1][0] << " | " << board[1][1] << " | " << board[1][2];
    		cout << "\n\t" << "---------";
    		cout << "\n\t" << board[2][0] << " | " << board[2][1] << " | " << board[2][2];
    		cout << "\n\t";}
    
    /************************QUESTION 14. (6 Points)**********************
    Declare a method named checkWinner that does the following:
    1. It has no arguments.
    2. It counts the number of board cells that do not have the SPACE character in them.
    3. It returns true if count equals 0(zero) and returns false if count is not equal to 0(zero).
    
    ********************************************************************/
    //Place Code Here
    
    	
    
    
    
    
    
    	virtual bool Fire(int move){
    		HitFlag = false;
    		if(board[move] != SPACE){
    			board[move] = SPACE;
    			HitFlag = true;
    			return(checkWinner());
    		}
    		
    		return(LOSER);
    	}
    
    	bool getHitFlag(){
    		return(HitFlag);
    	}
    };
    
    
    
    
    class Player : public Scorer{
    protected:
    	int Locations[MAXSHIPS];
    
    private:
    	BATTLEBOARD board;
    
    
    
    
    
    
    
    
    
    
    
    	virtual int getShipLocation(){
    /************************QUESTION 15. (6 Points)*************************
    The method getShipLocation()does the following:
    1. It has no arguments.
    2. It prompts the Player to "Enter Ship Location: " and then reads the value entered from the keyboard. If the value entered is illegal, prompt the Player to try again to enter a valid value.
    3. It returns the location entered by the Player.
    
    ***********************************************************************/
    //Place Code Here
    		
    		
    	}
    
    
    
    
    	
    
    
    
    virtual int getMove(){
    /************************QUESTION 16. (6 Points)**************************
    The method getMove()does the following:
    1. It has no arguments.
    2. It prompts the Player with "\nYour Move Human: " and then reads the value entered from the keyboard. If the value entered is illegal, prompt the Player to try again to enter a valid value.
    3. It returns the move entered by the Player.
    
    ************************************************************************/
    //Place Code Here
    
    	
    	}
    
    public:
    
    	Player(){}
    
    	void Display(){
    		board.Display();
    	}
    
    
    
    
    
    	void askPlayer2PlaceShips(){
    		int count = 0;
    		int location;
    
    		do{
    			location = getShipLocation();
    			Locations[count++] = location;
    		}while(count < MAXSHIPS);
    
    		board.PlaceShips(Locations);
    	}
    
    	void init(){
    		board.Reset();
    	}
    
    	bool Fire(int move){
    		return(board.Fire(move));
    	}
    
    	virtual bool launchAttack(Player &opponent){
    		int move = getMove();
    		return(opponent.Fire(move));
    	}
    
    	BATTLEBOARD &getBoard(){
    		return(board);
    	}
    
    	bool ShipWasSunk(){
    		return(board.getHitFlag());
    	}
    };
    
    
    class ComputerPlayer: public Player{
    private:	
    	int previousMoves[MAXSQUARES+1];
    	int	 index; // previousMoves index
    	PatternMemory *head;
    	PatternMemory *tail;
    	PatternMemory *current;
    	bool lastMoveSankEnemyShip;
    	bool lastMoveWonGame;
    	int matches;
    
    	/*
    	* Creates a new pattern memory and links it into to the chain of memories.
    	*/
    
    	void newNode(){
    		if((lastMoveWonGame && tail == NULL) ||(lastMoveWonGame && tail != NULL && tail->isFull())){
    			PatternMemory *n = new PatternMemory; // Create a new instance of the patten memory object
    			if(head == NULL){//Treatment for the first memory pattern
    				head = tail  = n;
    			}
    			else{
    				tail = tail->link(n);//all subsequent patterns link to the tail
    			}
    			current = head; //set current to the begining of the chain of memories
    			if(head != tail)// reset the read memory pointer for all subsequent memories.
    				current->reset();
    		}
    		else{
    			current = head;
    			if(tail->isEmpty() == false){// add new memory if tail memory has been written to.
    				PatternMemory *n = new PatternMemory;
    				tail = tail->link(n);
    			}
    			current->reset();
    		}
    	}
    
    	bool isMoveDuplicated(int move){
    		for(int i = 0;i<index;i++){
    			if(move == previousMoves[i])
    				return true;
    		}
    
    		return false;
    	}
    
    	// Selects random locations for MAXSHIPS(4) ships
    	int getShipLocation(){
    		int location;
    		bool dupFlag;
    
    		do{// make sure locations are unique
    			dupFlag = false;
    			location = rand() % MAXSQUARES;
    			for(int i=0;i<MAXSHIPS;i++){
    				if(Locations[i] == location){
    					dupFlag = true;
    					break;
    				}
    			}
    		}while(dupFlag == true);
    
    		return(location);
    	}
    
    	
    
    
    	//Get a unique random value for the next move
    /************************QUESTION 17. (6 Points)***************************
    Create a method named getRandomMove() that does the following:
    4. It has no arguments.
    5. It generates a random number between 0(zero) 
    and 8 (MAXSQUARES - 1) for the computerPlayer’s move.
    6. It returns the computerPlayer’s move.
    
    7. BONUS POINTS(5): 
    Add code to eliminate duplicate values from the random number generator so that only unique values are returned by the method.
    ************************************************************************/
    //Place Code Here
    
    	
    
    
    	// get the next move from the current memory
    	int getPatternMove(){
    		bool dupMoveFlag;
    		int move;
    
    		do{
    			move = current->getNextMove();
    			dupMoveFlag = isMoveDuplicated(move);
    		}while(dupMoveFlag == true);
    
    		if(move == MAXSQUARES)//if we get a 'sentinel' get a randomly generated move.
    			move = getRandomMove();
    
    		return(move);
    	}
    
    
    	// Get the next move
    	int getMove(){
    		int move;
    		bool dupMoveFlag;
    
    		if(current != NULL && ((index == 0 || lastMoveSankEnemyShip || matches >= MAXSHIPS/2) && current->hasData())){
    			/*
    			* Perform these actions if this is the first memory
    			* or the last move sank an enemy ship
    			* or we've had at least 50% matches with the current memory
    			* and the current memory has data to be read.
    			*/
    			if(lastMoveSankEnemyShip == false && matches >= MAXSHIPS/2 && current->isFull()){
    				if(tail->isEmpty()){
    					tail->copy(current, matches);
    					current = tail;
    					current->reset();
    				}
    
    			}
    			move = getPatternMove();
    		}
    		else if(current->hasData() && lastMoveSankEnemyShip == false){
    			/*
    			* Goto the next memory pattern if the last move did not sink an enemy ship
    			* and there were fewer than 50% matches with the current pattern.
    			*/
    			matches = 0;
    			current = current->nextPattern();
    			// if data is available, get the move from the pattern
    			// else get move from random move generator.
    			if(current != NULL){
    				if(current->isEmpty() == false){
    					current->reset();
    					move = getPatternMove();
    				}
    				else
    					move = getRandomMove();
    			}
    			else{
    				current = head;
    				move = getRandomMove();
    			}
    		}
    		else{
    			move = getRandomMove();
    		}
    
    		previousMoves[index++] = move;// store current move in previous moves data store
    		cout << "\nMy Move Is: " << move << endl;
    		return(move);
    	}
    
    public:
    
    	ComputerPlayer():head(NULL), tail(NULL){
    		srand((unsigned int)time(0));
    	}
    
    	void init(){
    		Player::init();
    		for(int i=0;i<=MAXSQUARES;i++){
    			previousMoves[i]=MAXSQUARES;
    		}
    
    		index = 0;
    		matches = 0;
    		newNode();
    		lastMoveSankEnemyShip=false;
    		lastMoveWonGame=true;
    	}
    
    	bool launchAttack(Player &opponent){
    		bool status = Player::launchAttack(opponent);
    		lastMoveSankEnemyShip=false;
    		if(opponent.ShipWasSunk() && current != NULL){
    			current->put(previousMoves[index - 1]);//memorize last move in pattern memory
    			lastMoveSankEnemyShip=true;
    			matches++;
    		}
    		lastMoveWonGame = status;
    		return(status);
    	}
    
    	void showMemory(){
    		PatternMemory *p = head;
    		while(p != NULL){
    			p->show();
    			p = p->nextPattern();
    		}
    	}
    
    };
    
    
    class BATTLESHIP{
    private:
    
    
    /************************QUESTION 18. (6 Points)***************************
    1. Declare a variable named human that is an instance of the Player class.
    2. Declare a variable named computer that is an instance of the ComputerPlayer class.
    ************************************************************************/
    //Place Code Here
    
    	
    	int	 index;
    	bool gameOver;
    
    	enum PLAYER {HUMAN, COMPUTER};
    
    	void BSinstructions()
    	{
    		cout << "\n\nWelcome to the ultimate man-machine showdown: BattleShip.\n";
    		cout << "--where human brain is pit against silicon processor\n\n";
    
    		cout << "Make your move known by entering a number, 0 - 8.  The number\n";
    		cout << "corresponds to the desired board position, as illustrated:\n\n";
    	    
    		cout << "       0 | 1 | 2\n";
    		cout << "       ---------\n";
    		cout << "       3 | 4 | 5\n";
    		cout << "       ---------\n";
    		cout << "       6 | 7 | 8\n\n";
    
    		cout << "Prepare yourself, human.  The battle is about to begin.\n\n";
    	}
    
    	void initGame(){
    		human.init();
    		human.askPlayer2PlaceShips();
    		computer.init();
    		computer.askPlayer2PlaceShips();
    		gameOver = false;
    	}
    
    public:
    
    	BATTLESHIP(){}
    
    
    	void playBattleShip(){
    /************************QUESTION 19. (6 Points)***************************
    1. Modify this method to ask the player if they want to play again. If the Player answers “yes”, then play the game again. If the answer is “no”, then exit the replay loop.
    ************************************************************************/
    //Place Code Here
     
    		
    			BSinstructions();
    			initGame();
    			human.Display();
    		
    			//The Game Loop
    			do{
    				if(human.launchAttack(computer) == WINNER){
    					gameOver = true;
    					cout << "You Sank My Battleship, Human!\n";
    					cout << "GAME OVER:\n\tYou Won, Human! How Embarrassing!!!\n";
    					human.awardPoints(20);
    					human.displayPoints("\tThe Human");
    					break;
    				}
    				else if(computer.ShipWasSunk()== true){
    					cout << "You Sank My Battleship, Human!\nI'll get you yet!!!\n";
    					human.awardPoints(5);
    					computer.PenaltyPoints(5);
    				}
    				else{
    					cout << "You Missed Pitiful Human!\nThe End Is Near!!!\n";
    					human.PenaltyPoints(2);
    				}
    				
    				if(computer.launchAttack(human) == WINNER){
    					gameOver = true;
    					human.Display();
    					cout << "I Sank Your Battleship, Human!\n";
    					cout << "GAME OVER:\n\tI Won, Human! You Are No Match For My Superior Intelligence!!!\n";
    					computer.awardPoints(20);
    					computer.displayPoints("\tThe Computer");
    					break;
    				}
    				else if(human.ShipWasSunk() == true){
    					cout << "I Sank Your Battleship, Human!\nYou Are Doomed!!!\n";
    					human.PenaltyPoints(5);
    					computer.awardPoints(5);
    				}
    				else{
    					cout << "I Missed You This Time, Pitiful Human!\nEnjoy It While You Can!!!\n";
    					computer.PenaltyPoints(2);
    				}
    
    				human.Display();
    				//computer.Display();
    			}while(gameOver == false);
    			
    			
    
    		//Place Code Here: play again loop
    
    
    
    //The code below is run after the player indicates they do
    //not wish to continue playing.
    		cout << endl << endl;
    
    /*************************************************************************
    BONUS POINTS(20): 
    Add code to print out congratulatory and game status messages to the Player. 
    1. The series winner is determined by who has the most points. Use human.getTotalPoints() to get the human player’s points and computer.getTotalPoints()to get the computer player’s points. If the human has more points than the computer, then the human has won the series.
    2. Use a conditional statement to determine who the series winner is and display the appropriate messages.
    3. If both player’s have equal scores, then declare a tie and display an appropriate message.
    ************************************************************************/
    //Place Code Here
    
    		
    
    
    		cout << "\nThanks For Playing BattleShip\n";
    	}
    
    };
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	/************************QUESTION 20. (6 Points)********************
    1. Declare a variable that is an instance of the BATTLESHIP class.
    2. Use the instance variable from step 1 above to activate the playBattleShip method to run the game.
           *****************************************************************/
    	//Place Code Here
    
    	
    	return 0;
    }

  2. #2
    2kaud's Avatar
    2kaud is online now Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,822

    Re: BattleShip Game Help (Urgent)

    We could help you, but would we for an assignment? See
    http://forums.codeguru.com/showthrea...ork-assignment

    What is your c++ question? We won't write the code for you as we would call that cheating. But if explain the area of c++ of whch you are having difficulty, we will provide guidance and advice.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured