forked from MarkusBecerra/BattleShip
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExecutive.cpp
More file actions
228 lines (179 loc) · 7.3 KB
/
Executive.cpp
File metadata and controls
228 lines (179 loc) · 7.3 KB
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
/**
* \Author: Chance Penner
* \Author: Markus Becerra
* \Author: Sarah Scott
* \Author: Thomas Gardner
* \Author: Haonan Hu
* \File: Executive.cpp
* \Date: 09/19/2019
* \Brief: File is cpp file
* \copyright: Group "Big SegFault Energy" All rights reserved
*/
#include "Executive.h"
#include <limits>
#include "algorithm" //for toupper
int Executive::boatCheck() //will return numOfBoats when valid
{
int numOfBoats = 0; //declaring numberOfBoats
std::string tempBoats = " "; //declaring tempBoats string for storing numOfBoats as a string
std::cout << "How many ships would you like to play with? (Choose 1-5): "; //prompt user for number of ships
std::getline(std::cin, tempBoats); //Gather the users desired number of boats in a getline
if(tempBoats.length() < 1 || tempBoats.length() > 1) //check if the length of the string is NOT equal to one
{
std::cout << "Must be a one-digit number from 1-5!\n"; //print error that the digit was greater than length 1
return boatCheck(); //return the boatCheck function to get a new input for the number of boats desired
}
else //if the tempBoats length was equal to 1
{
numOfBoats = tempBoats.at(0) - '0'; //set numOfBoats integer equal to the first character of the tempBoats string
if(numOfBoats < 1 || numOfBoats > 5) //if numOfBoats is not between one and five (inclusive)
{
std::cout << "Must be an integer from 1-5!\n"; //print error message that the number is out of the range
return boatCheck(); //return boatCheck function to get a new input for the number of boats desired
}
else
{
return numOfBoats; //if the number of boats is valid (1-5), return the integer itself
}
}
}
Executive::Executive() //Executive constructor
{
int numOfBoats = 0; //int numOfBoats to store the number of boats
try //DO WE NEED TRY CATCH HERE???!
{
numOfBoats = boatCheck(); //try block to set Executive constructor's numOfBoats to the value returned by boatCheck
}
catch(std::runtime_error &rte) //catch error if the function fails
{
std::cout << "Invalid number of ships"; //print error message if the function fails
}
player_1 = new Player(numOfBoats); //create player 1 object passing in the number of boats
player_2 = new Player(numOfBoats); //create player 2 object passing in the number of boats
m_gameOver = false; //m_gameOver member variable set to false at the beginning of the game
m_player_1Turn = 1; //m_player_1Turn member boolean set to 1, game starts with player 1's turn
std::cout <<"\nPlayer 1 place your ships\n"; //prompt player1 to place their ships
player_1 -> getBoard() -> setupBoard(); //call getBoard and setupBoard from board.cpp to create the two boards for player1
std::cout <<"\nPlayer 2 place your ships\n"; //promt player2 to place their ships
player_2 -> getBoard() -> setupBoard(); //call getBoard and setupBoard from board.cpp to create the two boards for player2
game(); //call Executive game function to start the game once both players have set up their boards
}
Executive::~Executive() //Executive destructor
{
delete player_1; //delete player1 object
delete player_2; //delete player2 object
}
void Executive::game()
{
std::string guess = " ";
while(!m_gameOver)
{
try
{
guess = " "; //reinitializes guess to prevent infinite out of boundary loop
while(guess.length() != 2)
{
if(m_player_1Turn % 2 == 1) //if it is player 1's turn
{
player_1->getBoard()->printShotBoard();
player_1->getBoard()->printMyBoard();
std::cout << "Player 1: Where would you like to shoot: "; //print player's board and opponent's board and ask for user a location to shoot
std::getline(std::cin, guess);
std::transform(guess.begin(), guess.end(),guess.begin(), ::toupper); //converts guess to uppercase
std::cout << "guess: " << guess << "\n"; //print out user's guess
if(guess.length() != 2)
{
std::cout << "Invalid coordinate! Try again.\n"; //error if user inputs a string which length is not 2
}
}
else //if it is player 2's turn
{
player_2->getBoard()->printShotBoard();
player_2->getBoard()->printMyBoard();
std::cout <<"Player 2: Where would you like to shoot: "; //print player's board and opponent's board and ask for user a location to shoot
std::getline(std::cin, guess);
std::transform(guess.begin(), guess.end(),guess.begin(), ::toupper); //converts guess to uppercase
if(guess.length() != 2)
{
std::cout << "Invalid coordinate! Try again.\n";//error if user inputs a string which length is not 2
}
}
}
shoot(guess); //shoot the location as user demand
if(m_player_1Turn % 2 == 1 && !m_gameOver) //if it is player 1's turn
{
std::cout << "PLAYER 1 TURN\n";
player_1->getBoard()->printShotBoard();
player_1->getBoard()->printMyBoard();
std::cout <<"Player 1 please hit enter and let other player shoot at your ships in secret: "; //print the board for checking hit or not and hit eneter for next player's turn
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); //get rid of user's ramdon input to crash the game
player_1->getBoard()->printIntermission();
}
else if(m_player_1Turn % 2 == 0 && !m_gameOver) //if it is player 2's turn
{
std::cout << "PLAYER 2 TURN\n";
player_2->getBoard()->printShotBoard();
player_2->getBoard()->printMyBoard();
std::cout <<"Player 2 please hit enter and let other player shoot at your ships in secret: ";//print the board for checking hit or not and hit eneter for next player's turn
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n'); //get rid of user's ramdon input to crash the game
player_2->getBoard()->printIntermission();
}
m_player_1Turn++; //change player turn
}
catch(std::runtime_error &rte)
{
std::cout << rte.what();
}
}
if(m_player_1Turn % 2 == 1) //m_player_1Turn gets changed right before this, which is why the value is comparing different than above
{
player_2->getBoard()->printShotBoard();
player_2->getBoard()->printMyBoard();
std::cout << "PLAYER 2 WINS!\n";
}
else
{
player_1->getBoard()->printShotBoard();
player_1->getBoard()->printMyBoard();
std::cout << "PLAYER 1 WINS!\n";
}
}
void Executive::shoot(std::string location)
{
int numberOfShips = player_1->getBoard()->getNumberofShips(); //sets the number of ships
bool hit = false;
if(m_player_1Turn % 2 == 1)
{
hit = player_2->gettingShot(location); //check player_2 has a ship at the location or not
player_1->shooting(location,hit); //update hit marker for player_1
for(int i=0;i<numberOfShips;i++) //checks for game over
{
if(player_2->getBoard()->getShip()[i].isSunk())
{
m_gameOver = true; //sets to true if they are sunk
}
else
{
m_gameOver = false; //sets back to false if any are not sunk and then breaks out of for loop
break;
}
}
}
else
{
hit = player_1->gettingShot(location); //check player_1 has a ship at the location or not
player_2->shooting(location,hit); //update hit marker for player_2
for(int i=0;i<numberOfShips;i++) //checks for game over
{
if(player_1->getBoard()->getShip()[i].isSunk())
{
m_gameOver = true; //sets to true if they are sunk
}
else
{
m_gameOver = false; //sets back to false if any are not sunk and then breaks out of for loop
break;
}
}
}
}