private void Board_MouseClick(Object sender, MouseEventArgs e)
{
bool accepted = false;
if(computer_enabled && turn == ChessColor.BLACK)
{
return;
}
if(selected != null && ((PictureBox)sender) != selected)
{
if (BoardPieces[selected].Type != PieceType.KING && Kings[BoardPieces[selected].Color].Check(white_pieces, black_pieces, piecePositions))
{
bool isPawnAtStart = false;
positionInfo startPos = piecePositions[BoardPieces[selected].Position.X][BoardPieces[selected].Position.Y];
positionInfo endPos = piecePositions[positionOnBoard[(PictureBox)sender].X][positionOnBoard[(PictureBox)sender].Y];
startPos.ocupied = false;
startPos.piece = null;
endPos.ocupied = true;
endPos.piece = BoardPieces[selected];
if (BoardPieces[selected].Type == PieceType.PAWN)
{
isPawnAtStart = ((Pawn)BoardPieces[selected]).startingPos;
}
BoardPieces[selected].MovePiece(endPos.piece.Position.X, endPos.piece.Position.Y);
if(Kings[BoardPieces[selected].Color].Check(white_pieces, black_pieces, piecePositions))
{
startPos.ocupied = true;
startPos.piece = BoardPieces[selected];
endPos.ocupied = false;
endPos.piece = null;
BoardPieces[selected].MovePiece(startPos.piece.Position.X, startPos.piece.Position.Y);
if (BoardPieces[selected].Type == PieceType.PAWN && isPawnAtStart)
{
((Pawn)BoardPieces[selected]).startingPos = true;
}
DeselectBoard();
return;
}
accepted = true;
}
if (accepted || BoardPieces[selected].checkValidMove(positionOnBoard[(PictureBox)sender], white_pieces, black_pieces, piecePositions))
{
positionInfo startPos = piecePositions[BoardPieces[selected].Position.X][BoardPieces[selected].Position.Y];
positionInfo endPos = piecePositions[positionOnBoard[(PictureBox)sender].X][positionOnBoard[(PictureBox)sender].Y];
bool isPawnAtStart = false;
if (BoardPieces[selected].Type == PieceType.PAWN)
{
isPawnAtStart = ((Pawn)BoardPieces[selected]).startingPos;
}
startPos.ocupied = false;
startPos.piece = null;
endPos.ocupied = true;
endPos.piece = BoardPieces[selected];
BoardPieces[selected].MovePiece(endPos.piece.Position.X, endPos.piece.Position.Y);
if (BoardPieces[selected].Type != PieceType.KING && Kings[BoardPieces[selected].Color].Check(white_pieces, black_pieces, piecePositions))
{
startPos.ocupied = true;
startPos.piece = BoardPieces[selected];
endPos.ocupied = false;
endPos.piece = null;
BoardPieces[selected].MovePiece(startPos.piece.Position.X, startPos.piece.Position.Y);
if (BoardPieces[selected].Type == PieceType.PAWN)
{
((Pawn)BoardPieces[selected]).startingPos = isPawnAtStart;
}
DeselectBoard();
return;
}
MovesMade.Add(new Moves(BoardPieces[selected], BoardPieces[selected].Position.X, BoardPieces[selected].Position.Y,
positionOnBoard[(PictureBox)sender].X, positionOnBoard[(PictureBox)sender].Y));
loadMoves();
BoardPieces[selected].MovePiece(positionOnBoard[(PictureBox)sender].X, positionOnBoard[(PictureBox)sender].Y);
if (BoardPieces[selected].Type == PieceType.PAWN && BoardPieces[selected].Color == ChessColor.WHITE && BoardPieces[selected].Position.Y == 8 ||
BoardPieces[selected].Type == PieceType.PAWN && BoardPieces[selected].Color == ChessColor.BLACK && BoardPieces[selected].Position.Y == 1)
{
PawnChange changePawnForm = new PawnChange(BoardPieces[selected]);
if (changePawnForm.ShowDialog() == DialogResult.OK)
{
piecePositions[positionOnBoard[(PictureBox)sender].X][positionOnBoard[(PictureBox)sender].Y].ocupied = false;
piecePositions[positionOnBoard[(PictureBox)sender].X][positionOnBoard[(PictureBox)sender].Y].piece = null;
if(BoardPieces[selected].Color == ChessColor.WHITE)
{
white_pieces.Remove(BoardPieces[selected]);
}
else
{
black_pieces.Remove(BoardPieces[selected]);
}
Controls.Remove(selected);
BoardPieces.Remove(selected);
InitializeSinglePiece(changePawnForm.chosen.Position.X, changePawnForm.chosen.Position.Y, changePawnForm.chosen.Type, changePawnForm.chosen.Color, changePawnForm.chosen.Color == ChessColor.WHITE ? Color.White : Color.Black);
selected = piecePositions[changePawnForm.chosen.Position.X][changePawnForm.chosen.Position.Y].piece.Piece;
}
}
AnimateMovement((PictureBox)sender);
if(Kings[BoardPieces[selected].Color == ChessColor.WHITE ? ChessColor.BLACK : ChessColor.WHITE].Check(white_pieces, black_pieces, piecePositions))
{
if(Kings[BoardPieces[selected].Color == ChessColor.WHITE ? ChessColor.BLACK : ChessColor.WHITE].victoryCondition(white_pieces, black_pieces, piecePositions))
{
Victory victoryForm = new Victory(BoardPieces[selected].Color == ChessColor.WHITE ? ChessColor.BLACK : ChessColor.WHITE);
if (victoryForm.ShowDialog() == DialogResult.OK)
{
NewGame();
return;
}
else
{
Application.Exit();
}
}
}
timeElapsed = 0;
turn = turn == ChessColor.BLACK ? ChessColor.WHITE : ChessColor.BLACK;
}
DeselectBoard();
}
selected = null;
}Оваа функција се користи за поместување на селектирана фигура на едно од предодредените позиции на таблата, прво се врши проверка дали игра компјутер и доколку игра дали е ред на црни фигури, доколку би играл компјутерот и на ред е играчот со црни фигури оваа функција нема да прави ништо, исто така се врши проверка на селектираниот елемент дали е валиден, потоа се проверува дали сопствениот крал на играчот на потег е во позиција Check, доколку е се симулира поместување на елементот во позадина со што за пиони се чува bool променлива која кажува дали е на почеток и доколку е се користи за да се ресетира пионот, почетната и крајната позиција се земаат од соодветната мапа, односно од мапа char во друга мапа која мапира int вредност во елемент од PositionInfo кој содржи информации за соодветното поле дали е зафатено и доколку е зафатено го содржи соодветниот елемент од типот ChessPiece, до оваа мапа се пристапува преку друга мапа која мапира од PictureBox во соодветна фигура (само за фигурите), бидејќи само PictureBox имаат click евенти, а за притиснатиот PictureBox се користи мапата positionOnBoard која мапира од PictureBox во соодветна позиција на таблата, тука исто така постои променлива што би дозволила пристап до следниот елемент доколку се направи потег и е прифатен, за да не се врши проверка за веќе преместена позиција, бидејќи преместување на тотално иста позидција е невалиден потег,потоа се изменуваат вредностите и се поместува фигурата во позадина и се извршува уште една проверка за дали кралот е во Check после извршениот потег доколку е, ќе се врати почетната состојба на таблата и нема да дозволи да се направи тој потег, потоа доколку кралот не бил од почеток во состојба Check, се проверува дали селектираното поле е валидно за поместување на фигурата, доколку е селектирано од обележаните места тој услов би поминал, сега исто како и претходниот пат се земаат стартната позиција и крајната позиција, се променуваат во позадина и се проверува дали кралот на тековниот играч влегол во Check по извршувањето на позицијата, во внатрешноста Check функцијата ги добива сите бели и црни фигури и поставувањето на таблата, и во зависност кој е на ред се земаат сите фигури од противникот, потоа за сите нивни можни потези се проверува дали може да ја стигнат позицијата на кралот доколку една фигура може оваа функција враќа вредност true, со што ќе се ресетира позицијата на поместената фигура и нема да се дозволи поместување, но доколку кралот не доаѓа до состојба Check, поместената фигура останува, и се прави записник на потегот, потоа се врши проверка дали поместената фигура била пион, доколку е се проверува дали стигнала до крајот на таблата, доколку е стигната се отвора форма за избор на фигура за замена, се заменува така што комплетно се брише пионот и ново креираната фигура, која е направена и сместена во формата за промена се користи за да се иницијализира тотално нова фигура на иста позиција но од различен тип, и се поставува за селектирана, исто така се прави и визуелниот приказ за корисникот дека фигурата е поместена, потоа се прави проверка по поместувањето на фигурата дали спротивниот крал е во check доколку е се прави уште една проверка за дали може да спречи загуба, оваа функција е имплементирана така што се проверува прво дали е CheckMate (тоа значи дека има фигура која го достигнува кралот а кралот неможе да направи сопствен потег бидејќи е блокиран) единствена шанса е да се помести друга фигура за одбрана на кралот, па поради тоа поставен е услов, бројот на фигури кои го достигаат кралот да е 1, бигејќи е невозможно со еден потег да се блокираат 2 фигури, доколку е само една фигура се земаат сите позиции кои се потребни на противникот да стигне до кралот (Од соодветната фигура до кралот, другите се игнорираат), и се проверува дали некоја друга со иста боја фигура може да пристигне до неа (за Rook, Bishop и Queen), а за Knight се гледа дали може да биде достигнат од друга фигура, доколку е можно ова се продолжува со игра како и нормално, но доколку се одлучи дека победил играчот се појавува нова форма за победа на која го пишува победникот и има 2 копчуња за избор, едното е за нова игра да започне, а другото е за да се исклучи играта, доколку играта продолжува нормално, се поставува тајмерот на 0 за следниот играч и се променува вредноста на turn променливата која одредува кој играч е на ред. Потоа за крај се повикува DeselectBoard функцијата која само ги променува боите на позадината на прикажаните потези за асоодветниот играч.
Се игра како класична игра на шах, прво се притиска на фигурата која сакаме да ја селектираме, потоа кога ќе се прикажат потезите се очекува играчот да избере еден од нив, во случај на клик надвор од избраните валидни потези се деселектира фигурата, за двата играчи има опција да се предат, со што е поставено скриено копче, кој се прикажува првиот пат кога се направи Check на кралот, но оваа опција постои цело време во менито, Home -> Surrender, доколку е селекриран mode Player v Player, но доколку е избрано да се игра против компјутер, копчето surrender дозволено е само за едните фигури.


