Skip to content

Instantly share code, notes, and snippets.

@john4
Created February 11, 2015 04:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save john4/0b01928877477469fcdb to your computer and use it in GitHub Desktop.
Save john4/0b01928877477469fcdb to your computer and use it in GitHub Desktop.
Single Player Console Battleship with Artificial Intelligence
/*
Author: John Martin
Class: Introduction to C++
Assignment: Final Project
Date Assigned: May 7, 2013
Due Date: May 14, 2013
Description: This program uses all concepts learned in the class to create
a single player battleship game with an Artificial Intelligence.
Certification of Authenticity:
I certify that this assignment is entirely my own work.
*/
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
bool canFire(int, int, int);
void updateMap();
string fire(int, int, int);
void displayGame();
void displayPlayerBoard();
void populatePlayerBoard();
void populateComputerBoard();
string computerMove();
bool placeShip(int, int, int, int, bool);
void updateScore();
//Declaration of global variables
//KEY FOR BOARD:
const string EMPTY = " ";
const string SHIP = "H";
const string HIT = "X";
const string MISS = "O";
string board1[10][10] = {{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY}},
board2[10][10] = {{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY}},
map[10][10] = {{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY},
{EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY,EMPTY}};
int turn = 0, playerHits = 0, computerHits = 0; //scoring
int currentPlayerPiece = 0, targeting = -1; //AI processing
int patrolBoat[2][2], destroyer[3][2], submarine[3][2], battleship[4][2], aircraftCarrier[5][2];
bool activeTargeting = false;
int main()
{
int row, column;
string fired;
//Opening sequences
cout << "Welcome to John Martin's amazing BATTLE SHIP BOARD GAME!!\n"
<< "This is a standard game of BATTLE SHIP, but against an Aritifical Intelligence.\n\n"
<< "You will need to know the piece values:\n"
<< "SHIP = H\nHIT = X\nMISS = O\n\n"
<< "Now you can assign your ships to the board...";
populatePlayerBoard();
cout << "\nPlease wait while computer board is populated...\n";
populateComputerBoard();
for(int i = 0; i < 4; i++)
{
cout << battleship[i][0] << battleship[i][1];
}
cout << "\n\n\n\n\n OKAY, WE'RE READY TO PLAY!\nENTER YOUR FIRE COORDINATES WHEN PROMPTED\n\n";
//Game loop to continue until one player has 17 hits (all ships sunk)
while(playerHits < 17 && computerHits < 17)
{
displayGame(); //1 Display the game
do{ //2 Ask for coordinates until can fire
cout << "It's your turn to fire!\nRow: ";
cin >> row;
cout << "Column: ";
cin >> column;
row = row - 1;
column = column - 1;
}
while(!canFire(2, row, column));
fired = fire(2, row, column); //3 Player fire
if(fired == SHIP) //4 Inform player of his or her result
cout << "Player: HIT!!";
else
cout << "Player: MISS";
cout << "Computer: " << computerMove(); //5 Command computer to fire & print result
updateScore(); //6 Update score and count for next turn
turn++;
}
return 0;
}
//This function returns true if the target space on the target board is either
//EMPTY or SHIP, otherwise returns false.
bool canFire(int fireAt, int row, int column)
{
if(fireAt == 2){
if(board2[row][column] == EMPTY || board2[row][column] == SHIP)
return true;
else
return false;
}
else{
if(board1[row][column] == EMPTY || board1[row][column] == SHIP)
return true;
else
return false;
}
}
//This function updates the player's map based on the computer's board.
void updateMap()
{
for(int r = 0; r < 10; r++)
{
for(int c = 0; c < 10; c++)
{
if(board2[r][c] == HIT)
map[r][c] = HIT;
else if(board2[r][c] == MISS)
map[r][c] = MISS;
else;
}
}
}
//This function accepts a firing command from either player and returns the value that
//was in the space on the board of the other player. Also updates player's map on turn by turn basis.
string fire(int fireAt, int row, int column)
{
string previousValue;
//Instructions for player firing at computer
if(fireAt == 2)
{
previousValue = board2[row][column];
if(board2[row][column] == EMPTY){
board2[row][column] = MISS;
map[row][column] = MISS;}
else if(board2[row][column] == SHIP){
board2[row][column] = HIT;
map[row][column] = HIT;}
else;
}
//Instructions for computer firing at player
else
{
previousValue = board1[row][column];
if(board1[row][column] == EMPTY)
board1[row][column] = MISS;
else if(board1[row][column] == SHIP)
board1[row][column] = HIT;
else;
}
return previousValue;
}
//This function displays the board and map to the player.
void displayGame()
{
cout << "\n\n\n\nTurn: " << turn << endl;
cout << "Player: " << playerHits << "\nComputer: " << computerHits << endl;
cout << "===============YOUR MAP=================" << endl;
cout << " | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10|" << endl;
for(int r = 0; r < 10; r++)
{
cout << r + 1;
if(r != 9)
cout << " ";
for(int c = 0; c < 10; c++)
{
if(c == 0)
cout << "| ";
else
cout << " | ";
cout << map[r][c];
}
cout << endl;
if(r != 9)
cout << "-------------------------------------------\n";
}
cout << "\n\n\n";
cout << "==============YOUR BOARD================" << endl;
cout << " | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10|" << endl;
for(int r = 0; r < 10; r++)
{
cout << r + 1;
if(r != 9)
cout << " ";
for(int c = 0; c < 10; c++)
{
if(c == 0)
cout << "| ";
else
cout << " | ";
cout << board1[r][c];
}
cout << endl;
if(r != 9)
cout << "-------------------------------------------\n";
}
}
//This function allows the computer to make it's intelligent move and return result.
string computerMove()
{
int row, column;
activeTargeting = false;
string hitOrMiss;
//If computer is targeting a damaged ship
if(targeting != -1)
{
if(targeting = 0){
for(int i = 0; i < 2; i++){
if(board1[patrolBoat[i][0]][patrolBoat[i][1]] == SHIP){
row = patrolBoat[i][0];
column = patrolBoat[i][1];
activeTargeting = true;}
}
}
else if(targeting = 1){
for(int i = 0; i < 3; i++){
if(board1[destroyer[i][0]][destroyer[i][1]] == SHIP){
row = destroyer[i][0];
column = destroyer[i][1];
activeTargeting = true;}
}
}
else if(targeting = 2){
for(int i = 0; i < 3; i++){
if(board1[submarine[i][0]][submarine[i][1]] == SHIP){
row = submarine[i][0];
column = submarine[i][1];
activeTargeting = true;}
}
}
else if(targeting = 3){
for(int i = 0; i < 4; i++){
if(board1[battleship[i][0]][battleship[i][1]] == SHIP){
row = battleship[i][0];
column = battleship[i][1];
activeTargeting = true;}
}
}
else{
for(int i = 0; i < 5; i++){
if(board1[aircraftCarrier[i][0]][aircraftCarrier[i][1]] == SHIP){
row = aircraftCarrier[i][0];
column = aircraftCarrier[i][1];
activeTargeting = true;}
}
}
}
//If no intelligent moves, make a random move
if(!activeTargeting)
{
do{
srand(time(NULL));
row = rand() % 10;
srand(rand()/0.97653467896);
column = rand() % 10;
}
while(!canFire(1, row, column));
}
//fire
string result = fire(1, row, column);
if(result == SHIP)
{
hitOrMiss = "HIT";
//which ship was hit?
for(int i = 0; i < 2; i++){
if(patrolBoat[i][0] == row && patrolBoat[i][1] == column)
targeting = 0;}
for(int i = 0; i < 3; i++){
if(destroyer[i][0] == row && destroyer[i][1] == column)
targeting = 1;}
for(int i = 0; i < 3; i++){
if(submarine[i][0] == row && submarine[i][1] == column)
targeting = 2;}
for(int i = 0; i < 4; i++){
if(battleship[i][0] == row && battleship[i][1] == column)
targeting = 3;}
for(int i = 0; i < 5; i++){
if(aircraftCarrier[i][0] == row && aircraftCarrier[i][1] == column)
targeting = 4;}
cout << targeting;
}
else
{
hitOrMiss = "MISS";
targeting = -1;
}
return hitOrMiss;
}
//This function displays the players board only; with NO MAP.
void displayPlayerBoard()
{
cout << " | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10|" << endl;
for(int r = 0; r < 10; r++)
{
cout << r + 1;
if(r != 9)
cout << " ";
for(int c = 0; c < 10; c++)
{
if(c == 0)
cout << "| ";
else
cout << " | ";
cout << board1[r][c];
}
cout << endl;
if(r != 9)
cout << "-------------------------------------------\n";
}
cout << endl << endl;
}
//This function is run at the start of the game to populate the player's board with ships.
void populatePlayerBoard()
{
int placement, row, column;
bool isVertical = false, isPlaced;
cout << "\n\nPLEASE REMEMBER TO PLACE YOUR SHIPS IN ADJACENT HORIZONTAL OR VERTICAL LINES\n"
<< "NEVER EXIT THE RANGE OF 1-10 WHEN USING THE COORDINATE SYSTEM!\n"
<< "IF THE SYSTEM ASKS YOU FOR THE SAME BOAT INFORMATION AGAIN, YOU CHOSE AN INVALID PLACEMENT\n\n";
//PATROL BOAT
cout << "Here is your board for your reference: \n";
displayPlayerBoard();
do{
cout << "First, place your PATROL BOAT (2 spaces).\n"
<< "Would you like this placed vertically (1) or horizontally (2)? (Enter '1' or '2'): ";
cin >> placement;
if(placement == 1)
isVertical = true;
else
isVertical = false;
cout << "Row: ";
cin >> row;
cout << "Column: ";
cin >> column;
row = row - 1;
column = column - 1;
isPlaced = placeShip(1, 2, row, column, isVertical);
}
while(!isPlaced);
currentPlayerPiece++;
//DESTROYER
cout << "Here is your board for your reference: \n";
displayPlayerBoard();
do{
cout << "Place your DESTROYER (3 spaces).\n"
<< "Would you like this placed vertically (1) or horizontally (2)? (Enter '1' or '2'): ";
cin >> placement;
if(placement == 1)
isVertical = true;
else
isVertical = false;
cout << "Row: ";
cin >> row;
cout << "Column: ";
cin >> column;
row = row - 1;
column = column - 1;
isPlaced = placeShip(1, 3, row, column, isVertical);
}
while(!isPlaced);
currentPlayerPiece++;
//SUBMARINE
cout << "Here is your board for your reference: \n";
displayPlayerBoard();
do{
cout << "Place your DESTROYER (3 spaces).\n"
<< "Would you like this placed vertically (1) or horizontally (2)? (Enter '1' or '2'): ";
cin >> placement;
if(placement == 1)
isVertical = true;
else
isVertical = false;
cout << "Row: ";
cin >> row;
cout << "Column: ";
cin >> column;
row = row - 1;
column = column - 1;
isPlaced = placeShip(1, 3, row, column, isVertical);
}
while(!isPlaced);
currentPlayerPiece++;
//BATTLESHIP
cout << "Here is your board for your reference: \n";
displayPlayerBoard();
do{
cout << "Place your BATTLESHIP (4 spaces).\n"
<< "Would you like this placed vertically (1) or horizontally (2)? (Enter '1' or '2'): ";
cin >> placement;
if(placement == 1)
isVertical = true;
else
isVertical = false;
cout << "Row: ";
cin >> row;
cout << "Column: ";
cin >> column;
row = row - 1;
column = column - 1;
isPlaced = placeShip(1, 4, row, column, isVertical);
}
while(!isPlaced);
currentPlayerPiece++;
//AIRCRAFT CARRIER
cout << "Here is your board for your reference: \n";
displayPlayerBoard();
do{
cout << "Place your AIRCRAFT CARRIER (5 spaces).\n"
<< "Would you like this placed vertically (1) or horizontally (2)? (Enter '1' or '2'): ";
cin >> placement;
if(placement == 1)
isVertical = true;
else
isVertical = false;
cout << "Row: ";
cin >> row;
cout << "Column: ";
cin >> column;
row = row - 1;
column = column - 1;
isPlaced = placeShip(1, 5, row, column, isVertical);
}
while(!isPlaced);
}
//This function populates the computer's board with ships
void populateComputerBoard()
{
int row, column, vert, ships[5] = {2, 3, 3, 4, 5};
bool isPlaced, isVertical;
for(int i = 0; i < 5; i++)
{
do{
srand(time(NULL));
row = rand() % 10;
column = rand() % 10;
vert = rand() % 2;
if(vert == 1)
isVertical = true;
else
isVertical = false;
isPlaced = placeShip(2, ships[i], row, column, isVertical);
}
while(!isPlaced);
}
}
//This function attempts to place a ship on the specified board, returns false if it cannot.
bool placeShip(int board, int size, int row, int column, bool isVertical)
{
bool isPlaced = true;
int i = 0;
//For human player
if(board == 1)
{
if(isVertical)
{ //row alternates
if(!(row + size > 9))
{
for(int r = row; r < row + size; r++)
{
if(board1[r][column] != EMPTY)
isPlaced = false;
}
if(isPlaced == true)
{
for(int r = row; r < row + size; r++)
{
board1[r][column] = SHIP;
if(currentPlayerPiece == 0)
{
patrolBoat[i][0] = r;
patrolBoat[i][1] = column;
}
else if(currentPlayerPiece == 1)
{
destroyer[i][0] = r;
destroyer[i][1] = column;
}
else if(currentPlayerPiece == 2)
{
submarine[i][0] = r;
submarine[i][1] = column;
}
else if(currentPlayerPiece = 3)
{
battleship[i][0] = r;
battleship[i][1] = column;
}
else
{
aircraftCarrier[i][0] = r;
aircraftCarrier[i][1] = column;
}
i++;
}
}
}
else
isPlaced = false;
}
else
{ //column alternates
if(!(column + size > 9))
{
for(int c = column; c < column + size; c++)
{
if(board1[row][c] != EMPTY)
isPlaced = false;
}
if(isPlaced == true)
{
for(int c = column; c < column + size; c++)
{
board1[row][c] = SHIP;
if(currentPlayerPiece == 0)
{
patrolBoat[i][0] = row;
patrolBoat[i][1] = c;
}
else if(currentPlayerPiece == 1)
{
destroyer[i][0] = row;
destroyer[i][1] = c;
}
else if(currentPlayerPiece == 2)
{
submarine[i][0] = row;
submarine[i][1] = c;
}
else if(currentPlayerPiece = 3)
{
battleship[i][0] = row;
battleship[i][1] = c;
}
else
{
aircraftCarrier[i][0] = row;
aircraftCarrier[i][1] = c;
}
i++;
}
}
}
else
isPlaced = false;
}
}
//For computer player
else
{
if(isVertical)
{ //row alternates
if(!(row + size > 9))
{
for(int r = row; r < row + size; r++)
{
if(board2[r][column] != EMPTY)
isPlaced = false;
}
if(isPlaced == true)
{
for(int r = row; r < row + size; r++)
{
board2[r][column] = SHIP;
}
}
}
else
isPlaced = false;
}
else
{ //column alternates
if(!(column + size > 9))
{
for(int c = column; c < column + size; c++)
{
if(board2[row][c] != EMPTY)
isPlaced = false;
}
if(isPlaced == true)
{
for(int c = column; c < column + size; c++)
{
board2[row][c] = SHIP;
}
}
}
else
isPlaced = false;
}
}
return isPlaced;
}
//This function updates the score
void updateScore()
{
int comp = 0, player = 0;
for(int r = 0; r < 10; r++)
{
for(int c = 0; c < 10; c++)
{
if(board1[r][c] == HIT)
comp++;
if(board2[r][c] == HIT)
player++;
}
}
computerHits = comp;
playerHits = player;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment