Skip to content
This repository was archived by the owner on Nov 18, 2020. It is now read-only.

Commit 73da208

Browse files
committed
Eigth module: refactoring
1 parent d461ef4 commit 73da208

5 files changed

Lines changed: 292 additions & 22 deletions

File tree

C++ For the Rest Of Us - Course.sln

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppFTROU.Module7", "CppFTRO
2626
EndProject
2727
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpSandbox", "CSharpSandbox\CSharpSandbox.csproj", "{424F8B7F-0824-43F4-8ED3-23C7FDEE3114}"
2828
EndProject
29+
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppFTROU.Module8", "CppFTROU.Module8\CppFTROU.Module8.vcxproj", "{BEA01A3B-9F5B-48A3-B294-B08781D14897}"
30+
EndProject
2931
Global
3032
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3133
Debug|Any CPU = Debug|Any CPU
@@ -118,6 +120,16 @@ Global
118120
{424F8B7F-0824-43F4-8ED3-23C7FDEE3114}.Release|x64.Build.0 = Release|Any CPU
119121
{424F8B7F-0824-43F4-8ED3-23C7FDEE3114}.Release|x86.ActiveCfg = Release|Any CPU
120122
{424F8B7F-0824-43F4-8ED3-23C7FDEE3114}.Release|x86.Build.0 = Release|Any CPU
123+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Debug|Any CPU.ActiveCfg = Debug|Win32
124+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Debug|x64.ActiveCfg = Debug|x64
125+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Debug|x64.Build.0 = Debug|x64
126+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Debug|x86.ActiveCfg = Debug|Win32
127+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Debug|x86.Build.0 = Debug|Win32
128+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Release|Any CPU.ActiveCfg = Release|Win32
129+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Release|x64.ActiveCfg = Release|x64
130+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Release|x64.Build.0 = Release|x64
131+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Release|x86.ActiveCfg = Release|Win32
132+
{BEA01A3B-9F5B-48A3-B294-B08781D14897}.Release|x86.Build.0 = Release|Win32
121133
EndGlobalSection
122134
GlobalSection(SolutionProperties) = preSolution
123135
HideSolutionNode = FALSE

CppFTROU.Module8/CppFTROU.Module8.cpp

Lines changed: 0 additions & 20 deletions
This file was deleted.

CppFTROU.Module8/CppFTROU.Module8.vcxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@
151151
</Link>
152152
</ItemDefinitionGroup>
153153
<ItemGroup>
154-
<ClCompile Include="CppFTROU.Module8.cpp" />
154+
<ClCompile Include="TicTacToe.cpp" />
155155
</ItemGroup>
156156
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
157157
<ImportGroup Label="ExtensionTargets">

CppFTROU.Module8/CppFTROU.Module8.vcxproj.filters

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</Filter>
1616
</ItemGroup>
1717
<ItemGroup>
18-
<ClCompile Include="CppFTROU.Module8.cpp">
18+
<ClCompile Include="TicTacToe.cpp">
1919
<Filter>Arquivos de Origem</Filter>
2020
</ClCompile>
2121
</ItemGroup>

CppFTROU.Module8/TicTacToe.cpp

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
#include <stdlib.h>
5+
6+
const char * CLS = "CLS",
7+
*TOP = "top row",
8+
*MIDDLE = "middle",
9+
*BOTTOM = "bottom row",
10+
*DIAGONAL = "diagonal",
11+
*LEFT = "left column",
12+
*RIGHT = "right column";
13+
14+
const char PLAYER_X = 'X',
15+
PLAYER_O = 'O',
16+
BOARD_DIV = '|',
17+
BOARD_LINE = '-',
18+
BOARD_INTERSECTION = '+';
19+
20+
const char INPUT_PLACEHOLDERS[9] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
21+
22+
const int MAX_ATTEMPTS = 9,
23+
BOARD_WIDTH = 3;
24+
25+
typedef struct { unsigned int x, y; } board_pos;
26+
27+
board_pos * get_board_pos_by_input(int & index) {
28+
auto * pos = new board_pos();
29+
pos->x = index % BOARD_WIDTH;
30+
pos->y = (index - pos->x) / BOARD_WIDTH;
31+
return pos;
32+
}
33+
34+
void relative_board_cell(
35+
std::string & output, char & placeholder,
36+
const bool & left_corner, const bool & right_corner
37+
) {
38+
if (left_corner)
39+
output += " ";
40+
41+
if (!left_corner && !right_corner)
42+
output += BOARD_DIV;
43+
44+
output += " ";
45+
46+
if (placeholder == PLAYER_X || placeholder == PLAYER_O)
47+
output += placeholder;
48+
else
49+
output += std::to_string((int)placeholder);
50+
51+
output += " ";
52+
53+
if (right_corner)
54+
output += "\n";
55+
56+
if (!left_corner && !right_corner)
57+
output += BOARD_DIV;
58+
}
59+
60+
void board_row_separator(std::string & output) {
61+
output += " ";
62+
output.append(3, BOARD_LINE);
63+
output += BOARD_INTERSECTION;
64+
output.append(3, BOARD_LINE);
65+
output += BOARD_INTERSECTION;
66+
output.append(3, BOARD_LINE);
67+
output += "\n";
68+
}
69+
70+
bool board_check_horizontal(
71+
char(&board_inputs)[BOARD_WIDTH][BOARD_WIDTH],
72+
const int & row, const char & player
73+
) {
74+
return board_inputs[row][0] == player
75+
&& board_inputs[row][1] == player
76+
&& board_inputs[row][2] == player;
77+
}
78+
79+
bool board_check_vertical(
80+
char(&board_inputs)[BOARD_WIDTH][BOARD_WIDTH],
81+
const int & col, const char & player
82+
) {
83+
return board_inputs[0][col] == player
84+
&& board_inputs[1][col] == player
85+
&& board_inputs[2][col] == player;
86+
}
87+
88+
bool board_check_diagonal(
89+
char(&board_inputs)[BOARD_WIDTH][BOARD_WIDTH],
90+
const char & player
91+
) {
92+
return (board_inputs[0][0] == player
93+
&& board_inputs[1][1] == player
94+
&& board_inputs[2][2] == player)
95+
|| (board_inputs[0][2] == player
96+
&& board_inputs[1][1] == player
97+
&& board_inputs[2][0] == player);
98+
}
99+
100+
void board_check_player(
101+
char(&board_inputs)[BOARD_WIDTH][BOARD_WIDTH],
102+
char & winner, const char * & condition,
103+
const char & player, std::string & condition_fmt
104+
) {
105+
if (board_check_horizontal(board_inputs, 0, player)) {
106+
condition = TOP;
107+
winner = player;
108+
return;
109+
}
110+
111+
if (board_check_horizontal(board_inputs, 1, player)) {
112+
condition_fmt += MIDDLE;
113+
condition_fmt += " row";
114+
condition = condition_fmt.c_str();
115+
winner = player;
116+
return;
117+
}
118+
119+
if (board_check_horizontal(board_inputs, 2, player)) {
120+
condition = BOTTOM;
121+
winner = player;
122+
return;
123+
}
124+
125+
if (board_check_vertical(board_inputs, 0, player)) {
126+
condition = LEFT;
127+
winner = player;
128+
return;
129+
}
130+
131+
if (board_check_vertical(board_inputs, 1, player)) {
132+
condition_fmt += MIDDLE;
133+
condition_fmt += " column";
134+
condition = condition_fmt.c_str();
135+
winner = player;
136+
return;
137+
}
138+
139+
if (board_check_vertical(board_inputs, 2, player)) {
140+
condition = RIGHT;
141+
winner = player;
142+
return;
143+
}
144+
145+
if (board_check_diagonal(board_inputs, player)) {
146+
condition = DIAGONAL;
147+
winner = player;
148+
return;
149+
}
150+
}
151+
152+
void get_player_choice(
153+
int & choice, int & index, char(&board_inputs)[BOARD_WIDTH][BOARD_WIDTH],
154+
bool & is_occupied, char & current_player, char & last_player, int & attempts
155+
) {
156+
if (choice != 0 && choice != -1) {
157+
index = choice - 1;
158+
159+
auto * pos = get_board_pos_by_input(index);
160+
auto * cell = &board_inputs[pos->y][pos->x];
161+
162+
is_occupied = *cell == PLAYER_X || *cell == PLAYER_O;
163+
if (!is_occupied) {
164+
*cell = current_player;
165+
last_player = current_player;
166+
current_player = current_player == PLAYER_X ? PLAYER_O : PLAYER_X;
167+
attempts++;
168+
}
169+
}
170+
}
171+
172+
bool check_for_end_game(int & attempts, char & winner) {
173+
return winner != ' ' || attempts == MAX_ATTEMPTS;
174+
}
175+
176+
void display_board(void) {
177+
auto last_player = PLAYER_O,
178+
current_player = PLAYER_X,
179+
winner = ' ';
180+
181+
auto attempts = 0,
182+
choice = -1,
183+
index = 0;
184+
185+
auto is_occupied = false, is_game_over = false;
186+
char board_inputs[BOARD_WIDTH][BOARD_WIDTH] = {};
187+
const char * condition;
188+
std::string output, condition_fmt;
189+
190+
for (auto row = 0; row < BOARD_WIDTH; row++)
191+
for (auto col = 0; col < BOARD_WIDTH; col++)
192+
board_inputs[row][col] = 1 + col + row * BOARD_WIDTH;
193+
194+
condition_fmt.clear();
195+
196+
while (true) {
197+
output.clear();
198+
output += "Current board state:\n";
199+
200+
get_player_choice(
201+
choice, index, board_inputs, is_occupied,
202+
current_player, last_player, attempts
203+
);
204+
205+
for (index = 0; index < BOARD_WIDTH; index++)
206+
{
207+
// Board formatting pattern:
208+
// 1 | 2 | 3
209+
// ---+---+---
210+
// 4 | 5 | 6
211+
// ---+---+---
212+
// 7 | 8 | 9
213+
214+
auto is_mid_row = index == 1;
215+
if (is_mid_row)
216+
board_row_separator(output);
217+
218+
relative_board_cell(output, board_inputs[index][0], true, false);
219+
relative_board_cell(output, board_inputs[index][1], false, false);
220+
relative_board_cell(output, board_inputs[index][2], false, true);
221+
222+
if (is_mid_row)
223+
board_row_separator(output);
224+
}
225+
226+
if (choice == 0)
227+
output += "\nNot a valid choice. Try again.\n";
228+
229+
if (is_occupied) {
230+
output += "\nThat square is not available. Try again.\n";
231+
is_occupied = false;
232+
}
233+
234+
board_check_player(board_inputs, winner, condition, PLAYER_X, condition_fmt);
235+
236+
if (winner != PLAYER_X)
237+
board_check_player(board_inputs, winner, condition, PLAYER_O, condition_fmt);
238+
239+
if (check_for_end_game(attempts, winner))
240+
break;
241+
242+
output += "\nPlayer ";
243+
output += current_player;
244+
output += ", enter a number between 1 and 9: ";
245+
std::cout << output << std::flush;
246+
std::cin >> choice;
247+
std::system(CLS);
248+
249+
if (choice < 1 || choice > 9)
250+
choice = 0;
251+
}
252+
253+
if (winner != ' ') {
254+
output += "\nPlayer ";
255+
output += winner;
256+
output += " wins on the ";
257+
output += condition;
258+
output += "!";
259+
}
260+
else
261+
output += "\nDraw. Nobody wins.";
262+
263+
std::cout << output << std::endl << std::endl;
264+
}
265+
266+
int main(void)
267+
{
268+
/*
269+
[Module 8] - Application Structure:
270+
This is a refactored version of TicTacToe.cpp from module 6.
271+
272+
Contains code organisation, virtualization and more changes
273+
for ease logic and code concept understanding.
274+
*/
275+
display_board();
276+
277+
return EXIT_SUCCESS;
278+
}

0 commit comments

Comments
 (0)