I've been learning C# and was looking for some feedback on my latest project, which is a standard Noughts and Crosses game. Two people are required to play (no AI yet).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace NaughtsAndCrossesGUI
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public bool isNaughtTurn;
public char[,] board = new char[3,3];
public string instructions = "2 People are needed\n\nChoose your symbol:\nNaught or Cross \n\nClick to place your symbol when it's your turn.When a line of one symbol is found that symbol wins";
public MainWindow()
{
InitializeComponent();
Title = "Nauts and Crosses";
}
//Button Input
#region
//Top Buttons
void TopLeftClick(object sender, RoutedEventArgs e)
{
Button(2, 0, board);
}
void TopMiddleClick(object sender, RoutedEventArgs e)
{
Button(2, 1, board);
}
void TopRightClick(object sender, RoutedEventArgs e)
{
Button(2, 2, board);
}
//Middle Buttons
void MiddleLeftClick(object sender, RoutedEventArgs e)
{
Button(1, 0, board);
}
void MiddleClick(object sender, RoutedEventArgs e)
{
Button(1, 1, board);
}
void MiddleRightClick(object sender, RoutedEventArgs e)
{
Button(1, 2, board);
}
//Bottom Buttons
void BottomLeftClick(object sender, RoutedEventArgs e)
{
Button(0, 0, board);
}
void BottomMiddleClick(object sender, RoutedEventArgs e)
{
Button(0, 1, board);
}
void BottomRightClick(object sender, RoutedEventArgs e)
{
Button(0, 2, board);
}
#endregion
//Framework
bool failedAttempt = false;
void Button(int p1, int p2, char[,] board)
{
if (inputToGrid(p1, p2, board, isNaughtTurn))
{
isNaughtTurn = !isNaughtTurn;
}
setTurnMsg(isNaughtTurn);
setButtons();
if (stateCheck() && !failedAttempt)
{
failedAttempt = true;
return;
}
if (stateCheck() && failedAttempt)
{
reset();
return;
}
}
void setButtons()
{
//Top
TopLeft.Content = board[2, 0];
TopMiddle.Content = board[2, 1];
TopRight.Content = board[2, 2];
//Middle
MiddleLeft.Content = board[1, 0];
Middle.Content = board[1, 1];
MiddleRight.Content = board[1, 2];
//Bottom
BottomLeft.Content = board[0, 0];
BottomMiddle.Content = board[0, 1];
BottomRight.Content = board[0, 2];
}
void setTurnMsg(bool noughtTurn)
{
TurnDisplayer.Content = "Current turn: ";
if (noughtTurn)
TurnDisplayer.Content += "Nought";
else
TurnDisplayer.Content += "Cross";
}
void reset()
{
board = new char[3, 3];
Instuctions.Text = instructions;
setTurnMsg(isNaughtTurn);
setButtons();
failedAttempt = false;
}
bool stateCheck()
{
switch (checkBoard(board))
{
case 'F':
TurnDisplayer.Content = "It's a Draw";
Instuctions.Text = "Click any square to \nreset";
return true;
case 'X':
TurnDisplayer.Content = "Cross Wins";
Instuctions.Text = "Click any square to \nreset";
return true;
case 'O':
TurnDisplayer.Content = "Nought Wins";
Instuctions.Text = "Click any square to \nreset";
return true;
}
return false;
}
static bool inputToGrid(int p1, int p2,char[,] grid,bool naughtTurn)
{
if (grid[p1, p2] == '\0')
{
if (naughtTurn)
grid[p1,p2] = 'O';
else
grid[p1,p2] = 'X';
return true;
}
return false;
}
static char OX(char c)
{
if (c.ToString().ToUpper() == "X")
{
return 'X';
}
else if (c.ToString().ToUpper() == "O")
{
return 'O';
}
return ' ';
}
/// <summary>
/// Returns the state of the board in terms of Noughts and Crosses Rules
/// O or X == Naught\Cross win
/// F == Full board
/// ' ' == Nothing to stop play
/// </summary>
static char checkBoard(char[,] board)
{
if ((OX(board[1, 1]) == "O"[0] || OX(board[1, 1]) == "X"[0]) && (board[2, 2] == board[1, 1] && board[1, 1] == board[0, 0]))
{
//Diagonal
return OX(board[1, 1]);
}
else if ((OX(board[1, 1]) == "O"[0] || OX(board[1, 1]) == "X"[0]) && (board[2, 0] == board[1, 1] && board[1, 1] == board[0, 2]))
{
//Diagonal
return OX(board[1, 1]);
}
else if ((OX(board[2, 1]) == "O"[0] || OX(board[2, 1]) == "X"[0]) && (board[2, 0] == board[2, 1] && board[2, 1] == board[2, 2]))
{
//Top row
return OX(board[2, 1]);
}
else if ((OX(board[1, 1]) == "O"[0] || OX(board[1, 1]) == "X"[0]) && (board[1, 0] == board[1, 1] && board[1, 1] == board[1, 2]))
{
//Middle row
return OX(board[1, 1]);
}
else if ((OX(board[0, 1]) == "O"[0] || OX(board[0, 1]) == "X"[0]) && (board[0, 0] == board[0, 1] && board[0, 1] == board[0, 2]))
{
//Bottom row
return OX(board[0, 1]);
}
else if ((OX(board[1, 0]) == "O"[0] || OX(board[1, 0]) == "X"[0]) && (board[2, 0] == board[1, 0] && board[1, 0] == board[0, 0]))
{
//left collumn
return OX(board[1, 0]);
}
else if ((OX(board[1, 1]) == "O"[0] || OX(board[1, 1]) == "X"[0]) && (board[2, 1] == board[1, 1] && board[1, 1] == board[0, 1]))
{
//middle collumn
return OX(board[1, 1]);
}
else if ((OX(board[1, 2]) == "O"[0] || OX(board[1, 2]) == "X"[0]) && (board[2, 2] == board[1, 2] && board[1, 2] == board[0, 2]))
{
//right collumn
return OX(board[1, 2]);
}
int filledTiles = 0;
for (int i = 0; i < board.GetLength(0); i++)
{
for (int j = 0; j < board.GetLength(1); j++)
{
if (board[i, j] != '\0')
{
filledTiles += 1;
}
}
}
if (filledTiles >= 9)
{
return 'F';
}
return " "[0];
}
}
}
<Window x:Class="NaughtsAndCrossesGUI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="604.445" Width="806.667">
<Viewbox Stretch="Uniform">
<Grid>
<Label x:Name="TurnDisplayer" Content="Current Turn: Cross" FontFamily="Ubuntu" FontSize="34" HorizontalAlignment="Left" Height="48" VerticalAlignment="Top" Width="353" Margin="10,96,0,0"/>
<!--Top Row-->
<Button x:Name="TopLeft" Content="" HorizontalAlignment="Left" Margin="368,122,0,0" VerticalAlignment="Top" Width="135" Height="143" Background="#FF32BEFF" BorderBrush="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="TopLeftClick"/>
<Button x:Name="TopMiddle" Content="" HorizontalAlignment="Left" Margin="507,122,0,0" VerticalAlignment="Top" Width="135" Height="143" BorderBrush="#FF32BEFF" Background="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="TopMiddleClick"/>
<Button x:Name="TopRight" Content="" HorizontalAlignment="Left" Margin="646,122,0,0" VerticalAlignment="Top" Width="136" Height="143" Background="#FF32BEFF" BorderBrush="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="TopRightClick"/>
<!--Middle Row-->
<Button x:Name="MiddleLeft" Content="" HorizontalAlignment="Left" Margin="368,269,0,0" VerticalAlignment="Top" Width="135" Height="143" BorderBrush="#FF32BEFF" Background="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="MiddleLeftClick"/>
<Button x:Name="Middle" Content="" HorizontalAlignment="Left" Margin="507,269,0,0" VerticalAlignment="Top" Width="135" Height="143" Background="#FF32BEFF" BorderBrush="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="MiddleClick"/>
<Button x:Name="MiddleRight" Content="" HorizontalAlignment="Left" Margin="646,269,0,0" VerticalAlignment="Top" Width="136" Height="143" BorderBrush="#FF32BEFF" Background="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="MiddleRightClick"/>
<!--Bottom Row-->
<Button x:Name="BottomLeft" Content="" HorizontalAlignment="Left" Margin="368,416,0,0" VerticalAlignment="Top" Width="135" Height="143" Background="#FF32BEFF" BorderBrush="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="BottomLeftClick"/>
<Button x:Name="BottomMiddle" Content="" HorizontalAlignment="Left" Margin="507,416,0,0" VerticalAlignment="Top" Width="135" Height="143" Background="#FF32BEFF" BorderBrush="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="BottomMiddleClick"/>
<Button x:Name="BottomRight" Content="" HorizontalAlignment="Left" Margin="647,416,0,0" VerticalAlignment="Top" Width="135" Height="143" Background="#FF32BEFF" BorderBrush="#FF32BEFF" FontSize="100" FontFamily="Ubuntu" Click="BottomRightClick"/>
<TextBlock x:Name="Name" TextWrapping="Wrap" Text="NOUGHTS AND CROSSES H" HorizontalAlignment="Left" Height="81" VerticalAlignment="Top" Width="772" FontSize="65" FontFamily="Ubuntu" Margin="0,10,0,0" />
<TextBlock x:Name="Instuctions" TextWrapping="Wrap" Text="2 People are needed 

Choose your symbol: 
Naught or Cross 

Click to place your symbol when it's your turn When a line of one symbol is found that symbol wins" HorizontalAlignment="Left" Height="376" Margin="0,193,0,0" VerticalAlignment="Top" Width="363" FontFamily="Source Code Pro ExtraLight" FontSize="24"/>
<Label Content="Instructions:" HorizontalAlignment="Left" Height="49" Margin="10,139,0,0" VerticalAlignment="Top" Width="334" FontFamily="Source Code Pro Black" FontSize="36" FontWeight="Bold"/>
</Grid>
</Viewbox>
And finally, if you want to see the finished project, I have a .exe available here. I do realise that as it's an .exe you may be wary of downloading. It is the code above compiled via Visual Studio but I understand if you don't feel comfortable doing so. On a side note, is there any way to get around the "I don't want to download a .exe" problem?
Command
andCommandParameter
property, which will allow you to have a single handler and nine arguments rather than nine handler methods. Also, regions can have names:#region Button Input ... #endregion Button Input
. Also, the method nameButton
is a noun. That probably isn't a good idea. Prefer verbs. \$\endgroup\$