initial commit
commit
d552ad2328
@ -0,0 +1,2 @@
|
|||||||
|
.DS_STORE
|
||||||
|
venv/
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 525 B |
Binary file not shown.
After Width: | Height: | Size: 626 B |
Binary file not shown.
After Width: | Height: | Size: 601 B |
Binary file not shown.
After Width: | Height: | Size: 724 B |
@ -0,0 +1,29 @@
|
|||||||
|
# Imports
|
||||||
|
import pygame
|
||||||
|
|
||||||
|
# Buton
|
||||||
|
class Button():
|
||||||
|
|
||||||
|
# Constructor Method
|
||||||
|
def __init__(self, image, x, y):
|
||||||
|
self.image = image
|
||||||
|
self.rect = self.image.get_rect()
|
||||||
|
self.rect.x = x
|
||||||
|
self.rect.y = y
|
||||||
|
self.clicked = False
|
||||||
|
|
||||||
|
# Draw
|
||||||
|
def draw(self, screen):
|
||||||
|
# Action
|
||||||
|
action = False
|
||||||
|
# Click
|
||||||
|
if self.rect.collidepoint(pygame.mouse.get_pos()):
|
||||||
|
if pygame.mouse.get_pressed()[0] == 1 and self.clicked == False:
|
||||||
|
self.clicked = True
|
||||||
|
if pygame.mouse.get_pressed()[0] == 0 and self.clicked == True:
|
||||||
|
self.clicked = False
|
||||||
|
action = True
|
||||||
|
# Draw Button
|
||||||
|
screen.blit(self.image, self.rect)
|
||||||
|
# Return Action
|
||||||
|
return action
|
@ -0,0 +1,189 @@
|
|||||||
|
# Imports
|
||||||
|
import pygame, time, random
|
||||||
|
|
||||||
|
# Animate X
|
||||||
|
def animate_X(screen, cell_x, cell_y):
|
||||||
|
# Position
|
||||||
|
cell_x *= 100
|
||||||
|
cell_y *= 100
|
||||||
|
# Animation
|
||||||
|
for i in range(35):
|
||||||
|
pygame.draw.line(screen, (255, 100, 100), (cell_x + 50 - i, cell_y + 50 - i), (cell_x + 50 + i, cell_y + 50 + i), 6)
|
||||||
|
pygame.draw.line(screen, (255, 100, 100), (cell_x + 50 - i, cell_y + 50 + i), (cell_x + 50 + i, cell_y + 50 - i), 6)
|
||||||
|
pygame.display.update()
|
||||||
|
time.sleep(0.006)
|
||||||
|
|
||||||
|
# Animate 0
|
||||||
|
def animate_0(screen, cell_x, cell_y):
|
||||||
|
# Position
|
||||||
|
cell_x *= 100
|
||||||
|
cell_y *= 100
|
||||||
|
# Animation
|
||||||
|
for i in range(39):
|
||||||
|
pygame.draw.circle(screen, (100, 100, 255), (cell_x + 50, cell_y + 50), i)
|
||||||
|
if i > 6:
|
||||||
|
pygame.draw.circle(screen, (255, 255, 200), (cell_x + 50, cell_y + 50), i - 6)
|
||||||
|
pygame.display.update()
|
||||||
|
time.sleep(0.006)
|
||||||
|
|
||||||
|
# Draw Board
|
||||||
|
def draw_board(screen, board):
|
||||||
|
# Background Color
|
||||||
|
screen.fill((255, 255, 200))
|
||||||
|
# Grid
|
||||||
|
for i in range(1,3):
|
||||||
|
pygame.draw.line(screen, (0, 0, 0), (i * 100, 0), (i * 100, 300), 6)
|
||||||
|
pygame.draw.line(screen, (0, 0, 0), (0, i * 100), (300, i * 100), 6)
|
||||||
|
# Markers
|
||||||
|
row_count = 0
|
||||||
|
for y in board:
|
||||||
|
column_count = 0
|
||||||
|
for x in y:
|
||||||
|
row_count *= 100
|
||||||
|
column_count *= 100
|
||||||
|
if x == 1:
|
||||||
|
pygame.draw.line(screen, (255, 100, 100), (column_count + 15, row_count + 15), (column_count + 85, row_count + 85), 6)
|
||||||
|
pygame.draw.line(screen, (255, 100, 100), (column_count + 85, row_count + 15), (column_count + 15, row_count + 85), 6)
|
||||||
|
elif x == -1:
|
||||||
|
pygame.draw.circle(screen, (100, 100, 255), (column_count + 50, row_count + 50), 39)
|
||||||
|
pygame.draw.circle(screen, (255, 255, 200), (column_count + 50, row_count + 50), 33)
|
||||||
|
row_count /= 100
|
||||||
|
column_count /= 100
|
||||||
|
column_count += 1
|
||||||
|
row_count += 1
|
||||||
|
|
||||||
|
# Check Winner
|
||||||
|
def check_winner(board):
|
||||||
|
# Winner
|
||||||
|
winner = None
|
||||||
|
# Check Draw
|
||||||
|
found_zero = True
|
||||||
|
for column in board:
|
||||||
|
for row in column:
|
||||||
|
if row == 0:
|
||||||
|
found_zero = False
|
||||||
|
if found_zero:
|
||||||
|
winner = 0
|
||||||
|
# Check Rows
|
||||||
|
if winner == None or winner == 0:
|
||||||
|
for row in board:
|
||||||
|
row_sum = 0
|
||||||
|
for column in row:
|
||||||
|
row_sum += column
|
||||||
|
if row_sum == 3:
|
||||||
|
winner = 1
|
||||||
|
break
|
||||||
|
elif row_sum == -3:
|
||||||
|
winner = -1
|
||||||
|
break
|
||||||
|
# Check Columns
|
||||||
|
if winner == None or winner == 0:
|
||||||
|
for column in range(3):
|
||||||
|
column_sum = 0
|
||||||
|
for y in board:
|
||||||
|
column_sum += y[column]
|
||||||
|
if column_sum == 3:
|
||||||
|
winner = 1
|
||||||
|
break
|
||||||
|
elif column_sum == -3:
|
||||||
|
winner = -1
|
||||||
|
break
|
||||||
|
# Check Diagonals
|
||||||
|
if winner == None or winner == 0:
|
||||||
|
diagonal_sum = 0
|
||||||
|
for i in range(3):
|
||||||
|
diagonal_sum += board[i][i]
|
||||||
|
if diagonal_sum == 3:
|
||||||
|
winner = 1
|
||||||
|
elif diagonal_sum == -3:
|
||||||
|
winner = -1
|
||||||
|
if winner == None or winner == 0:
|
||||||
|
diagonal_sum = 0
|
||||||
|
for i in range(3):
|
||||||
|
row = 2 - i
|
||||||
|
column = i
|
||||||
|
diagonal_sum += board[row][column]
|
||||||
|
if diagonal_sum == 3:
|
||||||
|
winner = 1
|
||||||
|
elif diagonal_sum == -3:
|
||||||
|
winner = -1
|
||||||
|
return winner
|
||||||
|
|
||||||
|
# AI Move
|
||||||
|
def ai_move(board):
|
||||||
|
# Move Loop
|
||||||
|
while True:
|
||||||
|
# Block Rows
|
||||||
|
for row_counter, row in enumerate(board):
|
||||||
|
player_one = 0
|
||||||
|
player_two = 0
|
||||||
|
empty_space = None
|
||||||
|
for column_counter, column in enumerate(row):
|
||||||
|
if column == 1:
|
||||||
|
player_one += 1
|
||||||
|
if column == -1:
|
||||||
|
player_two += 1
|
||||||
|
if column == 0:
|
||||||
|
empty_space = [row_counter, column_counter]
|
||||||
|
if player_one == 2 or player_two == 2:
|
||||||
|
if empty_space != None:
|
||||||
|
return empty_space[0], empty_space[1]
|
||||||
|
# Block Columns
|
||||||
|
for column in range(3):
|
||||||
|
player_one = 0
|
||||||
|
player_two = 0
|
||||||
|
empty_space = None
|
||||||
|
for row in range(3):
|
||||||
|
if board[row][column] == 1:
|
||||||
|
player_one += 1
|
||||||
|
if board[row][column] == -1:
|
||||||
|
player_two += 1
|
||||||
|
if board[row][column] == 0:
|
||||||
|
empty_space = [row, column]
|
||||||
|
if player_one == 2 or player_one == 2:
|
||||||
|
if empty_space != None:
|
||||||
|
return empty_space[0], empty_space[1]
|
||||||
|
# Block Diagonals
|
||||||
|
player_one = 0
|
||||||
|
player_two = 0
|
||||||
|
empty_space = None
|
||||||
|
for i in range(3):
|
||||||
|
if board[i][i] == 1:
|
||||||
|
player_one += 1
|
||||||
|
if board[i][i] == -1:
|
||||||
|
player_two += 1
|
||||||
|
if board[i][i] == 0:
|
||||||
|
empty_space = [i, i]
|
||||||
|
if player_one == 2 or player_two == 2:
|
||||||
|
if empty_space != None:
|
||||||
|
return empty_space[0], empty_space[1]
|
||||||
|
player_one = 0
|
||||||
|
player_two = 0
|
||||||
|
empty_space = None
|
||||||
|
if board[0][2] == 1:
|
||||||
|
player_one += 1
|
||||||
|
if board[0][2] == -1:
|
||||||
|
player_two += 1
|
||||||
|
if board[0][2] == 0:
|
||||||
|
empty_space = [0, 2]
|
||||||
|
if board[1][1] == 1:
|
||||||
|
player_one += 1
|
||||||
|
if board[1][1] == -1:
|
||||||
|
player_two += 1
|
||||||
|
if board[1][1] == 0:
|
||||||
|
empty_space = [0, 0]
|
||||||
|
if board[2][0] == 1:
|
||||||
|
player_one += 1
|
||||||
|
if board[2][0] == -1:
|
||||||
|
player_two += 1
|
||||||
|
if board[2][0] == 0:
|
||||||
|
empty_space = [2, 0]
|
||||||
|
if player_one == 2 or player_two == 2:
|
||||||
|
if empty_space != None:
|
||||||
|
return empty_space[0], empty_space[1]
|
||||||
|
# Random
|
||||||
|
while True:
|
||||||
|
row = random.randint(0, 2)
|
||||||
|
column = random.randint(0, 2)
|
||||||
|
if board[row][column] == 0:
|
||||||
|
return row, column
|
@ -0,0 +1,235 @@
|
|||||||
|
# Imports
|
||||||
|
import pygame, random
|
||||||
|
from button import Button
|
||||||
|
from game_functions import animate_X, animate_0, draw_board, check_winner, ai_move
|
||||||
|
|
||||||
|
# Setup
|
||||||
|
pygame.init()
|
||||||
|
screen = pygame.display.set_mode((300, 300))
|
||||||
|
pygame.display.set_caption("TicTacToe")
|
||||||
|
clock = pygame.time.Clock()
|
||||||
|
pygame.font.init()
|
||||||
|
font = pygame.font.Font("./assets/font.ttf", 70)
|
||||||
|
|
||||||
|
# Buttons
|
||||||
|
button_human = Button(pygame.image.load("./assets/vshuman.png"), 50, 135)
|
||||||
|
button_ai = Button(pygame.image.load("./assets/vsai.png"), 50, 185)
|
||||||
|
button_menu = Button(pygame.image.load("./assets/menu.png"), 50, 135)
|
||||||
|
button_restart = Button(pygame.image.load("./assets/restart.png"), 50, 185)
|
||||||
|
|
||||||
|
# Title Screen
|
||||||
|
def screen_title():
|
||||||
|
# Game Loop
|
||||||
|
counter = 0
|
||||||
|
run = True
|
||||||
|
while run:
|
||||||
|
# Tick
|
||||||
|
clock.tick(30)
|
||||||
|
# Event Handler
|
||||||
|
for event in pygame.event.get():
|
||||||
|
# Quit
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
exit()
|
||||||
|
counter += 1
|
||||||
|
if counter == 120:
|
||||||
|
run = False
|
||||||
|
# Display Title Screen
|
||||||
|
if run:
|
||||||
|
screen.fill((255, 255, 200))
|
||||||
|
text = font.render("Tic", 1, (255, 100, 100))
|
||||||
|
screen.blit(text, (25, 15))
|
||||||
|
text = font.render("Tac", 1, (0, 0, 0))
|
||||||
|
screen.blit(text, (95, 15))
|
||||||
|
text = font.render("Toe", 1, (100, 100, 255))
|
||||||
|
screen.blit(text, (180, 15))
|
||||||
|
text = font.render("by", 1, (0, 0, 0))
|
||||||
|
screen.blit(text, (120, 107))
|
||||||
|
text = font.render("Tylan", 1, (255, 100, 100))
|
||||||
|
screen.blit(text, (5, 210))
|
||||||
|
text = font.render("Tyson", 1, (100, 100, 255))
|
||||||
|
screen.blit(text, (140, 210))
|
||||||
|
# Update Display
|
||||||
|
pygame.display.update()
|
||||||
|
|
||||||
|
# Menu Screen
|
||||||
|
def screen_menu():
|
||||||
|
# Game Loop
|
||||||
|
option = None
|
||||||
|
run = True
|
||||||
|
while run:
|
||||||
|
# Tick
|
||||||
|
clock.tick(30)
|
||||||
|
# Event Handler
|
||||||
|
for event in pygame.event.get():
|
||||||
|
# Quit
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
exit()
|
||||||
|
# Display Title
|
||||||
|
screen.fill((255, 255, 200))
|
||||||
|
text = font.render("Tic", 1, (255, 100, 100))
|
||||||
|
screen.blit(text, (25, 15))
|
||||||
|
text = font.render("Tac", 1, (0, 0, 0))
|
||||||
|
screen.blit(text, (95, 15))
|
||||||
|
text = font.render("Toe", 1, (100, 100, 255))
|
||||||
|
screen.blit(text, (180, 15))
|
||||||
|
# Buttons
|
||||||
|
if button_human.draw(screen):
|
||||||
|
option = "human"
|
||||||
|
run = False
|
||||||
|
if button_ai.draw(screen):
|
||||||
|
option = "ai"
|
||||||
|
run = False
|
||||||
|
# Update Display
|
||||||
|
pygame.display.update()
|
||||||
|
# Return Option
|
||||||
|
return option
|
||||||
|
|
||||||
|
# Winner Screen
|
||||||
|
def screen_winner(winner, restart_option):
|
||||||
|
# Game Loop
|
||||||
|
option = None
|
||||||
|
run = True
|
||||||
|
while run:
|
||||||
|
# Tick
|
||||||
|
clock.tick(30)
|
||||||
|
# Event Handler
|
||||||
|
for event in pygame.event.get():
|
||||||
|
# Quit
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
pygame.quit()
|
||||||
|
exit()
|
||||||
|
# Display Title
|
||||||
|
screen.fill((255, 255, 200))
|
||||||
|
if winner == 0:
|
||||||
|
text = font.render("Draw!", 1, (0, 0, 0))
|
||||||
|
screen.blit(text, (75, 15))
|
||||||
|
if winner == 1:
|
||||||
|
text = font.render("X Won!", 1, (255, 100, 100))
|
||||||
|
screen.blit(text, (60, 15))
|
||||||
|
if winner == -1:
|
||||||
|
text = font.render("0 Won!", 1, (100, 100, 255))
|
||||||
|
screen.blit(text, (60, 15))
|
||||||
|
# Buttons
|
||||||
|
if button_menu.draw(screen):
|
||||||
|
option = None
|
||||||
|
run = False
|
||||||
|
if button_restart.draw(screen):
|
||||||
|
option = restart_option
|
||||||
|
run = False
|
||||||
|
# Update Display
|
||||||
|
pygame.display.update()
|
||||||
|
# Return Option
|
||||||
|
return option
|
||||||
|
|
||||||
|
# Title Screen
|
||||||
|
screen_title()
|
||||||
|
|
||||||
|
# Game Loop
|
||||||
|
option = None
|
||||||
|
human_first_run = True
|
||||||
|
ai_first_run = True
|
||||||
|
run = True
|
||||||
|
while run:
|
||||||
|
# Tick
|
||||||
|
clock.tick(30)
|
||||||
|
# Menu
|
||||||
|
if option == None:
|
||||||
|
option = screen_menu()
|
||||||
|
# VS Human
|
||||||
|
if option == "human":
|
||||||
|
if human_first_run:
|
||||||
|
start = random.randint(1, 2)
|
||||||
|
if start == 1:
|
||||||
|
player = 1
|
||||||
|
else:
|
||||||
|
player = -1
|
||||||
|
mouse_position = None
|
||||||
|
clicked = False
|
||||||
|
human_first_run = False
|
||||||
|
board = [
|
||||||
|
[0, 0, 0],
|
||||||
|
[0, 0, 0],
|
||||||
|
[0, 0, 0]
|
||||||
|
]
|
||||||
|
draw_board(screen, board)
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN and clicked == False:
|
||||||
|
clicked = True
|
||||||
|
if event.type == pygame.MOUSEBUTTONUP and clicked == True:
|
||||||
|
clicked = False
|
||||||
|
mouse_position = pygame.mouse.get_pos()
|
||||||
|
cell_x = mouse_position[0]
|
||||||
|
cell_y = mouse_position[1]
|
||||||
|
if board[cell_y // 100][cell_x // 100] == 0:
|
||||||
|
board[cell_y // 100][cell_x // 100] = player
|
||||||
|
if player == 1:
|
||||||
|
animate_X(screen, cell_x // 100, cell_y // 100)
|
||||||
|
elif player == -1:
|
||||||
|
animate_0(screen, cell_x // 100, cell_y // 100)
|
||||||
|
player *= - 1
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
run = False
|
||||||
|
winner = check_winner(board)
|
||||||
|
if winner != None:
|
||||||
|
human_first_run = True
|
||||||
|
option = screen_winner(winner, "human")
|
||||||
|
pygame.display.update()
|
||||||
|
# VS AI
|
||||||
|
if option == "ai":
|
||||||
|
if ai_first_run:
|
||||||
|
start = random.randint(1, 2)
|
||||||
|
player = 1
|
||||||
|
mouse_position = None
|
||||||
|
clicked = False
|
||||||
|
ai_first_run = False
|
||||||
|
board = [
|
||||||
|
[0, 0, 0],
|
||||||
|
[0, 0, 0],
|
||||||
|
[0, 0, 0]
|
||||||
|
]
|
||||||
|
if start == 1:
|
||||||
|
draw_board(screen, board)
|
||||||
|
pygame.display.update()
|
||||||
|
row, column = ai_move(board)
|
||||||
|
board[row][column] = player
|
||||||
|
animate_X(screen, column, row)
|
||||||
|
player *= -1
|
||||||
|
start = 0
|
||||||
|
draw_board(screen, board)
|
||||||
|
for event in pygame.event.get():
|
||||||
|
if event.type == pygame.MOUSEBUTTONDOWN and clicked == False:
|
||||||
|
clicked = True
|
||||||
|
if event.type == pygame.MOUSEBUTTONUP and clicked == True:
|
||||||
|
clicked = False
|
||||||
|
mouse_position = pygame.mouse.get_pos()
|
||||||
|
mouse_position = pygame.mouse.get_pos()
|
||||||
|
cell_x = mouse_position[0]
|
||||||
|
cell_y = mouse_position[1]
|
||||||
|
if board[cell_y // 100][cell_x // 100] == 0:
|
||||||
|
board[cell_y // 100][cell_x // 100] = player
|
||||||
|
if player == 1:
|
||||||
|
animate_X(screen, cell_x // 100, cell_y // 100)
|
||||||
|
elif player == -1:
|
||||||
|
animate_0(screen, cell_x // 100, cell_y // 100)
|
||||||
|
player *= - 1
|
||||||
|
winner = check_winner(board)
|
||||||
|
if winner == None:
|
||||||
|
row, column = ai_move(board)
|
||||||
|
board[row][column] = player
|
||||||
|
if player == 1:
|
||||||
|
animate_X(screen, column, row)
|
||||||
|
elif player == -1:
|
||||||
|
animate_0(screen, column, row)
|
||||||
|
player *= -1
|
||||||
|
if event.type == pygame.QUIT:
|
||||||
|
run = False
|
||||||
|
winner = check_winner(board)
|
||||||
|
if winner != None:
|
||||||
|
ai_first_run = True
|
||||||
|
option = screen_winner(winner, "ai")
|
||||||
|
pygame.display.update()
|
||||||
|
|
||||||
|
# Quit Pygame
|
||||||
|
pygame.quit()
|
@ -0,0 +1 @@
|
|||||||
|
pygame==2.3.0
|
Loading…
Reference in New Issue