Game
This commit is contained in:
parent
1dbe2e1bb6
commit
7b345ba39c
@ -5,6 +5,10 @@
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="TicTacToe.Cell"
|
||||
BorderThickness="2"
|
||||
BorderBrush="White">
|
||||
<TextBlock TextAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="40">X</TextBlock>
|
||||
BorderBrush="White"
|
||||
FontSize="40">
|
||||
<Button Name="Text" Click="Text_OnClick"
|
||||
HorizontalContentAlignment="Center" VerticalContentAlignment="Center"
|
||||
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
</Button>
|
||||
</UserControl>
|
||||
|
||||
@ -1,11 +1,26 @@
|
||||
using Avalonia.Controls;
|
||||
using System.Net.Mime;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
|
||||
namespace TicTacToe;
|
||||
|
||||
public partial class Cell : UserControl
|
||||
{
|
||||
public required Game Game;
|
||||
|
||||
public Cell()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void Text_OnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if(Text.Content != null)
|
||||
return;
|
||||
Text.Content = Game.CurrentPlayerSign;
|
||||
Game.Turn(GetValue(Grid.RowProperty), GetValue(Grid.ColumnProperty));
|
||||
IsEnabled = false;
|
||||
Foreground = Brushes.White;
|
||||
}
|
||||
}
|
||||
135
TicTacToe/Game.cs
Normal file
135
TicTacToe/Game.cs
Normal file
@ -0,0 +1,135 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace TicTacToe;
|
||||
|
||||
public class Game
|
||||
{
|
||||
/* 0 1 2 ...
|
||||
* 0 [ ][ ][ ]
|
||||
* 1 [ ][ ][ ]
|
||||
* 2 [ ][ ][ ]
|
||||
* ...
|
||||
*/
|
||||
public char[][] GameField => _gameField;
|
||||
public char CurrentPlayerSign => _players[_nextPlayerIndex];
|
||||
|
||||
public event Action<char>? PlayerWon;
|
||||
|
||||
private char[][] _gameField;
|
||||
private char[] _players = { 'X', '0' };
|
||||
private int _nextPlayerIndex = 0;
|
||||
private int _winSequenceLength;
|
||||
private int _sideLength;
|
||||
|
||||
public Game(int gameFieldSideSize, int winSequenceLength)
|
||||
{
|
||||
_winSequenceLength = winSequenceLength;
|
||||
_sideLength = gameFieldSideSize;
|
||||
_gameField = new char[gameFieldSideSize][];
|
||||
for (int y = 0; y < gameFieldSideSize; y++)
|
||||
{
|
||||
_gameField[y] = new char[gameFieldSideSize];
|
||||
for (int x = 0; x < gameFieldSideSize; x++)
|
||||
_gameField[y][x] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
public void Turn(int cell_row, int cell_col)
|
||||
{
|
||||
if (_gameField[cell_row][cell_col] != '\0')
|
||||
throw new Exception("the cell was already used");
|
||||
_gameField[cell_row][cell_col] = CurrentPlayerSign;
|
||||
if (CheckWinCombination(cell_row, cell_col))
|
||||
{
|
||||
PlayerWon?.Invoke(CurrentPlayerSign);
|
||||
return;
|
||||
}
|
||||
|
||||
_nextPlayerIndex++;
|
||||
if (_nextPlayerIndex >= _players.Length)
|
||||
_nextPlayerIndex = 0;
|
||||
}
|
||||
|
||||
private bool CheckWinCombination(int cell_row, int cell_col)
|
||||
{
|
||||
int sequenceLength = 0;
|
||||
// up
|
||||
for (int row = cell_row; row > -1; row--)
|
||||
{
|
||||
if(_gameField[row][cell_col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
// down
|
||||
sequenceLength--;
|
||||
for (int row = cell_row; row < _sideLength; row++)
|
||||
{
|
||||
if(_gameField[row][cell_col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
sequenceLength = 0;
|
||||
|
||||
// left
|
||||
for (int col = cell_col; col > -1; col--)
|
||||
{
|
||||
if(_gameField[cell_row][col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
// right
|
||||
sequenceLength--;
|
||||
for (int col = cell_col; col < _sideLength; col++)
|
||||
{
|
||||
if(_gameField[cell_row][col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
sequenceLength = 0;
|
||||
|
||||
// up-left
|
||||
for (int row = cell_row, col = cell_col; row > -1 && col > -1; row--, col--)
|
||||
{
|
||||
if(_gameField[row][col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
// down-right
|
||||
sequenceLength--;
|
||||
for (int row = cell_row, col = cell_col; col < _sideLength && row < _sideLength; row++, col++)
|
||||
{
|
||||
if(_gameField[row][col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
sequenceLength = 0;
|
||||
|
||||
|
||||
// up-right
|
||||
for (int row = cell_row, col = cell_col; row > -1 && col < _sideLength; row--, col++)
|
||||
{
|
||||
if(_gameField[row][col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
// down-left
|
||||
sequenceLength--;
|
||||
for (int row = cell_row, col = cell_col; col > -1 && row < _sideLength; row++, col--)
|
||||
{
|
||||
if(_gameField[row][col] != CurrentPlayerSign)
|
||||
break;
|
||||
if (++sequenceLength == _winSequenceLength)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2,17 +2,23 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
mc:Ignorable="d"
|
||||
x:Class="TicTacToe.MainWindow"
|
||||
Title="TicTacToe"
|
||||
FontSize="20">
|
||||
FontSize="20"
|
||||
Width="600"
|
||||
Height="600"
|
||||
d:DesignHeight="600"
|
||||
d:DesignWidth="600">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>40 *</Grid.RowDefinitions>
|
||||
<StackPanel Orientation="Horizontal" Spacing="20">
|
||||
<Label Target="SizeTextBox" VerticalContentAlignment="Center">Size:</Label>
|
||||
<TextBox Name="SizeTextBox"></TextBox>
|
||||
<TextBox Name="SizeTextBox" Width="60"></TextBox>
|
||||
<Button Click="RestartButton_OnClick">Restart</Button>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="1" Name="GameGrid"></Grid>
|
||||
<StackPanel Grid.Row="1" Name="WinPanel" IsEnabled="False"
|
||||
HorizontalAlignment="Center" VerticalAlignment="Center"><TextBlock Name="WinText"></TextBlock></StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@ -6,15 +6,35 @@ namespace TicTacToe;
|
||||
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private Game _game = new(3, 3);
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
DrawGame();
|
||||
_game.PlayerWon += ShowWin;
|
||||
}
|
||||
|
||||
|
||||
private void RestartButton_OnClick(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
int size = Convert.ToInt32(SizeTextBox.Text);
|
||||
_game = new Game(size, size);
|
||||
_game.PlayerWon += ShowWin;
|
||||
DrawGame();
|
||||
}
|
||||
|
||||
private void ShowWin(char playerChar)
|
||||
{
|
||||
GameGrid.IsVisible = false;
|
||||
WinPanel.IsVisible = true;
|
||||
WinText.Text = $"Player {playerChar} won!!1!";
|
||||
}
|
||||
|
||||
private void DrawGame()
|
||||
{
|
||||
GameGrid.IsVisible = true;
|
||||
WinPanel.IsVisible = false;
|
||||
int size = _game.GameField.Length;
|
||||
GameGrid.Children.Clear();
|
||||
GameGrid.RowDefinitions = new RowDefinitions();
|
||||
for(int y=0; y<size; y++)
|
||||
@ -23,13 +43,19 @@ public partial class MainWindow : Window
|
||||
for(int x=0; x<size; x++)
|
||||
GameGrid.ColumnDefinitions.Add(new ColumnDefinition());
|
||||
for(int y=0; y<size; y++)
|
||||
for (int x = 0; x < size; x++)
|
||||
for (int x = 0; x < size; x++)
|
||||
{
|
||||
var cellView = new Cell
|
||||
{
|
||||
var c = new Cell();
|
||||
c.SetValue(Grid.ColumnProperty, x);
|
||||
c.SetValue(Grid.RowProperty, y);
|
||||
GameGrid.Children.Add(c);
|
||||
|
||||
}
|
||||
Game = _game
|
||||
};
|
||||
cellView.SetValue(Grid.ColumnProperty, x);
|
||||
cellView.SetValue(Grid.RowProperty, y);
|
||||
char cellValue = _game.GameField[y][x];
|
||||
if (cellValue != '\0')
|
||||
cellView.Text.Content = cellValue.ToString();
|
||||
GameGrid.Children.Add(cellView);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user