/// <summary> /// Check cell on attacking by another figur. /// </summary> /// <param name="to">Checking cell position.</param> /// <returns>True if attacked, false if not.</returns> public bool CanAttackOnCopyBoard(FigurePosition to) { if (!to.IsValid()) { return(false); } foreach (var figure in figuresCopy.Values) { // check color if (figure.Color == CurrentMoveColor) { continue; } var from = figure.Position; // Cell not at attack, it occupied by enemy if (from == to) { return(false); } // check only-attack-rules if (figure.CanAttack(to, this)) { return(true); } } return(false); }
/// <summary> /// Find figure number on boardState /// </summary> /// <param name="position">Type position</param> /// <param name="findOnCopy">If true - search on boardState temporary copy</param> /// <returns>Type number or null</returns> public int?FindFigureNumber(FigurePosition position, bool findOnCopy) { Figure fpc; var figuresOnBoard = findOnCopy ? figuresCopy : figures; for (int i = 0; i < FiguresNumber; i++) { if (figuresOnBoard.TryGetValue(i, out fpc)) { if (fpc.Position == position) { return(i); } } } return(null); }
public void ComputerMove(String notation) { Trace.WriteLine(notation); /* Null move? */ if (notation == "0000") { /* End of the game for computer */ return; } /* Convert notation to coordinates */ var from = new FigurePosition(notation[0], int.Parse(notation[1].ToString(CultureInfo.InvariantCulture))); var to = new FigurePosition(notation[2], int.Parse(notation[3].ToString(CultureInfo.InvariantCulture))); Type promotionFigureType = null; if (notation.Length > 4) { /* Pawn promotion */ switch (notation[4]) { case 'n': promotionFigureType = typeof(Knight); break; case 'b': promotionFigureType = typeof(Bishop); break; case 'r': promotionFigureType = typeof(Rook); break; case 'q': promotionFigureType = typeof(Queen); break; } } var figureNumber = FindFigureNumber(from, false).Value; var moved = PlayerMove(figureNumber, to, true, promotionFigureType); Debug.Assert(moved); }
public bool IsPositionOccupied(FigurePosition position, bool afterMove) { return(FindFigureNumber(position, afterMove).HasValue); }
/// <summary> /// Change position of figure /// </summary> /// <param name="figureNumber">Number of figure.</param> /// <param name="to">Destination of figure.</param> /// <param name="computerMove"> </param> /// <param name="figureForPawnPromotionForComputer"> </param> /// <returns>True, if move was performed.</returns> public bool PlayerMove(int figureNumber, FigurePosition to, bool computerMove = false, Type figureForPawnPromotionForComputer = null) { if (!to.IsValid()) { return(false); } Figure movingFigure; if (!figures.TryGetValue(figureNumber, out movingFigure)) { return(false); } var from = movingFigure.Position; if (to == from) { return(false); } Figure attackedFigure = null; int? attackedFigureNumber = FindFigureNumber(to, false); if (attackedFigureNumber.HasValue) { if (!figures.TryGetValue(attackedFigureNumber.Value, out attackedFigure)) { return(false); } } if (movingFigure.Color != CurrentMoveColor) // if you try to move enemy piece? { return(false); } // Do not move computer's figures if (movingFigure.Color == computerColor && !computerMove) { return(false); } if (attackedFigureNumber.HasValue) { if (movingFigure.Color == attackedFigure.Color) { return(false); } } // Create copy of chessboard to test the future possible position figuresCopy.Clear(); for (var i = 0; i < figures.Count; i++) { figuresCopy.Add(figures.Keys[i], figures.Values[i]); } #region Figures rules if (!movingFigure.CanMove(to, this)) { return(false); } if (movingFigure is Pawn) { var pawn = (Pawn)movingFigure; if (to.Y == 8 || to.Y == 1) { pawnToPositionForTransformation = to; } if (EnPassant == to) { figuresCopy.Remove(FindFigureNumber(EnPassant + new Vector(0, -pawn.MoveVector()), true).Value); } } // casleing? else if (movingFigure is King) { if (Math.Abs(to.X - from.X) == 2) { var line = CurrentMoveColor == FigureColors.White ? 1 : 8; if (to.X > from.X) { var rookNumber = FindFigureNumber(new FigurePosition('h', line), true).Value; figuresCopy.Remove(rookNumber); figuresCopy.Add(rookNumber, new Rook(new FigurePosition('f', line), CurrentMoveColor)); } else { var rookNumber = FindFigureNumber(new FigurePosition('a', line), true).Value; figuresCopy.Remove(rookNumber); figuresCopy.Add(rookNumber, new Rook(new FigurePosition('d', line), CurrentMoveColor)); } } } #endregion #region Make move on copy boardState // Move figure on test copy of chessboard to check on attacks on King // Need to delete figure that positions on 'to' if it exists if (attackedFigureNumber.HasValue) { figuresCopy.Remove(attackedFigureNumber.Value); // got piece? } else { Console.WriteLine("attackedFigureNumber is FALSE"); } // Move figure to new position var figureType = figuresCopy. Values[figuresCopy.IndexOfKey(figureNumber)].GetType(); figuresCopy.Remove(figureNumber); figuresCopy.Add(figureNumber, (Figure)Activator.CreateInstance(figureType, to, CurrentMoveColor)); #endregion /* Check if king on attack cell on copy boardState <- still needed?*/ if (CanAttackOnCopyBoard(GetKingPositionOnCopy(CurrentMoveColor))) // king can be attacked? { return(false); } else { Console.WriteLine("CanAttackOnCopyBoard is false"); } #region Save copy boardState // Can make move on "real" chessboard figures.Clear(); for (int i = 0; i < figuresCopy.Count; i++) { figures.Add(figuresCopy.Keys[i], figuresCopy.Values[i]); } #endregion /* Move performed */ /* Change 3D model of figure if pawn promotion occured */ var movedFigure = figures[figureNumber]; if (movedFigure is Pawn) { if (movedFigure.Position.Y == 1 || movedFigure.Position.Y == 8) { if (computerMove) { ChangePawnOnBoard(figureForPawnPromotionForComputer ?? typeof(Queen)); } else { gameplayScreen.ShowFiguresBox(); } } } var isAnyFigureCaptured = attackedFigureNumber.HasValue; var isPawnMoved = movedFigure is Pawn; // En passant if (movedFigure is Pawn && Math.Abs(to.X - from.X) == 2 && to.Y == from.Y) { EnPassant = new FigurePosition(from.X, (from.Y + to.Y) / 2); } else { EnPassant = null; } // Castle if (movedFigure is King) { SetCastling(CurrentMoveColor, CastlingTypes.Queenside, false); SetCastling(CurrentMoveColor, CastlingTypes.Kingside, false); } if (movedFigure is Rook) { if (from.X == 'a') { SetCastling(CurrentMoveColor, CastlingTypes.Queenside, false); } if (from.X == 'h') { SetCastling(CurrentMoveColor, CastlingTypes.Kingside, false); } } // Alternate move. Fullmove number if (CurrentMoveColor == FigureColors.White) { CurrentMoveColor = FigureColors.Black; //TODO need logic to set for MP/saving GameState.CurrentPlayerMove = FigureColors.Black; } else { fullmoveNumber++; CurrentMoveColor = FigureColors.White; GameState.CurrentPlayerMove = FigureColors.White; } // Halmove clock if (isPawnMoved || isAnyFigureCaptured) { halfmoveClock = 0; } else if (halfmoveClock.HasValue) { halfmoveClock++; } return(true); }