Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
disc_drop_1 = join("sounds", "disc_drop_1.wav")
disc_drop_2 = join("sounds", "disc_drop_2.wav")
red_coin = load(join("images", "redball90px.png"))
board_pattern = load(join("images", "board1_100px.png"))
yellow_coin = load(join("images", "yellowball90px.png"))
black_coin = load(join("images", "blackball91px.png"))
10 changes: 7 additions & 3 deletions connect_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def mouse_click(self, event: MouseClickEvent):
if self.game_data.game_board.is_valid_location(col):
row: int = self.game_data.game_board.get_next_open_row(col)

self.renderer.drop_piece(row, col, self.game_data.turn + 1)

self.game_data.last_move_row.append(row)
self.game_data.last_move_col.append(col)
self.game_data.game_board.drop_piece(row, col, self.game_data.turn + 1)
Expand All @@ -69,10 +71,10 @@ def mouse_click(self, event: MouseClickEvent):
self.game_data.game_over = True

pygame.display.update()

self.game_data.turn += 1
self.game_data.turn = self.game_data.turn % 2

@bus.on("game:undo")
def undo(self):
"""
Expand All @@ -89,6 +91,8 @@ def undo(self):

self.game_data.turn += 1
self.game_data.turn = self.game_data.turn % 2
pygame.draw.rect(self.renderer.screen, black, (0, 0, self.game_data.width, self.game_data.sq_size))
self.renderer.draw_coin(self.renderer.game_data, self.renderer.game_data.posx - self.game_data.radius, self.game_data.margin)

def update(self):
"""
Expand All @@ -114,4 +118,4 @@ def print_board(self):
"""
Prints the state of the board to the console.
"""
self.game_data.game_board.print_board()
self.game_data.game_board.print_board()
9 changes: 4 additions & 5 deletions game_board.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ def print_board(self):
"""
Prints the state of the board to the console.
"""
print(flip(self.board, 0))
print(" ---------------------")
print(" " + str([1, 2, 3, 4, 5, 6, 7]))
#print(flip(self.board, 0))
#print(" " + "---"*self.cols)
#print(" " + str([i+1 for i in range(self.cols)]))

def drop_piece(self, row, col, piece):
"""
Expand Down Expand Up @@ -61,7 +61,6 @@ def check_square(self, piece, r, c):
"""
Checks if a particular square is a certain color. If
the space is off of the board it returns False.

:param piece: The piece color to look for.
:param r: The row to check.
:param c: The column to check.
Expand Down Expand Up @@ -153,4 +152,4 @@ def tie_move(self):
if self.board[r][c] != 0:
slots_filled += 1

return slots_filled == 42
return slots_filled == self.rows*self.cols
20 changes: 16 additions & 4 deletions game_data.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from typing import Tuple

from game_board import GameBoard
import pyautogui #For getting screen size


class GameData:
Expand All @@ -12,8 +13,12 @@ class GameData:
height: int
width: int
sq_size: int
font_size: int
character_width: int
margin: int
size: Tuple[int, int]
game_over: bool
posx: int
turn: int
last_move_row: [int]
last_move_col: [int]
Expand All @@ -27,8 +32,15 @@ def __init__(self):
self.game_board = GameBoard()
self.action = None

self.sq_size: int = 100
self.width: int = 7 * self.sq_size
self.height: int = 7 * self.sq_size
SCREEN_WIDTH, SCREEN_HEIGHT = pyautogui.size() #Resolution of the screen

self.height: int = (SCREEN_HEIGHT*7)//10
self.width: int = (SCREEN_WIDTH*8)//10
self.sq_size: int = min(self.height//(self.game_board.rows), self.width//(self.game_board.cols), 100)
self.font_size = int(self.sq_size*0.8)
self.character_width = self.font_size*3//5
self.margin: int = self.sq_size//20
self.height: int = self.sq_size * (self.game_board.rows) + self.sq_size
self.width: int = self.sq_size * self.game_board.cols
self.size: Tuple[int, int] = (self.width, self.height)
self.radius: int = int(self.sq_size / 2 - 5)
self.radius: int = int(self.sq_size / 2 - self.margin)
173 changes: 101 additions & 72 deletions game_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,21 @@
from typing import Any, Optional, Union

import pygame
import time
from pygame import mixer
from pygame.font import FontType
from pygame.ftfont import Font
from pygame.gfxdraw import aacircle, filled_circle

from assets import (black_coin, disc_drop_1, disc_drop_2, event_sound,
red_coin, yellow_coin)
from assets import (
black_coin,
board_pattern,
disc_drop_1,
disc_drop_2,
event_sound,
red_coin,
yellow_coin,
)
from config import black, blue, red, white, yellow
from events import GameOver, MouseHoverEvent, PieceDropEvent, bus
from game_data import GameData
Expand Down Expand Up @@ -44,11 +52,14 @@ def __init__(self, screen, game_data: GameData):
:param screen: The screen.
:param game_data: All of the data for the game.
"""
self.myfont = pygame.font.SysFont("monospace", 75)
self.label = self.myfont.render("CONNECT FOUR!!", 1, white)
screen.blit(self.label, (40, 10))
self.screen = screen
self.game_data = game_data
self.screen = screen

self.myfont = pygame.font.SysFont("monospace", self.game_data.font_size)
message = "CONNECT FOUR!"
self.label = self.myfont.render(message, 1, white)
self.screen.blit(self.label, ((self.game_data.width - len(message)*self.game_data.character_width)//2,
self.game_data.margin))

pygame.display.set_caption("Connect Four | Mayank Singh")
pygame.display.update()
Expand All @@ -60,14 +71,14 @@ def on_mouse_move(self, event: MouseHoverEvent):
:param event: Information about the hover, namely the x position
"""
posx = event.posx
self.game_data.posx = event.posx

pygame.draw.rect(
self.screen, black, (0, 0, self.game_data.width, self.game_data.sq_size)
)
self.draw_coin(
self.game_data,
posx - (self.game_data.sq_size / 2),
int(self.game_data.sq_size) - self.game_data.sq_size + 5,
posx - self.game_data.radius, self.game_data.margin,
)

def draw_red_coin(self, x, y):
Expand All @@ -76,15 +87,19 @@ def draw_red_coin(self, x, y):
:param x: The x position to draw the coin.
:param y: The y position to draw the coin.
"""
self.screen.blit(red_coin, (x, y))
radius = self.game_data.radius
sq_size = self.game_data.sq_size
self.screen.blit(pygame.transform.scale(red_coin, (2*radius, 2*radius)), (x, y))

def draw_yellow_coin(self, x, y):
"""
Draws a yellow coin.
:param x: The x position to draw the coin.
:param y: The y position to draw the coin.
"""
self.screen.blit(yellow_coin, (x, y))
radius = self.game_data.radius
sq_size = self.game_data.sq_size
self.screen.blit(pygame.transform.scale(yellow_coin, (2*radius, 2*radius)), (x, y))

def draw_black_coin(self, x, y):
"""
Expand All @@ -104,46 +119,20 @@ def draw_coin(self, game_data, x, y):
:param y: The y position for the coin to be drawn.
"""
if game_data.turn == 0:
self.screen.blit(red_coin, (x, y))
radius = game_data.radius
sq_size = game_data.sq_size
self.screen.blit(pygame.transform.scale(red_coin, (2*radius, 2*radius)), (x, y))
else:
self.screen.blit(yellow_coin, (x, y))
radius = game_data.radius
sq_size = game_data.sq_size
self.screen.blit(pygame.transform.scale(yellow_coin, (2*radius, 2*radius)), (x, y))

def draw(self, game_data: GameData):
"""
Draws the game state, including the board and the pieces.
:param game_data: All of the data associated with the game.
"""
if game_data.action == "undo":
filled_circle(
self.screen,
game_data.last_move_row,
game_data.last_move_col,
self.game_data.radius,
black,
)

aacircle(
self.screen,
game_data.last_move_row,
game_data.last_move_col,
self.game_data.radius,
black,
)

self.draw_black_coin(
game_data.last_move_col * self.game_data.sq_size + 5,
self.game_data.height
- (
game_data.last_move_row * self.game_data.sq_size
+ self.game_data.sq_size
- 5
),
)

game_data.game_board.print_board()
game_data.action = None

self.draw_board(game_data.game_board)
self.draw_board(game_data)

@bus.on("game:over")
def on_game_over(self, event: GameOver):
Expand All @@ -159,59 +148,99 @@ def on_game_over(self, event: GameOver):
color = yellow

if not event.was_tie:
self.label = self.myfont.render(f"PLAYER {event.winner} WINS!", 1, color)
self.screen.blit(self.label, (40, 10))
message = f"PLAYER {event.winner} WINS!"
self.label = self.myfont.render(message, 1, color)
self.screen.blit(self.label, ((self.game_data.width - len(message)*self.game_data.character_width)//2,
self.game_data.margin))

mixer.music.load(event_sound)
mixer.music.play(0)
else:
message = "GAME DRAW!"
self.label = self.myfont.render(message, 1, white)
self.screen.blit(self.label, ((self.game_data.width - len(message)*self.game_data.character_width)//2,
self.game_data.margin))

mixer.music.load(os.path.join("sounds", "event.ogg"))
mixer.music.play(0)
self.myfont = pygame.font.SysFont("monospace", 75)
self.label = self.myfont.render("GAME DRAW !!!!", 1, white)
self.screen.blit(self.label, (40, 10))

def draw_board(self, board):
def drop_piece(self, row, col, turn):
"""
Draws the game board to the screen.
:param board: The game board.
Animates the falling piece
:param row: The row in which the piece will land
:param col: The column in which the piece will fall
:param turn: Which player's coin fell
"""
sq_size = 100
height = 700
radius = int(sq_size / 2 - 5)
sq_size = self.game_data.sq_size
radius = self.game_data.radius

for c in range(board.cols):
for r in range(board.rows):
y = 0
acc = self.game_data.height*8
y_max = 0 + self.game_data.game_board.rows*sq_size - (row)*sq_size
delta_t = 0.005

t = 0
while(t<10):
t += delta_t
y = 0.5*acc*(t**2)
if(y>=y_max):
pygame.draw.rect(
self.screen,
blue,
(c * sq_size, (r + 1) * sq_size, sq_size, sq_size),
)
aacircle(
self.screen,
int(c * sq_size + sq_size / 2),
int((r + 1) * sq_size + sq_size / 2),
radius,
black,
(0,0, self.game_data.width, sq_size)
)
filled_circle(
self.screen,
int(c * sq_size + sq_size / 2),
int((r + 1) * sq_size + sq_size / 2),
radius,
black,
break
time.sleep(delta_t)
pygame.draw.rect(
self.screen,
black,
(col*sq_size, 0, sq_size, self.game_data.game_board.rows*sq_size - (row)*sq_size)
)
if turn==1:
self.draw_red_coin(
int(col * sq_size) + self.game_data.margin, int(y)
)

elif turn==2:
self.draw_yellow_coin(
int(col * sq_size) + self.game_data.margin, int(y)
)

for r in range(self.game_data.game_board.rows - row):
self.screen.blit(pygame.transform.scale(board_pattern, (sq_size, sq_size)), (col*sq_size, (r+1)*sq_size))
pygame.display.update()

def draw_board(self, data):
"""
Draws the game board to the screen.
:param data: All data associated with the game.
"""

board = data.game_board

sq_size = data.sq_size
height = data.height
radius = data.radius

pygame.draw.rect(
self.screen,
black,
(0, sq_size, self.game_data.width, self.game_data.height)
)
for c in range(board.cols):
for r in range(board.rows):
self.screen.blit(pygame.transform.scale(board_pattern, (sq_size, sq_size)), (c*sq_size, (r+1)*sq_size))

for c in range(board.cols):
for r in range(board.rows):
if board.board[r][c] == 1:
self.draw_red_coin(
int(c * sq_size) + 5, height - int(r * sq_size + sq_size - 5)
int(c * sq_size) + self.game_data.margin, height - int(r * sq_size + sq_size - self.game_data.margin)
)

elif board.board[r][c] == 2:
self.draw_yellow_coin(
int(c * sq_size) + 5, height - int(r * sq_size + sq_size - 5)
int(c * sq_size) + self.game_data.margin, height - int(r * sq_size + sq_size - self.game_data.margin)
)

pygame.display.update()
Binary file added images/board1_100px.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pygame
numpy
event-bus
event-bus
pyautogui