Академический Документы
Профессиональный Документы
Культура Документы
import pygame
import random
# User-defined functions
def main():
# initialize all pygame modules (some need initialization)
pygame.init()
# create a pygame display window
pygame.display.set_mode((500, 400))
# set the title of the display window
pygame.display.set_caption('Tic Tac Toe')
# get the display surface
w_surface = pygame.display.get_surface()
# create a game object
game = Game(w_surface)
# start the main game loop by calling the play method on the game object
game.play()
# quit pygame and clean up the pygame window
pygame.quit()
# User-defined classes
class Game:
# An object in this class represents a complete game.
# === objects that are part of every game that we will discuss
self.surface = surface
self.bg_color = pygame.Color('black')
self.FPS = 70
self.game_Clock = pygame.time.Clock()
self.close_clicked = False
self.continue_game = True
def play(self):
# Play the game until the player presses the close box.
# - self is the Game that should be continued or not.
def handle_events(self):
# Handle each user event by changing the game state appropriately.
# - self is the Game whose events will be handled
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
self.close_clicked = True
if event.type == pygame.MOUSEBUTTONUP and self.continue_game==True:
self.handle_mouse_up(event.pos) # event.pos is (x,y) coordinates
of the click
def handle_mouse_up(self,position):
# position is bound to whatever event.pos is bound to
for row in self.board:
for tile in row:
if tile.select(position,self.turn)==True: # select returns True
or False
self.filled.append(tile)
self.change_turn()
def change_turn(self):
if self.turn == self.player_1 : # Was it the X player's turn
self.turn = self.player_2 # Change turn to O plater
else:
self.turn = self.player_1
def draw(self):
# Draw all game objects.
# - self is the Game to draw
def update(self):
# Update the game objects for the next frame.
# - self is the Game to update
pass
def is_same(self,alist):
# - alist is the list of tiles [tile0,tile1,tile2]
# checks the values in the list
# return True is values are equal
# False otherwise
first = alist[0]
same = True
index = 1
while index < len(alist) and same == True:
same = first.is_equal(alist[index]) # 3 == 3, 1===2,
index = index + 1
if same == True:
self.flashers = alist
return same
def is_diagonal_win(self):
diagonal_win = False
diagonal1 = []
diagonal2 = []
for index in range(0,self.board_size):
item = self.board[index][index]
diagonal1.append(item)
item = self.board[index][self.board_size-index-1] #
3-0-1,3-1-1,3-2-1
diagonal2.append(item)
if self.is_same(diagonal1) == True or self.is_same(diagonal2) == True:
diagonal_win = True
return diagonal_win
def is_column_win(self):
column_win = False
for col_index in range(0,self.board_size):
column = []
for row_index in range(0,self.board_size):
item = self.board[row_index][col_index]
column.append(item)
#print(column) # replace
if self.is_same(column) == True:
column_win = True
return column_win
def is_row_win(self):
# return True or False
row_win = False
for row in self.board:
# row is a list of 3 tiles
if self.is_same(row) == True:
row_win = True
return row_win
def is_win(self):
if self.is_row_win() or self.is_column_win() or self.is_diagonal_win():
return True
else:
return False
def is_tie(self):
tie = False
if len(self.filled) == self.board_size**2:
tie = True
self.flashers = self.filled
return tie
def decide_continue(self):
# Check and remember if the game should continue
# - self is the Game to check
if self.is_win() or self.is_tie():
self.continue_game = False
class Tile:
# An object in this class represents a Tile
# Shared or Class Attributes
surface = None
font_size = 133
fg_color = pygame.Color('white')
border_width = 3
# Whenever we want to initialize or set the value if a class attribute
# we use a class method for it
@classmethod
def set_surface(cls,surface_from_Game):
cls.surface = surface_from_Game
def __init__(self, x,y,width,height):
# Initialize a Tile.
# - self is the Tile to initialize
# - x,y top left coordinates of the rectangle
# - - width, height are the dimensions of the rectangle
# Instance Attributes or Object Attributes
self.rect = pygame.Rect(x,y,width,height)
self.content = ''
self.flashing = False
def is_equal(self, other_tile):
# other_tile is referring to alist[index]
if self.content !='' and self.content == other_tile.content:
return True
else:
return False
def set_flashing(self):
self.flashing = True
def draw(self):
# Draw the dot on the surface
# - self is the Tile
if self.flashing == True:
# draw the white rectangle
pygame.draw.rect(Tile.surface, Tile.fg_color, self.rect,0)
self.flashing = False
else:
# draw the black rectangle with the white border and draw content
pygame.draw.rect(Tile.surface, Tile.fg_color,
self.rect,Tile.border_width)
self.draw_content()
def select(self,position,turn):
# position is a tuple (x,y) coordinates of the click
# turn is either X or O
# returns True or False
valid_click = False
if self.rect.collidepoint(position): # click
if self.content == '': # click inside an unoccupied tile?
self.content = turn
valid_click = True
else:
self.flashing = True
return valid_click
def draw_content(self):
# 5 steps to draw text on the graphical window
# 1. color- Tile.fg_color
# 2. create a font object
font = pygame.font.SysFont('',Tile.font_size)
# 3. Create a text box
text_box = font.render(self.content, True, Tile.fg_color)
text_box_width = text_box.get_width()
text_box_height = text_box.get_height()
# 4. Compute the location
d_x = (self.rect.width - text_box_width) //2
d_y = (self.rect.height - text_box_height)//2
x = self.rect.x + d_x
y = self.rect.y + d_y
location = (x,y)
#5 pin/blit the text_box on the surface
Tile.surface.blit(text_box,location)
main()