private List <Move> GetRawMoves_Pawn(Peice[,] board) { Point location = GetLocation(board); List <Move> validmoves = new List <Move>(); int yoffset = 1; if (mySide == PSide.Black) { yoffset = -1; } //Side indicated forward direction //Take diaganols for (int i = 1; true; i = -1) //X-Axis direction { Point newloc = new Point(location.X + i, location.Y + yoffset); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.enemy) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } //En Passant else if (moveType == TileTypes.free) //diagonal free { //Get side piece Point sideloc = new Point(newloc.X, location.Y); Peice sidePeice = board[sideloc.X, sideloc.Y]; //Rules: 1)Piece type of pawn 2)Pawn first moved last turn 3)Pawn moved two-spaces if (GetTileType(board, sideloc) == TileTypes.enemy && sidePeice.lastmove == myGame.turn_count - 1 && sideloc.Y == (int)(sidePeice.mySide) * 7 + (yoffset * -3)) { validmoves.Add(new Move(newloc, MoveTypes.enpass, sideloc)); } } if (i == -1) { break; } } //Forward directional movement for (int i = 1; i <= 2; i++) { Point newloc = new Point(location.X, location.Y + (yoffset * i)); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.free) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } if (!firstmove || moveType != TileTypes.free) { break; } } return(validmoves); }
internal static List<Peice> getPeices(Peice[,] board, PSide side) { List<Peice> sideList = new List<Peice>(); foreach (Peice peice in board) { if (peice != null && peice.MySide == side) { sideList.Add(peice); } } return sideList; }
internal static Point getKing(Peice[,] board, PSide side) { for (int x = 0; x < 8; x++) { for (int y = 0; y < 8; y++) { if (board[x, y] != null && board[x, y].MySide == side && board[x, y].MyType == Peices.PType.King) { return new Point(x, y); } } } throw new Exception("Searched for king on board for " + side.ToString() + " side, not present"); }
private GameObject GetPiecePrefab(Chess.Peices.Peice piece) { return(piece.MySide switch { PSide.White => piece.MyType switch { PType.King => whiteKing, PType.Queen => whiteQueen, PType.Rook => whiteRook, PType.Bishop => whiteBishop, PType.Knight => whiteKnight, PType.Pawn => whitePawn, _ => throw new ArgumentOutOfRangeException() },
private List <Move> GetRawMoves_King(Peice[,] board) { Point location = GetLocation(board); List <Move> validmoves = new List <Move>(); foreach (Point offset in king_offsets) { Point newloc = new Point(location.X + offset.X, location.Y + offset.Y); TileTypes moveType = GetTileType(board, newloc); if (moveType != TileTypes.blocked) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } } //Castling if (firstmove && !myGame.ischecked[(int)mySide]) //Conditional, ensure king first move and not in check { Point[] CastlePoints = { new Point(0, (int)mySide * 7), new Point(7, (int)mySide * 7) }; //Get peices at both corners of side foreach (Point rookPoint in CastlePoints) { Peice rook = board[rookPoint.X, rookPoint.Y]; if (rook != null && rook.mySide == mySide && rook.myType == PType.Rook && rook.firstmove == true) //Conditional peice is side rook, no prior movements { bool directpath = true; int dir = Math.Sign(rookPoint.X - location.X); //Ensure all peices between rook and king are clear, and aren't in line of fire/attacked for (int xoffset = dir; board[location.X + xoffset, location.Y] != rook; xoffset += dir) { Point testloc = new Point(location.X + xoffset, location.Y); if (GetTileType(board, testloc) != TileTypes.free || myGame.inattacksquares[(int)mySide].Any(attack => attack.movPoint == testloc)) { directpath = false; break; } } Point newloc = new Point(location.X + dir * 2, location.Y); Point newrookloc = new Point(newloc.X + dir * -1, location.Y); if (directpath) { validmoves.Add(new Move(newloc, MoveTypes.castle, rookPoint, newrookloc)); } } } } return(validmoves); }
internal static void movePeice(Peice[,] board, Point fromPoint, Move toMove) { Peice movpeice = board[fromPoint.X, fromPoint.Y]; board[fromPoint.X, fromPoint.Y] = null; board[toMove.movPoint.X, toMove.movPoint.Y] = movpeice; switch (toMove.moveType) { case MoveTypes.enpass: { board[toMove.ensidePoint.X, toMove.ensidePoint.Y] = null; break; } case MoveTypes.castle: { Peice rookPeice = board[toMove.rookPoint.X, toMove.rookPoint.Y]; board[toMove.rookPoint.X, toMove.rookPoint.Y] = null; board[toMove.newrookPoint.X, toMove.newrookPoint.Y] = rookPeice; break; } } }
} //Gets piece location on board private TileTypes GetTileType(Peice[,] board, Point newloc) { if (ChessGame.inBounds(newloc)) { if (board[newloc.X, newloc.Y] == null) return TileTypes.free; if(board[newloc.X, newloc.Y].mySide != mySide) return TileTypes.enemy; } return TileTypes.blocked; } //Gets tile type of new position for move
private Point GetLocation(Peice[,] board) { for(int x = 0; x < 8; x++) { for(int y = 0; y < 8; y++) { if (board[x, y] == this) { return new Point(x, y); } } } throw new Exception(); } //Gets piece location on board
private List<Move> GetRawMoves_Pawn(Peice[,] board) { Point location = GetLocation(board); List<Move> validmoves = new List<Move>(); int yoffset = 1; if (mySide == PSide.Black) { yoffset = -1; } //Side indicated forward direction //Take diaganols for (int i = 1; true; i = -1) //X-Axis direction { Point newloc = new Point(location.X + i, location.Y + yoffset); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.enemy) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } //En Passant else if(moveType == TileTypes.free) //diagonal free { //Get side piece Point sideloc = new Point(newloc.X, location.Y); Peice sidePeice = board[sideloc.X, sideloc.Y]; //Rules: 1)Piece type of pawn 2)Pawn first moved last turn 3)Pawn moved two-spaces if (GetTileType(board, sideloc) == TileTypes.enemy && sidePeice.lastmove == myGame.turn_count - 1 && sideloc.Y == (int)(sidePeice.mySide) * 7 + (yoffset * -3)) { validmoves.Add(new Move(newloc, MoveTypes.enpass, sideloc)); } } if (i == -1) { break; } } //Forward directional movement for (int i = 1; i <= 2; i++) { Point newloc = new Point(location.X, location.Y + (yoffset * i)); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.free) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } if (!firstmove || moveType != TileTypes.free) { break; } } return validmoves; }
private List<Move> GetRawMoves_Knight(Peice[,] board) { Point location = GetLocation(board); List<Move> validmoves = new List<Move>(); foreach (Point offset in knight_offsets) { Point newloc = new Point(location.X + offset.X, location.Y + offset.Y); TileTypes moveType = GetTileType(board, newloc); if (moveType != TileTypes.blocked) { validmoves.Add(new Move(newloc, MoveTypes.standard)); }; } return validmoves; }
private List<Move> GetRawMoves_Bishop(Peice[,] board) { Point location = GetLocation(board); List<Move> validmoves = new List<Move>(); foreach (Point quad in quadoffsets) //Iterate through quadrant-movemetns for diagonals { Point offset = quad; while (true) { Point newloc = new Point(location.X + offset.X, location.Y + offset.Y); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.free) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } else if (moveType == TileTypes.enemy) { validmoves.Add(new Move(newloc, MoveTypes.standard)); break; } else { break; } //blocked offset.X += quad.X; offset.Y += quad.Y; //Increment offsets in specific direction } } return validmoves; }
private List<Move> GetRawMoves_Queen(Peice[,] board) { List<Move> validmoves = new List<Move>(); //Queen moves represnted by combination of rook and bishop validmoves.AddRange(GetRawMoves_Rook(board)); validmoves.AddRange(GetRawMoves_Bishop(board)); return validmoves; }
private List<Move> GetRawMoves_King(Peice[,] board) { Point location = GetLocation(board); List<Move> validmoves = new List<Move>(); foreach (Point offset in king_offsets) { Point newloc = new Point(location.X + offset.X, location.Y + offset.Y); TileTypes moveType = GetTileType(board, newloc); if (moveType != TileTypes.blocked) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } } //Castling if(firstmove && !myGame.ischecked[(int)mySide]) //Conditional, ensure king first move and not in check { Point[] CastlePoints = { new Point(0, (int)mySide * 7), new Point(7, (int)mySide * 7) }; //Get peices at both corners of side foreach(Point rookPoint in CastlePoints) { Peice rook = board[rookPoint.X, rookPoint.Y]; if(rook != null && rook.mySide == mySide && rook.myType == PType.Rook && rook.firstmove == true) //Conditional peice is side rook, no prior movements { bool directpath = true; int dir = Math.Sign(rookPoint.X - location.X); //Ensure all peices between rook and king are clear, and aren't in line of fire/attacked for(int xoffset = dir; board[location.X + xoffset, location.Y] != rook; xoffset += dir) { Point testloc = new Point(location.X + xoffset, location.Y); if(GetTileType(board, testloc) != TileTypes.free || myGame.inattacksquares[(int)mySide].Any(attack => attack.movPoint == testloc)) { directpath = false; break; } } Point newloc = new Point(location.X + dir * 2, location.Y); Point newrookloc = new Point(newloc.X + dir * -1,location.Y); if (directpath) { validmoves.Add(new Move(newloc, MoveTypes.castle, rookPoint, newrookloc)); } } } } return validmoves; }
//Methods returning un-filtered moves for piece types private List<Move> GetRawMoves(Peice[,] board) { switch (myType) //Assign appropriate move function { case (PType.King): { return GetRawMoves_King(board); } case (PType.Queen): { return GetRawMoves_Queen(board); } case (PType.Rook): { return GetRawMoves_Rook(board); } case (PType.Bishop): { return GetRawMoves_Bishop(board); } case (PType.Knight): { return GetRawMoves_Knight(board); } case (PType.Pawn): { return GetRawMoves_Pawn(board); } } return null; }
private List<Move> GetRawMoves_Rook(Peice[,] board) { Point location = GetLocation(board); List<Move> validmoves = new List<Move>(); for (int i = -1; true; i = 1) //Axis direction { //X-axis movement for (int xoffset = i; true; xoffset += i) { Point newloc = new Point(location.X + xoffset, location.Y); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.free) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } else if (moveType == TileTypes.enemy) { validmoves.Add(new Move(newloc, MoveTypes.standard)); break; } else { break; } //blocked } //Y-axis movement for (int yoffset = i; true; yoffset += i) { Point newloc = new Point(location.X, location.Y + yoffset); TileTypes moveType = GetTileType(board, newloc); if (moveType == TileTypes.free) { validmoves.Add(new Move(newloc, MoveTypes.standard)); } else if (moveType == TileTypes.enemy) { validmoves.Add(new Move(newloc, MoveTypes.standard)); break; } else { break; } //blocked } if (i == 1) { break; } } return validmoves; }
public void OnTake(Peice peice) { PlaySound(Sounds.take); PBoxWhite.Invalidate(); PBoxBlack.Invalidate(); }
} //Draw game public bool MakeMove(Point toPoint) { if (selectedpiece == null) { return false; } if (selectedpiece.myMoves.Any(mov => mov.movPoint == toPoint)) //Is selected move for peice valid? { bool activemove = false; //Move from chosen point Move mov = GetMove(toPoint).Value; //Move piece Peice lastoccup; if (mov.moveType == MoveTypes.enpass) { lastoccup = GetPeice(mov.ensidePoint); } else { lastoccup = Gameboard[toPoint.X, toPoint.Y]; } movePeice(Gameboard, selectedpiece.MyLocation, mov); //Transform pawn if (selectedpiece.MyType == PType.Pawn) { activemove = true; if (PAWNTRANFORM && (int)altSide(turn) * 7 == toPoint.Y) { selectedpiece.ChangeType(GetPieceTransform()); } } //Move events if (OnPieceMove != null) { OnPieceMove(new Tuple<Peice, Point>(selectedpiece, toPoint)); } //Take events if (lastoccup != null) { PieceList.Remove(lastoccup); TakenList.Add(lastoccup); activemove = true; if (OnPieceTaken != null) { OnPieceTaken(lastoccup); } } //Aftermove update for piece selectedpiece.AfterMove(); //Update inactive move counter if (!activemove) { inactive_count++; } else { inactive_count = 0; } } else { return false; } turn_count++; ischecked = new bool[2]; inattacksquares[(int)turn].Clear(); //Update for next turn, calculate possible moves turn = altSide(turn); int movecount = 0; foreach (Peice peice in getPeices(Gameboard, turn)) { movecount += peice.UpdateMoves(); } //Display endgame messege if (ischecked[(int)turn] && movecount != 0) //Checked { if (OnCheck != null) { OnCheck(turn, EndGames.Check); } } else if (ischecked[(int)turn] && movecount == 0) //Chekmated { if (OnEndGame != null) { OnEndGame(turn, EndGames.Checkmate); }; active = false; } else if (!ischecked[(int)turn] && movecount == 0) //Stalemated { if (OnEndGame != null) { OnEndGame(turn, EndGames.Stalemate); } active = false; } //Game continues for next turn selectedpiece = null; return true; } //Play turn, move to point