I've recently created my own 2-player chess game, no AI... at least for now.
I do plan to do that in the future, so one of my concerns is if the code is flexible enough to just use the same classes in all the different modes so I can avoid rewriting the same code over and over again. I've tried to explain most of the logic with comments in the main Form
but I've skipped most of the explanation of what's going in the other classes, so if anything is unclear I will be happy to answer in the comments.
User Interface
The game itself starts in the MainMenuForm
:
public partial class MainMenuForm : Form
{
public MainMenuForm()
{
InitializeComponent();
}
private void bExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void bOptions_Click(object sender, EventArgs e)
{
OptionsForm optf = new OptionsForm();
optf.ShowDialog();
}
private void bOnline_Click(object sender, EventArgs e)
{
}
private void b2Players_Click(object sender, EventArgs e)
{
CooperativeForm cpf = new CooperativeForm();
cpf.ShowDialog();
}
private void b1Player_Click(object sender, EventArgs e)
{
}
}
As I've mentioned earlier currently the only working mode is the 2-Players mode so the other buttons are disabled and have nothing inside they're Click
event handler.
From here you can go to the OptionsForm
:
It mostly works with the Properties.Settings
The form itself is implemented like this :
public partial class OptionsForm : Form
{
private bool settingsSaved = false;
private bool closeOptions = false;
private bool enableTurnHelper = Properties.Settings.Default.EnabledTurnHelper;
private bool enableTurnTracking = Properties.Settings.Default.EnabledTurnTracking;
private bool enableTurnTimers = Properties.Settings.Default.EnabledTurnTimers;
private uint timerTime = Properties.Settings.Default.TurnTimer;
public OptionsForm()
{
InitializeComponent();
if (enableTurnTimers)
{
cbEnableTurnTimers.Checked = true;
lbTimerTime.Visible = true;
tbTimerTime.Visible = true;
tbTimerTime.Text = (timerTime/60).ToString();
}
if (enableTurnTracking)
{
cbEnableTurnTracking.Checked = true;
}
if (enableTurnHelper)
{
cbEnableTurnHelper.Checked = true;
}
}
private void bEnableTurnTimers_Click(object sender, EventArgs e)
{
cbEnableTurnTimers.Checked = !cbEnableTurnTimers.Checked;
lbTimerTime.Visible = !lbTimerTime.Visible;
tbTimerTime.Visible = !tbTimerTime.Visible;
enableTurnTimers = GetValue(cbEnableTurnTimers);
}
private void bEnableTurnTracking_Click(object sender, EventArgs e)
{
cbEnableTurnTracking.Checked = !cbEnableTurnTracking.Checked;
enableTurnTracking = GetValue(cbEnableTurnTracking);
}
private void bEnableTurnHelper_Click(object sender, EventArgs e)
{
cbEnableTurnHelper.Checked = !cbEnableTurnHelper.Checked;
enableTurnHelper = GetValue(cbEnableTurnHelper);
}
private void bSave_Click(object sender, EventArgs e)
{
if (!CheckFormat(tbTimerTime.Text, out timerTime))
{
return;
}
settingsSaved = true;
Properties.Settings.Default.EnabledTurnHelper = enableTurnHelper;
Properties.Settings.Default.EnabledTurnTimers = enableTurnTimers;
Properties.Settings.Default.EnabledTurnTracking = enableTurnTracking;
Properties.Settings.Default.TurnTimer = timerTime*60;
Properties.Settings.Default.Save();
MessageBox.Show(@"Your settings have been saved succesfully !");
}
private static bool GetValue(CheckBox inputCheckBox)
{
return inputCheckBox.Checked;
}
private void Options_Closing(object sender, FormClosingEventArgs e)
{
if (!settingsSaved && !closeOptions)
{
uint tempParse;
bool tempTryParse = uint.TryParse(tbTimerTime.Text, out tempParse);
if (Properties.Settings.Default.EnabledTurnHelper != enableTurnHelper ||
Properties.Settings.Default.EnabledTurnTimers != enableTurnTimers ||
Properties.Settings.Default.EnabledTurnTracking != enableTurnTracking ||
Properties.Settings.Default.TurnTimer != tempParse * 60)
{
DialogResult replayDialog =
MessageBox.Show(
@"Your settings haven't been saved yet !" + Environment.NewLine +
@"Would you like to leave ?",
@"Settings not saved", MessageBoxButtons.YesNo);
if (replayDialog == DialogResult.Yes)
{
closeOptions = true;
Close();
}
else e.Cancel = true;
}
}
}
private void tbTimerTime_KeyPress(object sender, KeyPressEventArgs e)
{
TextBox tb = (TextBox) sender;
string text = tb.Text;
if (e.KeyChar == (char)Keys.Enter)
{
e.Handled = true;
CheckFormat(text, out timerTime);
}
}
private static bool CheckFormat(string input, out uint output)
{
uint tempParse;
if (!uint.TryParse(input, out tempParse))
{
MessageBox.Show(@"Timer time input can be only digits ");
output = Properties.Settings.Default.TurnTimer;
return false;
}
if (tempParse > 60 || tempParse <= 0)
{
MessageBox.Show(@"Timer time must be in the range 1 - 60 minutes !");
output = Properties.Settings.Default.TurnTimer;
return false;
}
output = tempParse;
return true;
}
}
It does check if you have saved your settings upon closing the form. If you are done with editing your setting you can go close this form and go to play in the CooperativeModeForm
which is where all my code is.
/// <summary>
/// Currently the only available Game Mode is being implemented in here.
/// </summary>
public sealed partial class CooperativeForm : Form
{
private readonly Timer timer = new Timer();
//variable used by the Turn Tracking Feature if checked in the Options menu.
private static Tuple<Point, Figure, PictureBox> passedTurn;
// tile size.
private const int tileWidth = 85;
private const int tileHeight = 75;
//figure size.
private const int figureWidth = 75;
private const int figureHeight = 65;
// since there's difference in the tile size and the figure size this helps place it in the middle of the tile it's left on.
private const int marginsLeftToCenterTile = 5;
// size of the board 8x8.
public const int size = 8;
// all the tiles are pictureboxs
public static readonly PictureBox[][] DrawnBoard = new PictureBox[size][];
//boolean board which helps with the checking of where a figure is placed ??
public static bool[][] Board = new bool[8][];
// all the figures are stored here.
public static List<Figure> Figures = new List<Figure>();
// Figure class doesn't have a PictureBox property so this is basically chained to a specific figure.
private static readonly PictureBox[] figuresImages = new PictureBox[32];
// boolean variable to determine wheter the player is dragging a figure.
private bool isMoved;
// variable to keep track of the current figure it's updated whenever a figure is being pressed not neccessary to be moved.
private Figure currentFigure;
// if the player's movement was unavailable those variables will help return it to it's previous place
private int previousX;
private int previousY;
// this variable keeps track of the current player
private static FigureColor currentColor = FigureColor.White;
// keeping track of the current turn
private static int currentTurn;
// white and black figures are stored here
public static readonly List<Figure> WhiteFigures = new List<Figure>();
public static readonly List<Figure> BlackFigures = new List<Figure>();
// variables converting the const figure and tile size's into Size variables.
private static readonly Size figureSize = new Size(figureWidth, figureHeight);
private static readonly Size tileSize = new Size(tileWidth, tileHeight);
// taking the user's input for the time length from the resources.
private readonly uint timerMaxValue = Properties.Settings.Default.TurnTimer;
// pictureBox which acts as a Board it's currently not useful but will help with future updates
// because currently figures back color isn't perfect they are not completely transparent they take
// either black or white depending on what they are standing on. Not supporting if in between.
private PictureBox parentBoardPictureBox = new PictureBox();
// variable to keep track of the Turn Helper's highlighted tiles which must be set back to normal color
// whenever the figure is released.
private readonly List<Tuple<int, int, Color>> highlightedTiles = new List<Tuple<int, int, Color>>();
// variables to keep track of the white and black turns which are used by the Turn Tracking Option
// if checked in the Options Menu.
private readonly List<List<object>> whiteTurns = new List<List<object>>();
private readonly List<List<object>> blackTurns = new List<List<object>>();
private ListView TurnTrackingList = new ListView();
private static readonly char[] letters = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
/// <summary>
/// Reduces the flickering caused by dragging a figure/PictureBox.
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
public CooperativeForm()
{
InitializeComponent();
BackColor = Color.SaddleBrown;
FillBoard();
DrawBoard();
DrawLines();
LoadAllFigures();
if (Properties.Settings.Default.EnabledTurnTimers)
{
pbTimer.Visible = true;
pbTimer.Maximum = (int) timerMaxValue;
pbTimer.Value = pbTimer.Maximum;
timer.Interval = 1000;
timer.Tick += timer_Tick;
timer.Start();
}
}
private void timer_Tick(object sender, EventArgs e)
{
pbTimer.Value--;
if (pbTimer.Value <= 0)
{
pbTimer.Value = (int) timerMaxValue;
currentColor = currentColor == FigureColor.Black
? FigureColor.White
: FigureColor.Black;
}
}
/// <summary> Method to load and draw all the figures using several other methods </summary>
private void LoadAllFigures()
{
if (Properties.Settings.Default.EnabledTurnTracking)
{
flpBlackPlayerWinnings.Height /= 2;
flpWhitePlayerWinnings.Height /= 2;
flpWhitePlayerWinnings.Location = new Point(flpWhitePlayerWinnings.Location.X, flpBlackPlayerWinnings.Location.Y + flpBlackPlayerWinnings.Height + 10);
EnableTurnTracking();
}
if (Figures.Count > 0)
{
Restart();
}
else
{
AddKings();
AddQueens();
AddRooks();
AddBishops();
AddKnights();
AddPawns();
DrawFigures();
}
}
// Methods to add the figures to each team </summary>
private static void AddPawns()
{
IEnumerable<FigureDefinition> blackDefinitions = new PawnDefinitions().BlackPawns;
IEnumerable<FigureDefinition> whiteDefinitions = new PawnDefinitions().WhitePawns;
AddPawnsByColor(whiteDefinitions);
AddPawnsByColor(blackDefinitions);
}
private static void AddPawnsByColor(IEnumerable<FigureDefinition> definitions)
{
foreach (PawnPiece piece in definitions.Select(definition => new PawnPiece(definition)))
{
AddFigure(piece);
}
}
private static void AddKnights()
{
IEnumerable<FigureDefinition> blackDefinitions = new KnightDefinitions().BlackKnights;
IEnumerable<FigureDefinition> whiteDefinitions = new KnightDefinitions().WhiteKnights;
AddKnightsByColor(whiteDefinitions);
AddKnightsByColor(blackDefinitions);
}
private static void AddKnightsByColor(IEnumerable<FigureDefinition> definitions)
{
foreach (KnightPiece piece in definitions.Select(definition => new KnightPiece(definition)))
{
AddFigure(piece);
}
}
private static void AddBishops()
{
IEnumerable<FigureDefinition> blackDefinitions = new BishopDefinitions().BlackBishops;
IEnumerable<FigureDefinition> whiteDefinitions = new BishopDefinitions().WhiteBishops;
AddBishopsByColor(whiteDefinitions);
AddBishopsByColor(blackDefinitions);
}
private static void AddBishopsByColor(IEnumerable<FigureDefinition> definitions)
{
foreach (BishopPiece piece in definitions.Select(definition => new BishopPiece(definition)))
{
AddFigure(piece);
}
}
private static void AddRooks()
{
IEnumerable<FigureDefinition> blackDefinitions = new TopDefinitions().BlackRooks;
IEnumerable<FigureDefinition> whiteDefinitions = new TopDefinitions().WhiteRooks;
AddRooksByColor(whiteDefinitions);
AddRooksByColor(blackDefinitions);
}
private static void AddRooksByColor(IEnumerable<FigureDefinition> definitions)
{
foreach (RookPiece piece in definitions.Select(definition => new RookPiece(definition)))
{
AddFigure(piece);
}
}
private static void AddQueens()
{
IEnumerable<FigureDefinition> blackDefinitions = new QueenDefinitions().BlackQueens;
IEnumerable<FigureDefinition> whiteDefinitions = new QueenDefinitions().WhiteQueens;
AddQueensByColor(whiteDefinitions);
AddQueensByColor(blackDefinitions);
}
private static void AddQueensByColor(IEnumerable<FigureDefinition> definitions)
{
foreach (QueenPiece piece in definitions.Select(definition => new QueenPiece(definition)))
{
AddFigure(piece);
}
}
private static void AddKings()
{
IEnumerable<FigureDefinition> blackDefinitions = new KingDefinitions().BlackKings;
IEnumerable<FigureDefinition> whiteDefinitions = new KingDefinitions().WhiteKings;
AddKingsByColor(whiteDefinitions);
AddKingsByColor(blackDefinitions);
}
private static void AddKingsByColor(IEnumerable<FigureDefinition> definitions)
{
foreach (KingPiece piece in definitions.Select(definition => new KingPiece(definition)))
{
AddFigure(piece);
}
}
/// <summary> Method to add figure to the
/// <seealso cref="Figures"/>
/// List </summary>
private static void AddFigure(Figure newFigure)
{
Figures.Add(newFigure);
AddToTeam(newFigure);
}
// Methods to add/remove figure/figures to teams
private static void AddToTeam(Figure newFigure)
{
if (newFigure.PieceColor == FigureColor.Black)
{
BlackFigures.Add(newFigure);
}
else
{
WhiteFigures.Add(newFigure);
}
}
private static void AddMultipleFiguresToTeam(params Figure[] inputFigures)
{
foreach (var inputFigure in inputFigures)
{
AddToTeam(inputFigure);
}
}
private static void RemoveFromTeam(Figure inputFigure)
{
if (inputFigure.PieceColor == FigureColor.Black)
{
BlackFigures.Remove(inputFigure);
}
else
{
WhiteFigures.Remove(inputFigure);
}
}
private static void RemoveMultipleFiguresFromTeam(params Figure[] inputFigures)
{
foreach (var inputFigure in inputFigures)
{
RemoveFromTeam(inputFigure);
}
}
private static void RemoveMultipleFiguresFromFiguresList(params Figure[] inputFigures)
{
foreach (var inputFigure in inputFigures)
{
Figures.Remove(inputFigure);
}
}
private static void AddMultipleFiguresToFiguresList(params Figure[] inputFigures)
{
foreach (var inputFigure in inputFigures)
{
Figures.Add(inputFigure);
}
}
private void DrawFigures()
{
for (int i = 0; i < Figures.Count; i++)
{
int x = Figures[i].StartingPosition.Item1;
int y = Figures[i].StartingPosition.Item2;
LoadFigure(i, x, y);
}
}
private void LoadFigure(int i, int x, int y)
{
figuresImages[i] = new PictureBox
{
Size = figureSize,
BackgroundImage = Figures[i].PieceImage,
BackgroundImageLayout = ImageLayout.Stretch,
AllowDrop = true,
Location =
new Point(DrawnBoard[x][y].Location.X + marginsLeftToCenterTile,
DrawnBoard[x][y].Location.Y + marginsLeftToCenterTile),
BackColor = DrawnBoard[x][y].BackColor
};
figuresImages[i].MouseDown += Figure_MouseDown;
figuresImages[i].MouseMove += Figure_MouseMove;
figuresImages[i].MouseUp += Figure_MouseUp;
parentBoardPictureBox.Controls.Add(figuresImages[i]);
figuresImages[i].BringToFront();
}
// Creating the Board's lines, rows and columns
private void DrawLines()
{
DrawLineNumbers();
DrawLineAlphabet();
}
private void DrawLineNumbers()
{
const int horizontal = 5;
int vertical = tileHeight;
for (int i = 0; i < size; i++)
{
Label nextLabel = new Label
{
AutoSize = true,
Location = new Point(horizontal, vertical),
Text = (i + 1).ToString(),
Font = new Font("Microsoft Sans Serif", 16),
};
vertical += tileHeight;
Controls.Add(nextLabel);
}
}
private void DrawLineAlphabet()
{
const int vertical = tileHeight*9 - 10;
int horizontal = tileWidth - 15;
for (int i = 0; i < size; i++)
{
Label nextLabel = new Label
{
AutoSize = true,
Location = new Point(horizontal, vertical),
Text = letters[i].ToString(),
Font = new Font("Microsoft Sans Serif", 16),
};
horizontal += tileWidth;
Controls.Add(nextLabel);
}
}
private static void FillBoard()
{
for (int i = 0; i < size; i++)
{
bool[] row = new bool[size];
bool value = i == 0 || i == 1 || i == 6 || i == 7;
for (int j = 0; j < size; j++)
{
row[j] = value;
}
Board[i] = row;
}
}
private void DrawBoard()
{
const int startHorizontal = 40;
const int startVertical = 580;
parentBoardPictureBox = new PictureBox
{
Location = new Point(startHorizontal, startVertical - 7*tileHeight),
Size = new Size(8*tileWidth,8*tileHeight),
};
const int startHorizontalTile = 0;
const int startVerticalTile = 7*tileHeight;
Controls.Add(parentBoardPictureBox);
int horizontal = startHorizontalTile;
int vertical = startVerticalTile;
bool white = false;
for (int i = 0; i < DrawnBoard.Length; i++)
{
DrawnBoard[i] = CreateBoardRow(ref horizontal, ref vertical, ref white);
white = !white;
vertical -= tileHeight;
horizontal = startHorizontalTile;
}
}
private PictureBox[] CreateBoardRow(ref int horizontal,ref int vertical, ref bool white)
{
PictureBox[] Row = new PictureBox[size];
for (int i = 0; i < Row.Length; i++)
{
Row[i] = new PictureBox
{
Size = tileSize,
Location = new Point(horizontal, vertical),
BorderStyle = BorderStyle.Fixed3D,
};
if (white)
{
white = false;
Row[i].BackColor = Color.White;
}
else
{
white = true;
Row[i].BackColor = Color.Black;
}
parentBoardPictureBox.Controls.Add(Row[i]);
horizontal += tileWidth;
}
return Row;
}
//Mouse events handling the movement of the figures and validates the figure's movement
private void Figure_MouseDown(object sender, MouseEventArgs e)
{
PictureBox thisPB = (PictureBox)sender;
isMoved = true;
previousX = thisPB.Location.X;
previousY = thisPB.Location.Y;
int newColumn;
int newRow = GetNewTile(thisPB, out newColumn);
if (Properties.Settings.Default.EnabledTurnHelper)
{
Figure tempFigure = GetFigure(thisPB);
if (tempFigure.PieceColor == currentColor)
{
tempFigure.UpdateMoves(tempFigure);
foreach (Tuple<int, int> move in tempFigure.Moves)
{
highlightedTiles.Add(new Tuple<int, int, Color>(move.Item1, move.Item2,
DrawnBoard[move.Item1][move.Item2].BackColor));
DrawnBoard[move.Item1][move.Item2].BackColor = Color.LightGreen;
}
}
}
passedTurn = new Tuple<Point, Figure, PictureBox>(new Point(previousX, previousY), GetFigure(thisPB), thisPB);
}
private void Figure_MouseMove(object sender, MouseEventArgs e)
{
if (isMoved)
{
PictureBox thisPB = (PictureBox)sender;
thisPB.BringToFront();
var temp = GetFigure(thisPB);
if (temp.PieceColor == currentColor)
{
currentFigure = GetFigure(thisPB);
thisPB.Location = new Point(thisPB.Left + e.X, thisPB.Top + e.Y);
thisPB.Refresh();
}
}
}
private void Figure_MouseUp(object sender, MouseEventArgs e)
{
foreach (var highlightedTile in highlightedTiles)
{
DrawnBoard[highlightedTile.Item1][highlightedTile.Item2].BackColor = highlightedTile.Item3;
}
highlightedTiles.Clear();
isMoved = false;
KingIsDefeated();
if (currentFigure == null) return;
PictureBox thisPB = (PictureBox)sender;
int newColumn;
int newRow = GetNewTile(thisPB, out newColumn);
if (MustReplacePawn(currentFigure, new Tuple<int, int>(newRow, newColumn)))
{
DoPawnReplaceMove(newRow, newColumn, thisPB);
return;
}
Rochade rochade = new Rochade();
Rochade.newKingMove = new Tuple<int, int>(newRow, newColumn);
rochade.DoRochade(currentFigure);
if (rochade.RochadeKing != null && rochade.RochadeKing.PieceColor == currentColor) // rochade succed
{
DoRochadeMove(rochade, thisPB);
return;
}
currentFigure.UpdateMoves(currentFigure);
if (currentFigure.IsValidMove(new Tuple<int, int>(newRow, newColumn)) &&
!currentFigure.WillExposeKing(currentFigure, new Tuple<int, int>(newRow, newColumn)))
{
DoStandartMove(newRow, newColumn, thisPB);
}
else
{
thisPB.Location = new Point(previousX, previousY);
}
Color tempTileColor = GetTile(currentFigure).BackColor;
thisPB.BackColor = tempTileColor;
currentFigure = null;
KingIsDefeated();
}
// All the different possible moves are being checked here
private void KingIsDefeated()
{
Figure blackKing = BlackFigures.Single(blackFigure => blackFigure.PieceType == FigureType.King);
Figure whiteKing = WhiteFigures.Single(whiteFigure => whiteFigure.PieceType == FigureType.King);
int count = blackKing.Moves.Count(blackKingMove => blackKing.WillExposeKing(blackKing, blackKingMove));
if (count == blackKing.Moves.Count && blackKing.Moves.Count > 0)
{
WinningCondition(blackKing);
}
count = whiteKing.Moves.Count(whiteKingMove => whiteKing.WillExposeKing(whiteKing, whiteKingMove));
if (count == whiteKing.Moves.Count && whiteKing.Moves.Count > 0)
{
WinningCondition(whiteKing);
}
}
private void DoRochadeMove(Rochade rochade, Control thisPB)
{
PassedTurns passedTurns = new PassedTurns();
UpdateTimerValue();
List<Figure> figureList = currentFigure.PieceColor == FigureColor.Black
? BlackFigures
: WhiteFigures;
Figure currentKing = figureList.Single(x => x.PieceType == FigureType.King);
Figure currentRook = figureList.
Single(x => x.PieceType == FigureType.Rook &&
Equals(x.StartingPosition, rochade.RochadeRook.StartingPosition));
PictureBox rookPb = GetFigureTile(currentRook);
RemoveMultipleFiguresFromTeam(currentKing, currentRook);
RemoveMultipleFiguresFromFiguresList(currentKing, currentRook);
currentKing = rochade.RochadeKing;
currentRook = rochade.RochadeRook;
AddMultipleFiguresToFiguresList(currentKing, currentRook);
AddMultipleFiguresToTeam(currentKing, currentRook);
currentKing.UpdateMoves(currentKing);
currentRook.UpdateMoves(currentRook);
rookPb.Location =
new Point(
DrawnBoard[currentRook.CurrentPosition.Item1][currentRook.CurrentPosition.Item2].Location.X +
marginsLeftToCenterTile,
DrawnBoard[currentRook.CurrentPosition.Item1][currentRook.CurrentPosition.Item2].Location.Y +
marginsLeftToCenterTile);
UpdateBoard();
passedTurn = null;
currentColor = currentColor == FigureColor.Black
? FigureColor.White
: FigureColor.Black;
currentFigure = currentKing;
thisPB.Location =
new Point(
DrawnBoard[currentKing.CurrentPosition.Item1][currentKing.CurrentPosition.Item2].Location.X +
marginsLeftToCenterTile,
DrawnBoard[currentKing.CurrentPosition.Item1][currentKing.CurrentPosition.Item2].Location.Y +
marginsLeftToCenterTile);
currentTurn++;
UpdateTurnTracking(passedTurns, currentFigure, "Rochade");
}
private void DoPawnReplaceMove(int newRow, int newColumn, Control thisPB)
{
PassedTurns passedTurns = new PassedTurns();
UpdateTimerValue();
currentFigure.CurrentPosition = new Tuple<int, int>(newRow, newColumn);
thisPB.Location = new Point(DrawnBoard[newRow][newColumn].Location.X + marginsLeftToCenterTile,
DrawnBoard[newRow][newColumn].Location.Y + marginsLeftToCenterTile);
RemoveFromTeam(currentFigure);
Figures.Remove(currentFigure);
currentFigure = ReplacePawn(currentFigure, new Tuple<int, int>(newRow, newColumn), thisPB);
AddToTeam(currentFigure);
Figures.Add(currentFigure);
currentFigure.UpdateMoves(currentFigure);
passedTurn = null;
UpdateBoard();
currentTurn++;
UpdateAllFiguresMoves();
UpdateTurnTracking(passedTurns, currentFigure, "Replaced Pawn");
}
private void DoStandartMove(int newRow, int newColumn, Control thisPB)
{
PassedTurns passedTurns = new PassedTurns();
UpdateTimerValue();
currentFigure.WasMoved = true;
currentFigure.CurrentPosition = new Tuple<int, int>(newRow, newColumn);
thisPB.Location = new Point(DrawnBoard[newRow][newColumn].Location.X + marginsLeftToCenterTile,
DrawnBoard[newRow][newColumn].Location.Y + marginsLeftToCenterTile);
currentColor = currentColor == FigureColor.Black
? FigureColor.White
: FigureColor.Black;
string tempAction;
if (currentFigure.WillCollideWithEnemy(currentFigure.CurrentPosition, currentFigure.PieceColor).Item1)
{
RemoveFigure(currentFigure);
tempAction = "Took a Figure";
}
else
{
tempAction = "Normal";
}
UpdateBoard();
currentTurn++;
UpdateAllFiguresMoves();
UpdateTurnTracking(passedTurns, currentFigure, tempAction);
}
// Checks and enables the timer if checked in the options
private void UpdateTimerValue()
{
if (Properties.Settings.Default.EnabledTurnTimers)
{
pbTimer.Value = (int) timerMaxValue;
}
}
/// <summary>
/// Updates the Board's boolean array
/// <seealso cref="Board"/>
/// </summary>
private static void UpdateBoard()
{
foreach (bool[] row in Board)
{
for (int j = 0; j < Board.Length; j++)
{
row[j] = false;
}
}
for (int i = 0; i < Board.Length; i++)
{
for (int j = 0; j < Board.Length; j++)
{
if (figuresImages.TakeWhile(figureImage => figureImage != null)
.Any(figureImage => DrawnBoard[i][j].Location == figureImage.Location))
{
Board[i][j] = true;
}
}
}
}
/// <summary>
/// Method to determine where the player has dropped his figure located in the
/// <seealso cref="DrawnBoard"/>
/// </summary>
private static int GetNewTile(Control thisPB, out int newColumn)
{
int newRow = 0;
newColumn = 0;
int closestX = int.MaxValue;
int closestY = int.MaxValue;
for (int i = 0; i < DrawnBoard.Length; i++)
{
for (int j = 0; j < DrawnBoard.Length; j++)
{
int horizontalDifference = thisPB.Location.X - DrawnBoard[i][j].Location.X;
int verticalDifference = thisPB.Location.Y - DrawnBoard[i][j].Location.Y;
if (horizontalDifference <= closestX && verticalDifference <= closestY && horizontalDifference > -1 &&
verticalDifference > -1)
{
closestX = thisPB.Location.X - DrawnBoard[i][j].Location.X;
closestY = thisPB.Location.Y - DrawnBoard[i][j].Location.Y;
newRow = i;
newColumn = j;
}
}
}
return newRow;
}
/// <summary>
/// Method to determine which figure is being moved by comparing it's image to the ones in
/// <seealso cref="figuresImages"/>
/// </summary>
private static Figure GetFigure(Control sender)
{
return (from figuresImage in figuresImages.TakeWhile(figuresImage => figuresImage != null)
where figuresImage.Location.X == sender.Location.X && figuresImage.Location.Y == sender.Location.Y
from figure1 in Figures
where Equals(figure1.PieceImage, figuresImage.BackgroundImage)
select figure1).FirstOrDefault();
}
/// <summary>
/// Method returning the current tile that the figure was placed on
/// </summary>
private static PictureBox GetTile(Figure inputCurrentFigure)
{
return DrawnBoard[inputCurrentFigure.CurrentPosition.Item1][inputCurrentFigure.CurrentPosition.Item2];
}
/// <summary>
/// Method returning the current tile that the figure is standing on
/// </summary>
private static PictureBox GetFigureTile(Figure inputCurrentFigure)
{
return
figuresImages.TakeWhile(figuresImage => figuresImage != null)
.FirstOrDefault(
figuresImage =>
figuresImage.Location.X == GetTile(inputCurrentFigure).Location.X + marginsLeftToCenterTile &&
figuresImage.Location.Y == GetTile(inputCurrentFigure).Location.Y + marginsLeftToCenterTile &&
Equals(figuresImage.BackgroundImage, inputCurrentFigure.PieceImage));
}
//this button is currently disabled usually it rerolls the last turn played
//if a figure is removed the turn cant be undone
private void bUndo_Click(object sender, EventArgs e)
{
if (passedTurn == null || currentTurn == 0)
{
return;
}
TurnTrackingList.Items[TurnTrackingList.Items.Count - 1].Remove();
Tuple<Point, Figure, PictureBox> previous = passedTurn;
previous.Item3.Location = previous.Item1;
int newColumn;
int newRow = GetNewTile(previous.Item3, out newColumn);
previous.Item2.CurrentPosition = new Tuple<int, int>(newRow, newColumn);
currentColor = currentColor == FigureColor.Black
? FigureColor.White
: FigureColor.Black;
if (Equals(previous.Item2.CurrentPosition, previous.Item2.StartingPosition))
{
previous.Item2.WasMoved = false;
}
UpdateBoard();
UpdateAllFiguresMoves();
currentTurn--;
}
/// <summary>
/// Method removing figures also checking if the removed figure is king if so the game ends.
/// </summary>
private void RemoveFigure(Figure inputCurrentFigure)
{
Tuple<int, int> turnRoute = inputCurrentFigure.CurrentPosition;
Figure enemyFigure = inputCurrentFigure.WillCollideWithEnemy(turnRoute, inputCurrentFigure.PieceColor).Item2;
PictureBox enemyFigurePictureBox = GetFigureTile(enemyFigure);
enemyFigurePictureBox.MouseMove -= Figure_MouseMove;
enemyFigurePictureBox.MouseDown -= Figure_MouseDown;
enemyFigurePictureBox.MouseUp -= Figure_MouseUp;
enemyFigurePictureBox.BackColor = Color.White;
if (Properties.Settings.Default.EnabledTurnTracking)
{
enemyFigurePictureBox.Width -= enemyFigurePictureBox.Width / 3;
enemyFigurePictureBox.Height -= enemyFigurePictureBox.Height / 3;
}
if (inputCurrentFigure.PieceColor == FigureColor.Black)
{
flpBlackPlayerWinnings.Controls.Add(enemyFigurePictureBox);
WhiteFigures.Remove(enemyFigure);
}
else
{
flpWhitePlayerWinnings.Controls.Add(enemyFigurePictureBox);
BlackFigures.Remove(enemyFigure);
}
if (enemyFigure.PieceType == FigureType.King)
{
WinningCondition(enemyFigure);
return;
}
inputCurrentFigure.WillCollideWithEnemy(turnRoute, inputCurrentFigure.PieceColor).Item2.CurrentPosition =
new Tuple<int, int>(-1, -1);
passedTurn = null;
}
private void WinningCondition(Figure enemyFigure)
{
const string replayText = @"Would You like to play again ?";
string winningText = @"White Player Wins !";
if (enemyFigure.PieceColor == FigureColor.White)
{
winningText = @"Black Player Wins !";
}
DialogResult replayDialog = MessageBox.Show(winningText + Environment.NewLine + replayText,
@"Congratulations", MessageBoxButtons.YesNo);
if (replayDialog == DialogResult.Yes)
{
Restart();
}
else
{
DialogResult exitApplicationDialog =
MessageBox.Show(@"You are about to exit the application are you sure ?", @"Quit",
MessageBoxButtons.YesNo);
if (exitApplicationDialog == DialogResult.Yes)
{
Application.Exit();
}
else
{
Close();
}
}
}
private void Restart()
{
passedTurn = null;
Figures.Clear();
for (int i = 0; i < figuresImages.Length; i++)
{
if (figuresImages[i] == null)
{
break;
}
figuresImages[i].Dispose();
figuresImages[i] = null;
}
isMoved = false;
currentFigure = null;
previousX = 0;
previousY = 0;
currentColor = currentColor == FigureColor.Black
? FigureColor.White
: FigureColor.Black;
currentTurn = 0;
WhiteFigures.Clear();
BlackFigures.Clear();
AddKings();
AddQueens();
AddRooks();
AddBishops();
AddKnights();
AddPawns();
DrawFigures();
}
/// <summary>
/// Whenever one figure is moved all the other figures moves also change so this is called whenever a figure is being moved
/// </summary>
private static void UpdateAllFiguresMoves()
{
foreach (var figure in Figures)
{
figure.UpdateMoves(figure);
}
}
/// <summary>
/// Method to replace the pawn with selected figure from
/// <seealso cref="ReplacePawnForm"/>
/// </summary>
private static Figure ReplacePawn(Figure currentFigure, Tuple<int, int> newMove,Control pb)
{
ReplacePawnForm replacedPawnForm = new ReplacePawnForm(currentFigure.PieceColor, newMove);
replacedPawnForm.ShowDialog();
currentFigure = replacedPawnForm.ReplacedFigure;
pb.BackgroundImage = currentFigure.PieceImage;
return currentFigure;
}
/// <summary>
/// Method that determines if a pawn must be replaced i.e it has reached the other end of the board
/// </summary>
private static bool MustReplacePawn(Figure currentFigure, Tuple<int,int> newMove)
{
if (currentFigure.PieceType != FigureType.Pawn || !currentFigure.Moves.Contains(newMove)) return false;
if (currentFigure.PieceColor == FigureColor.Black)
{
if (newMove.Item1 == 0)
{
return true;
}
}
else
{
if (newMove.Item1 == 7)
{
return true;
}
}
return false;
}
//Methods to enable and update turn tracking if it was checked in Options
private void EnableTurnTracking()
{
TurnTrackingList = new ListView
{
View = View.Details,
GridLines = true,
Location = new Point(flpWhitePlayerWinnings.Location.X, flpWhitePlayerWinnings.Location.Y + flpWhitePlayerWinnings.Height + 40),
Size = new Size(flpWhitePlayerWinnings.Width, flpWhitePlayerWinnings.Height * 2 - 30),
BorderStyle = BorderStyle.FixedSingle,
BackColor = Color.White
};
TurnTrackingList.Columns.Add("Turn", -2, HorizontalAlignment.Left);
TurnTrackingList.Columns.Add("White Player", -2, HorizontalAlignment.Left);
TurnTrackingList.Columns.Add("Black Player", -2, HorizontalAlignment.Left);
TurnTrackingList.Columns.Add("Piece Type", -2, HorizontalAlignment.Left);
TurnTrackingList.Columns.Add("Action", -2, HorizontalAlignment.Left);
TurnTrackingList.AutoResizeColumn(0, ColumnHeaderAutoResizeStyle.HeaderSize);
Controls.Add(TurnTrackingList);
}
private void UpdateTurnTrackingList(FigureColor figureColor)
{
int actualTurn = currentTurn%2 == 0 ? currentTurn/2 : currentTurn/2 + 1;
ListViewItem turnTrackingRow = new ListViewItem(actualTurn.ToString(), 0); // first item only here
object[] turnTrackingRowItems = new object[4];
if (figureColor == FigureColor.Black)
{
Tuple<int, int> tempPosition = (Tuple<int, int>)blackTurns[actualTurn - 1][(int)PassedTurns.ItemsOrder.Position];
int x = tempPosition.Item2;
int y = size - tempPosition.Item1;
string formatedPosition = letters[x] + " , " + y;
turnTrackingRowItems[(int) PassedTurns.ListsOrder.WhitePlayer] = string.Empty;
turnTrackingRowItems[(int) PassedTurns.ListsOrder.BlackPlayer] = formatedPosition;
turnTrackingRowItems[(int) PassedTurns.ListsOrder.PieceType] =
blackTurns[actualTurn - 1][(int) PassedTurns.ItemsOrder.PieceType];
turnTrackingRowItems[(int) PassedTurns.ListsOrder.Action] =
blackTurns[actualTurn - 1][(int) PassedTurns.ItemsOrder.Action];
}
else
{
Tuple<int, int> tempPosition = (Tuple<int, int>)whiteTurns[actualTurn - 1][(int)PassedTurns.ItemsOrder.Position];
int x = tempPosition.Item2;
int y = size - tempPosition.Item1;
string formatedPosition = letters[x] + " , " + y;
turnTrackingRowItems[(int) PassedTurns.ListsOrder.BlackPlayer] = string.Empty;
turnTrackingRowItems[(int) PassedTurns.ListsOrder.WhitePlayer] = formatedPosition;
turnTrackingRowItems[(int) PassedTurns.ListsOrder.PieceType] =
whiteTurns[actualTurn - 1][(int) PassedTurns.ItemsOrder.PieceType];
turnTrackingRowItems[(int) PassedTurns.ListsOrder.Action] =
whiteTurns[actualTurn - 1][(int) PassedTurns.ItemsOrder.Action];
}
foreach (object item in turnTrackingRowItems)
{
turnTrackingRow.SubItems.Add(item.ToString());
}
TurnTrackingList.Items.AddRange(new[] {turnTrackingRow});
}
private void UpdateTurnTracking(PassedTurns passedTurns, Figure inputFigure,string inputAction)
{
passedTurns.AddNewMove(inputFigure.CurrentPosition, inputFigure.PieceType, inputAction);
if (inputFigure.PieceColor == FigureColor.Black)
{
blackTurns.Add(passedTurns.GetPassedTurns());
}
else
{
whiteTurns.Add(passedTurns.GetPassedTurns());
}
UpdateTurnTrackingList(inputFigure.PieceColor);
}
}
Most of my comments are here so I hope that it will be a little bit easier to understand what's going on.
Figures
The Figure
class is the base class for all figures:
public abstract class Figure
{
public enum FigureType
{
Pawn,
Knight,
Bishop,
Rook,
Queen,
King
}
public enum FigureColor
{
White,
Black
}
private readonly FigureDefinition definition;
public List<Tuple<int, int>> Moves { get; set; }
public bool WasMoved
{
get { return definition.WasMoved; }
set { definition.WasMoved = value; }
}
public FigureColor PieceColor
{
get { return definition.PieceColor; }
set { definition.PieceColor = value; }
}
public FigureType PieceType
{
get { return definition.PieceType; }
set { definition.PieceType = value; }
}
public Image PieceImage
{
get { return definition.PieceImage; }
set { definition.PieceImage = value; }
}
public Tuple<int, int> StartingPosition
{
get { return definition.StartingPosition; }
set { definition.StartingPosition = value; }
}
public Tuple<int, int> CurrentPosition
{
get { return definition.CurrentPosition; }
set { definition.CurrentPosition = value; }
}
protected Figure(FigureDefinition definition)
{
this.definition = definition;
}
protected abstract List<Tuple<int, int>> GetValidTurns();
public bool IsValidMove(Tuple<int, int> newPosition) => Moves.Contains(newPosition);
protected bool IsOutOfBounds(Tuple<int, int> newPosition) =>
newPosition.Item1 > CooperativeForm.size - 1 ||
newPosition.Item2 > CooperativeForm.size - 1 ||
newPosition.Item1 < 0 ||
newPosition.Item2 < 0;
public bool WillCollideWithAlly(Tuple<int, int> turnRoute, FigureColor currentColor)
{
bool willCollide = false;
foreach (Figure figure in CooperativeForm.Figures)
{
if (figure == null)
{
break;
}
if (figure.CurrentPosition.Item1 == turnRoute.Item1 &&
figure.CurrentPosition.Item2 == turnRoute.Item2 &&
figure.PieceColor == currentColor)
{
willCollide = true;
}
}
return willCollide;
}
public Tuple<bool, Figure> WillCollideWithEnemy(Tuple<int, int> turnRoute, FigureColor currentColor)
{
bool willCollide = false;
Figure enemyFigure = null;
foreach (Figure figure in CooperativeForm.Figures)
{
if (figure == null)
{
break;
}
if (figure.CurrentPosition.Item1 == turnRoute.Item1 &&
figure.CurrentPosition.Item2 == turnRoute.Item2 &&
figure.PieceColor != currentColor)
{
willCollide = true;
enemyFigure = figure;
break;
}
}
return new Tuple<bool, Figure>(willCollide, enemyFigure);
}
public bool WillExposeKing(Figure currentFigure, Tuple<int, int> newPosition)
{
List<Figure> enemyPieces = currentFigure.PieceColor == FigureColor.Black
? CooperativeForm.WhiteFigures
: CooperativeForm.BlackFigures;
List<Figure> allyPieces = currentFigure.PieceColor == FigureColor.Black
? CooperativeForm.BlackFigures
: CooperativeForm.WhiteFigures;
Figure allyKing = allyPieces.SingleOrDefault(x => x.PieceType == FigureType.King);
if (allyKing == null) return false;
Tuple<int, int> previousPosition =
allyPieces.SingleOrDefault(x => Equals(x.CurrentPosition, currentFigure.CurrentPosition))?
.CurrentPosition;
if (previousPosition == null) return false;
currentFigure.CurrentPosition = newPosition;
foreach (var enemyPiece in enemyPieces)
{
enemyPiece.Moves = enemyPiece.GetValidTurns();
if (enemyPiece.Moves.Contains(allyKing.CurrentPosition))
{
if (!Equals(currentFigure.CurrentPosition, enemyPiece.CurrentPosition))
{
currentFigure.CurrentPosition = previousPosition;
return true;
}
}
}
currentFigure.CurrentPosition = previousPosition;
return false;
}
protected List<Tuple<int, int>> RemoveFailedTurns(Figure currentFigure, List<Tuple<int, int>> inputValidMoves)
{
List<Tuple<int,int>> itemsToRemove = inputValidMoves.Where(inputValidMove => WillCollideWithAlly(inputValidMove, currentFigure.PieceColor)).ToList();
foreach (Tuple<int, int> item in itemsToRemove)
{
inputValidMoves.Remove(item);
}
return inputValidMoves;
}
public void UpdateMoves(Figure inputFigure)
{
inputFigure.Moves = RemoveFailedTurns(this, GetValidTurns()).Distinct().ToList();
}
}
Combined with the FigureDefinition
Class :
public class FigureDefinition
{
public Figure.FigureColor PieceColor { get; set; }
public Figure.FigureType PieceType { get; set; }
public Image PieceImage { get; set; }
public Tuple<int, int> StartingPosition { get; set; }
public Tuple<int, int> CurrentPosition { get; set; }
public Tuple<int, int>[] ValidTurns { get; set; }
public bool WasMoved { get; set; }
}
Now every single Piece is inheriting this Figure
class
PawnPiece
Class
public sealed class PawnPiece : Figure
{
public PawnPiece(FigureDefinition definition) : base(definition)
{
Moves = RemoveFailedTurns(this, GetValidTurns());
Moves = Moves.Distinct().ToList();
}
protected override List<Tuple<int, int>> GetValidTurns()
{
List<Tuple<int, int>> validMoves = new List<Tuple<int, int>>();
int newRow = PieceColor == FigureColor.White ? 1 : -1;
if (Equals(StartingPosition, CurrentPosition))
{
Tuple<int, int> moveForwardStarting = new Tuple<int, int>(CurrentPosition.Item1 + 2 * newRow,
CurrentPosition.Item2);
if (!WillCollideWithAlly(moveForwardStarting, PieceColor) &&
!WillCollideWithEnemy(moveForwardStarting, PieceColor).Item1)
{
validMoves.Add(moveForwardStarting);
}
}
Tuple<int, int> moveForward = new Tuple<int, int>(CurrentPosition.Item1 + newRow, CurrentPosition.Item2);
Tuple<int, int> moveLeftDiagonal = new Tuple<int, int>(CurrentPosition.Item1 + newRow,
CurrentPosition.Item2 - 1);
Tuple<int, int> moveRightDiagonal = new Tuple<int, int>(CurrentPosition.Item1 + newRow,
CurrentPosition.Item2 + 1);
if (!IsOutOfBounds(moveForward) &&
!WillCollideWithEnemy(moveForward, PieceColor).Item1 &&
!WillCollideWithAlly(moveForward, PieceColor))
{
validMoves.Add(moveForward);
}
if (!IsOutOfBounds(moveLeftDiagonal) &&
WillCollideWithEnemy(moveLeftDiagonal, PieceColor).Item1 &&
!WillCollideWithAlly(moveLeftDiagonal, PieceColor))
{
validMoves.Add(moveLeftDiagonal);
}
if (!IsOutOfBounds(moveRightDiagonal) &&
WillCollideWithEnemy(moveRightDiagonal, PieceColor).Item1 &&
!WillCollideWithAlly(moveRightDiagonal, PieceColor))
{
validMoves.Add(moveRightDiagonal);
}
return validMoves;
}
}
Each Piece class is combined with a PieceDefinitons
Class which looks like this
public class PawnDefinitions
{
private static readonly GeneratePieces generatedPieces = new GeneratePieces(Figure.FigureType.Pawn, 0, 7, 1,
ImagePaths.WhitePawnImagePath, ImagePaths.BlackPawnImagePath);
public IEnumerable<FigureDefinition> WhitePawns = generatedPieces.GenerateWhitePieces();
public IEnumerable<FigureDefinition> BlackPawns = generatedPieces.GenerateBlackPieces();
}
Here we see the Class GeneratePiece
I'm going to post it after all the other piece's class's.
KnightPiece
Class :
public sealed class KnightPiece : Figure
{
public KnightPiece(FigureDefinition definition) : base(definition)
{
Moves = RemoveFailedTurns(this, GetValidTurns());
Moves = Moves.Distinct().ToList();
}
protected override List<Tuple<int, int>> GetValidTurns()
{
int newRow = PieceColor == FigureColor.White ? 1 : -1;
List<Tuple<int, int>> tempMoves = new List<Tuple<int, int>>
{
new Tuple<int,
int>(CurrentPosition.Item1 + 1,
CurrentPosition.Item2 + 2),
new Tuple<int,
int>(CurrentPosition.Item1 + 2,
CurrentPosition.Item2 + 1),
new Tuple<int,
int>(CurrentPosition.Item1 - 1,
CurrentPosition.Item2 + 2),
new Tuple<int,
int>(CurrentPosition.Item1 - 2,
CurrentPosition.Item2 + 1),
new Tuple<int,
int>(CurrentPosition.Item1 + 2,
CurrentPosition.Item2 - 1),
new Tuple<int,
int>(CurrentPosition.Item1 - 2,
CurrentPosition.Item2 - 1),
new Tuple<int,
int>(CurrentPosition.Item1 + 1,
CurrentPosition.Item2 - 2),
new Tuple<int,
int>(CurrentPosition.Item1 - 1,
CurrentPosition.Item2 - 2)
};
List<Tuple<int, int>> validMoves =
tempMoves.Where(
tempMove =>
!IsOutOfBounds(tempMove) &&
!WillCollideWithAlly(tempMove, PieceColor)).ToList();
return validMoves;
}
}
KnightsDefinitons
Class :
public class KnightDefinitions
{
private static readonly GeneratePieces generatedPieces = new GeneratePieces(Figure.FigureType.Knight, 1, 6, 5,
ImagePaths.WhiteKnightImagePath, ImagePaths.BlackKnightImagePath);
public IEnumerable<FigureDefinition> WhiteKnights = generatedPieces.GenerateWhitePieces();
public IEnumerable<FigureDefinition> BlackKnights = generatedPieces.GenerateBlackPieces();
}
BishopPiece
Class :
public sealed class BishopPiece : Figure
{
public BishopPiece(FigureDefinition definition) : base(definition)
{
Moves = RemoveFailedTurns(this, GetValidTurns());
Moves = Moves.Distinct().ToList();
}
protected override List<Tuple<int, int>> GetValidTurns()
{
int n = 1;
Tuple<int, int> rightUpDiagonal = new Tuple<int, int>(CurrentPosition.Item1 + n, CurrentPosition.Item2 + n);
Tuple<int, int> leftUpDiagonal = new Tuple<int, int>(CurrentPosition.Item1 + n, CurrentPosition.Item2 - n);
Tuple<int, int> rightDownDiagonal = new Tuple<int, int>(CurrentPosition.Item1 - n, CurrentPosition.Item2 + n);
Tuple<int, int> leftDownDiagonal = new Tuple<int, int>(CurrentPosition.Item1 - n, CurrentPosition.Item2 - n);
List<Tuple<int, int>> startingMoves = new List<Tuple<int, int>>
{
rightUpDiagonal,
leftUpDiagonal,
rightDownDiagonal,
leftDownDiagonal
};
List<Tuple<int, int>> validMoves =
startingMoves.Where(
startingMove =>
!IsOutOfBounds(startingMove) && !WillCollideWithAlly(startingMove, PieceColor))
.ToList();
while (!IsOutOfBounds(rightUpDiagonal) && !WillCollideWithAlly(rightUpDiagonal, PieceColor) &&
!WillCollideWithEnemy(rightUpDiagonal, PieceColor).Item1)
{
validMoves.Add(rightUpDiagonal);
n++;
rightUpDiagonal = new Tuple<int, int>(CurrentPosition.Item1 + n, CurrentPosition.Item2 + n);
if (WillCollideWithEnemy(rightUpDiagonal, PieceColor).Item1)
{
validMoves.Add(rightUpDiagonal);
break;
}
}
n = 1;
while (!IsOutOfBounds(leftUpDiagonal) && !WillCollideWithAlly(leftUpDiagonal, PieceColor) &&
!WillCollideWithEnemy(leftUpDiagonal, PieceColor).Item1)
{
validMoves.Add(leftUpDiagonal);
n++;
leftUpDiagonal = new Tuple<int, int>(CurrentPosition.Item1 + n, CurrentPosition.Item2 - n);
if (WillCollideWithEnemy(leftUpDiagonal, PieceColor).Item1)
{
validMoves.Add(leftUpDiagonal);
break;
}
}
n = 1;
while (!IsOutOfBounds(rightDownDiagonal) && !WillCollideWithAlly(rightDownDiagonal, PieceColor) &&
!WillCollideWithEnemy(rightDownDiagonal, PieceColor).Item1)
{
validMoves.Add(rightDownDiagonal);
n++;
rightDownDiagonal = new Tuple<int, int>(CurrentPosition.Item1 - n, CurrentPosition.Item2 + n);
if (WillCollideWithEnemy(rightDownDiagonal, PieceColor).Item1)
{
validMoves.Add(rightDownDiagonal);
break;
}
}
n = 1;
while (!IsOutOfBounds(leftDownDiagonal) && !WillCollideWithAlly(leftDownDiagonal, PieceColor) &&
!WillCollideWithEnemy(leftDownDiagonal, PieceColor).Item1)
{
validMoves.Add(leftDownDiagonal);
n++;
leftDownDiagonal = new Tuple<int, int>(CurrentPosition.Item1 - n, CurrentPosition.Item2 - n);
if (WillCollideWithEnemy(leftDownDiagonal, PieceColor).Item1)
{
validMoves.Add(leftDownDiagonal);
break;
}
}
return validMoves;
}
}
BishopDefinitons
Class :
public class BishopDefinitions
{
private static readonly GeneratePieces generatedPieces = new GeneratePieces(Figure.FigureType.Bishop, 2, 5, 3,
ImagePaths.WhiteBishopImagePath, ImagePaths.BlackBishopImagePath);
public IEnumerable<FigureDefinition> WhiteBishops = generatedPieces.GenerateWhitePieces();
public IEnumerable<FigureDefinition> BlackBishops = generatedPieces.GenerateBlackPieces();
}