Untitled
unknown
plain_text
3 years ago
7.7 kB
5
Indexable
from tkinter import * #Declare all my parameters as global variables WINDOW_SIZE = 600 GRID_LINE_WIDTH = 2 SYMBOL_WIDTH = WINDOW_SIZE / 12 SYMBOL_SIZE = 0.5 CELL_SIZE = WINDOW_SIZE / 3 #Prettification of our app X_COLOR = 'dodger blue' O_COLOR = 'tomato' DRAW_SCREEN_COLOR = 'light sea green' GRID_COLOR = 'light grey' BG_COLOR = 'white' #Keep track of game states STATE_TITLE_SCREEN = 0 STATE_X_TURN = 1 STATE_O_TURN = 2 STATE_GAME_OVER = 3 FIRST_PLAYER = 2 EMPTY = 0 X = 1 O = 2 class Game(Tk): def __init__(self): Tk.__init__(self) self.canvas = Canvas( height=WINDOW_SIZE, width=WINDOW_SIZE, bg=BG_COLOR) self.canvas.pack() self.bind('<x>', self.exit) self.canvas.bind('<Button-1>', self.click) self.gamestate = STATE_TITLE_SCREEN self.title_screen() self.board = [ [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] def title_screen(self): # placeholder title screen self.canvas.delete('all') #just in case self.canvas.create_rectangle( 0, 0, WINDOW_SIZE, WINDOW_SIZE, fill=O_COLOR, outline='') self.canvas.create_rectangle( int(WINDOW_SIZE/15), int(WINDOW_SIZE/15), int(WINDOW_SIZE*14/15), int(WINDOW_SIZE*14/15), width=int(WINDOW_SIZE/20), outline=X_COLOR) self.canvas.create_rectangle( int(WINDOW_SIZE/10), int(WINDOW_SIZE/10), int(WINDOW_SIZE*9/10), int(WINDOW_SIZE*9/10), fill=X_COLOR, outline='') self.canvas.create_text( WINDOW_SIZE/2, WINDOW_SIZE/3, text='TIC TAC TOE', fill='white', font=('Franklin Gothic', int(-WINDOW_SIZE/12), 'bold')) self.canvas.create_text( int(WINDOW_SIZE/2), int(WINDOW_SIZE/2.5), text='[PLAY]', fill='white', font=('Franklin Gothic', int(-WINDOW_SIZE/25))) def new_board(self): """ Clears canvas and game board memory, draws a new board on the canvas """ # delete all objects self.canvas.delete('all') # reset self.board = [ [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY], [EMPTY, EMPTY, EMPTY]] # draw grid for n in range(1, 3): # vertical self.canvas.create_line( CELL_SIZE*n, 0, CELL_SIZE*n, WINDOW_SIZE, width=GRID_LINE_WIDTH, fill=GRID_COLOR) # horizontal self.canvas.create_line( 0, CELL_SIZE*n, WINDOW_SIZE, CELL_SIZE*n, width=GRID_LINE_WIDTH, fill=GRID_COLOR) def gameover_screen(self, outcome): #placeholder gameover screen self.canvas.delete('all') if outcome == 'X WINS': wintext = 'X wins' wincolor = X_COLOR elif outcome == 'O WINS': wintext = 'O wins' wincolor = O_COLOR elif outcome == 'DRAW': wintext = 'Draw' wincolor = DRAW_SCREEN_COLOR self.canvas.create_rectangle( 0, 0, WINDOW_SIZE, WINDOW_SIZE, fill=wincolor, outline='') self.canvas.create_text( int(WINDOW_SIZE/2), int(WINDOW_SIZE/2), text=wintext, fill='white', font=('Franklin Gothic', int(-WINDOW_SIZE/6), 'bold')) self.canvas.create_text( int(WINDOW_SIZE/2), int(WINDOW_SIZE/1.65), text='[click to play again]', fill='white', font=('Franklin Gothic', int(-WINDOW_SIZE/25))) def click(self, event): """ Handles most of the game logic """ x = self.ptgrid(event.x) y = self.ptgrid(event.y) if self.gamestate == STATE_TITLE_SCREEN: self.new_board() self.gamestate = FIRST_PLAYER elif (self.gamestate == STATE_X_TURN and self.board[y][x] == EMPTY): self.new_move(X, x, y) if self.has_won(X): self.gamestate = STATE_GAME_OVER self.gameover_screen('X WINS') elif self.is_a_draw(): self.gamestate = STATE_GAME_OVER self.gameover_screen('DRAW') else: self.gamestate = STATE_O_TURN elif (self.gamestate == STATE_O_TURN and self.board[y][x] == EMPTY): self.new_move(O, x, y) if self.has_won(O): self.gamestate = STATE_GAME_OVER self.gameover_screen('O WINS') elif self.is_a_draw(): self.gamestate = STATE_GAME_OVER self.gameover_screen('DRAW') else: self.gamestate = STATE_X_TURN elif self.gamestate == STATE_GAME_OVER: #reset self.new_board() self.gamestate = FIRST_PLAYER def new_move(self, player, grid_x, grid_y): if player == X: self.draw_X(grid_x, grid_y) self.board[grid_y][grid_x] = X elif player == O: self.draw_O(grid_x, grid_y) self.board[grid_y][grid_x] = O def draw_X(self, grid_x, grid_y): """ draw the X symbol at x, y in the grid """ x = self.gtpix(grid_x) y = self.gtpix(grid_y) delta = CELL_SIZE/2*SYMBOL_SIZE self.canvas.create_line( x-delta, y-delta, x+delta, y+delta, width=SYMBOL_WIDTH, fill=X_COLOR) self.canvas.create_line( x+delta, y-delta, x-delta, y+delta, width=SYMBOL_WIDTH, fill=X_COLOR) def draw_O(self, grid_x, grid_y): """ draw an O symbol at x, y in the grid """ x = self.gtpix(grid_x) y = self.gtpix(grid_y) delta = CELL_SIZE/2*SYMBOL_SIZE self.canvas.create_oval( x-delta, y-delta, x+delta, y+delta, width=SYMBOL_WIDTH, outline=O_COLOR) def has_won(self, symbol): for y in range(3): if self.board[y] == [symbol, symbol, symbol]: return True for x in range(3): if self.board[0][x] == self.board[1][x] == self.board[2][x] == symbol: return True if self.board[0][0] == self.board[1][1] == self.board[2][2] == symbol: return True elif self.board[0][2] == self.board[1][1] == self.board[2][0] == symbol: return True # no win sequence found return False def is_a_draw(self): for row in self.board: if EMPTY in row: return False #no empty cell left, the game is a draw return True def gtpix(self, grid_coord): # gtpix = grid_to_pixels # for a grid coordinate, returns the pixel coordinate of the center # of the corresponding cell pixel_coord = grid_coord * CELL_SIZE + CELL_SIZE / 2 return pixel_coord def ptgrid(self, pixel_coord): # ptgrid = pixels_to_grid # the opposit of gtpix() # somehow the canvas has a few extra pixels on the right and bottom side if pixel_coord >= WINDOW_SIZE: pixel_coord = WINDOW_SIZE - 1 grid_coord = int(pixel_coord / CELL_SIZE) return grid_coord def exit(self, event): self.destroy() def main(): root = Game() root.mainloop() main() #https://paste.ofcode.org/ktkzkLRMLRwZ34MvPD5QCb
Editor is loading...