From e755229fd16b5c84935b68778c5c6fbaa2b9a2d1 Mon Sep 17 00:00:00 2001 From: aitorfi Date: Fri, 8 Oct 2021 17:27:14 +0200 Subject: [PATCH 1/2] First commit. --- Others/MiniMaxAlgorithm.java | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Others/MiniMaxAlgorithm.java diff --git a/Others/MiniMaxAlgorithm.java b/Others/MiniMaxAlgorithm.java new file mode 100644 index 000000000000..8ab3f2079593 --- /dev/null +++ b/Others/MiniMaxAlgorithm.java @@ -0,0 +1,7 @@ +package Others; + +public class MiniMaxAlgorithm { + public void miniMax() { + // TODO: Implement MiniMax algorithm. + } +} \ No newline at end of file From 9a4258b0fdc833d7ca69c5354ad676c74b966e67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aitor=20Fidalgo=20S=C3=A1nchez?= Date: Sun, 10 Oct 2021 19:08:15 +0300 Subject: [PATCH 2/2] MiniMax algorithm implemented. --- Others/MiniMaxAlgorithm.java | 125 ++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/Others/MiniMaxAlgorithm.java b/Others/MiniMaxAlgorithm.java index 8ab3f2079593..06bfa732c281 100644 --- a/Others/MiniMaxAlgorithm.java +++ b/Others/MiniMaxAlgorithm.java @@ -1,7 +1,128 @@ package Others; +import java.util.Arrays; +import java.util.Random; + +/** + * MiniMax is an algorithm used int artificial intelligence and game theory for + * minimizing the possible loss for the worst case scenario. + * + * See more (https://en.wikipedia.org/wiki/Minimax, + * https://www.geeksforgeeks.org/minimax-algorithm-in-game-theory-set-1-introduction/). + * + * @author aitofi (https://github.com/aitorfi) + */ public class MiniMaxAlgorithm { - public void miniMax() { - // TODO: Implement MiniMax algorithm. + /** + * Game tree represented as an int array containing scores. Each array element + * is a leaf node. + */ + private int[] scores; + private int height; + + /** + * Initializes the scores with 8 random leaf nodes + */ + public MiniMaxAlgorithm() { + scores = getRandomScores(3, 99); + height = log2(scores.length); + } + + public static void main(String[] args) { + MiniMaxAlgorithm miniMaxAlgorith = new MiniMaxAlgorithm(); + boolean isMaximizer = true; // Specifies the player that goes first. + boolean verbose = true; // True to show each players choices. + int bestScore; + + bestScore = miniMaxAlgorith.miniMax(0, isMaximizer, 0, verbose); + + if (verbose) { + System.out.println(); + } + + System.out.println(Arrays.toString(miniMaxAlgorith.getScores())); + System.out.println( + "The best score for " + (isMaximizer ? "Maximizer" : "Minimizer") + " is " + String.valueOf(bestScore)); + } + + /** + * Returns the optimal score assuming that both players play their best. + * + * @param depth Indicates how deep we are into the game tree. + * @param isMaximizer True if it is maximizers turn; otherwise false. + * @param index Index of the leaf node that is being evaluated. + * @param verbose True to show each players choices. + * @return The optimal score for the player that made the first move. + */ + public int miniMax(int depth, boolean isMaximizer, int index, boolean verbose) { + int bestScore, score1, score2; + + if (depth == height) { // Leaf node reached. + return scores[index]; + } + + score1 = miniMax(depth + 1, !isMaximizer, index * 2, verbose); + score2 = miniMax(depth + 1, !isMaximizer, (index * 2) + 1, verbose); + + if (isMaximizer) { + // Maximizer player wants to get the maximum possible score. + bestScore = Math.max(score1, score2); + } else { + // Minimizer player wants to get the minimum possible score. + bestScore = Math.min(score1, score2); + } + + // Leaf nodes can be sequentially inspected by + // recurssively multiplying (0 * 2) and ((0 * 2) + 1): + // (0 x 2) = 0; ((0 x 2) + 1) = 1 + // (1 x 2) = 2; ((1 x 2) + 1) = 3 + // (2 x 2) = 4; ((2 x 2) + 1) = 5 ... + + if (verbose) { + System.out.println(String.format("From %02d and %02d, %s chooses %02d", score1, score2, + (isMaximizer ? "Maximizer" : "Minimizer"), bestScore)); + } + + return bestScore; + } + + /** + * Returns an array of random numbers which lenght is a power of 2. + * + * @param size The power of 2 that will determine the lenght of the array. + * @param maxScore The maximum possible score. + * @return An array of random numbers. + */ + public static int[] getRandomScores(int size, int maxScore) { + int[] randomScores = new int[(int) Math.pow(2, size)]; + Random rand = new Random(); + + for (int a : randomScores) { + a = rand.nextInt(maxScore) + 1; + } + + return randomScores; + } + + // A utility function to find Log n in base 2 + private int log2(int n) { + return (n == 1) ? 0 : log2(n / 2) + 1; + } + + public void setScores(int[] scores) { + if (scores.length % 1 == 0) { + this.scores = scores; + height = log2(this.scores.length); + } else { + System.out.println("The number of scores must be a power of 2."); + } + } + + public int[] getScores() { + return scores; + } + + public int getHeight() { + return height; } } \ No newline at end of file