1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace TicTacToe
7 {
8 public class Player
9 {
10 private string playerPiece = "n";
11
12
13 //METHODS
14 //Move takes a multi-dimensional array board, and a string piece that are both ref
15 public void Move(ref string[,] board, ref string piece)
16 {
17 playerPiece = piece;
18 int rows = 3;
19 int columns = 3;
20 bool turnOver = false;
21 bool validMove = false;
22 string playerMove;
23
24
25 do
26 {
27 //Reset counters
28 int availabilityCounter = 0;
29 bool playerMoveValid = false;
30
31 ///Check the board to see if any moves are available
32 for (int i = 0; i < rows; i++)
33 {
34 for (int j = 0; j < columns; j++)
35 {
36
37
38 if ((board[i, j] == "o") || (board[i, j] == "x"))
39 {
40 availabilityCounter++;
41 if (availabilityCounter == 9)
42 {
43 turnOver = true;
44 }
45 }
46
47 }
48 }
49
50
51 if (!turnOver)
52 {
53
54
55 Console.WriteLine("\n\nPLEASE CHOOSE A NUMBER FOR YOUR NEXT MOVE: \n\n");
56 playerMove = Console.ReadLine();
57 do
58 {
59
60 //See if the player's move is equal to a string 1-9 and increase the playerMove counter if it is found
61 //If the playerMove counter = 1 then the move has been found, if not then please ask the player to enter a valid move
62 for (int r = 1; r <= 9; r++)
63 {
64 if (playerMove == Convert.ToString(r))
65 {
66 playerMoveValid = true;
67 }
68 }
69
70 //Make sure the player has entered a space on the board
71 //if they haven't make them choose again
72 if (!playerMoveValid)
73 {
74 Console.WriteLine("\nThat is not a valid choice please enter a new number...\n");
75 playerMove = Console.ReadLine();
76 }
77
78 } while (!playerMoveValid);
79
80 //This loop searchs through the board looking for player's desired move while his/her turn is not over
81 for (int i = 0; i < rows; i++)
82 {
83 for (int j = 0; j < columns; j++)
84 {
85
86
87 //Find the player's desired move, see if the spot is occupied, if not, place the player piece
88 if ((board[i, j] == playerMove) & (board[i, j] != "o") & (board[i, j] != "x"))
89 {
90 board[i, j] = playerPiece;
91 turnOver = true;
92 validMove = true;
93 }
94
95 }
96 }
97
98 //If the move is not available because the space is occupied inform the player
99 if (!validMove)
100 {
101 Console.WriteLine("THAT MOVE IS NOT AVAILABLE!\n");
102 }
103
104 }
105
106 //Updated so that while statement does check for mutually exclusive events. turnOver will never be true when validMove is false so I only need to check one of them.
107 } while ((!turnOver));
108
109 }//End move player
110
111 }//End player class
112
113
114 public class Computer
115 {
116 private string computerPiece = "n";
117
118 //METHODS
119 //Move takes a multidimensional array board refernce and a string piece reference
120 public void Move(ref string[,] board, ref string cPiece)
121 {
122 //create an instance of the random class
123 Random RandomClass = new Random();
124 computerPiece = cPiece;
125 bool turnOver = false;
126 int rows = 3;
127 int columns = 3;
128
129 //AI
130 //The computer will make a move based on random numbers
131 do
132 {
133
134 int availabilityCounter = 0;
135
136 ///Check the board to see if any moves are available
137 for (int i = 0; i < rows; i++)
138 {
139 for (int j = 0; j < columns; j++)
140 {
141
142 if ((board[i, j] == "o") || (board[i, j] == "x"))
143 {
144 availabilityCounter++;
145 if (availabilityCounter == 9)
146 {
147 turnOver = true;
148 }
149 }
150 }
151 }
152
153 if (!turnOver)
154 {
155
156
157 int randomOne = RandomClass.Next(0, 3);
158 int randomTwo = RandomClass.Next(0, 3);
159
160 //End turn when the computer places a piece
161 if ((board[randomOne, randomTwo] != "x") & (board[randomOne, randomTwo] != "o"))
162 {
163 board[randomOne, randomTwo] = cPiece;
164
165 turnOver = true;
166 }
167 }
168
169 } while ((!turnOver));
170
171 }//End Move
172
173 }//End Computer
174
175
176
177 public class Board
178 {
179 //Creates a game board with pre-set values
180 private string[,] gameBoard =
181 {
182 {"1","2","3"}, {"4","5","6"}, {"7","8","9"}
183 };
184
185
186 //Methods
187 //Display just displays the updated game board
188 public void Display()
189 {
190
191 Console.WriteLine("\n{0} {1} {2}\n", gameBoard[0, 0], gameBoard[0, 1], gameBoard[0, 2]);
192 Console.WriteLine("{0} {1} {2}\n", gameBoard[1, 0], gameBoard[1, 1], gameBoard[1, 2]);
193 Console.WriteLine("{0} {1} {2}\n\n", gameBoard[2, 0], gameBoard[2, 1], gameBoard[2, 2]);
194
195 }
196
197 //CheckBoard accepts a board and checks it to see who has won, then returns a string that describes who won
198 public string Check()//use gameBoard member here instead!
199 {
200 string gameOver = "n";
201
202
203 //Conditions for winning the game
204 string[,] winningCombos =
205 {
206 {gameBoard[0,0], gameBoard[0,1], gameBoard[0,2]},
207 {gameBoard[1,0], gameBoard[1,1], gameBoard[1,2]},
208 {gameBoard[2,0], gameBoard[2,1], gameBoard[2,2]},
209 {gameBoard[0,0], gameBoard[1,0], gameBoard[2,0]},
210 {gameBoard[0,1], gameBoard[1,1], gameBoard[2,1]},
211 {gameBoard[0,2], gameBoard[1,2], gameBoard[2,2]},
212 {gameBoard[0,0], gameBoard[1,1], gameBoard[2,2]},
213 {gameBoard[0,2], gameBoard[1,1], gameBoard[2,0]}
214 };
215
216 int totalCombos = 8;
217
218 //Check the Board to see if anyone has won
219 for (int i = 0; i < totalCombos; i++)
220 {
221
222 //Check all the winning rows to see if x's won
223 if ((winningCombos[i, 0] == "x") & (winningCombos[i, 1] == "x") & (winningCombos[i, 2] == "x"))
224 {
225 gameOver = "X";
226 }
227
228 //Check all the winning rows to see if o's have won
229 if ((winningCombos[i, 0] == "o") & (winningCombos[i, 1] == "o") & (winningCombos[i, 2] == "o") & (gameOver != "X"))
230 {
231 gameOver = "O";
232 }
233
234 }
235
236 //return the status of the game
237 return gameOver;
238
239 }//End Check
240
241 //accessor method for retrieving the board
242 public string[,] Get()
243 {
244 return gameBoard;
245 }
246
247 }//End Board
248
249
250 public class GameLoop
251 {
252
253
254 public void Run()
255 {
256 string userResponse = "";
257 string gameStatus = "n";
258
259 do
260 {
261
262 Console.WriteLine("\n\nWELCOME TO ANEXA'S TIC TAC TOE GAME!!");
263
264 //Create a new Player, a new Board, and a new Computer
265 Player newPlayer = new Player();
266 Computer newComputer = new Computer();
267 Board newBoard = new Board();
268 //the variable turn will helps to determine when the game is a tie
269 int turn = 0;
270
271 //Use the Board accessor method to get the newly created board and store it in newGameBoard
272 string[,] newGameBoard = newBoard.Get();
273
274
275 Console.WriteLine("\nWould you like to be X's or O's?");
276 string userXorO = Console.ReadLine();
277
278 //If the user does not enter x or o then keep asking until they do
279 do
280 {
281 if ((userXorO != "x") & (userXorO != "o"))
282 {
283 Console.WriteLine("You must type lower case x or lower case o to continue: ");
284 userXorO = Console.ReadLine();
285 }
286
287 } while ((userXorO != "x") & (userXorO != "o"));
288
289 //display the updated newGameBoard
290 newBoard.Display();
291
292
293
294 do
295 {
296
297 string playerGamePiece = userXorO;
298
299 //If the player chooses x then they will always move first
300 if (userXorO == "x")
301 {
302 string computerPiece = "o";
303
304 //Get the player move
305 newPlayer.Move(ref newGameBoard, ref playerGamePiece);
306 //Get the status of the game after the player's move
307 gameStatus = newBoard.Check();
308 //Display the updated board after the move
309 newBoard.Display();
310 //increase the turn count so we can tell when there's a tie
311 turn++;
312
313 //same logic as player move
314 newComputer.Move(ref newGameBoard, ref computerPiece);
315 gameStatus = newBoard.Check();
316 newBoard.Display();
317 turn++;
318
319 }
320
321 //if the player chooses o then they will always move after the computer
322 else if (userXorO == "o")
323 {
324 string computerPiece = "x";
325
326 //same as above
327 newComputer.Move(ref newGameBoard, ref computerPiece);
328 gameStatus = newBoard.Check();
329 newBoard.Display();
330 turn++;
331
332 //same as above
333 newPlayer.Move(ref newGameBoard, ref playerGamePiece);
334 gameStatus = newBoard.Check();
335 newBoard.Display();
336 turn++;
337 }
338
339
340 //if the gameStatus has X as the winner, and the player's piece is X, then congratulate them
341 if ((gameStatus == "X") & (userXorO == "x"))
342 {
343 Console.WriteLine("YOU WON!\n");
344 Console.WriteLine("Would you like to play again? (y or n)");
345 userResponse = Console.ReadLine();
346 }
347
348 //if the game status has X as the winner and the player piece is o, then tell them they lost
349 else if ((gameStatus == "X") & (userXorO == "o"))
350 {
351 Console.WriteLine("YOU LET THE COMPUTER BEAT YOU?\n");
352 Console.WriteLine("Would you like to play again? ( y or n )");
353 userResponse = Console.ReadLine();
354 }
355
356 //Same logic as above
357 if ((gameStatus == "O") & (userXorO == "x"))
358 {
359 Console.WriteLine("YOU LET THE COMPUTER BEAT YOU?\n");
360 Console.WriteLine("Would you like to play again? ( y or n )");
361 userResponse = Console.ReadLine();
362 }
363
364 else if ((gameStatus == "O") & (userXorO == "o"))
365 {
366 Console.WriteLine("YOU WON!\n");
367 Console.WriteLine("Would you like to play again? (y or n)");
368 userResponse = Console.ReadLine();
369 }
370
371 //if we have gone through all 9 turns and the game status does not show x or o as a winner then there is a tie, inform the player
372 if ((turn > 9) & (gameStatus != "X") & (gameStatus != "O"))
373 {
374 Console.WriteLine("IT'S A TIE!!!\n");
375 Console.WriteLine("WOULD YOU LIKE TO PLAY AGAIN? (y or n)\n\n");
376 userResponse = Console.ReadLine();
377 gameStatus = "T";
378 }
379
380 //continue to get player moves while the there is no winner and no tie
381 } while ((gameStatus != "X") & (gameStatus != "O") & (gameStatus != "T"));
382
383 //If the player chooses to quit then end the overall game loop. If the player chooses to continue playing start at the top of the outer do, while loop
384 } while (userResponse != "n");
385
386 }//Run
387
388 static void Mainn()
389 {
390 //Create an instance of the gameloop class and run it
391 GameLoop g = new GameLoop();
392 g.Run();
393 }
394
395 }//End GameLoop
396 }