private MinMaxScore MinMaxPlay(Board board, int depth, Play play) { Board newBoard = new Board(board); if (play != null) { // make move. newBoard.MarkBoard(play); // see if play results in final state. MinMaxScore minMaxScore = GetMinMaxScore(newBoard, play, depth); // if so, return score. if (minMaxScore != null) { return(minMaxScore); } } // update marker type. Marker marker = play == null ? Marker.O : (play.PlayerId == Marker.O) ? Marker.X : Marker.O; depth++; List <Play> possiblePlays = PossiblePlaysInCurrentBoardState(newBoard, marker); // Compute every possible move's score and add to list List <MinMaxScore> moves = possiblePlays.Select(possibleMove => MinMaxPlay(newBoard, depth, possibleMove)).ToList(); // Find maximum score on list. MinMaxScore maxMinMaxScoreMove = FindMaxScore(moves); return(maxMinMaxScoreMove); }
private MinMaxScore GetMinMaxScore(Board board, Play play, int depth) { MinMaxScore minMaxScore = new MinMaxScore { Play = play, Points = 0 }; // Check win condition for player X if (board.IsVictoryCondition(Marker.X)) { minMaxScore.Points = play.PlayerId == Marker.X ? 10 - depth : depth - 10; return(minMaxScore); } // Check win condition for player O if (board.IsVictoryCondition(Marker.O)) { minMaxScore.Points = play.PlayerId == Marker.O ? 10 - depth : depth - 10; return(minMaxScore); } // Check draw condition if (board.AreAllPositionMarked()) { return(minMaxScore); } // otherwise... return(null); }
private Play DecidePlay(Board board) { // Ground Rule #1: start marking center position. int center = (board.Size - 1) / 2; if (board.GetMarkAtPosition(center, center) == Marker.Empty) { return(PlayAtCenter(center)); } // Ground Rule #2: if center's already marked and board's only marked once, mark a corner. if (board.GetTotalMarks() == 1) { return(PlayAtAnyCorner(board)); } // Generic move. MinMaxScore maximumScore = MinMaxPlay(board, 0, null); return(maximumScore.Play); }