1+ import random
2+ import time
3+
4+ # Colors
5+ RESET = "\033 [0m"
6+ BLUE = "\033 [94m"
7+ RED = "\033 [91m"
8+ GREEN = "\033 [92m"
9+ YELLOW = "\033 [93m"
10+ CYAN = "\033 [96m"
11+ MAGENTA = "\033 [95m"
12+ BOLD = "\033 [1m"
13+
14+ # Title
15+ print (BOLD + CYAN )
16+ print ("=" * 70 )
17+ print ("🔲 DOTS & BOXES AI - ADVANCED VERSION 🔲" )
18+ print ("=" * 70 )
19+ print (RESET )
20+
21+ print (YELLOW + "🎮 GAME MODES" + RESET )
22+ print ("1. 👥 Player vs Player" )
23+ print ("2. 🤖 Player vs AI" )
24+
25+ mode = input ("\n 🎯 Select mode (1 or 2): " )
26+
27+ if mode not in ['1' , '2' ]:
28+ print (RED + "\n ❌ Invalid mode selected!" + RESET )
29+ exit ()
30+
31+ # AI difficulty
32+ ai_difficulty = "easy"
33+
34+ if mode == '2' :
35+ print ("\n 🧠 AI LEVELS" )
36+ print ("1. 🟢 Easy" )
37+ print ("2. 🟡 Intermediate" )
38+ print ("3. 🔴 Hard" )
39+
40+ diff = input ("\n 🎯 Select AI difficulty: " )
41+
42+ if diff == '1' :
43+ ai_difficulty = 'easy'
44+ elif diff == '2' :
45+ ai_difficulty = 'medium'
46+ elif diff == '3' :
47+ ai_difficulty = 'hard'
48+ else :
49+ print (RED + "\n ❌ Invalid difficulty!" + RESET )
50+ exit ()
51+
52+ # Board size
53+ size = input ("\n 📏 Enter board size (2-8): " )
54+
55+ if not size .isdigit ():
56+ print (RED + "\n ❌ Invalid size!" + RESET )
57+ exit ()
58+
59+ size = int (size )
60+
61+ if size < 2 or size > 8 :
62+ print (RED + "\n ❌ Size must be between 2 and 8!" + RESET )
63+ exit ()
64+
65+ # Board data
66+ horizontal_lines = [[False for _ in range (size )] for _ in range (size + 1 )]
67+ vertical_lines = [[False for _ in range (size + 1 )] for _ in range (size )]
68+ boxes = [[' ' for _ in range (size )] for _ in range (size )]
69+
70+ player_score = 0
71+ computer_score = 0
72+ current_player = 1
73+ total_boxes = size * size
74+
75+
76+ def print_board ():
77+ print ("\n " )
78+ for row in range (size ):
79+ line = ""
80+ for col in range (size ):
81+ line += "•"
82+ if horizontal_lines [row ][col ]:
83+ if boxes [row ][col ] == 'P' :
84+ line += BLUE + "━━" + RESET
85+ elif boxes [row ][col ] == 'A' :
86+ line += RED + "━━" + RESET
87+ else :
88+ line += "━━"
89+ else :
90+ line += " "
91+ line += "•"
92+ print (line )
93+
94+ line = ""
95+ for col in range (size ):
96+ if vertical_lines [row ][col ]:
97+ if boxes [row ][col ] == 'P' :
98+ line += BLUE + "┃" + RESET
99+ elif boxes [row ][col ] == 'A' :
100+ line += RED + "┃" + RESET
101+ else :
102+ line += "┃"
103+ else :
104+ line += " "
105+
106+ if boxes [row ][col ] == 'P' :
107+ line += BLUE + "■ " + RESET
108+ elif boxes [row ][col ] == 'A' :
109+ line += RED + "■ " + RESET
110+ else :
111+ line += " "
112+
113+ if vertical_lines [row ][size ]:
114+ line += "┃"
115+ print (line )
116+
117+ line = ""
118+ for col in range (size ):
119+ line += "•"
120+ line += "━━" if horizontal_lines [size ][col ] else " "
121+ line += "•"
122+ print (line )
123+ print ("\n " )
124+
125+
126+ def check_boxes (symbol ):
127+ global player_score , computer_score
128+ completed = False
129+ for row in range (size ):
130+ for col in range (size ):
131+ if boxes [row ][col ] == ' ' :
132+ top = horizontal_lines [row ][col ]
133+ bottom = horizontal_lines [row + 1 ][col ]
134+ left = vertical_lines [row ][col ]
135+ right = vertical_lines [row ][col + 1 ]
136+ if top and bottom and left and right :
137+ boxes [row ][col ] = symbol
138+ completed = True
139+ if symbol == 'P' :
140+ player_score += 1
141+ else :
142+ computer_score += 1
143+ return completed
144+
145+
146+ def get_available_moves ():
147+ moves = []
148+ for row in range (size + 1 ):
149+ for col in range (size ):
150+ if not horizontal_lines [row ][col ]:
151+ moves .append (('h' , row , col ))
152+ for row in range (size ):
153+ for col in range (size + 1 ):
154+ if not vertical_lines [row ][col ]:
155+ moves .append (('v' , row , col ))
156+ return moves
157+
158+
159+ def count_box_sides (row , col ):
160+ count = 0
161+ if horizontal_lines [row ][col ]:
162+ count += 1
163+ if horizontal_lines [row + 1 ][col ]:
164+ count += 1
165+ if vertical_lines [row ][col ]:
166+ count += 1
167+ if vertical_lines [row ][col + 1 ]:
168+ count += 1
169+ return count
170+
171+
172+ def simulate_move (move ):
173+ direction , row , col = move
174+ if direction == 'h' :
175+ horizontal_lines [row ][col ] = True
176+ else :
177+ vertical_lines [row ][col ] = True
178+
179+
180+ def undo_move (move ):
181+ direction , row , col = move
182+ if direction == 'h' :
183+ horizontal_lines [row ][col ] = False
184+ else :
185+ vertical_lines [row ][col ] = False
186+
187+
188+ def completes_box (move ):
189+ simulate_move (move )
190+ for row in range (size ):
191+ for col in range (size ):
192+ if count_box_sides (row , col ) == 4 :
193+ undo_move (move )
194+ return True
195+ undo_move (move )
196+ return False
197+
198+
199+ def creates_danger (move ):
200+ simulate_move (move )
201+ for row in range (size ):
202+ for col in range (size ):
203+ if count_box_sides (row , col ) == 3 :
204+ undo_move (move )
205+ return True
206+ undo_move (move )
207+ return False
208+
209+
210+ def ai_move ():
211+ available_moves = get_available_moves ()
212+
213+ if ai_difficulty == 'easy' :
214+ return random .choice (available_moves )
215+
216+ elif ai_difficulty == 'medium' :
217+ for move in available_moves :
218+ if completes_box (move ):
219+ return move
220+ safe_moves = [m for m in available_moves if not creates_danger (m )]
221+ return random .choice (safe_moves ) if safe_moves else random .choice (available_moves )
222+
223+ else : # hard
224+ best_move = None
225+ best_score = - 999
226+ for move in available_moves :
227+ score = 0
228+ if completes_box (move ):
229+ score += 100
230+ if creates_danger (move ):
231+ score -= 50
232+ simulate_move (move )
233+ for row in range (size ):
234+ for col in range (size ):
235+ sides = count_box_sides (row , col )
236+ if sides == 2 :
237+ score += 2
238+ elif sides == 1 :
239+ score += 1
240+ undo_move (move )
241+ if score > best_score :
242+ best_score = score
243+ best_move = move
244+ return best_move
245+
246+
247+ # Main game loop
248+ while player_score + computer_score < total_boxes :
249+ print_board ()
250+ print (BOLD + "=" * 70 + RESET )
251+ print (BLUE + f"🔵 Player Score: { player_score } " + RESET )
252+ if mode == '2' :
253+ print (RED + f"🤖 AI Score: { computer_score } " + RESET )
254+ else :
255+ print (RED + f"🔴 Player 2 Score: { computer_score } " + RESET )
256+ print (BOLD + "=" * 70 + RESET )
257+
258+ if current_player == 1 or mode == '1' :
259+ if current_player == 1 :
260+ print (BLUE + "\n 🔵 Player 1 Turn" + RESET )
261+ else :
262+ print (RED + "\n 🔴 Player 2 Turn" + RESET )
263+
264+ direction = input ("➡️ Horizontal(h) or Vertical(v): " ).lower ()
265+ if direction not in ['h' , 'v' ]:
266+ print (RED + "❌ Invalid direction!" + RESET )
267+ continue
268+
269+ row = input ("📍 Enter row: " )
270+ col = input ("📍 Enter column: " )
271+
272+ if not row .isdigit () or not col .isdigit ():
273+ print (RED + "❌ Invalid position!" + RESET )
274+ continue
275+
276+ row , col = int (row ), int (col )
277+
278+ try :
279+ if direction == 'h' :
280+ if horizontal_lines [row ][col ]:
281+ print (YELLOW + "⚠️ Line already taken!" + RESET )
282+ continue
283+ horizontal_lines [row ][col ] = True
284+ else :
285+ if vertical_lines [row ][col ]:
286+ print (YELLOW + "⚠️ Line already taken!" + RESET )
287+ continue
288+ vertical_lines [row ][col ] = True
289+ except :
290+ print (RED + "❌ Position out of range!" + RESET )
291+ continue
292+
293+ symbol = 'P' if current_player == 1 else 'A'
294+ got_box = check_boxes (symbol )
295+ if not got_box :
296+ current_player = 2 if current_player == 1 else 1
297+
298+ else :
299+ print (RED + "\n 🤖 AI is thinking..." + RESET )
300+ time .sleep (1 )
301+
302+ move = ai_move ()
303+ direction , row , col = move
304+ print (CYAN + f"🎯 AI selected: { direction } ({ row } , { col } )" + RESET )
305+
306+ if direction == 'h' :
307+ horizontal_lines [row ][col ] = True
308+ else :
309+ vertical_lines [row ][col ] = True
310+
311+ got_box = check_boxes ('A' )
312+ if not got_box :
313+ current_player = 1
314+
315+ # Game over
316+ print_board ()
317+ print (BOLD + GREEN )
318+ print ("=" * 70 )
319+ print ("🏁 GAME OVER 🏁" )
320+ print ("=" * 70 )
321+ print (RESET )
322+
323+ print (BLUE + f"🔵 Player Score: { player_score } " + RESET )
324+ if mode == '2' :
325+ print (RED + f"🤖 AI Score: { computer_score } " + RESET )
326+ else :
327+ print (RED + f"🔴 Player 2 Score: { computer_score } " + RESET )
328+
329+ print ()
330+
331+ if player_score > computer_score :
332+ print (GREEN + BOLD + "🎉 PLAYER 1 WINS!" + RESET )
333+ elif computer_score > player_score :
334+ if mode == '2' :
335+ print (RED + BOLD + "🤖 AI WINS!" + RESET )
336+ else :
337+ print (RED + BOLD + "🎉 PLAYER 2 WINS!" + RESET )
338+ else :
339+ print (YELLOW + BOLD + "🤝 IT'S A DRAW!" + RESET )
340+
341+ print (CYAN + "\n 👋 Thanks for playing Dots & Boxes!\n " + RESET )
0 commit comments