-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
212 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import pygame | ||
from src.constants import WIDTH, HEIGHT, SQUARE_SIZE, PADDING, ROWS, COLS | ||
from src.game import Game | ||
|
||
FPS = 60 | ||
|
||
WIN = pygame.display.set_mode((WIDTH, HEIGHT)) | ||
pygame.display.set_caption("Ultimate Tic-Tac-Toe") | ||
|
||
|
||
def get_row_col_from_mouse(pos): | ||
x, y = pos | ||
row = (y - PADDING) // SQUARE_SIZE | ||
col = (x - PADDING) // SQUARE_SIZE | ||
return row, col | ||
|
||
|
||
def main(): | ||
running = True | ||
clock = pygame.time.Clock() | ||
game = Game(WIN) | ||
|
||
while running: | ||
clock.tick(FPS) | ||
|
||
for event in pygame.event.get(): | ||
if event.type == pygame.QUIT: | ||
running = False | ||
|
||
if event.type == pygame.MOUSEBUTTONDOWN: | ||
pos = pygame.mouse.get_pos() | ||
row, col = get_row_col_from_mouse(pos) | ||
if 0 <= row < ROWS and 0 <= col < COLS: | ||
if game.select(row, col): | ||
running = False | ||
|
||
game.update() | ||
pygame.quit() | ||
|
||
|
||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
import pygame | ||
from src.constants import ROWS, COLS, SQUARE_SIZE, BLACK, WHITE, WIDTH, HEIGHT, PADDING, X_big, O_big | ||
from .symbol import Symbol | ||
|
||
|
||
class Board: | ||
def __init__(self): | ||
self.board = [] | ||
self.create_board() | ||
self.turn = "X" | ||
self.field_won = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] | ||
self.last = (-1, -1) | ||
|
||
def draw_board(self, win): | ||
win.fill(WHITE) | ||
|
||
for i in range(1, 3): | ||
pygame.draw.line(win, BLACK, | ||
(PADDING + i * 3 * SQUARE_SIZE, PADDING), | ||
(PADDING + i * 3 * SQUARE_SIZE, HEIGHT - PADDING), | ||
4) | ||
pygame.draw.line(win, BLACK, | ||
(PADDING, PADDING + i * 3 * SQUARE_SIZE), | ||
(WIDTH - PADDING, PADDING + i * 3 * SQUARE_SIZE), | ||
4) | ||
|
||
for i in range(3): | ||
for j in range(3): | ||
offset_x = j * SQUARE_SIZE * 3 | ||
offset_y = i * SQUARE_SIZE * 3 | ||
|
||
if self.field_won[i][j] != 0: | ||
win.blit(X_big if self.field_won[i][j] == "X" else O_big, | ||
(PADDING + offset_x + | ||
(3 * SQUARE_SIZE - X_big.get_width()) // 2, | ||
PADDING + offset_y + | ||
(3 * SQUARE_SIZE - X_big.get_width()) // 2)) | ||
else: | ||
for r in range(2): | ||
start_x = PADDING + ((r + 1) * SQUARE_SIZE) + offset_x | ||
start_y = PADDING + 5 + offset_y | ||
end_x = start_x | ||
end_y = start_y + (3 * SQUARE_SIZE) - 10 | ||
pygame.draw.line(win, BLACK, (start_x, start_y), | ||
(end_x, end_y)) | ||
for c in range(2): | ||
start_x = PADDING + 5 + offset_x | ||
start_y = PADDING + ((c + 1) * SQUARE_SIZE) + offset_y | ||
end_x = start_x + (3 * SQUARE_SIZE) - 10 | ||
end_y = start_y | ||
pygame.draw.line(win, BLACK, (start_x, start_y), | ||
(end_x, end_y)) | ||
|
||
def is_field_won(self, field): | ||
for i in range(3): | ||
if field[i][0] == self.turn and field[i][1] == self.turn and field[i][2] == self.turn: | ||
return True | ||
if field[0][i] == self.turn and field[1][i] == self.turn and field[2][i] == self.turn: | ||
return True | ||
if field[0][0] == self.turn and field[1][1] == self.turn and field[2][2] == self.turn: | ||
return True | ||
if field[0][2] == self.turn and field[1][1] == self and field[2][0] == self.turn: | ||
return True | ||
return False | ||
|
||
def is_game_won(self): | ||
if self.is_field_won(self.field_won): | ||
return True | ||
return False | ||
|
||
def get_field(self, row, col): | ||
field = [] | ||
for i in range(3): | ||
field.append( | ||
[0 if self.board[row * 3 + i][col * 3 + j] == 0 else self.board[row * 3 + i][col * 3 + j].type for j in | ||
range(3)]) | ||
return field | ||
|
||
def get_possible_moves(self): | ||
moves = [] | ||
next_field = (self.last[0] - (self.last[0] // 3 * 3), self.last[1] - (self.last[1] // 3 * 3)) | ||
|
||
if self.field_won[next_field[0]][next_field[1]] != 0 or self.last == (-1, -1): | ||
for i in range(ROWS): | ||
for j in range(COLS): | ||
if self.board[i][j] == 0 and self.field_won[i // 3][j // 3] == 0: | ||
moves.append((i, j)) | ||
else: | ||
for i in range(next_field[0]*3, next_field[0]*3 + 3): | ||
for j in range(next_field[1]*3, next_field[1]*3 + 3): | ||
if self.board[i][j] == 0: | ||
moves.append((i, j)) | ||
return moves | ||
|
||
def move(self, row, col): | ||
self.board[row][col] = Symbol(row, col, self.turn) | ||
self.last = (row, col) | ||
|
||
def change_turn(self): | ||
if self.turn == "X": | ||
self.turn = "O" | ||
else: | ||
self.turn = "X" | ||
|
||
def draw(self, win): | ||
self.draw_board(win) | ||
for row in range(ROWS): | ||
for col in range(COLS): | ||
if self.board[row][col] != 0 and self.field_won[row // 3][col // 3] == 0: | ||
self.board[row][col].draw(win) | ||
|
||
def create_board(self): | ||
for row in range(ROWS): | ||
self.board.append([0 for _ in range(COLS)]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import pygame | ||
|
||
WIDTH, HEIGHT = 500, 500 | ||
ROWS, COLS = 9, 9 | ||
SQUARE_SIZE = (WIDTH - 50) // COLS | ||
PADDING = 25 | ||
|
||
# Colors | ||
BLACK = (0, 0, 0) | ||
WHITE = (255, 255, 255) | ||
|
||
# Game Assets | ||
X = pygame.transform.scale(pygame.image.load('assets/x.png'), (32, 32)) | ||
O = pygame.transform.scale(pygame.image.load('assets/o.png'), (32, 32)) | ||
X_big = pygame.transform.scale(pygame.image.load('assets/x.png'), (112, 112)) | ||
O_big = pygame.transform.scale(pygame.image.load('assets/o.png'), (112, 112)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import pygame | ||
from .board import Board | ||
|
||
|
||
class Game: | ||
|
||
def __init__(self, win): | ||
self.board = Board() | ||
self.win = win | ||
|
||
def update(self): | ||
self.board.draw(self.win) | ||
pygame.display.update() | ||
|
||
def select(self, row, col): | ||
moves = self.board.get_possible_moves() | ||
if (row, col) in moves: | ||
self.board.move(row, col) | ||
if self.board.is_field_won(self.board.get_field(row // 3, col // 3)): | ||
self.board.field_won[row // 3][col // 3] = self.board.turn | ||
return self.board.is_game_won() | ||
self.board.change_turn() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import pygame | ||
from .constants import SQUARE_SIZE, PADDING, X, O | ||
|
||
class Symbol: | ||
|
||
def __init__(self, row, col, symbol): | ||
self.type = symbol | ||
self.row = row | ||
self.col = col | ||
self.x = 0 | ||
self.y = 0 | ||
self.calc_pos() | ||
|
||
def calc_pos(self): | ||
self.y = PADDING + (self.row * SQUARE_SIZE) | ||
self.x = PADDING + (self.col * SQUARE_SIZE) | ||
|
||
def draw(self, win): | ||
win.blit(X if self.type == "X" else O, (self.x + ((SQUARE_SIZE - X.get_width())//2), self.y + ((SQUARE_SIZE - X.get_height())//2))) |