-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtic tac toe.py
More file actions
119 lines (98 loc) · 4.26 KB
/
tic tac toe.py
File metadata and controls
119 lines (98 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import pygame as pg
import sys
from random import randint
WIN_SIZE = 900
CELL_SIZE = WIN_SIZE // 3
INF = float('inf')
vec2 = pg.math.Vector2
CELL_CENTER = vec2(CELL_SIZE / 2)
class TicTacToe:
def __init__(self, game):
self.game = game
self.field_image = self.get_scaled_image(path='tic tac toe/resources/field.png', res=[WIN_SIZE] * 2)
self.O_image = self.get_scaled_image(path='tic tac toe/resources/o.png', res=[CELL_SIZE] * 2)
self.X_image = self.get_scaled_image(path='tic tac toe/resources/x.png', res=[CELL_SIZE] * 2)
self.game_array = [[INF, INF, INF],
[INF, INF, INF],
[INF, INF, INF]]
self.player = randint(0, 1)
self.line_indices_array = [[(0, 0), (0, 1), (0, 2)],
[(1, 0), (1, 1), (1, 2)],
[(2, 0), (2, 1), (2, 2)],
[(0, 0), (1, 0), (2, 0)],
[(0, 1), (1, 1), (2, 1)],
[(0, 2), (1, 2), (2, 2)],
[(0, 0), (1, 1), (2, 2)],
[(0, 2), (1, 1), (2, 0)]]
self.winner = None
self.game_steps = 0
self.font = pg.font.SysFont('Verdana', CELL_SIZE // 4, True)
def check_winner(self):
for line_indices in self.line_indices_array:
sum_line = sum([self.game_array[i][j] for i, j in line_indices])
if sum_line in {0, 3}:
self.winner = 'XO'[sum_line == 0]
self.winner_line = [vec2(line_indices[0][::-1]) * CELL_SIZE + CELL_CENTER,
vec2(line_indices[2][::-1]) * CELL_SIZE + CELL_CENTER]
def run_game_process(self):
current_cell = vec2(pg.mouse.get_pos()) // CELL_SIZE
col, row = map(int, current_cell)
left_click = pg.mouse.get_pressed()[0]
if left_click and self.game_array[row][col] == INF and not self.winner:
self.game_array[row][col] = self.player
self.player = not self.player
self.game_steps += 1
self.check_winner()
def draw_objects(self):
for y, row in enumerate(self.game_array):
for x, obj in enumerate(row):
if obj != INF:
self.game.screen.blit(self.X_image if obj else self.O_image, vec2(x, y) * CELL_SIZE)
def draw_winner(self):
if self.winner:
pg.draw.line(self.game.screen, 'red', *self.winner_line, CELL_SIZE // 8)
label = self.font.render(f'Player "{self.winner}" wins!', True, 'white', 'black')
self.game.screen.blit(label, (WIN_SIZE // 2 - label.get_width() // 2, WIN_SIZE // 4))
def draw(self):
self.game.screen.blit(self.field_image, (0, 0))
self.draw_objects()
self.draw_winner()
@staticmethod
def get_scaled_image(path, res):
img = pg.image.load(path)
return pg.transform.smoothscale(img, res)
def print_caption(self):
pg.display.set_caption(f'Player "{"OX"[self.player]}" turn!')
if self.winner:
pg.display.set_caption(f'Player "{self.winner}" wins! Press Space to Restart')
elif self.game_steps == 9:
pg.display.set_caption(f'Game Over! Press Space to Restart')
def run(self):
self.print_caption()
self.draw()
self.run_game_process()
class Game:
def __init__(self):
pg.init()
self.screen = pg.display.set_mode([WIN_SIZE] * 2)
self.clock = pg.time.Clock()
self.tic_tac_toe = TicTacToe(self)
def new_game(self):
self.tic_tac_toe = TicTacToe(self)
def check_events(self):
for event in pg.event.get():
if event.type == pg.QUIT:
pg.quit()
sys.exit()
if event.type == pg.KEYDOWN:
if event.key == pg.K_SPACE:
self.new_game()
def run(self):
while True:
self.tic_tac_toe.run()
self.check_events()
pg.display.update()
self.clock.tick(60)
if __name__ == '__main__':
game = Game()
game.run()