128 lines
3.7 KiB
Java
128 lines
3.7 KiB
Java
package Uebung_04;
|
|
|
|
import java.util.Random;
|
|
|
|
public class ComputerPlayer extends Player {
|
|
private Random random;
|
|
|
|
// Constructor
|
|
public ComputerPlayer(char symbol) {
|
|
super(symbol);
|
|
this.random = new Random();
|
|
}
|
|
|
|
@Override
|
|
public void makeMove(Board board) {
|
|
int[] bestMove = getBestMove(board, 10000); // Number of simulations
|
|
int
|
|
|
|
row = bestMove[0];
|
|
int col = bestMove[1];
|
|
|
|
if (board.getBoard()[row][col] == ' ') {
|
|
board.getBoard()[row][col] = symbol;
|
|
} else {
|
|
System.out.println("Error: Invalid move. Choosing the first available empty space.");
|
|
makeRandomMove(board);
|
|
}
|
|
}
|
|
|
|
private int[] getBestMove(Board board, int simulations) {
|
|
int[] bestMove = new int[]{-1, -1};
|
|
double bestWinRate = -1;
|
|
|
|
for (int i = 0; i < 3; i++) {
|
|
for (int j = 0; j < 3; j++) {
|
|
if (board.getBoard()[i][j] == ' ') {
|
|
double winRate = monteCarlo(board, i, j, simulations);
|
|
|
|
if (winRate > bestWinRate) {
|
|
bestWinRate = winRate;
|
|
bestMove[0] = i;
|
|
bestMove[1] = j;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
System.out.printf("Best Move: (%d, %d) with Win Rate = %.2f%n", bestMove[0] + 1, bestMove[1] + 1, bestWinRate);
|
|
|
|
return bestMove;
|
|
}
|
|
|
|
private double monteCarlo(Board board, int row, int col, int simulations) {
|
|
int winCount = 0;
|
|
|
|
for (int k = 0; k < simulations; k++) {
|
|
Board copyBoard = copyBoard(board);
|
|
copyBoard.getBoard()[row][col] = symbol;
|
|
|
|
if (simulateGame(copyBoard)) {
|
|
winCount++;
|
|
}
|
|
}
|
|
|
|
return (double) winCount / simulations;
|
|
}
|
|
|
|
private void makeRandomMove(Board board) {
|
|
// Fallback method if no valid moves are found
|
|
int row, col;
|
|
do {
|
|
row = random.nextInt(3);
|
|
col = random.nextInt(3);
|
|
} while (board.getBoard()[row][col] != ' ');
|
|
|
|
board.getBoard()[row][col] = symbol;
|
|
}
|
|
|
|
private boolean simulateGame(Board board) {
|
|
// Check for a win in rows
|
|
for (int i = 0; i < 3; i++) {
|
|
if (board.getBoard()[i][0] == symbol &&
|
|
board.getBoard()[i][1] == symbol &&
|
|
board.getBoard()[i][2] == symbol) {
|
|
return true; // Computer wins
|
|
}
|
|
}
|
|
|
|
// Check for a win in columns
|
|
for (int j = 0; j < 3; j++) {
|
|
if (board.getBoard()[0][j] == symbol &&
|
|
board.getBoard()[1][j] == symbol &&
|
|
board.getBoard()[2][j] == symbol) {
|
|
return true; // Computer wins
|
|
}
|
|
}
|
|
|
|
// Check for a win in diagonals
|
|
if (board.getBoard()[0][0] == symbol &&
|
|
board.getBoard()[1][1] == symbol &&
|
|
board.getBoard()[2][2] == symbol) {
|
|
return true; // Computer wins
|
|
}
|
|
|
|
if (board.getBoard()[0][2] == symbol &&
|
|
board.getBoard()[1][1] == symbol &&
|
|
board.getBoard()[2][0] == symbol) {
|
|
return true; // Computer wins
|
|
}
|
|
|
|
return false; // No win
|
|
}
|
|
|
|
private Board copyBoard(Board original) {
|
|
Board copy = new Board();
|
|
char[][] originalBoard = original.getBoard();
|
|
char[][] copyBoard = copy.getBoard();
|
|
|
|
for (int i = 0; i < originalBoard.length; i++) {
|
|
for (int j = 0; j < originalBoard[i].length; j++) {
|
|
copyBoard[i][j] = originalBoard[i][j];
|
|
}
|
|
}
|
|
|
|
return copy;
|
|
}
|
|
}
|