/// <summary> /// Initializes a new instance of the <see cref="CheckersMove"/> class. /// </summary> /// <param name="sourcePoint">The source point.</param> /// <param name="destinationPoint">The destination point.</param> /// <param name="jumpedPoint">The jumped point.</param> /// <param name="nextMove">The next move.</param> public CheckersMove(CheckersPoint sourcePoint, CheckersPoint destinationPoint, CheckersPoint jumpedPoint, CheckersMove nextMove) { SourcePoint = sourcePoint; DestinationPoint = destinationPoint; JumpedPoint = jumpedPoint; NextMove = nextMove; }
/// <summary> /// Gets the minimax clone. /// </summary> /// <returns>Minimax clone of this object</returns> public object GetMinimaxClone() { CheckersMove clone = new CheckersMove(); if (this.DestinationPoint != null) { clone.DestinationPoint = (CheckersPoint)this.DestinationPoint.GetMinimaxClone(); } if (this.SourcePoint != null) { clone.SourcePoint = (CheckersPoint)this.SourcePoint.GetMinimaxClone(); } if (this.JumpedPoint != null) { clone.JumpedPoint = (CheckersPoint)this.JumpedPoint.GetMinimaxClone(); } if (this.NextMove != null) { clone.NextMove = (CheckersMove)this.NextMove.GetMinimaxClone(); } return(clone); }
/// <summary> /// Initializes a new instance of the <see cref="CheckersMove"/> class. /// </summary> /// <param name="sourcePoint">The source point.</param> /// <param name="destinationPoint">The destination point.</param> public CheckersMove(CheckersPoint sourcePoint, CheckersPoint destinationPoint) { SourcePoint = sourcePoint; DestinationPoint = destinationPoint; JumpedPoint = null; NextMove = null; }
/// <summary> /// Method for the aiThread. Main loop for running an AI game /// </summary> /// <exception cref="AIException">If the is a problem running the game</exception> private void RunAIDuel() { int numberOfTurns = 0; while (checkerBoard.GetWinner() == null) { //AI vs AI CheckersMove aiMove = AIController.MinimaxStart(checkerBoard); if (aiMove != null && numberOfTurns++ < MaxTurns) { while (aiMove != null) { MakeMove(aiMove); aiMove = aiMove.NextMove; Thread.Sleep(Settings.TimeToSleeepBetweenMoves); } } else { //AI could not find a valid move. Is the game over? are we in a dead lock? //Show error to user? throw new AIException("The AI could not find any valid moves or the AI are just going back and forth, This must have ended in a tie"); } } }
/// <summary> /// Method runs each time a checker button is clicked. This is for user control /// </summary> /// <param name="sender">Button sender.</param> private void ButtonClickWork(object sender) { Button button = (Button)sender; CheckersSquareUserControl checkerSquareUC = (CheckersSquareUserControl)((Grid)button.Parent).Parent; Logger.Info("Row: " + checkerSquareUC.CheckersPoint.Row + " Column: " + checkerSquareUC.CheckersPoint.Column); DisableAllButtons(); if (currentMove == null) { currentMove = new CheckersMove(); } if (currentMove.SourcePoint == null) { currentMove.SourcePoint = checkerSquareUC.CheckersPoint; SetBackgroundColor(checkerSquareUC, Brushes.Green); //starting a move, enable spaces where a valid move is present currentAvailableMoves = checkerSquareUC.CheckersPoint.GetPossibleMoves(checkerBoard); //Add self move to act as cancel currentAvailableMoves.Add(new CheckersMove(checkerSquareUC.CheckersPoint, checkerSquareUC.CheckersPoint)); ColorBackgroundOfPoints(currentAvailableMoves, Brushes.Aqua); EnableButtonsWithPossibleMove(currentAvailableMoves); } else { currentMove.DestinationPoint = checkerSquareUC.CheckersPoint; SetBackgroundColor(checkerSquareUC, Brushes.Green); //get move from the list that has this point as its destination MakeMoveReturnModel returnModel = MakeMove(GetMoveFromList(checkerSquareUC.CheckersPoint)); if (returnModel.WasMoveMade && returnModel.IsTurnOver && Settings.IsAIGame) { //Disable buttons so the user cant click anything while the AI is thinking DisableAllButtons(); //AI needs to make a move now CheckersMove aiMove = AIController.MinimaxStart(checkerBoard); if (aiMove != null) { while (aiMove != null) { MakeMove(aiMove); aiMove = aiMove.NextMove; Thread.Sleep(Settings.TimeToSleeepBetweenMoves); } } else { //AI could not find a valid move. Is the game over? are we in a dead lock? //Show error to user } } } }
/// <summary> /// Makes the move on the board. /// </summary> /// <param name="moveToMake">The move to make.</param> /// <param name="swapTurn">if set to <c>true</c> [swap turn].</param> /// <returns>true if the current turn was finished</returns> public bool MakeMoveOnBoard(CheckersMove moveToMake, bool swapTurn) { CheckersPoint moveSource = moveToMake.SourcePoint; CheckersPoint moveDestination = moveToMake.DestinationPoint; //was this a cancel? if (moveSource != moveDestination) { CheckersPoint realDestination = this.BoardArray[moveDestination.Row][moveDestination.Column].CheckersPoint; CheckersPoint realSource = this.BoardArray[moveSource.Row][moveSource.Column].CheckersPoint; realDestination.Checker = (CheckerPiece)realSource.Checker.GetMinimaxClone(); realSource.Checker = CheckerPieceFactory.GetCheckerPiece(CheckerPieceType.nullPiece); //was this a jump move? CheckersPoint jumpedPoint = moveToMake.JumpedPoint; if (jumpedPoint != null) { //delete the checker piece that was jumped CheckersSquareUserControl jumpedSquareUserControl = this.BoardArray[jumpedPoint.Row][jumpedPoint.Column]; jumpedSquareUserControl.CheckersPoint.Checker = CheckerPieceFactory.GetCheckerPiece(CheckerPieceType.nullPiece); jumpedSquareUserControl.UpdateSquare(); } //Is this piece a king now? if (!(realDestination.Checker is KingCheckerPiece) && (realDestination.Row == 7 || realDestination.Row == 0)) { //Should be a king now if (realDestination.Checker is IRedPiece) { realDestination.Checker = new RedKingCheckerPiece(); } else { realDestination.Checker = new BlackKingCheckerPiece(); } } //Is this players turn over? if (moveToMake.NextMove == null && swapTurn) { //Swap the current players turn SwapTurns(); return(true); } else { return(false); } } return(false); }
/// <summary> /// Initializes the checkers game. /// </summary> private void InitializeCheckers() { this.Dispatcher.Invoke(() => { checkerBoard = new CheckerBoard(); checkerBoard.MakeBoard(new RoutedEventHandler(Button_Click)); lst.ItemsSource = checkerBoard.BoardArray; currentMove = null; SetTitle(string.Format("Checkers! {0}'s turn!", checkerBoard.CurrentPlayerTurn)); DisableAllButtons(); EnableButtonsWithMove(); }); }
/// <summary> /// Return a heuristic value for the board. This evaluation checks to see if any pieces are in danger /// </summary> /// <param name="rootPlayer">The minimax root player.</param> /// <returns>heuristic for the board</returns> public int ScoreC(PlayerColor rootPlayer) { int score = 0; int kingDangerValue = Settings.KingDangerValue; int pawnDangerValue = Settings.PawnDangerValue; if (Settings.RunningGeneticAlgo) { if (rootPlayer == PlayerColor.Red) { kingDangerValue = Genetic.RandomGenome.GetRandomGenomeInstance().KingDangerValueGene; pawnDangerValue = Genetic.RandomGenome.GetRandomGenomeInstance().PawnDangerValueGene; } else { kingDangerValue = Genetic.WinningGenome.GetWinningGenomeInstance().KingDangerValueGene; pawnDangerValue = Genetic.WinningGenome.GetWinningGenomeInstance().PawnDangerValueGene; } } List <CheckersMove> movesForOtherPlayer = GetMovesForPlayer(); foreach (CheckersMove move in movesForOtherPlayer) { CheckersMove moveToCheck = move; do { if (moveToCheck.JumpedPoint != null) { //A piece is in danger if (moveToCheck.JumpedPoint.Checker is KingCheckerPiece) { score -= kingDangerValue; } else { score -= pawnDangerValue; } } moveToCheck = moveToCheck.NextMove; }while (moveToCheck != null); } return(score); }
/// <summary> /// Makes a move on the User Interface. /// </summary> /// <param name="moveToMake">The move to make.</param> /// <returns>Make Move Model Return. This model has two boolean properties that represent what happened this move</returns> private MakeMoveReturnModel MakeMove(CheckersMove moveToMake) { bool moveWasMade = false; bool isTurnOver = false; CheckersPoint source = moveToMake.SourcePoint; CheckersPoint destination = moveToMake.DestinationPoint; Logger.Info("Piece1 " + source.Row + ", " + source.Column); Logger.Info("Piece2 " + destination.Row + ", " + destination.Column); //was this a cancel? if (source != destination) { isTurnOver = checkerBoard.MakeMoveOnBoard(moveToMake); CheckersSquareUserControl sourceUC = checkerBoard.BoardArray[source.Row][source.Column]; CheckersSquareUserControl destUC = checkerBoard.BoardArray[destination.Row][destination.Column]; //Use dispatcher to run the Update method on the UI thread sourceUC.UpdateSquare(); destUC.UpdateSquare(); moveWasMade = true; //check for a winner object winner = checkerBoard.GetWinner(); if (winner != null && winner is PlayerColor winnerColor && !Settings.RunningGeneticAlgo) { MessageBox.Show("Winner Winner Chicken Dinner: " + winnerColor); } } ColorBackgroundOfPoints(currentAvailableMoves, Brushes.Black); SetTitle(string.Format("Checkers! {0}'s turn!", checkerBoard.CurrentPlayerTurn)); EnableButtonsWithMove(); currentMove = null; return(new MakeMoveReturnModel() { IsTurnOver = isTurnOver, WasMoveMade = moveWasMade }); }
/// <summary> /// Makes the move on the board. Returns a boolean that represents if the turn was finished after making this move /// </summary> /// <param name="moveToMake">Move to make</param> /// <returns>True if the turn is over</returns> public bool MakeMoveOnBoard(CheckersMove moveToMake) { return(MakeMoveOnBoard(moveToMake, true)); }