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 override IEnumerable<Move> GetValidMoves(Square[][] board) { var legalMoves = new List<Move>(); if (!CurrentColumn.HasValue || !CurrentRow.HasValue || !Alive) return legalMoves; var column = CurrentColumn.Value; var row = CurrentRow.Value; var possibleEndPositions = PossibleEndPositions(column, row); foreach (var position in possibleEndPositions) { var newRow = position.Row; var newColumn = position.Column; if (EndPositionIsWithinBounds(newRow, newColumn)) { var occupant = board[newRow][newColumn].ChessPiece; if (occupant == null || occupant.Team != Team) legalMoves.Add(SetupNewMove(newRow, newColumn)); } } return legalMoves; }
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; }
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 (!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; }
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 bool IsInCheck(Square[][] board) { if (Alive && CurrentColumn.HasValue && CurrentRow.HasValue) { var square = board[CurrentRow.Value][CurrentColumn.Value]; var team = GetOppositeTeam(); if (square.TargetedByTeam(board, team)) return true; } return false; }
public override IEnumerable<Move> GetValidMoves(Square[][] board) { var legalMoves = new List<Move>(); if (!CurrentColumn.HasValue || !CurrentRow.HasValue || !Alive) return legalMoves; var column = CurrentColumn.Value; var row = CurrentRow.Value; var endPositions = new List<Tuple<int, int>>(); GetDiagonalMoves(board, row, column, endPositions); legalMoves.AddRange(endPositions.Select(p => SetupNewMove(p.Item1, p.Item2))); return legalMoves; }
public override IEnumerable<Move> GetValidMoves(Square[][] board) { var legalMoves = new List<Move>(); if (!CurrentColumn.HasValue || !CurrentRow.HasValue || !Alive) return legalMoves; var column = CurrentColumn.Value; var row = CurrentRow.Value; var newRow = row + LegalDirectionByTeam(); var openingMove = SetupNewMove(newRow + 1, column); var normalMove = SetupNewMove(newRow, column); if (board[normalMove.EndRow][normalMove.EndColumn].ChessPiece == null) { legalMoves.Add(normalMove); if (ValidOpeningPushWithNoDefender(board, openingMove)) legalMoves.Add(openingMove); } if (column - 1 >= 0) { var attackLeft = SetupNewMove(newRow, column - 1); var leftOccupant = board[attackLeft.EndRow][attackLeft.EndColumn].ChessPiece; if (leftOccupant != null && leftOccupant.Team != Team) legalMoves.Add(attackLeft); } if (column + 1 < 8) { var attackRight = SetupNewMove(newRow, column + 1); var rightOccupant = board[attackRight.EndRow][attackRight.EndColumn].ChessPiece; if (rightOccupant != null && rightOccupant.Team != Team) legalMoves.Add(attackRight); } return legalMoves; }
public override System.Collections.Generic.IEnumerable<Move> GetValidMoves(Square[][] board) { var legalMoves = new List<Move>(); if (!CurrentColumn.HasValue || !CurrentRow.HasValue || !Alive) return legalMoves; var column = CurrentColumn.Value; var row = CurrentRow.Value; var possibleEndPosition = new[] { new Tuple<int, int>(row, column + 1), new Tuple<int, int>(row, column - 1), new Tuple<int, int>(row + 1, column + 1), new Tuple<int, int>(row + 1, column - 1), new Tuple<int, int>(row - 1, column + 1), new Tuple<int, int>(row - 1, column - 1), new Tuple<int, int>(row + 1, column), new Tuple<int, int>(row - 1, column), }; foreach (var position in possibleEndPosition) { var newRow = position.Item1; var newColumn = position.Item2; if (newRow < 8 && newRow >= 0) if (newColumn < 8 && newColumn >= 0) { var occupant = board[newRow][newColumn].ChessPiece; if (occupant == null || occupant.Team != Team) legalMoves.Add(SetupNewMove(newRow, newColumn)); } } return legalMoves; }
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; }
protected ChessPiece GetAttacker(Square[][] board, Move move) { return board[move.StartRow][move.StartColumn].ChessPiece; }
public abstract bool IsLegalMove(Square[][] board, Move move, IEnumerable<Move> pastMoves = null);
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++; }
private void DestroyOccupant(Square[][] board, Move move) { var occupant = GetDestinationPiece(board, move); if (occupant != null) { occupant.Alive = false; occupant.CurrentColumn = null; occupant.CurrentRow = null; } }
public abstract IEnumerable<Move> GetValidMoves(Square[][] board);
public Board(Square[][] board) { Squares = board; }
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 void GetHorizontalMoves(Square[][] board, int row, int column, List<Tuple<int, int>> endPositions) { ChessPiece occupant; for (var r = row; r < 8; r++) { occupant = board[r][column].ChessPiece; if (occupant != null && occupant.Team == Team) break; endPositions.Add(new Tuple<int, int>(r, column)); if (occupant != null && occupant.Team != Team) break; } for (var r = row; r >= 0; r--) { occupant = board[r][column].ChessPiece; if (occupant != null && occupant.Team == Team) break; endPositions.Add(new Tuple<int, int>(r, column)); if (occupant != null && occupant.Team != Team) break; } }
protected void GetVerticalMoves(Square[][] board, int column, int row, List<Tuple<int, int>> endPositions) { ChessPiece occupant; for (var c = column; c < 8; c++) { occupant = board[row][c].ChessPiece; if (occupant != null && occupant.Team == Team) break; endPositions.Add(new Tuple<int, int>(row, c)); if (occupant != null && occupant.Team != Team) break; } for (var c = column; c < 8; c--) { occupant = board[row][c].ChessPiece; if (occupant != null && occupant.Team == Team) break; endPositions.Add(new Tuple<int, int>(row, c)); if (occupant != null && occupant.Team != Team) break; } }
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 GetDestinationPiece(Square[][] board, Move move) { return board[move.EndRow][move.EndColumn].ChessPiece; }
private static IOrderedEnumerable<Square> OrderSquaresForBoard(Square[] squares) { var orderedSquares = squares.OrderBy(s => s.Row).ThenBy(s => s.Column); return orderedSquares; }
private static void VerifyBoardHasAllSquares(Square[] squares) { if (squares.Count() != 64) throw new InvalidDataException("There must be 64 squares to initialize a board."); }
public Board(Square[] squares) { VerifyBoardHasAllSquares(squares); SetupSquareMatrix(squares); }
private bool IsLegalEnPassant(Square[][] board, Move move, IEnumerable<Move> pastMoves) { if (pastMoves == null) return false; var lastMove = pastMoves.LastOrDefault(); if (lastMove == null) return false; var piece = GetDestinationPiece(board, lastMove); if (IsPawnsSecondMoveInProperDirection(move, lastMove, piece)) { return true; } return false; }
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; }
private Square[] RepairMissingSquares(Game game, Square[] squares) { if (!squares.Any()) { var missingSquares = new Board().Squares.SelectMany(s => s).ToArray(); foreach (var square in missingSquares) { square.Game = game; square.ChessPiece = square.ChessPiece; UnitOfWork.Add(square); } UnitOfWork.Commit(); squares = missingSquares; } return squares; }
private void SetupSquareMatrix(Square[] squares) { var orderedSquares = OrderSquaresForBoard(squares); var row = new List<Square>(); var tempSquares = new List<Square[]>(); foreach (var square in orderedSquares) { row.Add(square); if (row.Count != 8) { continue; } tempSquares.Add(row.ToArray()); row = new List<Square>(); } Squares = tempSquares.ToArray(); }