1
\$\begingroup\$

I have been studying C#, and I am trying to model the Tic Tac Toe game. Is my program reasonable or is there anything I need to improve?

 enum Result
{
 None,
 Win,
 Draw
}
public class TicTacToe
{
 static char[] board = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
 char player = 'O';
 Result result = Result.None;
 public void PlayGame()
 {
 Intro();
 do
 {
 Console.Clear();
 Console.WriteLine("Player 1 : O Player 2 : X");
 DrawBoard();
 Console.WriteLine($"\nPlayer {player}'s Turn \nPlease Enter the empty number");
 label:
 int choice = 0;
 while (!int.TryParse(Console.ReadLine(), out choice))
 {
 Console.WriteLine("Enter the num please");
 }
 if (choice >= 10)
 {
 Console.WriteLine("Please enter btw 1 - 9");
 goto label;
 }
 if (board[choice] != 'X' && board[choice] != 'O')
 {
 board[choice] = player;
 ChangeTurn();
 }
 CheckWin();
 } while (result != Result.Draw && result != Result.Win);
 Console.Clear();
 DrawBoard();
 GameResult();
 Console.ReadKey();
 }
 void ChangeTurn()
 {
 if (player == 'X')
 player = 'O';
 else if (player == 'O')
 player = 'X';
 }
 void GameResult()
 {
 if (result == Result.Win)
 {
 ChangeTurn();
 Console.WriteLine("Player {0} has won", player);
 }
 else if(result == Result.Draw)
 {
 Console.WriteLine("Draw");
 }
 Console.ReadLine();
 }
 void Intro()
 {
 Console.WriteLine("Welcome to TieTacToe");
 Console.WriteLine("Press any Key to continue");
 Console.ReadKey();
 Console.Clear();
 }
 void DrawBoard()
 {
 int x = 1;
 Console.WriteLine();
 for (int row = 0; row < 3; row++)
 {
 Console.Write("| ");
 for (int col = 0; col < 3; col++)
 {
 Console.Write(board[x]);
 Console.Write(" | ");
 x++;
 }
 Console.WriteLine();
 }
 } 
 void CheckWin()
 {
 // horzontial
 if (board[1] == board[2] && board[2] == board[3])
 {
 result = Result.Win;
 }
 else if (board[4] == board[5] && board[5] == board[6])
 {
 result = Result.Win;
 }
 else if (board[7] == board[8] && board[8] == board[9])
 {
 result = Result.Win;
 }
 // vertical
 else if (board[1] == board[4] && board[4] == board[7])
 {
 result = Result.Win;
 }
 else if (board[2] == board[5] && board[5] == board[8])
 {
 result = Result.Win;
 }
 else if (board[3] == board[6] && board[6] == board[9])
 {
 result = Result.Win;
 }
 // X
 else if (board[1] == board[5] && board[5] == board[9])
 {
 result = Result.Win;
 }
 else if (board[3] == board[5] && board[5] == board[7])
 {
 result = Result.Win;
 }
 else if (board[1] != '1' && board[2] != '2' && board[3] != '3' && board[4] != '4' && board[5] != '5' && board[6] != '6' && board[7] != '7' && board[8] != '8' && board[9] != '9')
 {
 result = Result.Draw;
 }
 else
 {
 result = Result.None;
 }
 }
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Oct 11, 2018 at 15:20
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

If you want to be completely safe, I would also check the 'choice' to make sure that it was not a negative number.

Goto's should be avoided. You can easily refactor your code to use a while loop and break.

In your function GameResult(), I would use a switch statement instead of the if chain.

I am also thinking that CheckWin() might be a bit too cumbersome with all of the if statements and the checking of the individual cells. I might keep a "shadow board" behind the scenes, where a cell is 1 if it is an X and -1 if it is an O. Some simple addition and a test to see if the Math.Abs(sum) == 3 is an easy way to test for a win. For example:

if (Math.Abs(board[1] + board[2] + board[3]) == 3)
 result = Result.Win;

You can even refactor what I wrote above by keeping a list of the triplets to check.

Good luck with your studies of C#.

Sᴀᴍ Onᴇᴌᴀ
29.5k16 gold badges45 silver badges201 bronze badges
answered Oct 11, 2018 at 16:35
\$\endgroup\$
4
  • \$\begingroup\$ thank you for your helpful comments. One thing, I understand that CheckWin()is repeated too much with if statements. How can I keep "shadow board". If its not too much asking, could you show me? \$\endgroup\$ Commented Oct 12, 2018 at 4:57
  • \$\begingroup\$ The "shadow board" would be the exact same thing as your variable 'board', but it would just contain 3 values ... -1 for the letter O, 0 if the box has not been filled out, and 1 for the letter X. static int[] shadowBoard = new int[10]; When the user fills in the X or O, you also fill in the shadowBoard with the appropriate numeric value. board[choice] = player; shadowBoard[choice] = player == 'X' ? 1 : -1; \$\endgroup\$ Commented Oct 12, 2018 at 16:38
  • \$\begingroup\$ Can someone please help me with the formatting for my comment above? I tried indenting by 4 spaces, but I cannot get the text to show up as code. \$\endgroup\$ Commented Oct 12, 2018 at 16:39
  • \$\begingroup\$ thank you vert much. I will try to reprogram it based on your advice. \$\endgroup\$ Commented Oct 13, 2018 at 13:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.