private static bool IsPawnReachable(Chess chess, Point from, Point to, Dictionary <Point, Chess> locationChess) { switch (chess.Side) { case PlayerSide.White: if (to.Y == from.Y - 1) { if (to.X == from.X) { // pawn go straight forward return(!locationChess.ContainsKey(to)); } else if (to.X == from.X + 1 || to.X == from.X - 1) { return(IsOppositeChess(to, locationChess, chess.Side)); } else { return(false); } } else if (to.Y == from.Y - 2) { return(!HasChess(new Point(from.X, from.Y - 1), locationChess) && !HasChess(to, locationChess) && from.Y == 6); } else { return(false); } break; case PlayerSide.Black: if (to.Y == from.Y + 1) { if (to.X == from.X) { // pawn go straight forward return(!locationChess.ContainsKey(to)); } else if (to.X == from.X + 1 || to.X == from.X - 1) { return(IsOppositeChess(to, locationChess, chess.Side)); } else { return(false); } } else if (to.Y == from.Y + 2) { return(!HasChess(new Point(from.X, from.Y + 1), locationChess) && !HasChess(to, locationChess) && from.Y == 1); } else { return(false); } break; default: return(false); } }
private void PerformChessMove(ChessMove instruction) { PlayerSide thisSide = GetThisPlayerSide(instruction); // chess if there has a chess if (!HasChess(instruction.From, this.LocationChess)) { throw new InvalidChessOperation(); } // check who's turn if (thisSide != this.WhosTurn) { throw new InvalidChessOperation(); } // check if during promotion if (this.IsDuringPromotion) { // only allow to perform chess change throw new InvalidChessOperation(); } // if else: // basic movement // if checked after // update `FreshTwoStepAdvancePawnLocation` // en passant // if checked after // castling // if checked before // if checked middle // if checked after Chess chess = this.LocationChess[instruction.From]; if (IsReachable(chess, instruction.From, instruction.To, this.LocationChess)) { if (IsChecked(thisSide, this.LocationChess, instruction)) { throw new InvalidChessOperation(); } UpdateFreshTwoStepAdvancePawnLocation(chess, instruction.From, instruction.To); } else if (IsEnPassant(chess, instruction.From, instruction.To)) { if (IsChecked(thisSide, this.LocationChess, instruction)) { throw new InvalidChessOperation(); } // remove the killed pawn switch (chess.Side) { case PlayerSide.White: this.LocationChess.Remove(this.FreshTwoStepAdvanceBlackPawnLocation.Value); break; case PlayerSide.Black: this.LocationChess.Remove(this.FreshTwoStepAdvanceWhitePawnLocation.Value); break; } } else if (IsCastling(chess, instruction.From, instruction.To)) { // move rook Point rookDestination = new Point((instruction.From.X + instruction.To.X) / 2, instruction.From.Y); Point rookSource = new Point(0, 0); switch (chess.Side) { case PlayerSide.White: if (instruction.To.X > instruction.From.X) { rookSource = new Point(7, 7); } else { rookSource = new Point(0, 7); } break; case PlayerSide.Black: if (instruction.To.X > instruction.From.X) { rookSource = new Point(7, 0); } else { rookSource = new Point(0, 0); } break; } this.LocationChess[rookDestination] = this.LocationChess[rookSource]; this.LocationChess.Remove(rookSource); } else { throw new InvalidChessOperation(); } // castling change availability if (chess.Type == ChessType.King) { switch (chess.Side) { case PlayerSide.White: this.CouldWhiteCastlingLeft = false; this.CouldWhiteCastlingRight = false; break; case PlayerSide.Black: this.CouldBlackCastlingLeft = false; this.CouldBlackCastlingRight = false; break; } } else if (chess.Type == ChessType.Rook) { switch (instruction.From.Y) { case 0: switch (instruction.From.X) { case 0: this.CouldBlackCastlingLeft = false; break; case 7: this.CouldBlackCastlingRight = false; break; } break; case 7: switch (instruction.From.X) { case 0: this.CouldWhiteCastlingLeft = false; break; case 7: this.CouldWhiteCastlingRight = false; break; } break; } } // promotion if (this.LocationChess[instruction.From].Type == ChessType.Pawn && (instruction.To.Y == 7 || instruction.To.Y == 0)) { this.IsDuringPromotion = true; } else { this.WhosTurn = GetOppositeSide(GetThisPlayerSide(instruction)); } // ~~mark check~~ }
private bool IsCastling(Chess chess, Point from, Point to) { if (chess.Type != ChessType.King) { return(false); } if (Math.Abs(to.X - from.X) == 2 && from.X == 4) { // source -> destination: direction switch (to.X) { case 2: // king goes left if (!HasChess(new Point(1, from.Y), this.LocationChess) && !HasChess(new Point(2, from.Y), this.LocationChess) && !HasChess(new Point(3, from.Y), this.LocationChess) && (chess.Side == PlayerSide.Black && this.CouldBlackCastlingLeft || chess.Side == PlayerSide.White && this.CouldWhiteCastlingLeft ) ) { ChessMove moveOneStep = new ChessMove() { From = from, // To = new Point(from.X - 1, from.Y) To = new Point((from.X + to.X) / 2, from.Y) }; ChessMove moveTwoSteps = new ChessMove() { From = from, To = to }; return(!IsChecked(chess.Side, this.LocationChess) && !IsChecked(chess.Side, this.LocationChess, moveOneStep) && !IsChecked(chess.Side, this.LocationChess, moveTwoSteps)); } else { return(false); } case 6: // king goes right if (!HasChess(new Point(5, from.Y), this.LocationChess) && !HasChess(new Point(6, from.Y), this.LocationChess) && (chess.Side == PlayerSide.Black && this.CouldBlackCastlingRight || chess.Side == PlayerSide.White && this.CouldWhiteCastlingRight ) ) { ChessMove moveOneStep = new ChessMove() { From = from, // To = new Point(from.X + 1, from.Y) To = new Point((from.X + to.X) / 2, from.Y) }; ChessMove moveTwoSteps = new ChessMove() { From = from, To = to }; return(!IsChecked(chess.Side, this.LocationChess) && !IsChecked(chess.Side, this.LocationChess, moveOneStep) && !IsChecked(chess.Side, this.LocationChess, moveTwoSteps)); } else { return(false); } default: return(false); } } else { return(false); } }