Skip to content

Commit 649422a

Browse files
Create tic_tac_toc.py
1 parent 557c7f8 commit 649422a

File tree

1 file changed

+168
-0
lines changed

1 file changed

+168
-0
lines changed
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
import pygame
2+
import sys
3+
import numpy as np
4+
5+
pygame.init()
6+
7+
WIDTH, HEIGHT = 600, 600
8+
LINE_WIDTH = 15
9+
BOARD_ROWS = 3
10+
BOARD_COLS = 3
11+
SQUARE_SIZE = WIDTH // BOARD_COLS
12+
CIRCLE_RADIUS = SQUARE_SIZE // 3
13+
CIRCLE_WIDTH = 15
14+
CROSS_WIDTH = 25
15+
SPACE = SQUARE_SIZE // 4
16+
17+
BG_COLOR = (28, 170, 156)
18+
LINE_COLOR = (23, 145, 135)
19+
CIRCLE_COLOR = (239, 231, 200)
20+
CROSS_COLOR = (66, 66, 66)
21+
22+
screen = pygame.display.set_mode((WIDTH, HEIGHT))
23+
pygame.display.set_caption('Tic Tac Toe')
24+
screen.fill(BG_COLOR)
25+
26+
board = np.zeros((BOARD_ROWS, BOARD_COLS))
27+
28+
def draw_lines():
29+
for row in range(1, BOARD_ROWS):
30+
pygame.draw.line(screen, LINE_COLOR, (0, row * SQUARE_SIZE), (WIDTH, row * SQUARE_SIZE), LINE_WIDTH)
31+
for col in range(1, BOARD_COLS):
32+
pygame.draw.line(screen, LINE_COLOR, (col * SQUARE_SIZE, 0), (col * SQUARE_SIZE, HEIGHT), LINE_WIDTH)
33+
34+
# Draw figures (O and X)
35+
def draw_figures():
36+
for row in range(BOARD_ROWS):
37+
for col in range(BOARD_COLS):
38+
if board[row][col] == 1:
39+
pygame.draw.circle(screen, CIRCLE_COLOR,
40+
(int(col * SQUARE_SIZE + SQUARE_SIZE // 2), int(row * SQUARE_SIZE + SQUARE_SIZE // 2)),
41+
CIRCLE_RADIUS, CIRCLE_WIDTH)
42+
elif board[row][col] == 2:
43+
pygame.draw.line(screen, CROSS_COLOR,
44+
(col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE),
45+
(col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SPACE), CROSS_WIDTH)
46+
pygame.draw.line(screen, CROSS_COLOR,
47+
(col * SQUARE_SIZE + SPACE, row * SQUARE_SIZE + SPACE),
48+
(col * SQUARE_SIZE + SQUARE_SIZE - SPACE, row * SQUARE_SIZE + SQUARE_SIZE - SPACE),
49+
CROSS_WIDTH)
50+
51+
52+
def mark_square(row, col, player):
53+
board[row][col] = player
54+
55+
56+
def available_square(row, col):
57+
return board[row][col] == 0
58+
59+
def is_board_full():
60+
return np.all(board != 0)
61+
62+
def check_win(player):
63+
64+
for row in range(BOARD_ROWS):
65+
if np.all(board[row, :] == player):
66+
return True
67+
for col in range(BOARD_COLS):
68+
if np.all(board[:, col] == player):
69+
return True
70+
if board[0, 0] == player and board[1, 1] == player and board[2, 2] == player:
71+
return True
72+
if board[0, 2] == player and board[1, 1] == player and board[2, 0] == player:
73+
return True
74+
return False
75+
76+
77+
# Minimax algorithm
78+
def minimax(board, depth, is_maximizing):
79+
if check_win(2): # AI win
80+
return 1
81+
elif check_win(1): # Player win
82+
return -1
83+
elif is_board_full():
84+
return 0
85+
86+
if is_maximizing:
87+
best_score = -np.inf
88+
for row in range(BOARD_ROWS):
89+
for col in range(BOARD_COLS):
90+
if available_square(row, col):
91+
board[row][col] = 2
92+
score = minimax(board, depth + 1, False)
93+
board[row][col] = 0
94+
best_score = max(score, best_score)
95+
return best_score
96+
else:
97+
best_score = np.inf
98+
for row in range(BOARD_ROWS):
99+
for col in range(BOARD_COLS):
100+
if available_square(row, col):
101+
board[row][col] = 1
102+
score = minimax(board, depth + 1, True)
103+
board[row][col] = 0
104+
best_score = min(score, best_score)
105+
return best_score
106+
107+
108+
# AI Move
109+
def ai_move():
110+
best_score = -np.inf
111+
move = None
112+
for row in range(BOARD_ROWS):
113+
for col in range(BOARD_COLS):
114+
if available_square(row, col):
115+
board[row][col] = 2
116+
score = minimax(board, 0, False)
117+
board[row][col] = 0
118+
if score > best_score:
119+
best_score = score
120+
move = (row, col)
121+
if move:
122+
mark_square(move[0], move[1], 2)
123+
124+
def restart():
125+
screen.fill(BG_COLOR)
126+
draw_lines()
127+
global board
128+
board = np.zeros((BOARD_ROWS, BOARD_COLS))
129+
130+
131+
player = 1 # Player 1 is human
132+
game_over = False
133+
134+
draw_lines()
135+
136+
while True:
137+
for event in pygame.event.get():
138+
if event.type == pygame.QUIT:
139+
pygame.quit()
140+
sys.exit()
141+
142+
if event.type == pygame.MOUSEBUTTONDOWN and not game_over:
143+
mouseX = event.pos[0] # X coordinate
144+
mouseY = event.pos[1] # Y coordinate
145+
146+
clicked_row = mouseY // SQUARE_SIZE
147+
clicked_col = mouseX // SQUARE_SIZE
148+
149+
if available_square(clicked_row, clicked_col):
150+
mark_square(clicked_row, clicked_col, player)
151+
if check_win(player):
152+
game_over = True
153+
player = 2
154+
155+
if player == 2 and not game_over:
156+
ai_move()
157+
if check_win(2):
158+
game_over = True
159+
player = 1
160+
161+
if event.type == pygame.KEYDOWN:
162+
if event.key == pygame.K_r:
163+
restart()
164+
game_over = False
165+
player = 1
166+
167+
draw_figures()
168+
pygame.display.update()

0 commit comments

Comments
 (0)