Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualKhatharr

Posted 15 November 2012 - 10:25 PM

SpaceFree() could be IsSpaceFree(), for more clarity that it's checking rather than freeing.

Looking mostly good so far. (I don't like your formatting but that's a preference issue, lol.)

Will edit here after looking at the rest.

In the main fn, why do-while rather than just while? You set the condition prior to the loop. Also, it's not an issue in this case since the code is so short and clean, but in terms of design the 'play again' block could be segregated to its own function.

DrawExampleBoard() seems superfluous. All it does is write some lines and its only call is in the midst of a series of drawn lines. Do you intend to call it elsewhere in a later version?

You call DrawBoard() prior to calling TicTacToeGame(). Why not move it into the beginning of TicTacToeGame()? It seems more natural for it to be there.

I see main()'s board getting passed into a lot of member functions. Why not make it a member variable?

TakeInput() - huge switch statement in here. DRY. Convert the enum to your target value (It feels really gross doing this with a switch, but idk enough about C# console input to do it by character value.) and then run the code once on the derived value. If you want to change the action taken on the value later you won't need to change it nine times. Your code will also be smaller.

[source lang="csharp"]int slot = -1;switch(keyPressed.Key) { //... case ConsoleKey.NumPad9: case ConsoleKey.D9: slot = 8; break; default: Console.WriteLine("\nPlease use your numpad or the keys 1-9 to choose a spot to mark."); break;}if(slot != -1) { validKeyPressed = MakeMove(board, marker, slot);}[/source]

TakeInput() has another do-while that could be a while.


[source lang="csharp"] if(MakeMove(board, marker, 0)) { validKeyPressed = true; break; //this line is not necessary } break;[/source]

Still looking.

Going by function name, TakeInput() should not call MakeMove(). It should return the derived value and then the caller of TakeInput() should call MakeMove() with that value. This would technically be the better thing to do here, but in this case you could get away with just renaming TakeInput() to TakeTurn(), since that's what it's really doing here.

Did you not get a compiler warning for MakeMove()'s return paths? This is how to avoid it:
[source lang="csharp"] // Marks spot on the tic tac toe board with a marker if the space is free static bool MakeMove(char[] board, char marker, int move) { if(SpaceFree(board, move)) { board[move] = marker; return true; } Console.WriteLine("\nThat spot is taken."); return false; }[/source]

Try to find ways to make your data work for you, instead of you working for the data:
[source lang="csharp"] // The Tic Tac Toe Game's heart static void TicTacToeGame(char[] board) { char playerTurn = 'O'; string winner = ""; while(!gameOver) { Console.WriteLine("It is " + playerTurn + "'s turn to move!"); TakeInput(board, playerTurn); DrawBoard(board); winner = CheckWinner(board, playerTurn); playerTurn = (playerTurn == 'O') ? 'X' : 'O'; } Console.WriteLine(winner); }[/source]

This may save you some room:
[source lang="csharp"] static bool CheckWinSet(char board[], int a, int b, int c) { return (board[a] == board[b]) && (board[b] == board[c]); } static string CheckWinner(char[] board, char marker) { while(true) { //for breaking // Horizontal Win if(gameOver = CheckWinSet(board, 0, 1, 2)) {break;} if(gameOver = CheckWinSet(board, 3, 4, 5)) {break;} if(gameOver = CheckWinSet(board, 6, 7, 8)) {break;} // Vertical Win if(gameOver = CheckWinSet(board, 0, 3, 6)) {break;} if(gameOver = CheckWinSet(board, 1, 4, 7)) {break;} if(gameOver = CheckWinSet(board, 2, 5, 8)) {break;} // Diagonal Win if(gameOver = CheckWinSet(board, 0, 4, 8)) {break;} if(gameOver = CheckWinSet(board, 2, 4, 6)) {break;} break; } if(gameOver) { return marker + " wins!\n"; } // Tie Game if(BoardFull(board)) { gameOver = true; return "No one wins, it's a tie!\n"; } return null; }[/source]

You may be able to find a stdlib function that searches for a specific character in a string. I dunno if C# has it, but if so you can tack a zero on to the end of your board array and then search it for ' ' rather than using BoardFull().


Overall, this is pretty good. It's clean and easy to read and I was able to track the flow of the program with no difficulty. I think you're quite ready to move on to the next level of complexity. You may want to look into some articles about general program structure and etc, but really you did quite well here. I have no significant complaints. I know I said a lot, but I don't want you to think that your own version was 'wrong'. It's just that there's always a 'better' way. (I'm resisting the temptation to change CheckWinner() to a loop that runs through static int[3] arrays) I'm sure that there are far better ways than what I showed you as well. You'll naturally pick up better flow habits as you practice and see more code and come across interesting ideas.

Good job! Posted Image

#8Khatharr

Posted 15 November 2012 - 10:23 PM

SpaceFree() could be IsSpaceFree(), for more clarity that it's checking rather than freeing.

Looking mostly good so far. (I don't like your formatting but that's a preference issue, lol.)

Will edit here after looking at the rest.

In the main fn, why do-while rather than just while? You set the condition prior to the loop. Also, it's not an issue in this case since the code is so short and clean, but in terms of design the 'play again' block could be segregated to its own function.

DrawExampleBoard() seems superfluous. All it does is write some lines and its only call is in the midst of a series of drawn lines. Do you intend to call it elsewhere in a later version?

You call DrawBoard() prior to calling TicTacToeGame(). Why not move it into the beginning of TicTacToeGame()? It seems more natural for it to be there.

I see main()'s board getting passed into a lot of member functions. Why not make it a member variable?

TakeInput() - huge switch statement in here. DRY. Convert the enum to your target value (It feels really gross doing this with a switch, but idk enough about C# console input to do it by character value.) and then run the code once on the derived value. If you want to change the action taken on the value later you won't need to change it nine times. Your code will also be smaller.

[source lang="csharp"]int slot = -1;switch(keyPressed.Key) { //... case ConsoleKey.NumPad9: case ConsoleKey.D9: slot = 8; break; default: Console.WriteLine("\nPlease use your numpad or the keys 1-9 to choose a spot to mark."); break;}if(slot != -1) { validKeyPressed = MakeMove(board, marker, slot);}[/source]

TakeInput() has another do-while that could be a while.


[source lang="csharp"] if(MakeMove(board, marker, 0)) { validKeyPressed = true; break; //this line is not necessary } break;[/source]

Still looking.

Going by function name, TakeInput() should not call MakeMove(). It should return the derived value and then the caller of TakeInput() should call MakeMove() with that value. This would technically be the better thing to do here, but in this case you could get away with just renaming TakeInput() to TakeTurn(), since that's what it's really doing here.

Did you not get a compiler warning for MakeMove()'s return paths? This is how to avoid it:
[source lang="csharp"] // Marks spot on the tic tac toe board with a marker if the space is free static bool MakeMove(char[] board, char marker, int move) { if(SpaceFree(board, move)) { board[move] = marker; return true; } Console.WriteLine("\nThat spot is taken."); return false; }[/source]

Try to find ways to make your data work for you, instead of you working for the data:
[source lang="csharp"] // The Tic Tac Toe Game's heart static void TicTacToeGame(char[] board) { char playerTurn = 'O'; string winner = ""; while(!gameOver) { Console.WriteLine("It is " + playerTurn + "'s turn to move!"); TakeInput(board, playerTurn); DrawBoard(board); winner = CheckWinner(board, playerTurn); playerTurn = (playerTurn == 'O') ? 'X' : 'O'; } Console.WriteLine(winner); }[/source]

This may save you some room:
[source lang="csharp"] static bool CheckWinSet(char board[], int a, int b, int c) { return (board[a] == board[b]) && (board[b] == board[c]); } static string CheckWinner(char[] board, char marker) { while(true) { //for breaking // Horizontal Win if(gameOver = CheckWinSet(board, 0, 1, 2)) {break;} if(gameOver = CheckWinSet(board, 3, 4, 5)) {break;} if(gameOver = CheckWinSet(board, 6, 7, 8)) {break;} // Vertical Win if(gameOver = CheckWinSet(board, 0, 3, 6)) {break;} if(gameOver = CheckWinSet(board, 1, 4, 7)) {break;} if(gameOver = CheckWinSet(board, 2, 5, 8)) {break;} // Diagonal Win if(gameOver = CheckWinSet(board, 0, 4, 8)) {break;} if(gameOver = CheckWinSet(board, 2, 4, 6)) {break;} break; } if(gameOver) { return marker + " wins!\n"; } // Tie Game if(BoardFull(board)) { gameOver = true; return "No one wins, it's a tie!\n"; } return null; }[/source]

You may be able to find a stdlib function that searches for a specific character in a string. I dunno if C# has it, but if so you can tack a zero on to the end of your board array and then search it for ' ' rather than using BoardFull().


Overall, this is pretty good. It's clean and easy to read and I was able to track the flow of the program with no difficulty. I think you're quite ready to move on to the next level of complexity. You may want to look into some articles about general program structure and etc, but really you did quite well here. I have no significant complaints. I know I said a lot, but I don't want you to think that your own version was 'wrong'. It's just that there's always a 'better' way. I'm sure that there are far better ways than what I showed you as well. You'll naturally pick up better flow habits as you practice and see more code and come across interesting ideas.

Good job! Posted Image

#7Khatharr

Posted 15 November 2012 - 10:18 PM

SpaceFree() could be IsSpaceFree(), for more clarity that it's checking rather than freeing.

Looking mostly good so far. (I don't like your formatting but that's a preference issue, lol.)

Will edit here after looking at the rest.

In the main fn, why do-while rather than just while? You set the condition prior to the loop. Also, it's not an issue in this case since the code is so short and clean, but in terms of design the 'play again' block could be segregated to its own function.

DrawExampleBoard() seems superfluous. All it does is write some lines and its only call is in the midst of a series of drawn lines. Do you intend to call it elsewhere in a later version?

You call DrawBoard() prior to calling TicTacToeGame(). Why not move it into the beginning of TicTacToeGame()? It seems more natural for it to be there.

I see main()'s board getting passed into a lot of member functions. Why not make it a member variable?

TakeInput() - huge switch statement in here. DRY. Convert the enum to your target value (It feels really gross doing this with a switch, but idk enough about C# console input to do it by character value.) and then run the code once on the derived value. If you want to change the action taken on the value later you won't need to change it nine times. Your code will also be smaller.

[source lang="csharp"]int slot = -1;switch(keyPressed.Key) { //... case ConsoleKey.NumPad9: case ConsoleKey.D9: slot = 8; break; default: Console.WriteLine("\nPlease use your numpad or the keys 1-9 to choose a spot to mark."); break;}if(slot != -1) { validKeyPressed = MakeMove(board, marker, slot);}[/source]

TakeInput() has another do-while that could be a while.


[source lang="csharp"] if(MakeMove(board, marker, 0)) { validKeyPressed = true; break; //this line is not necessary } break;[/source]

Still looking.

Going by function name, TakeInput() should not call MakeMove(). It should return the derived value and then the caller of TakeInput() should call MakeMove() with that value. This would technically be the better thing to do here, but in this case you could get away with just renaming TakeInput() to TakeTurn(), since that's what it's really doing here.

Did you not get a compiler warning for MakeMove()'s return paths? This is how to avoid it:
[source lang="csharp"] // Marks spot on the tic tac toe board with a marker if the space is free static bool MakeMove(char[] board, char marker, int move) { if(SpaceFree(board, move)) { board[move] = marker; return true; } Console.WriteLine("\nThat spot is taken."); return false; }[/source]

Try to find ways to make your data work for you, instead of you working for the data:
[source lang="csharp"] // The Tic Tac Toe Game's heart static void TicTacToeGame(char[] board) { char playerTurn = 'O'; string winner = ""; while(!gameOver) { Console.WriteLine("It is " + playerTurn + "'s turn to move!"); TakeInput(board, playerTurn); DrawBoard(board); winner = CheckWinner(board, playerTurn); playerTurn = (playerTurn == 'O') ? 'X' : 'O'; } Console.WriteLine(winner); }[/source]

This may save you some room:
[source lang="csharp"] static bool CheckWinSet(char board[], int a, int b, int c) { return (board[a] == board[b]) && (board[b] == board[c]); } static string CheckWinner(char[] board, char marker) { while(true) { //for breaking // Horizontal Win if(gameOver = CheckWinSet(board, 0, 1, 2)) {break;} if(gameOver = CheckWinSet(board, 3, 4, 5)) {break;} if(gameOver = CheckWinSet(board, 6, 7, 8)) {break;} // Vertical Win if(gameOver = CheckWinSet(board, 0, 3, 6)) {break;} if(gameOver = CheckWinSet(board, 1, 4, 7)) {break;} if(gameOver = CheckWinSet(board, 2, 5, 8)) {break;} // Diagonal Win if(gameOver = CheckWinSet(board, 0, 4, 8)) {break;} if(gameOver = CheckWinSet(board, 2, 4, 6)) {break;} break; } if(gameOver) { return marker + " wins!\n"; } // Tie Game if(BoardFull(board)) { gameOver = true; return "No one wins, it's a tie!\n"; } return null; }[/source]

You may be able to find a stdlib function that searches for a specific character in a string. I dunno if C# has it, but if so you can tack a zero on to the end of your board array and then search it for ' ' rather than using BoardFull().


Overall, this is pretty good. It's clean and easy to read and I was able to track the flow of the program with no difficulty. I think you're quite ready to move on to the next level of complexity. You may want to look into some articles about general program structure and etc, but really you did quite well here. I have no significant complaints. I know I said a lot, but I don't want you to think that your own version was 'wrong'. It's just that there's always a 'better' way. I'm sure that there are far better ways than what I showed you as well. You'll naturally pick up better flow habits as you practice and see more code and come across interesting ideas.

Good job! Posted Image

#6Khatharr

Posted 15 November 2012 - 10:17 PM

SpaceFree() could be IsSpaceFree(), for more clarity that it's checking rather than freeing.

Looking mostly good so far. (I don't like your formatting but that's a preference issue, lol.)

Will edit here after looking at the rest.

In the main fn, why do-while rather than just while? You set the condition prior to the loop. Also, it's not an issue in this case since the code is so short and clean, but in terms of design the 'play again' block could be segregated to its own function.

DrawExampleBoard() seems superfluous. All it does is write some lines and its only call is in the midst of a series of drawn lines. Do you intend to call it elsewhere in a later version?

You call DrawBoard() prior to calling TicTacToeGame(). Why not move it into the beginning of TicTacToeGame()? It seems more natural for it to be there.

I see main()'s board getting passed into a lot of member functions. Why not make it a member variable?

TakeInput() - huge switch statement in here. DRY. Convert the enum to your target value (It feels really gross doing this with a switch, but idk enough about C# enums to do it mathematically.) and then run the code once on the derived value. If you want to change the action taken on the value later you won't need to change it nine times. Your code will also be smaller.

[source lang="csharp"]int slot = -1;switch(keyPressed.Key) { //... case ConsoleKey.NumPad9: case ConsoleKey.D9: slot = 8; break; default: Console.WriteLine("\nPlease use your numpad or the keys 1-9 to choose a spot to mark."); break;}if(slot != -1) { validKeyPressed = MakeMove(board, marker, slot);}[/source]

TakeInput() has another do-while that could be a while.


[source lang="csharp"] if(MakeMove(board, marker, 0)) { validKeyPressed = true; break; //this line is not necessary } break;[/source]

Still looking.

Going by function name, TakeInput() should not call MakeMove(). It should return the derived value and then the caller of TakeInput() should call MakeMove() with that value. This would technically be the better thing to do here, but in this case you could get away with just renaming TakeInput() to TakeTurn(), since that's what it's really doing here.

Did you not get a compiler warning for MakeMove()'s return paths? This is how to avoid it:
[source lang="csharp"] // Marks spot on the tic tac toe board with a marker if the space is free static bool MakeMove(char[] board, char marker, int move) { if(SpaceFree(board, move)) { board[move] = marker; return true; } Console.WriteLine("\nThat spot is taken."); return false; }[/source]

Try to find ways to make your data work for you, instead of you working for the data:
[source lang="csharp"] // The Tic Tac Toe Game's heart static void TicTacToeGame(char[] board) { char playerTurn = 'O'; string winner = ""; while(!gameOver) { Console.WriteLine("It is " + playerTurn + "'s turn to move!"); TakeInput(board, playerTurn); DrawBoard(board); winner = CheckWinner(board, playerTurn); playerTurn = (playerTurn == 'O') ? 'X' : 'O'; } Console.WriteLine(winner); }[/source]

This may save you some room:
[source lang="csharp"] static bool CheckWinSet(char board[], int a, int b, int c) { return (board[a] == board[b]) && (board[b] == board[c]); } static string CheckWinner(char[] board, char marker) { while(true) { //for breaking // Horizontal Win if(gameOver = CheckWinSet(board, 0, 1, 2)) {break;} if(gameOver = CheckWinSet(board, 3, 4, 5)) {break;} if(gameOver = CheckWinSet(board, 6, 7, 8)) {break;} // Vertical Win if(gameOver = CheckWinSet(board, 0, 3, 6)) {break;} if(gameOver = CheckWinSet(board, 1, 4, 7)) {break;} if(gameOver = CheckWinSet(board, 2, 5, 8)) {break;} // Diagonal Win if(gameOver = CheckWinSet(board, 0, 4, 8)) {break;} if(gameOver = CheckWinSet(board, 2, 4, 6)) {break;} break; } if(gameOver) { return marker + " wins!\n"; } // Tie Game if(BoardFull(board)) { gameOver = true; return "No one wins, it's a tie!\n"; } return null; }[/source]

You may be able to find a stdlib function that searches for a specific character in a string. I dunno if C# has it, but if so you can tack a zero on to the end of your board array and then search it for ' ' rather than using BoardFull().


Overall, this is pretty good. It's clean and easy to read and I was able to track the flow of the program with no difficulty. I think you're quite ready to move on to the next level of complexity. You may want to look into some articles about general program structure and etc, but really you did quite well here. I have no significant complaints. I know I said a lot, but I don't want you to think that your own version was 'wrong'. It's just that there's always a 'better' way. I'm sure that there are far better ways than what I showed you as well. You'll naturally pick up better flow habits as you practice and see more code and come across interesting ideas.

Good job! Posted Image

#5Khatharr

Posted 15 November 2012 - 10:15 PM

SpaceFree() could be IsSpaceFree(), for more clarity that it's checking rather than freeing.

Looking mostly good so far. (I don't like your formatting but that's a preference issue, lol.)

Will edit here after looking at the rest.

In the main fn, why do-while rather than just while? You set the condition prior to the loop. Also, it's not an issue in this case since the code is so short and clean, but in terms of design the 'play again' block could be segregated to its own function.

DrawExampleBoard() seems superfluous. All it does is write some lines and its only call is in the midst of a series of drawn lines. Do you intend to call it elsewhere in a later version?

You call DrawBoard() prior to calling TicTacToeGame(). Why not move it into the beginning of TicTacToeGame()? It seems more natural for it to be there.

I see main()'s board getting passed into a lot of member functions. Why not make it a member variable?

TakeInput() - huge switch statement in here. DRY. Convert the enum to your target value and then run the code once on the derived value. If you want to change the action taken on the value later you won't need to change it nine times. Your code will also be smaller.

[source lang="csharp"]int slot = -1;switch(keyPressed.Key) { //... case ConsoleKey.NumPad9: case ConsoleKey.D9: slot = 8; break; default: Console.WriteLine("\nPlease use your numpad or the keys 1-9 to choose a spot to mark."); break;}if(slot != -1) { validKeyPressed = MakeMove(board, marker, slot);[/source]}

TakeInput() has another do-while that could be a while.


[source lang="csharp"] if(MakeMove(board, marker, 0)) { validKeyPressed = true; break; //this line is not necessary } break;[/source]

Still looking.

Going by function name, TakeInput() should not call MakeMove(). It should return the derived value and then the caller of TakeInput() should call MakeMove() with that value. This would technically be the better thing to do here, but in this case you could get away with just renaming TakeInput() to TakeTurn(), since that's what it's really doing here.

Did you not get a compiler warning for MakeMove()'s return paths? This is how to avoid it:
[source lang="csharp"] // Marks spot on the tic tac toe board with a marker if the space is free static bool MakeMove(char[] board, char marker, int move) { if(SpaceFree(board, move)) { board[move] = marker; return true; } Console.WriteLine("\nThat spot is taken."); return false; }[/source]

Try to find ways to make your data work for you, instead of you working for the data:
[source lang="csharp"] // The Tic Tac Toe Game's heart static void TicTacToeGame(char[] board) { char playerTurn = 'O'; string winner = ""; while(!gameOver) { Console.WriteLine("It is " + playerTurn + "'s turn to move!"); TakeInput(board, playerTurn); DrawBoard(board); winner = CheckWinner(board, playerTurn); playerTurn = (playerTurn == 'O') ? 'X' : 'O'; } Console.WriteLine(winner); }[/source]

This may save you some room:
[source lang="csharp"] static bool CheckWinSet(char board[], int a, int b, int c) { return (board[a] == board[b]) && (board[b] == board[c]); } static string CheckWinner(char[] board, char marker) { while(true) { //for breaking // Horizontal Win if(gameOver = CheckWinSet(board, 0, 1, 2)) {break;} if(gameOver = CheckWinSet(board, 3, 4, 5)) {break;} if(gameOver = CheckWinSet(board, 6, 7, 8)) {break;} // Vertical Win if(gameOver = CheckWinSet(board, 0, 3, 6)) {break;} if(gameOver = CheckWinSet(board, 1, 4, 7)) {break;} if(gameOver = CheckWinSet(board, 2, 5, 8)) {break;} // Diagonal Win if(gameOver = CheckWinSet(board, 0, 4, 8)) {break;} if(gameOver = CheckWinSet(board, 2, 4, 6)) {break;} break; } if(gameOver) { return marker + " wins!\n"; } // Tie Game if(BoardFull(board)) { gameOver = true; return "No one wins, it's a tie!\n"; } return null; }[/source]

You may be able to find a stdlib function that searches for a specific character in a string. I dunno if C# has it, but if so you can tack a zero on to the end of your board array and then search it for ' ' rather than using BoardFull().


Overall, this is pretty good. It's clean and easy to read and I was able to track the flow of the program with no difficulty. I think you're quite ready to move on to the next level of complexity. You may want to look into some articles about general program structure and etc, but really you did quite well here. I have no significant complaints. I know I said a lot, but I don't want you to think that your own version was 'wrong'. It's just that there's always a 'better' way. I'm sure that there are far better ways than what I showed you as well. You'll naturally pick up better flow habits as you practice and see more code and come across interesting ideas.

Good job! Posted Image

#4Khatharr

Posted 15 November 2012 - 10:15 PM

Looking over it as I type this, first suggestion is that your function names could be slightly less ambiguous.

For instance, SpaceFree() could be IsSpaceFree(), etc.

Looking mostly good so far. (I don't like your formatting but that's a preference issue, lol.)

Will edit here after looking at the rest.

In the main fn, why do-while rather than just while? You set the condition prior to the loop. Also, it's not an issue in this case since the code is so short and clean, but in terms of design the 'play again' block could be segregated to its own function.

DrawExampleBoard() seems superfluous. All it does is write some lines and its only call is in the midst of a series of drawn lines. Do you intend to call it elsewhere in a later version?

You call DrawBoard() prior to calling TicTacToeGame(). Why not move it into the beginning of TicTacToeGame()? It seems more natural for it to be there.

I see main()'s board getting passed into a lot of member functions. Why not make it a member variable?

TakeInput() - huge switch statement in here. DRY. Convert the enum to your target value and then run the code once on the derived value. If you want to change the action taken on the value later you won't need to change it nine times. Your code will also be smaller.

[source lang="csharp"]int slot = -1;switch(keyPressed.Key) { //... case ConsoleKey.NumPad9: case ConsoleKey.D9: slot = 8; break; default: Console.WriteLine("\nPlease use your numpad or the keys 1-9 to choose a spot to mark."); break;}if(slot != -1) { validKeyPressed = MakeMove(board, marker, slot);[/source]}

TakeInput() has another do-while that could be a while.


[source lang="csharp"] if(MakeMove(board, marker, 0)) { validKeyPressed = true; break; //this line is not necessary } break;[/source]

Still looking.

Going by function name, TakeInput() should not call MakeMove(). It should return the derived value and then the caller of TakeInput() should call MakeMove() with that value. This would technically be the better thing to do here, but in this case you could get away with just renaming TakeInput() to TakeTurn(), since that's what it's really doing here.

Did you not get a compiler warning for MakeMove()'s return paths? This is how to avoid it:
[source lang="csharp"] // Marks spot on the tic tac toe board with a marker if the space is free static bool MakeMove(char[] board, char marker, int move) { if(SpaceFree(board, move)) { board[move] = marker; return true; } Console.WriteLine("\nThat spot is taken."); return false; }[/source]

Try to find ways to make your data work for you, instead of you working for the data:
[source lang="csharp"] // The Tic Tac Toe Game's heart static void TicTacToeGame(char[] board) { char playerTurn = 'O'; string winner = ""; while(!gameOver) { Console.WriteLine("It is " + playerTurn + "'s turn to move!"); TakeInput(board, playerTurn); DrawBoard(board); winner = CheckWinner(board, playerTurn); playerTurn = (playerTurn == 'O') ? 'X' : 'O'; } Console.WriteLine(winner); }[/source]

This may save you some room:
[source lang="csharp"] static bool CheckWinSet(char board[], int a, int b, int c) { return (board[a] == board[b]) && (board[b] == board[c]); } static string CheckWinner(char[] board, char marker) { while(true) { //for breaking // Horizontal Win if(gameOver = CheckWinSet(board, 0, 1, 2)) {break;} if(gameOver = CheckWinSet(board, 3, 4, 5)) {break;} if(gameOver = CheckWinSet(board, 6, 7, 8)) {break;} // Vertical Win if(gameOver = CheckWinSet(board, 0, 3, 6)) {break;} if(gameOver = CheckWinSet(board, 1, 4, 7)) {break;} if(gameOver = CheckWinSet(board, 2, 5, 8)) {break;} // Diagonal Win if(gameOver = CheckWinSet(board, 0, 4, 8)) {break;} if(gameOver = CheckWinSet(board, 2, 4, 6)) {break;} break; } if(gameOver) { return marker + " wins!\n"; } // Tie Game if(BoardFull(board)) { gameOver = true; return "No one wins, it's a tie!\n"; } return null; }[/source]

You may be able to find a stdlib function that searches for a specific character in a string. I dunno if C# has it, but if so you can tack a zero on to the end of your board array and then search it for ' ' rather than using BoardFull().


Overall, this is pretty good. It's clean and easy to read and I was able to track the flow of the program with no difficulty. I think you're quite ready to move on to the next level of complexity. You may want to look into some articles about general program structure and etc, but really you did quite well here. I have no significant complaints. I know I said a lot, but I don't want you to think that your own version was 'wrong'. It's just that there's always a 'better' way. I'm sure that there are far better ways than what I showed you as well. You'll naturally pick up better flow habits as you practice and see more code and come across interesting ideas.

Good job! Posted Image

PARTNERS