1+ from flask import Flask , render_template , request , jsonify
2+
3+ app = Flask (__name__ )
4+
5+ class TicTacToe :
6+ def __init__ (self ):
7+ """Initialize the Tic-Tac-Toe game."""
8+ self .board = [[" " for _ in range (3 )] for _ in range (3 )]
9+ self .players = ["X" , "O" ]
10+ self .current_player = 0
11+
12+ def reset (self ):
13+ self .board = [[" " for _ in range (3 )] for _ in range (3 )]
14+ self .current_player = 0
15+
16+ def check_winner (self ):
17+ """Checks if there is a winner or a draw."""
18+ for i in range (3 ):
19+ if self .board [i ][0 ] == self .board [i ][1 ] == self .board [i ][2 ] != " " :
20+ return self .board [i ][0 ] # Row winner
21+ if self .board [0 ][i ] == self .board [1 ][i ] == self .board [2 ][i ] != " " :
22+ return self .board [0 ][i ] # Column winner
23+
24+ if self .board [0 ][0 ] == self .board [1 ][1 ] == self .board [2 ][2 ] != " " :
25+ return self .board [0 ][0 ]
26+ if self .board [0 ][2 ] == self .board [1 ][1 ] == self .board [2 ][0 ] != " " :
27+ return self .board [0 ][2 ]
28+
29+ for row in self .board :
30+ if " " in row :
31+ return None # Game is still ongoing
32+
33+ return "Draw" # No spaces left and no winner
34+
35+ def make_move (self , row , col ):
36+ """Handles a player's move."""
37+ if self .board [row ][col ] != " " :
38+ raise ValueError ("Cell is already occupied!" )
39+
40+ self .board [row ][col ] = self .players [self .current_player ]
41+
42+ def switch_player (self ):
43+ """Switches to the next player."""
44+ self .current_player = 1 - self .current_player
45+
46+ def find_best_move (self ):
47+ """Finds the best move for the AI using Minimax."""
48+ def minimax (board , is_maximizing ):
49+ winner = self .check_winner ()
50+ if winner == self .players [1 ]:
51+ return 1
52+ elif winner == self .players [0 ]:
53+ return - 1
54+ elif winner == "Draw" :
55+ return 0
56+
57+ if is_maximizing :
58+ best_score = float ('-inf' )
59+ for i in range (3 ):
60+ for j in range (3 ):
61+ if board [i ][j ] == " " :
62+ board [i ][j ] = self .players [1 ]
63+ score = minimax (board , False )
64+ board [i ][j ] = " "
65+ best_score = max (best_score , score )
66+ return best_score
67+ else :
68+ best_score = float ('inf' )
69+ for i in range (3 ):
70+ for j in range (3 ):
71+ if board [i ][j ] == " " :
72+ board [i ][j ] = self .players [0 ]
73+ score = minimax (board , True )
74+ board [i ][j ] = " "
75+ best_score = min (best_score , score )
76+ return best_score
77+
78+ best_score = float ('-inf' )
79+ best_move = (- 1 , - 1 )
80+ for i in range (3 ):
81+ for j in range (3 ):
82+ if self .board [i ][j ] == " " :
83+ self .board [i ][j ] = self .players [1 ]
84+ score = minimax (self .board , False )
85+ self .board [i ][j ] = " "
86+ if score > best_score :
87+ best_score = score
88+ best_move = (i , j )
89+ return best_move
90+
91+ # Initialize game
92+ game = TicTacToe ()
93+
94+ @app .route ('/' )
95+ @app .route ('/' )
96+ def index ():
97+ # Prepare the board with indices
98+ board_with_indices = [
99+ [{"value" : cell , "row" : i , "col" : j } for j , cell in enumerate (row )]
100+ for i , row in enumerate (game .board )
101+ ]
102+ return render_template (
103+ 'index.html' ,
104+ board = board_with_indices ,
105+ current_player = game .players [game .current_player ]
106+ )
107+
108+ @app .route ('/move' , methods = ['POST' ])
109+ def move ():
110+ data = request .get_json ()
111+ row , col = data ['row' ], data ['col' ]
112+
113+ try :
114+ game .make_move (row , col )
115+ winner = game .check_winner ()
116+ if not winner :
117+ game .switch_player ()
118+ if game .current_player == 1 : # AI's turn
119+ ai_move = game .find_best_move ()
120+ game .make_move (ai_move [0 ], ai_move [1 ])
121+ winner = game .check_winner ()
122+ if not winner :
123+ game .switch_player ()
124+
125+ return jsonify ({
126+ 'board' : game .board ,
127+ 'winner' : winner ,
128+ 'current_player' : game .players [game .current_player ]
129+ })
130+ except ValueError as e :
131+ return jsonify ({'error' : str (e )}), 400
132+
133+ @app .route ('/restart' , methods = ['POST' ])
134+ def restart ():
135+ # Reset the game board and state
136+ global game
137+ game .reset () # Assuming there's a reset method in your game class
138+ return '' , 204 # Respond with no content
139+
140+ if __name__ == '__main__' :
141+ app .run (host = '0.0.0.0' , port = 5000 , debug = True , threaded = True )
0 commit comments