public override bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null) { var defender = GetDestinationPiece(board, move); if (move.RowChange != LegalDirectionByTeam()) if (!ValidOpeningPushWithNoDefender(board, move)) return false; if (move.ColumnChange != 0) { CheckForMultipleColumnMovement(move); CheckForLegalDirection(move); if (defender == null && !IsLegalEnPassant(board, move, pastMoves)) return false; ValidateNotAttackingSameTeam(board, move); return true; } if (defender != null) throw new Exception("There is a piece in the way!"); return true; }
public bool IsLegalCastle(Square[][] board, Move move) { var source = board[move.StartRow][move.StartColumn]; var destination = board[move.EndRow][move.EndColumn]; var direction = GetMovementModifier(move.ColumnChange); var rook = direction > 0 ? board[move.EndRow][7].ChessPiece : board[move.EndRow][0].ChessPiece; if (move.RowChange != 0) throw new Exception("Illegal move."); if (MoveCount > 0) throw new Exception("You may only castle if your king has not moved yet."); if (destination.ChessPiece != null) throw new Exception("You may not castle to an occupied square."); if (rook == null || rook.PieceType != Data.Enum.PieceType.Rook || rook.MoveCount > 0) throw new Exception("The rook on that side has already moved."); if (HasCollision(board, move)) throw new Exception("There is a piece in the way of the castle."); if (IsInCheck(board)) throw new Exception("You may not castle while in check."); if (destination.TargetedByTeam(board, GetOppositeTeam())) throw new Exception("You may not castle into check."); return true; }
private static bool IsValidKnightMove(Move move) { var possibleMoves = PossibleEndPositions(move.StartColumn, move.StartRow); var moveIsPossible = possibleMoves.Any(m => m.Row == move.EndRow && m.Column == move.EndColumn); return moveIsPossible; }
public override bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null) { ValidateNotAttackingSameTeam(board, move); if (move.RowChange != 0 && move.ColumnChange != 0) throw new Exception("You only move horizontal or vertical with a rook."); if (HasCollision(board, move)) throw new Exception("There is a piece between you and your destination."); return true; }
public override bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null) { ValidateNotAttackingSameTeam(board, move); if (Math.Abs(move.RowChange) != Math.Abs(move.ColumnChange)) throw new Exception("You may only move diagonally with a bishop."); if (HasCollision(board, move)) throw new Exception("There is a piece between your bishop and your destination!"); return true; }
public override bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null) { ValidateNotAttackingSameTeam(board, move); if (!InBounds(move.EndRow, move.EndColumn)) throw new Exception("You have moved out of bounds!"); if (!IsValidKnightMove(move)) //L-movement throw new Exception("You may only move in a proper 'L' pattern for a knight."); return true; }
public override bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null) { ValidateNotAttackingSameTeam(board, move); if (!HasLegalMovementModifiers(move)) throw new Exception("You may move diagonal, vertical, or horizontal with a queen."); if (HasCollision(board, move)) throw new Exception("There is a piece between your queen and your destination!"); return true; }
private bool HasLegalMovementModifiers(Move move) { if (Math.Abs(move.RowChange) == Math.Abs(move.ColumnChange)) //diagonal return true; if (move.RowChange != 0 && move.ColumnChange == 0) //vertical return true; if (move.RowChange == 0 && move.ColumnChange != 0) //horizontal return true; return false; }
public bool Equals(Move move) { if (StartColumn != move.StartColumn) return false; if (EndColumn != move.EndColumn) return false; if (StartRow != move.StartRow) return false; if (EndRow != move.EndRow) return false; return true; }
public bool TargetedByTeam(Square[][] board, Enum.Team team) { foreach (var row in board) foreach (var square in row.Where(square => square.ChessPiece != null && square.ChessPiece.Team == team)) { var possibleMove = new Move { EndColumn = Column, EndRow = Row, StartColumn = square.Column, StartRow = square.Row }; try { if (square.ChessPiece.IsLegalMove(board, possibleMove)) return true; } catch { } } return false; }
public abstract bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null);
private void DestroyOccupant(Square[][] board, Move move) { var occupant = GetDestinationPiece(board, move); if (occupant != null) { occupant.Alive = false; occupant.CurrentColumn = null; occupant.CurrentRow = null; } }
protected void ValidateNotAttackingSameTeam(Square[][] board, Move move) { var attacker = GetAttacker(board, move); var occupant = GetDestinationPiece(board, move); if (occupant != null && occupant.Team == attacker.Team) throw new Exception("You may not attack the same team."); }
protected bool HasCollision(Square[][] board, Move move) { var rowModifier = GetMovementModifier(move.RowChange); var columnModifier = GetMovementModifier(move.ColumnChange); var row = move.StartRow + rowModifier; var column = move.StartColumn + columnModifier; while (row != move.EndRow || column != move.EndColumn) { if (!InBounds(row, column)) return true; //out of bounds if (board[row][column].ChessPiece != null) return true; //collison row += rowModifier; column += columnModifier; } return false; }
protected ChessPiece GetDestinationPiece(Square[][] board, Move move) { return board[move.EndRow][move.EndColumn].ChessPiece; }
private void PerformEnPassant(Move move) { var direction = move.RowChange > 0 ? 1 : -1; var enemySquare = _board.Squares[move.EndRow - direction][move.EndColumn]; enemySquare.ChessPiece.Alive = false; enemySquare.ChessPiece = null; }
private static bool FitsCastleCriteria(Move move, ChessPiece piece) { return piece.PieceType == PieceType.King && Math.Abs(move.ColumnChange) > 1; }
public void MovePiece(Move move) { var piece = _board.Squares[move.StartRow][move.StartColumn].ChessPiece; var defender = _board.Squares[move.EndRow][move.EndColumn].ChessPiece; var currentTeam = TeamToMove(); ValidateActiveGame(); ValidateIsCurrentTeam(piece); ValidateIsLegalMove(move, piece); PerformMove(move, defender, piece); MarkGameProgress(piece, defender); ValidateKingNotInCheck(currentTeam); }
private void IncrementMoveData(Move move) { Game.Moves.Add(move); Game.MoveCount++; Game.MoveCountSinceProgress++; }
private void ValidateIsLegalMove(Move move, ChessPiece piece) { var teamName = Enum.GetName(typeof(Team), piece.Team); var pieceName = Enum.GetName(typeof(PieceType), piece.PieceType); var orderedMoves = Game.Moves.OrderBy(i => i.MoveId); if (!piece.IsLegalMove(_board.Squares, move, orderedMoves)) throw new Exception("This is not a legal move for a " + teamName + " " + pieceName + "."); }
private bool SavesKing(Move move) { var currentTeam = TeamToMove(); var squares = GetMockSquares(_board.Squares); var piece = squares[move.StartRow][move.StartColumn].ChessPiece; piece.Move(squares, move); if (IsKingInCheck(currentTeam, squares)) { return false; } return true; }
private void PerformMove(Move move, ChessPiece defender, ChessPiece piece) { if (FitsEnPassantCriteria(move, defender, piece)) { PerformEnPassant(move); } if (FitsCastleCriteria(move, piece)) { MoveRookForCastle(move); } if (defender != null) { if (piece.Team == Team.Dark) Game.DarkScore += defender.ScoreValue; if (piece.Team == Team.Light) Game.LightScore += defender.ScoreValue; } piece.Move(_board.Squares, move); IncrementMoveData(move); }
public void Move(Square[][] board, Move move) { DestroyOccupant(board, move); board[move.EndRow][move.EndColumn].ChessPiece = this; board[move.StartRow][move.StartColumn].ChessPiece = null; CurrentColumn = move.EndColumn; CurrentRow = move.EndRow; MoveCount++; }
public bool ValidOpeningPushWithNoDefender(Square[][] board, Move move) { return MoveCount == 0 && move.RowChange == LegalDirectionByTeam() * 2 && move.ColumnChange == 0 && board[move.EndRow - LegalDirectionByTeam()][move.EndColumn].ChessPiece == null && board[move.EndRow][move.EndColumn].ChessPiece == null; }
protected ChessPiece GetAttacker(Square[][] board, Move move) { return board[move.StartRow][move.StartColumn].ChessPiece; }
private static bool FitsEnPassantCriteria(Move move, ChessPiece defender, ChessPiece piece) { return defender == null && piece.PieceType == PieceType.Pawn && Math.Abs(move.ColumnChange) == 1; }
private Exception NewMoveFailureException(Move move, Exception ex) { var start = move.StartColumn + ", " + move.StartRow; var end = move.EndColumn + ", " + move.EndRow; var reasonForFailure = ex.Message; return new ArgumentException(String.Format("Moving {0} to {1} is illegal. {2}", start, end, reasonForFailure)); }
private void MoveRookForCastle(Move move) { var direction = move.ColumnChange > 0 ? 1 : -1; var rook = direction > 0 ? _board.Squares[move.EndRow][7].ChessPiece : _board.Squares[move.EndRow][0].ChessPiece; var rookMove = new Move() { EndColumn = move.EndColumn - direction, EndRow = move.EndRow, StartColumn = rook.CurrentColumn ?? 0, StartRow = move.StartRow, }; rook.Move(_board.Squares, rookMove); }
public ActionResult MakeMove(long id, Move move) { var game = GetChessGame(id); var gameManager = new GameManager(game); if (!IsPlayersMove(game, CurrentUser)) throw new Exception("It is not your turn!"); try { var movingTeam = gameManager.TeamToMove(); gameManager.MovePiece(move); if (gameManager.IsDraw()) gameManager.MarkGameAsDraw(); else if (gameManager.IsCheckmate()) gameManager.MarkWinningTeam(movingTeam); UnitOfWork.Commit(); var model = GetGameModel(game); return Json(model, JsonRequestBehavior.AllowGet); } catch (Exception ex) { throw NewMoveFailureException(move, ex); } }
private bool IsPawnsSecondMoveInProperDirection(Move move, Entities.Move lastMove, ChessPiece piece) { return piece.PieceType == PieceType.Pawn && lastMove.EndRow == move.EndRow - LegalDirectionByTeam() && lastMove.EndColumn == move.EndColumn && piece.MoveCount == 1; }