-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchess.cpp
More file actions
260 lines (231 loc) · 8.17 KB
/
Copy pathchess.cpp
File metadata and controls
260 lines (231 loc) · 8.17 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
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
/** Tanner Sundwall, 2/22/19, CS410P, HW4: Chess
*
* chess.cpp
*
* The goal of this project is to create a program that utilizes what I've learned
* from this course.
*
* My project in particular is a functional chess game playable from within
* the command console.
*
* Features that made it:
* * All unique movesets of all 6 types of pieces.
* * Actual win condition of chess: not capturing the king, but checkmate.
* * Notify player of check.
* * Allow players to forfeit or draw.
* * Stalemate condition.
* * Prevent player from moving king into a position to be captured.
* * Tracker for captured and uncaptured pieces.
* * Navigatable command-based menus.
* * Other stuff.
*
* Features that didn't make it:
* * Special moves: castling, pawn promotion, or en passant.
* * Draw conditions: threefold repetition, fifty-move rule.
* * AI
* * Non-broken input parser. The current method in which input is parsed is very easy to segfault.
*/
#include "board.h"
#include <iostream>
using namespace std;
bool checkOptionSelected(int option, int optionCount);
void printInstructions();
void printPieceInfo();
int main(int argc, char **argv)
{
// This is the entire chess game's loop. It can only be stopped by inputting
// the option for "Exit" from the main menu.
//
// Due to everything in here using cin >> ..., it's rather easy to break. Sorry about that.
for (;;)
{
int option = 0; // Option selected by the user.
int optionCount = 0; // Number of options available for user to select.
// Main menu loop.
do
{
optionCount = 0;
cout << "\nWelcome to Tanner's console-based chess game!\n"
<< "Please input a number to select an option below:\n"
<< " " << ++optionCount << ". Play against human\n"
<< " " << ++optionCount << ". Play against AI\n"
<< " " << ++optionCount << ". Instructions\n"
<< " " << "0. Exit\n"
<< " : ";
cin >> option;
cin.ignore();
// Exit chess program.
if (!option)
{
return 0;
}
} while (!checkOptionSelected(option, optionCount));
// Play chess against a human.
if (option == 1)
{
Board board;
board.play_human();
}
// Play chess against AI.
else if (option == 2)
{
Board board;
board.play_ai();
}
// Print chess instructions.
else if (option == 3)
{
printInstructions();
}
}
}
/**
* Ensures that the user inputs an option within the range of options available.
* @param option Option chosen by the user.
* @param optionCount Number of options available to pick from.
* @return Whether or not the user inputted a valid option value.
*/
bool checkOptionSelected(int option, int optionCount)
{
if (option > 0 && option <= optionCount)
{
return true;
}
cout << "\nInvalid user input. Please input a number between 0 and " << optionCount << " next time." << endl;
pressEnterToContinue();
return false;
}
/**
* Print chess instructions.
*/
void printInstructions()
{
int option = 0;
int optionCount = 0;
// Main loop for instructions menu.
// Will loop forever until user inputs command for "Exit".
for (;;)
{
do
{
optionCount = 0;
cout << "\nWhat would you like to know about this chess game?\n"
<< "Please input a number to select an option below:\n"
<< " " << ++optionCount << ". The Pieces\n"
<< " " << ++optionCount << ". How to Play\n"
<< " " << "0. Exit\n"
<< " : ";
cin >> option;
cin.ignore();
// Exit printInstructions function
if (!option)
{
return;
}
} while (!checkOptionSelected(option, optionCount));
// Bring us to menu for displaying info about each chess piece.
if (option == 1)
{
printPieceInfo();
}
// Print directions regarding how to actually play this chess game.
else if (option == 2)
{
cout << "\nTwo players will take turns moving their pieces.\n"
<< "The game will indicate whose turn (white or black) it is.\n"
<< "The player whose turn it is will need to input the location\n"
<< "of the piece they want to move, and then the location they\n"
<< "want to move it to.\n"
<< "For example:\n"
<< " It's white's turn to move.\n"
<< " White wants to move a pawn located at d2 to d4.\n"
<< " White needs to input: d2 d4\n"
<< " If the move is valid, the board will be printed again\n"
<< " with that pawn now located at d4 rather than d2.\n";
pressEnterToContinue();
}
}
}
/**
* Print piece info.
*/
void printPieceInfo()
{
int option = 0;
int optionCount = 0;
// Main loop for piece info menu.
// Will loop forever like the other menus until the user inputs command for "Exit".
for (;;)
{
do
{
optionCount = 0;
cout << "\nWhich chess piece would you like to know more about?\n"
<< "Please input a number to select an option below:\n"
<< " " << ++optionCount << ". The King\n"
<< " " << ++optionCount << ". The Queen\n"
<< " " << ++optionCount << ". The Rooks\n"
<< " " << ++optionCount << ". The Bishops\n"
<< " " << ++optionCount << ". The Knights\n"
<< " " << ++optionCount << ". The Pawns\n"
<< " " << "0. Exit\n"
<< " : ";
cin >> option;
cin.ignore();
// Exit printPieceInfo function
if (!option)
{
return;
}
} while (!checkOptionSelected(option, optionCount));
// Print info about King.
if (option == 1)
{
cout << "\nThe King\n"
<< "The most important piece in the game of chess.\n"
<< "If this piece is put in checkmate (put in a situation\n"
<< "where capture is unavoidable), the owner loses the game.\n"
<< "Moves exactly one vacant square in any direction." << endl;
pressEnterToContinue();
}
// Print info about Queen.
else if (option == 2)
{
cout << "\nThe Queen\n"
<< "Moves any number of vacant squares in any direction." << endl;
pressEnterToContinue();
}
// Print info about Rook.
else if (option == 3)
{
cout << "\nThe Rooks\n"
<< "Move any number of vacant squares forwards, backwards,\n"
<< "left, or right in a straight line." << endl;
pressEnterToContinue();
}
// Print info about Bishop.
else if (option == 4)
{
cout << "\nThe Bishops\n"
<< "Move any number of vacant squares diagonally in a straight line." << endl;
pressEnterToContinue();
}
// Print info about Knight.
else if (option == 5)
{
cout << "\nThe Knights\n"
<< "Move on an extended diagonal from one corner of any 2x3 rectangle\n"
<< "of squares to the furthest opposite corner." << endl;
pressEnterToContinue();
}
// Print info about Pawn.
else if (option == 6)
{
cout << "\nThe Pawns\n"
<< "Move forward exactly one space, or two spaces when on their starting\n"
<< "square. Can only capture the opponent's pieces one space forward to the\n"
<< "left or right diagonally." << endl;
pressEnterToContinue();
}
}
}