Skip to content

Commit febc601

Browse files
Add MiniMax algorithm (TheAlgorithms#2563)
Co-authored-by: aitorfi <afidalgo@birt.eus>
1 parent 5dd3366 commit febc601

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

Others/MiniMaxAlgorithm.java

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package Others;
2+
3+
import java.util.Arrays;
4+
import java.util.Random;
5+
6+
/**
7+
* MiniMax is an algorithm used int artificial intelligence and game theory for
8+
* minimizing the possible loss for the worst case scenario.
9+
*
10+
* See more (https://en.wikipedia.org/wiki/Minimax,
11+
* https://www.geeksforgeeks.org/minimax-algorithm-in-game-theory-set-1-introduction/).
12+
*
13+
* @author aitofi (https://github.com/aitorfi)
14+
*/
15+
public class MiniMaxAlgorithm {
16+
/**
17+
* Game tree represented as an int array containing scores. Each array element
18+
* is a leaf node.
19+
*/
20+
private int[] scores;
21+
private int height;
22+
23+
/**
24+
* Initializes the scores with 8 random leaf nodes
25+
*/
26+
public MiniMaxAlgorithm() {
27+
scores = getRandomScores(3, 99);
28+
height = log2(scores.length);
29+
}
30+
31+
public static void main(String[] args) {
32+
MiniMaxAlgorithm miniMaxAlgorith = new MiniMaxAlgorithm();
33+
boolean isMaximizer = true; // Specifies the player that goes first.
34+
boolean verbose = true; // True to show each players choices.
35+
int bestScore;
36+
37+
bestScore = miniMaxAlgorith.miniMax(0, isMaximizer, 0, verbose);
38+
39+
if (verbose) {
40+
System.out.println();
41+
}
42+
43+
System.out.println(Arrays.toString(miniMaxAlgorith.getScores()));
44+
System.out.println(
45+
"The best score for " + (isMaximizer ? "Maximizer" : "Minimizer") + " is " + String.valueOf(bestScore));
46+
}
47+
48+
/**
49+
* Returns the optimal score assuming that both players play their best.
50+
*
51+
* @param depth Indicates how deep we are into the game tree.
52+
* @param isMaximizer True if it is maximizers turn; otherwise false.
53+
* @param index Index of the leaf node that is being evaluated.
54+
* @param verbose True to show each players choices.
55+
* @return The optimal score for the player that made the first move.
56+
*/
57+
public int miniMax(int depth, boolean isMaximizer, int index, boolean verbose) {
58+
int bestScore, score1, score2;
59+
60+
if (depth == height) { // Leaf node reached.
61+
return scores[index];
62+
}
63+
64+
score1 = miniMax(depth + 1, !isMaximizer, index * 2, verbose);
65+
score2 = miniMax(depth + 1, !isMaximizer, (index * 2) + 1, verbose);
66+
67+
if (isMaximizer) {
68+
// Maximizer player wants to get the maximum possible score.
69+
bestScore = Math.max(score1, score2);
70+
} else {
71+
// Minimizer player wants to get the minimum possible score.
72+
bestScore = Math.min(score1, score2);
73+
}
74+
75+
// Leaf nodes can be sequentially inspected by
76+
// recurssively multiplying (0 * 2) and ((0 * 2) + 1):
77+
// (0 x 2) = 0; ((0 x 2) + 1) = 1
78+
// (1 x 2) = 2; ((1 x 2) + 1) = 3
79+
// (2 x 2) = 4; ((2 x 2) + 1) = 5 ...
80+
81+
if (verbose) {
82+
System.out.println(String.format("From %02d and %02d, %s chooses %02d", score1, score2,
83+
(isMaximizer ? "Maximizer" : "Minimizer"), bestScore));
84+
}
85+
86+
return bestScore;
87+
}
88+
89+
/**
90+
* Returns an array of random numbers which lenght is a power of 2.
91+
*
92+
* @param size The power of 2 that will determine the lenght of the array.
93+
* @param maxScore The maximum possible score.
94+
* @return An array of random numbers.
95+
*/
96+
public static int[] getRandomScores(int size, int maxScore) {
97+
int[] randomScores = new int[(int) Math.pow(2, size)];
98+
Random rand = new Random();
99+
100+
for (int a : randomScores) {
101+
a = rand.nextInt(maxScore) + 1;
102+
}
103+
104+
return randomScores;
105+
}
106+
107+
// A utility function to find Log n in base 2
108+
private int log2(int n) {
109+
return (n == 1) ? 0 : log2(n / 2) + 1;
110+
}
111+
112+
public void setScores(int[] scores) {
113+
if (scores.length % 1 == 0) {
114+
this.scores = scores;
115+
height = log2(this.scores.length);
116+
} else {
117+
System.out.println("The number of scores must be a power of 2.");
118+
}
119+
}
120+
121+
public int[] getScores() {
122+
return scores;
123+
}
124+
125+
public int getHeight() {
126+
return height;
127+
}
128+
}

0 commit comments

Comments
 (0)