1- use crate :: board:: { Board , Player , Cell } ;
1+ use crate :: board:: { Cell , Player } ;
22use crate :: game:: Game ;
33
44/// AI player that uses the Minimax algorithm to play optimally
@@ -24,11 +24,11 @@ impl AI {
2424
2525 for & position in & available_moves {
2626 let mut game_copy = self . clone_game ( game) ;
27-
27+
2828 game_copy. make_move ( position) ;
29-
29+
3030 let score = self . minimax ( & game_copy, 0 , false ) ;
31-
31+
3232 if score > best_score {
3333 best_score = score;
3434 best_move = Some ( position) ;
@@ -45,9 +45,9 @@ impl AI {
4545 // Check terminal states (game over)
4646 if let Some ( winner) = game. check_winner ( ) {
4747 return if winner == self . player {
48- 10 - depth as i32 // AI wins: prefer winning sooner (higher score for fewer moves)
48+ 10 - depth as i32 // AI wins: prefer winning sooner (higher score for fewer moves)
4949 } else {
50- depth as i32 - 10 // AI loses: prefer losing later (less negative score)
50+ depth as i32 - 10 // AI loses: prefer losing later (less negative score)
5151 } ;
5252 }
5353
@@ -56,32 +56,32 @@ impl AI {
5656 }
5757
5858 let available_moves = game. get_available_moves ( ) ;
59-
59+
6060 if is_maximizing {
6161 // AI's turn - maximize the score
6262 let mut max_score = i32:: MIN ;
63-
63+
6464 for & position in & available_moves {
6565 let mut game_copy = self . clone_game ( game) ;
6666 game_copy. make_move ( position) ;
67-
67+
6868 let score = self . minimax ( & game_copy, depth + 1 , false ) ;
6969 max_score = max_score. max ( score) ;
7070 }
71-
71+
7272 max_score
7373 } else {
7474 // Opponent's turn - minimize the score (from AI's perspective)
7575 let mut min_score = i32:: MAX ;
76-
76+
7777 for & position in & available_moves {
7878 let mut game_copy = self . clone_game ( game) ;
7979 game_copy. make_move ( position) ;
80-
80+
8181 let score = self . minimax ( & game_copy, depth + 1 , true ) ;
8282 min_score = min_score. min ( score) ;
8383 }
84-
84+
8585 min_score
8686 }
8787 }
@@ -91,17 +91,16 @@ impl AI {
9191 fn clone_game ( & self , game : & Game ) -> Game {
9292 let mut new_game = Game :: new ( ) ;
9393
94- let board = game. get_board ( ) ;
94+ let board = game. get_board ( ) ;
9595
96- let mut moves = Vec :: new ( ) ;
96+ let mut moves = Vec :: new ( ) ;
9797 for position in 1 ..=9 {
9898 if let Some ( Cell :: Occupied ( player) ) = board. get_cell ( position) {
9999 moves. push ( ( position, player) ) ;
100100 }
101101 }
102102
103-
104- let mut x_moves = Vec :: new ( ) ;
103+ let mut x_moves = Vec :: new ( ) ;
105104 let mut o_moves = Vec :: new ( ) ;
106105
107106 for ( pos, player) in moves {
@@ -111,7 +110,7 @@ impl AI {
111110 }
112111 }
113112
114- let mut move_sequence = Vec :: new ( ) ;
113+ let mut move_sequence = Vec :: new ( ) ;
115114 let max_len = x_moves. len ( ) . max ( o_moves. len ( ) ) ;
116115
117116 for i in 0 ..max_len {
@@ -123,7 +122,7 @@ impl AI {
123122 }
124123 }
125124
126- for & position in & move_sequence {
125+ for & position in & move_sequence {
127126 new_game. make_move ( position) ;
128127 }
129128
@@ -140,7 +139,7 @@ mod tests {
140139 fn test_ai_creation ( ) {
141140 let ai = AI :: new ( Player :: O ) ;
142141 assert_eq ! ( ai. player, Player :: O ) ;
143-
142+
144143 let ai_x = AI :: new ( Player :: X ) ;
145144 assert_eq ! ( ai_x. player, Player :: X ) ;
146145 }
@@ -149,13 +148,13 @@ mod tests {
149148 fn test_ai_blocks_winning_move ( ) {
150149 let mut game = Game :: new ( ) ;
151150 let ai = AI :: new ( Player :: O ) ;
152-
151+
153152 // X threatens to win in top row
154153 game. make_move ( 1 ) ; // X
155154 game. make_move ( 4 ) ; // O (AI's previous move)
156155 game. make_move ( 2 ) ; // X
157156 // Now X threatens to win at position 3
158-
157+
159158 let ai_move = ai. get_best_move ( & game) ;
160159 assert_eq ! ( ai_move, Some ( 3 ) ) ; // AI should block at position 3
161160 }
@@ -164,15 +163,15 @@ mod tests {
164163 fn test_ai_takes_winning_move ( ) {
165164 let mut game = Game :: new ( ) ;
166165 let ai = AI :: new ( Player :: O ) ;
167-
166+
168167 // Set up a scenario where AI can win
169168 game. make_move ( 1 ) ; // X
170169 game. make_move ( 4 ) ; // O
171170 game. make_move ( 2 ) ; // X
172171 game. make_move ( 5 ) ; // O
173172 game. make_move ( 7 ) ; // X
174173 // Now O can win at position 6
175-
174+
176175 let ai_move = ai. get_best_move ( & game) ;
177176 assert_eq ! ( ai_move, Some ( 6 ) ) ; // AI should win at position 6
178177 }
@@ -181,7 +180,7 @@ mod tests {
181180 fn test_ai_chooses_valid_move_on_empty_board ( ) {
182181 let game = Game :: new ( ) ;
183182 let ai = AI :: new ( Player :: X ) ;
184-
183+
185184 let ai_move = ai. get_best_move ( & game) ;
186185 // On an empty board, any move should be valid (1-9)
187186 // The AI should choose some valid position
@@ -194,13 +193,17 @@ mod tests {
194193 fn test_ai_no_moves_available ( ) {
195194 let mut game = Game :: new ( ) ;
196195 let ai = AI :: new ( Player :: O ) ;
197-
196+
198197 // Fill the board completely
199198 for position in 1 ..=9 {
200- let player = if position % 2 == 1 { Player :: X } else { Player :: O } ;
199+ let _player = if position % 2 == 1 {
200+ Player :: X
201+ } else {
202+ Player :: O
203+ } ;
201204 game. make_move ( position) ;
202205 }
203-
206+
204207 let ai_move = ai. get_best_move ( & game) ;
205208 assert_eq ! ( ai_move, None ) ; // No moves available
206209 }
@@ -209,7 +212,7 @@ mod tests {
209212 fn test_minimax_prefers_winning_sooner ( ) {
210213 let mut game = Game :: new ( ) ;
211214 let ai = AI :: new ( Player :: O ) ;
212-
215+
213216 // Create a scenario where AI has multiple ways to win
214217 // AI should prefer the immediate win over a longer path to victory
215218 game. make_move ( 1 ) ; // X
@@ -218,8 +221,8 @@ mod tests {
218221 game. make_move ( 5 ) ; // O
219222 game. make_move ( 8 ) ; // X
220223 // AI can win immediately at position 6
221-
224+
222225 let ai_move = ai. get_best_move ( & game) ;
223226 assert_eq ! ( ai_move, Some ( 6 ) ) ; // Should take the immediate win
224227 }
225- }
228+ }
0 commit comments