public override BaseChessPiece GetCaptured(Point2D at, ref bool enpassant) { BaseChessPiece basePiece = base.GetCaptured(at, ref enpassant); if (basePiece != null && basePiece.Color != m_Color) { return(basePiece); // Normal capture } if (at.X == m_Position.X) { return(null); // Straight movement } Point2D p = new Point2D(at.X, m_Position.Y); basePiece = m_BChessboard[p]; if (basePiece != null && basePiece.Color != m_Color) { enpassant = true; return(basePiece); } else { return(null); } }
public override bool CanMoveTo(Point2D newLocation, ref string err) { if (!base.CanMoveTo(newLocation, ref err)) { return(false); } // Care only about absolutes for knights int dx = Math.Abs(newLocation.X - m_Position.X); int dy = Math.Abs(newLocation.Y - m_Position.Y); if (!((dx == 1 && dy == 2) || (dx == 2 && dy == 1))) { err = "Knights can only make L shaped moves (2-3 tiles length)"; return(false); // Wrong move } // Verify target piece BaseChessPiece piece = m_BChessboard[newLocation]; if (piece == null || piece.Color != m_Color) { return(true); } else { err = "You can't capture pieces of your same color"; return(false); } }
public override ArrayList GetMoves(bool capture) { ArrayList moves = new ArrayList(); for (int dx = -2; dx <= 2; dx++) { for (int dy = -2; dy <= 2; dy++) { if (!((Math.Abs(dx) == 1 && Math.Abs(dy) == 2) || (Math.Abs(dx) == 2 && Math.Abs(dy) == 1))) { continue; } Point2D p = new Point2D(m_Position.X + dx, m_Position.Y + dy); if (!m_BChessboard.IsValid(p)) { continue; } BaseChessPiece piece = m_BChessboard[p]; if (piece == null) { moves.Add(p); } else if (capture && piece.Color != m_Color) { moves.Add(p); } } } return(moves); }
/// <summary> /// Creates a new Move object without capturing a piece /// </summary> /// <param name="piece">The chess piece performing the move</param> /// <param name="target">The target location of the move</param> public Move( BaseChessPiece piece, Point2D target ) { m_Piece = piece; m_From = m_Piece.Position; m_To = target; m_Captured = m_Piece.GetCaptured( target, ref m_EnPassant ); }
/// <summary> /// Callback for selecting the piece to move /// </summary> public void OnPickPieceTarget(Mobile from, object targeted) { m_Black.CloseGump(typeof(EndGameGump)); m_White.CloseGump(typeof(EndGameGump)); if (!(targeted is IPoint2D)) { from.SendMessage(0x40, "Invalid selection"); SendMoveTarget(from); return; } BaseChessPiece piece = m_Board[m_Board.WorldToBoard(new Point2D(targeted as IPoint2D))]; if (piece == null || piece.Color != GetColor(from)) { from.SendMessage(0x40, "Invalid selection"); SendMoveTarget(from); return; } m_MovingPiece = piece; from.Target = new ChessTarget(this, from, "Where do you wish to move?", OnPieceMove); }
/// <summary> /// Creates a new Move object without capturing a piece /// </summary> /// <param name="piece">The chess piece performing the move</param> /// <param name="target">The target location of the move</param> public Move(BaseChessPiece piece, Point2D target) { m_Piece = piece; m_From = m_Piece.Position; m_To = target; m_Captured = m_Piece.GetCaptured(target, ref m_EnPassant); }
public override ArrayList GetMoves(bool capture) { ArrayList moves = new ArrayList(); for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { if (dx == 0 && dy == 0) { continue; // Can't move to same spot } Point2D p = new Point2D(m_Position.X + dx, m_Position.Y + dy); if (!m_BChessboard.IsValid(p)) { continue; } BaseChessPiece piece = m_BChessboard[p]; if (piece == null) { moves.Add(p); } else if (capture && piece.Color != m_Color) { moves.Add(p); } } } return(moves); }
/// <summary> /// Tries to perfrom a move. Will send any diagnostic messages to user if failed. /// Will perform the move if it's valid. /// </summary> /// <param name="err">This string will hold any error messages if the move fails</param> /// <param name="piece">The piece being moved</param> /// <param name="to">The world location of the move target</param> /// <returns>True if the move is legal</returns> public bool TryMove(ref string err, BaseChessPiece piece, Point2D to) { Point2D p2 = WorldToBoard(to); if (piece == null) { err = "You must select a piece for your move"; return(false); } if (!piece.CanMoveTo(p2, ref err)) { return(false); // Invalid move } if (piece.IsCastle(p2)) { // This move is making a castle. All needed verification is made by the AllowCastle() function. Rook rook = piece as Rook; if (rook == null) { rook = this[p2] as Rook; } m_IsMoving = true; rook.Castle(); return(true); } Move move = new Move(piece, p2); ApplyMove(move); // bool ok = !IsCheck( piece.Color ) || IsCheckMate( piece.EnemyColor ); bool ok = !IsCheck(piece.Color); UndoMove(move); if (ok) { m_IsMoving = true; piece.MoveTo(move); foreach (BaseChessPiece pass in m_Table.Values) { if (pass != piece) { pass.AllowEnPassantCapture = false; // Reset en passant allowance } } } else { err = "That move would put your king under check"; } return(ok); }
public ChessMobile(BaseChessPiece piece) : base(AIType.AI_Use_Default, FightMode.None, 1, 1, 0.2, 0.2) { m_WayPoints = new List <WayPoint>(); InitStats(25, 100, 100); m_Piece = piece; Blessed = true; Paralyzed = true; Direction = m_Piece.Facing; }
public ChessMobile( BaseChessPiece piece ) : base( AIType.AI_Use_Default, FightMode.None, 1, 1, 0.2, 0.2 ) { m_WayPoints = new ArrayList(); InitStats( 25, 100, 100 ); m_Piece = piece; Blessed = true; Paralyzed = true; Direction = m_Piece.Facing; }
/// <summary> /// Verifies if a given player is in check /// </summary> /// <param name="color">The color being examined</param> /// <returns>True if the specified king is checked</returns> public bool IsCheck(ChessColor color) { BaseChessPiece king = GetKing(color); if (king == null) { // This occurs when the game is performing a simulation // In this case a potential move kills the king, // therefore the king is indeed attacked. return(true); } return(IsAttacked(king.Position, king.EnemyColor)); }
/// <summary> /// Callback for the move finalization /// </summary> public void OnPieceMove(Mobile from, object targeted) { string err = null; if (!(targeted is IPoint2D)) { err = "Invalid Move"; m_MovingPiece = null; if (GetColor(from) == ChessColor.Black) { SendAllGumps(null, err); } else { SendAllGumps(err, null); } return; } if (!m_Board.TryMove(ref err, m_MovingPiece, new Point2D(targeted as IPoint2D))) { m_MovingPiece = null; if (GetColor(from) == ChessColor.Black) { SendAllGumps(null, err); } else { SendAllGumps(err, null); } return; } // Move has been made. Wait until it's over if (m_Status == GameStatus.WhiteToMove) { m_Status = GameStatus.WhiteMoving; SendAllGumps("Making your move", null); } else { m_Status = GameStatus.BlackMoving; SendAllGumps(null, "Making your move"); } }
/// <summary> /// Verifies if the specified mobile is the owner or a given chess piece /// </summary> /// <param name="m">The mobile being checked</param> /// <param name="piece">The piece being examined for ownership</param> /// <returns>True if the mobile is the owner of the specified piece</returns> private bool IsOwner(Mobile m, BaseChessPiece piece) { if (m == m_Black && piece.Color == ChessColor.Black) { return(true); } else if (m == m_White && piece.Color == ChessColor.White) { return(true); } else { return(false); } }
/// <summary> /// Gets the piece that this piece would capture when moving to a specific location. /// This function assumes that the square can be reached. /// </summary> /// <param name="at">The target location with the potential capture</param> /// <param name="enpassant">Will hold a value stating whether this move is made en passant</param> /// <returns>A BaseChessPiece if a capture is possible, null otherwise</returns> public virtual BaseChessPiece GetCaptured(Point2D at, ref bool enpassant) { enpassant = false; BaseChessPiece piece = m_BChessboard[at]; if (piece != null && piece.Color != m_Color) { return(piece); } else { return(null); } }
public override bool CanMoveTo(Point2D newLocation, ref string err) { if (!base.CanMoveTo(newLocation, ref err)) { return(false); } int dx = newLocation.X - m_Position.X; int dy = newLocation.Y - m_Position.Y; if (Math.Abs(dx) != Math.Abs(dy)) { err = "Bishops can move only on diagonals"; return(false); // Not a diagonal movement } int xDirection = dx > 0 ? 1 : -1; int yDirection = dy > 0 ? 1 : -1; if (Math.Abs(dx) > 1) { // Verify that the path to target is empty for (int i = 1; i < Math.Abs(dx); i++) // Skip the bishop square and stop before target { int xOffset = xDirection * i; int yOffset = yDirection * i; if (m_BChessboard[m_Position.X + xOffset, m_Position.Y + yOffset] != null) { err = "Bishops can't move over other pieces"; return(false); } } } // Verify target piece BaseChessPiece piece = m_BChessboard[newLocation]; if (piece == null || piece.Color != m_Color) { return(true); } else { err = "You can't capture pieces of your own color"; return(false); } }
public override ArrayList GetMoves(bool capture) { ArrayList moves = new ArrayList(); int[] xDirection = new int[] { -1, 1, 0, 0 }; int[] yDirection = new int[] { 0, 0, 1, -1 }; for (int i = 0; i < 4; i++) { int xDir = xDirection[i]; int yDir = yDirection[i]; int offset = 1; while (true) { Point2D p = new Point2D(m_Position.X + offset * xDir, m_Position.Y + offset * yDir); if (!m_BChessboard.IsValid(p)) { break; } BaseChessPiece piece = m_BChessboard[p]; if (piece == null) { moves.Add(p); offset++; continue; } if (capture && piece.Color != m_Color) { moves.Add(p); break; } break; } } return(moves); }
public override bool CanMoveTo(Point2D newLocation, ref string err) { if (!base.CanMoveTo(newLocation, ref err)) { return(false); } // Verify if this is a castle BaseChessPiece rook = m_BChessboard[newLocation]; if (rook is Rook && rook.Color == m_Color) { // Trying to castle return(m_BChessboard.AllowCastle(this, rook, ref err)); } int dx = newLocation.X - m_Position.X; int dy = newLocation.Y - m_Position.Y; if (Math.Abs(dx) > 1 || Math.Abs(dy) > 1) { err = "The can king can move only 1 tile at a time"; return(false); // King can move only 1 tile away from its position } // Verify target piece BaseChessPiece piece = m_BChessboard[newLocation]; if (piece == null || piece.Color != m_Color) { return(true); } else { err = "You can't capture pieces of your same color"; return(false); } }
/// <summary> /// A pawn has been promoted and should be changed on the board /// </summary> /// <param name="pawn">The pawn that has been promoted</param> /// <param name="to">The type of piece it should be promoted to</param> public void OnPawnPromoted(BaseChessPiece pawn, PawnPromotion to) { BaseChessPiece promoted = null; switch (to) { case PawnPromotion.Queen: promoted = new Queen(this, pawn.Color, pawn.Position); break; case PawnPromotion.Rook: promoted = new Rook(this, pawn.Color, pawn.Position); break; case PawnPromotion.Knight: promoted = new Knight(this, pawn.Color, pawn.Position); break; case PawnPromotion.Bishop: promoted = new Bishop(this, pawn.Color, pawn.Position); break; } if (promoted != null) { m_Table[pawn.Position] = promoted; pawn.Die(false); } PushGame(pawn.EnemyColor, null); }
public override bool CanMoveTo(Point2D newLocation, ref string err) { if (!base.CanMoveTo(newLocation, ref err)) { return(false); } int dx = newLocation.X - m_Position.X; int dy = newLocation.Y - m_Position.Y; if (dx == 0 || dy == 0) { // Straight movement if (Math.Abs(dx) > 1) // If it's just 1 step no need to check for intermediate pieces { int direction = dx > 0 ? 1 : -1; // Moving along X axis for (int i = 1; i < Math.Abs(dx); i++) { int offset = direction * i; if (m_BChessboard[m_Position.X + offset, m_Position.Y] != null) { err = "The queen can't move over other pieces"; return(false); } } } else if (Math.Abs(dy) > 1) { // Moving along Y axis int direction = dy > 0 ? 1 : -1; for (int i = 1; i < Math.Abs(dy); i++) { int offset = direction * i; if (m_BChessboard[m_Position.X, m_Position.Y + offset] != null) { err = "The queen can't move over other pieces"; return(false); } } } } else { // Diagonal movement if (Math.Abs(dx) != Math.Abs(dy)) { err = "The queen moves only on straight lines or diagonals"; return(false); // Uneven } if (Math.Abs(dx) > 1) { int xDirection = dx > 0 ? 1 : -1; int yDirection = dy > 0 ? 1 : -1; for (int i = 1; i < Math.Abs(dx); i++) { int xOffset = xDirection * i; int yOffset = yDirection * i; if (m_BChessboard[m_Position.X + xOffset, m_Position.Y + yOffset] != null) { err = "The queen can't move over other pieces"; return(false); } } } } // Verify target piece BaseChessPiece piece = m_BChessboard[newLocation]; if (piece == null || piece.Color != m_Color) { return(true); } else { err = "You can't capture pieces of your same color"; return(false); } }
/// <summary> /// Adds a chess piece to the board table /// </summary> /// <param name="piece">The piece being added</param> private void AddPiece(BaseChessPiece piece) { m_Table.Add(piece.Position, piece); }
/// <summary> /// Verifies if the specified mobile is the owner or a given chess piece /// </summary> /// <param name="m">The mobile being checked</param> /// <param name="piece">The piece being examined for ownership</param> /// <returns>True if the mobile is the owner of the specified piece</returns> private bool IsOwner( Mobile m, BaseChessPiece piece ) { if ( m == m_Black && piece.Color == ChessColor.Black ) return true; else if ( m == m_White && piece.Color == ChessColor.White) return true; else return false; }
/// <summary> /// Tries to perfrom a move. Will send any diagnostic messages to user if failed. /// Will perform the move if it's valid. /// </summary> /// <param name="err">This string will hold any error messages if the move fails</param> /// <param name="piece">The piece being moved</param> /// <param name="to">The world location of the move target</param> /// <returns>True if the move is legal</returns> public bool TryMove( ref string err, BaseChessPiece piece, Point2D to ) { Point2D p2 = WorldToBoard( to ); if ( piece == null ) { err = "You must select a piece for your move"; return false; } if ( ! piece.CanMoveTo( p2, ref err ) ) { return false; // Invalid move } if ( piece.IsCastle( p2 ) ) { // This move is making a castle. All needed verification is made by the AllowCastle() function. Rook rook = piece as Rook; if ( rook == null ) rook = this[ p2 ] as Rook; m_IsMoving = true; rook.Castle(); return true; } Move move = new Move( piece, p2 ); ApplyMove( move ); // bool ok = !IsCheck( piece.Color ) || IsCheckMate( piece.EnemyColor ); bool ok = !IsCheck( piece.Color ); UndoMove( move ); if ( ok ) { m_IsMoving = true; piece.MoveTo( move ); foreach( BaseChessPiece pass in m_Table.Values ) { if ( pass != piece ) pass.AllowEnPassantCapture = false; // Reset en passant allowance } } else { err = "That move would put your king under check"; } return ok; }
/// <summary> /// Verifies if the requested castle moved is allowed /// </summary> /// <param name="king">The King performing the castle</param> /// <param name="rook">The Rook</param> /// <param name="err">Will hold any error messages</param> /// <returns>True if the castle move is allowed</returns> public bool AllowCastle(BaseChessPiece king, BaseChessPiece rook, ref string err) { #region Castle Rules // 1 Your king has been moved earlier in the game. // 2 The rook that castles has been moved earlier in the game. // 3 There are pieces standing between your king and rook. // 4 The king is in check. // 5 The king moves through a square that is attacked by a piece of the opponent. // 6 The king would be in check after castling. #endregion if (king.HasMoved || rook.HasMoved) { err = "You can't castle if the rook or king have already moved"; return(false); // Rules 1 and 2 } if (IsCheck(king.Color)) { err = "You can't castle if your king is in check"; return(false); // Rule 4 } bool queenside = rook.Position.X == 0; if (queenside) { for (int i = 1; i < 4; i++) { if (this[i, king.Position.Y] != null) { err = "You can't castle if there are pieces between the king and the rook"; return(false); // Rule 3 queenside } } } else { if (this[5, king.Position.Y] != null || this[6, king.Position.Y] != null) { err = "You can't castle if there are pieces between the king and the rook"; return(false); // Rule 3 kingside } } // King always moves 2 int kingX = king.Position.X + (queenside ? -2 : 2); int kingTransit = king.Position.X + (queenside ? -1 : 1); if (IsAttacked(new Point2D(kingTransit, king.Position.Y), king.EnemyColor)) { err = "The king cannot move through a square that is under attack by the opponent"; return(false); // Rule 5 } if (IsAttacked(new Point2D(kingX, king.Position.Y), king.EnemyColor)) { err = "The king would be in check after the castle"; return(false); // Rule 6 } return(true); }
/// <summary> /// Adds a chess piece to the board table /// </summary> /// <param name="piece">The piece being added</param> private void AddPiece( BaseChessPiece piece ) { m_Table.Add( piece.Position, piece ); }
/// <summary> /// Callback for selecting the piece to move /// </summary> public void OnPickPieceTarget( Mobile from, object targeted ) { m_Black.CloseGump( typeof( EndGameGump ) ); m_White.CloseGump( typeof( EndGameGump ) ); if ( ! ( targeted is IPoint2D ) ) { from.SendMessage( 0x40, "Invalid selection" ); SendMoveTarget( from ); return; } BaseChessPiece piece = m_Board[ m_Board.WorldToBoard( new Point2D( targeted as IPoint2D ) ) ]; if ( piece == null || piece.Color != GetColor( from ) ) { from.SendMessage( 0x40, "Invalid selection" ); SendMoveTarget( from ); return; } m_MovingPiece = piece; from.Target = new ChessTarget( this, from, "Where do you wish to move?", OnPieceMove ); }
/// <summary> /// A pawn has been promoted and should be changed on the board /// </summary> /// <param name="pawn">The pawn that has been promoted</param> /// <param name="to">The type of piece it should be promoted to</param> public void OnPawnPromoted( BaseChessPiece pawn, PawnPromotion to ) { BaseChessPiece promoted = null; switch ( to ) { case PawnPromotion.Queen: promoted = new Queen( this, pawn.Color, pawn.Position ); break; case PawnPromotion.Rook: promoted = new Rook( this, pawn.Color, pawn.Position ); break; case PawnPromotion.Knight: promoted = new Knight( this, pawn.Color, pawn .Position ); break; case PawnPromotion.Bishop: promoted = new Bishop( this, pawn.Color, pawn.Position ); break; } if ( promoted != null ) { m_Table[ pawn.Position ] = promoted; pawn.Die( false ); } PushGame( pawn.EnemyColor, null ); }
public override List <Point2D> GetMoves(bool capture) { List <Point2D> moves = new List <Point2D>(); int direction = m_Color == ChessColor.Black ? 1 : -1; Point2D step = new Point2D(m_Position.X, m_Position.Y + direction); if (m_BChessboard.IsValid(step) && m_BChessboard[step] == null) { moves.Add(step); // Verify if this pawn can make a second step step.Y += direction; if (!m_HasMoved && m_BChessboard[step] == null) { moves.Add(step); // Point2D is a value type } } if (capture) { // Verify captures too Point2D p1 = new Point2D(m_Position.X + 1, m_Position.Y + direction); Point2D p2 = new Point2D(m_Position.X - 1, m_Position.Y + direction); if (m_BChessboard.IsValid(p1)) { BaseChessPiece piece1 = m_BChessboard[p1]; if (piece1 != null && piece1.Color != m_Color) { moves.Add(p1); } else { Point2D pass1 = new Point2D(m_Position.X - 1, m_Position.Y); if (m_BChessboard.IsValid(pass1)) { BaseChessPiece passpiece1 = m_BChessboard[pass1]; if (passpiece1 != null && passpiece1.Color != m_Color && passpiece1.AllowEnPassantCapture) { moves.Add(p1); } } } } if (m_BChessboard.IsValid(p2)) { BaseChessPiece piece2 = m_BChessboard[p2]; if (piece2 != null && piece2.Color != m_Color) { moves.Add(p2); } else { Point2D pass2 = new Point2D(m_Position.X + 1, m_Position.Y); if (m_BChessboard.IsValid(p2)) { BaseChessPiece passpiece2 = m_BChessboard[pass2]; if (passpiece2 != null && passpiece2.AllowEnPassantCapture && passpiece2.Color != m_Color) { moves.Add(pass2); } } } } } return(moves); }
/// <summary> /// Verifies if the requested castle moved is allowed /// </summary> /// <param name="king">The King performing the castle</param> /// <param name="rook">The Rook</param> /// <param name="err">Will hold any error messages</param> /// <returns>True if the castle move is allowed</returns> public bool AllowCastle( BaseChessPiece king, BaseChessPiece rook, ref string err ) { #region Castle Rules // 1 Your king has been moved earlier in the game. // 2 The rook that castles has been moved earlier in the game. // 3 There are pieces standing between your king and rook. // 4 The king is in check. // 5 The king moves through a square that is attacked by a piece of the opponent. // 6 The king would be in check after castling. #endregion if ( king.HasMoved || rook.HasMoved ) { err = "You can't castle if the rook or king have already moved"; return false; // Rules 1 and 2 } if ( IsCheck( king.Color ) ) { err = "You can't castle if your king is in check"; return false; // Rule 4 } bool queenside = rook.Position.X == 0; if ( queenside ) { for ( int i = 1; i < 4; i++ ) { if ( this[ i, king.Position.Y ] != null ) { err = "You can't castle if there are pieces between the king and the rook"; return false; // Rule 3 queenside } } } else { if ( this[ 5, king.Position.Y ] != null || this[ 6, king.Position.Y ] != null ) { err = "You can't castle if there are pieces between the king and the rook"; return false; // Rule 3 kingside } } // King always moves 2 int kingX = king.Position.X + ( queenside ? -2 : 2 ); int kingTransit = king.Position.X + ( queenside ? -1 : 1 ); if ( IsAttacked( new Point2D( kingTransit, king.Position.Y ), king.EnemyColor ) ) { err = "The king cannot move through a square that is under attack by the opponent"; return false; // Rule 5 } if ( IsAttacked( new Point2D( kingX, king.Position.Y ), king.EnemyColor ) ) { err = "The king would be in check after the castle"; return false; // Rule 6 } return true; }
public override bool CanMoveTo(Point2D newLocation, ref string err) { if (!base.CanMoveTo(newLocation, ref err)) { return(false); } // Verify if this is a castle BaseChessPiece king = m_BChessboard[newLocation]; if (king is King && king.Color == m_Color) { // Trying to castle return(m_BChessboard.AllowCastle(king, this, ref err)); } int dx = newLocation.X - m_Position.X; int dy = newLocation.Y - m_Position.Y; // Rooks can only move in one direction if (dx != 0 && dy != 0) { err = "Rooks can only move on straight lines"; return(false); } if (dx != 0) { // Moving on the X axis int direction = dx > 0 ? 1 : -1; if (Math.Abs(dx) > 1) { // Verify that the cells in between are empty for (int i = 1; i < Math.Abs(dx); i++) // Start 1 tile after the rook, and stop one tile before destination { int offset = direction * i; if (m_BChessboard[m_Position.X + offset, m_Position.Y] != null) { err = "Rooks can't move over pieces"; return(false); // There's a piece on the } } } // Verify if there's a piece to each at the end BaseChessPiece piece = m_BChessboard[newLocation]; if (piece == null || piece.Color != m_Color) { return(true); } else { err = "You can't capture pieces of your same color"; return(false); } } else { // Moving on the Y axis int direction = dy > 0 ? 1 : -1; if (Math.Abs(dy) > 1) { // Verify that the cells in between are empty for (int i = 1; i < Math.Abs(dy); i++) { int offset = direction * i; if (m_BChessboard[m_Position.X, m_Position.Y + offset] != null) { err = "The rook can't move over other pieces"; return(false); // Piece on the way } } } // Verify for piece at end BaseChessPiece piece = m_BChessboard[newLocation]; if (piece == null || piece.Color != m_Color) { return(true); } else { err = "You can't capture pieces of your same color"; return(false); } } }
/// <summary> /// Callback for the move finalization /// </summary> public void OnPieceMove( Mobile from, object targeted ) { string err = null; if ( ! ( targeted is IPoint2D ) ) { err = "Invalid Move"; m_MovingPiece = null; if ( GetColor( from ) == ChessColor.Black ) SendAllGumps( null, err ); else SendAllGumps( err, null ); return; } if ( ! m_Board.TryMove( ref err, m_MovingPiece, new Point2D( targeted as IPoint2D ) ) ) { m_MovingPiece = null; if ( GetColor( from ) == ChessColor.Black ) SendAllGumps( null, err ); else SendAllGumps( err, null ); return; } // Move has been made. Wait until it's over if ( m_Status == GameStatus.WhiteToMove ) { m_Status = GameStatus.WhiteMoving; SendAllGumps( "Making your move", null ); } else { m_Status = GameStatus.BlackMoving; SendAllGumps( null, "Making your move" ); } }
public override bool CanMoveTo(Point2D newLocation, ref string err) { if (!base.CanMoveTo(newLocation, ref err)) { return(false); } if (newLocation.X == m_Position.X) { // Regular move int dy = newLocation.Y - m_Position.Y; // Trying to move more than two pieces, or more than one piece after the first move if (Math.Abs(dy) > 2 || (Math.Abs(dy)) > 1 && m_HasMoved) { err = "You can move only 1 tile at a time, or 2 if it's the pawn's first move"; return(false); } // Verify direction if (m_Color == ChessColor.Black && dy < 0) { err = "You can't move pawns backwards"; return(false); } if (m_Color == ChessColor.White && dy > 0) { err = "You can't move pawns backwards"; return(false); } // Verify if there are pieces (any) on the target squares for (int i = 1; i <= Math.Abs(dy); i++) { int offset = m_Color == ChessColor.Black ? i : -i; if (m_BChessboard[m_Position.X, m_Position.Y + offset] != null) { err = "Pawns can't move over other pieces, and capture in diagonal"; return(false); } } return(true); } else { // Trying to capture? int dx = newLocation.X - m_Position.X; int dy = newLocation.Y - m_Position.Y; if (Math.Abs(dx) != 1 || Math.Abs(dy) != 1) { err = "Pawns move straight ahead, or capture in diagonal only"; return(false); } // Verify direction if (m_Color == ChessColor.Black && dy < 0) { err = "You can't move pawns backwards"; return(false); } if (m_Color == ChessColor.White && dy > 0) { err = "You can't move pawns backwards"; return(false); } // Verify if there's a piece to capture BaseChessPiece piece = m_BChessboard[newLocation]; if (piece != null && piece.Color != m_Color) { return(true); } else { // Verify for an en passant capture Point2D passant = new Point2D(m_Position.X + dx, m_Position.Y); BaseChessPiece target = m_BChessboard[passant]; if (target != null && target.AllowEnPassantCapture && target.Color != m_Color) { return(true); } else { err = "You must capture a piece when moving in diagonal"; return(false); } } } }