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;
}
}
}
1 Answer 1
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#.
-
\$\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\$user10443653– user104436532018年10月12日 04:57:10 +00:00Commented 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\$Marc Adler– Marc Adler2018年10月12日 16:38:42 +00:00Commented 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\$Marc Adler– Marc Adler2018年10月12日 16:39:28 +00:00Commented Oct 12, 2018 at 16:39
-
\$\begingroup\$ thank you vert much. I will try to reprogram it based on your advice. \$\endgroup\$user10443653– user104436532018年10月13日 13:03:58 +00:00Commented Oct 13, 2018 at 13:03