/// <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); }