1+ package com .thealgorithms .others ;
2+
3+ import org .junit .jupiter .api .BeforeEach ;
4+ import org .junit .jupiter .api .Test ;
5+ import static org .junit .jupiter .api .Assertions .*;
6+
7+ import java .io .ByteArrayOutputStream ;
8+ import java .io .PrintStream ;
9+
10+ /**
11+ * Test class for MiniMaxAlgorithm
12+ * Tests the minimax algorithm implementation for game tree evaluation
13+ */
14+ class MiniMaxAlgorithmTest {
15+
16+ private MiniMaxAlgorithm miniMax ;
17+ private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream ();
18+ private final PrintStream originalOut = System .out ;
19+
20+ @ BeforeEach
21+ void setUp () {
22+ miniMax = new MiniMaxAlgorithm ();
23+ System .setOut (new PrintStream (outputStream ));
24+ }
25+
26+ @ Test
27+ void testConstructorCreatesValidScores () {
28+ // The default constructor should create scores array of length 8 (2^3)
29+ assertEquals (8 , miniMax .getScores ().length );
30+ assertEquals (3 , miniMax .getHeight ());
31+
32+ // All scores should be positive (between 1 and 99)
33+ for (int score : miniMax .getScores ()) {
34+ assertTrue (score >= 1 && score <= 99 );
35+ }
36+ }
37+
38+ @ Test
39+ void testSetScoresWithValidPowerOfTwo () {
40+ int [] validScores = {10 , 20 , 30 , 40 };
41+ miniMax .setScores (validScores );
42+
43+ assertArrayEquals (validScores , miniMax .getScores ());
44+ assertEquals (2 , miniMax .getHeight ()); // log2(4) = 2
45+ }
46+
47+ @ Test
48+ void testSetScoresWithInvalidLength () {
49+ int [] invalidScores = {10 , 20 , 30 }; // Length 3 is not a power of 2
50+ miniMax .setScores (invalidScores );
51+
52+ // Should print error message and not change the scores
53+ String output = outputStream .toString ();
54+ assertTrue (output .contains ("The number of scores must be a power of 2." ));
55+
56+ // Scores should remain unchanged (original length 8)
57+ assertEquals (8 , miniMax .getScores ().length );
58+ }
59+
60+ @ Test
61+ void testSetScoresWithSingleElement () {
62+ int [] singleScore = {42 };
63+ miniMax .setScores (singleScore );
64+
65+ assertArrayEquals (singleScore , miniMax .getScores ());
66+ assertEquals (0 , miniMax .getHeight ()); // log2(1) = 0
67+ }
68+
69+ @ Test
70+ void testMiniMaxWithKnownScores () {
71+ // Test with a known game tree: [3, 12, 8, 2]
72+ int [] testScores = {3 , 12 , 8 , 2 };
73+ miniMax .setScores (testScores );
74+
75+ // Maximizer starts: should choose max(min(3,12), min(8,2)) = max(3, 2) = 3
76+ int result = miniMax .miniMax (0 , true , 0 , false );
77+ assertEquals (3 , result );
78+ }
79+
80+ @ Test
81+ void testMiniMaxWithMinimizerFirst () {
82+ // Test with minimizer starting first
83+ int [] testScores = {3 , 12 , 8 , 2 };
84+ miniMax .setScores (testScores );
85+
86+ // Minimizer starts: should choose min(max(3,12), max(8,2)) = min(12, 8) = 8
87+ int result = miniMax .miniMax (0 , false , 0 , false );
88+ assertEquals (8 , result );
89+ }
90+
91+ @ Test
92+ void testMiniMaxWithLargerTree () {
93+ // Test with 8 elements: [5, 6, 7, 4, 5, 3, 6, 2]
94+ int [] testScores = {5 , 6 , 7 , 4 , 5 , 3 , 6 , 2 };
95+ miniMax .setScores (testScores );
96+
97+ // Maximizer starts
98+ int result = miniMax .miniMax (0 , true , 0 , false );
99+ // Expected: max(min(max(5,6), max(7,4)), min(max(5,3), max(6,2)))
100+ // = max(min(6, 7), min(5, 6)) = max(6, 5) = 6
101+ assertEquals (6 , result );
102+ }
103+
104+ @ Test
105+ void testMiniMaxVerboseOutput () {
106+ int [] testScores = {3 , 12 , 8 , 2 };
107+ miniMax .setScores (testScores );
108+
109+ miniMax .miniMax (0 , true , 0 , true );
110+
111+ String output = outputStream .toString ();
112+ assertTrue (output .contains ("Maximizer" ));
113+ assertTrue (output .contains ("Minimizer" ));
114+ assertTrue (output .contains ("chooses" ));
115+ }
116+
117+ @ Test
118+ void testGetRandomScoresLength () {
119+ int [] randomScores = MiniMaxAlgorithm .getRandomScores (4 , 50 );
120+ assertEquals (16 , randomScores .length ); // 2^4 = 16
121+
122+ // All scores should be between 1 and 50
123+ for (int score : randomScores ) {
124+ assertTrue (score >= 1 && score <= 50 );
125+ }
126+ }
127+
128+ @ Test
129+ void testGetRandomScoresWithDifferentParameters () {
130+ int [] randomScores = MiniMaxAlgorithm .getRandomScores (2 , 10 );
131+ assertEquals (4 , randomScores .length ); // 2^2 = 4
132+
133+ // All scores should be between 1 and 10
134+ for (int score : randomScores ) {
135+ assertTrue (score >= 1 && score <= 10 );
136+ }
137+ }
138+
139+ @ Test
140+ void testMainMethod () {
141+ // Test that main method runs without errors
142+ assertDoesNotThrow (() -> MiniMaxAlgorithm .main (new String []{}));
143+
144+ String output = outputStream .toString ();
145+ assertTrue (output .contains ("The best score for" ));
146+ assertTrue (output .contains ("Maximizer" ));
147+ }
148+
149+ @ Test
150+ void testHeightCalculation () {
151+ // Test height calculation for different array sizes
152+ int [] scores2 = {1 , 2 };
153+ miniMax .setScores (scores2 );
154+ assertEquals (1 , miniMax .getHeight ()); // log2(2) = 1
155+
156+ int [] scores16 = new int [16 ];
157+ miniMax .setScores (scores16 );
158+ assertEquals (4 , miniMax .getHeight ()); // log2(16) = 4
159+ }
160+
161+ @ Test
162+ void testEdgeCaseWithZeroScores () {
163+ int [] zeroScores = {0 , 0 , 0 , 0 };
164+ miniMax .setScores (zeroScores );
165+
166+ int result = miniMax .miniMax (0 , true , 0 , false );
167+ assertEquals (0 , result );
168+ }
169+
170+ @ Test
171+ void testEdgeCaseWithNegativeScores () {
172+ int [] negativeScores = {-5 , -2 , -8 , -1 };
173+ miniMax .setScores (negativeScores );
174+
175+ // Tree evaluation with maximizer first:
176+ // Level 1 (minimizer): min(-5,-2) = -5, min(-8,-1) = -8
177+ // Level 0 (maximizer): max(-5, -8) = -5
178+ int result = miniMax .miniMax (0 , true , 0 , false );
179+ assertEquals (-5 , result );
180+ }
181+
182+ void tearDown () {
183+ System .setOut (originalOut );
184+ }
185+ }
0 commit comments