Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
pygame tic tac toe
#1
I found a pygame tic tac toe on the web and applied it to classes (mvc). It does not yet have the win functions (draws a line for winner) as the original code does. The original code doesn't have a computer player. I am going to attempt to add one. As of now it's just player clicks
for both x and o. Winner or tie is printed in console. Anyhow here is the code.

Updated the code to add lines. I don't really like drawing the lines in the model and I'm sure the code can be optimized much more.

import pygame, numpy as np, math, sys

class Model:
    def __init__(self):
        self.board = np.zeros((3, 3))

    def marksquare(self, row, col, player):
        self.board[row][col] = player

    def open_square(self, row, col):
        is_open = self.board[row][col] == 0
        return is_open

    def vertical_win(self, player):
        for col in range(3):
            if self.board[0][col] == self.board[1][col] == self.board[2][col] == player:
                self.draw_vline(player, col)
                return True
        return False

    def horizontal_win(self, player):
        for row in range(3):
            if self.board[row][0] == self.board[row][1] ==  self.board[row][2] == player:
                self.draw_hline(player, row)
                return True
        return False

    def diagonal_win(self, player):
        if self.board[0][0] == player and self.board[1][1] == player and self.board[2][2] == player:
            self.draw_diag(player)
            return True
        elif self.board[0][2] == player and self.board[1][1] == player and self.board[2][0] == player:
            self.draw_diag(player, False)
            return True
        else:
            return False

    def win(self, player):
        vertwin = self.vertical_win(player)
        horzwin = self.horizontal_win(player)
        diagwin = self.diagonal_win(player)

        if vertwin or horzwin or diagwin:
            return True
        else:
            return False

    def fullboard(self):
        for col in range(3):
            for row in range(3):
                if self.board[row][col] == 0:
                    return False
        return True

    def draw_vline(self, player, col):
        posx = col * 200 + 100
        if player == 1:
            pygame.draw.line(View().screen, (150,0,200), (posx, 10), (posx, 590), 15)
        else:
            pygame.draw.line(View().screen, (255,0,0), (posx, 10), (posx, 590), 15)

    def draw_hline(self, player, row):
        posy = row * 200 + 100
        if player == 1:
            pygame.draw.line(View().screen, (150,0,200), (10, posy), (590, posy), 15)
        else:
            pygame.draw.line(View().screen, (255,0,0), (10, posy), (590, posy), 15)

    def draw_diag(self, player, down=True):
        if down:
            if player == 1:
                pygame.draw.line(View().screen, (150,0,200), (25, 25), (575, 575), 15)
            else:
                pygame.draw.line(View().screen, (255,0,0), (25, 25), (575, 575), 15)
        else:
            if player == 1:
                pygame.draw.line(View().screen, (150,0,200), (25, 575), (575, 25), 15)
            else:
                pygame.draw.line(View().screen, (255,0,0), (25, 575), (575, 25), 15)

class View:
    def __init__(self):
        bgcolor = (200, 200, 200)
        line = (0, 0, 0)
        self.square_size = 200
        self.screen_width = 3 * self.square_size
        self.screen_height = 3 * self.square_size
        self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))
        self.screen.fill(bgcolor)
        pygame.draw.line(self.screen, line, (0, 200), (600, 200), 10)
        pygame.draw.line(self.screen, line, (0, 400), (600, 400), 10)
        pygame.draw.line(self.screen, line, (200, 0), (200, 600), 10)
        pygame.draw.line(self.screen, line, (400, 0), (400, 600), 10)


class Controller:
    def __init__(self, model, view):
        self.model = model
        self.view = view

    def figure(self):
        for col in range(3):
            for row in range(3):
                if self.model.board[row][col] == 1:
                    pygame.draw.circle(self.view.screen, (150, 0, 200),
                                       (int(col * self.view.square_size + self.view.square_size / 2),
                                        int(row * self.view.square_size + self.view.square_size / 2)),
                                       60, 15)
                elif self.model.board[row][col] == 2:
                    pygame.draw.line(self.view.screen, (255,0,0),
                                     (col * self.view.square_size + 55, row * self.view.square_size + 55),
                                     (col * self.view.square_size + self.view.square_size - 55, row *self.view.square_size + self.view.square_size - 55), 25)
                    pygame.draw.line(self.view.screen, (255,0,0),
                                     (col * self.view.square_size + 55, row * self.view.square_size + self.view.square_size - 55),
                                     (col * self.view.square_size + self.view.square_size - 55, row * self.view.square_size + 55), 25)

if __name__ == '__main__':
    pygame.init()
    controller = Controller(Model(), View())
    gameover = False
    player = 0
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()

            if event.type == pygame.MOUSEBUTTONDOWN and not gameover:
                positiony = event.pos[1]
                positionx = event.pos[0]
                row = int(math.floor(positiony / controller.view.square_size))
                col = int(math.floor(positionx / controller.view.square_size))

                if player % 2 == 0:
                    if controller.model.open_square(row, col):
                        controller.model.marksquare(row, col, 1)
                        if controller.model.win(1):
                            print('O wins')
                            gameover = True
                        player = 1
                else:
                    if controller.model.open_square(row, col):
                        controller.model.marksquare(row, col, 2)
                        if controller.model.win(2):
                            print('X wins')
                            gameover = True
                        player = 2

                if controller.model.fullboard():
                    print('tie game')
                    gameover = True

        controller.figure()
        pygame.display.update()
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply
#2
This question is already posted in the general forum
https://python-forum.io/thread-37358-pos...#pid157880
Yoriz write May-31-2022, 05:27 PM:
The spammer above has been purged.
I welcome all feedback.
The only dumb question, is one that doesn't get asked.
My Github
How to post code using bbtags


Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020