python - Pygame 井字游戏逻辑?我该怎么做

标签 python pygame tic-tac-toe

我正在尝试用 pygame 制作一个井字游戏,我想知道我将如何处理这里的逻辑,这是我目前所拥有的。视频 < 我只有当我点击中间按钮时它才会在屏幕上显示播放器 2 x 然后悬停在我鼠标上的图像将变成 O 以便播放器 1 转 但我的问题是,如果玩家 1 连续获得 3 个或玩家 2 连续获得 3 个,我将如何执行逻辑 我真的很困惑,我需要有人陪我把它扔掉
我现在的井字游戏代码

import pygame,random
pygame.init()

# draw our window
window = pygame.display.set_mode((500,540),pygame.NOFRAME)
pygame.display.set_caption("Tic Tac TOE")



MANUAL_CURSOR = pygame.image.load('nw.png').convert_alpha()


MANUAL_CURSOR2 = pygame.image.load('nOW.png').convert_alpha()



bg = pygame.image.load("ticO.png")
fps = 40

clock = pygame.time.Clock()

class button():
    def __init__(self, color, x,y,width,height, text=''):
        self.color = color
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.text = text
        self.over = False

    def draw(self,window,outline=None):
                #Call this method to draw the button on the screen
        if outline:
            pygame.draw.rect(window, outline, (self.x-2,self.y-2,self.width+4,self.height+4),0)
                    
        pygame.draw.rect(window, self.color, (self.x,self.y,self.width,self.height),0)
                
        if self.text != '':
            font = pygame.font.SysFont('comicsans', 60)
            text = font.render(self.text, 1, (0,0,0))
            window.blit(text, (self.x + (self.width/2 - text.get_width()/2), self.y + (self.height/2 - text.get_height()/2)))

    def isOver(self, pos):
                #Pos is the mouse position or a tuple of (x,y) coordinates
        if pos[0] > self.x and pos[0] < self.x + self.width:
            if pos[1] > self.y and pos[1] < self.y + self.height:
                return True
                    
        return False

    def playSoundIfMouseIsOver(self, pos, sound):
        if self.isOver(pos):            
            if not self.over:
                beepsound.play()
                self.over = True
        else:
            self.over = False



class particle:
    def __init__(self,x):
        self.x = x
        self.partilight = pygame.image.load("noW.png")
    def draw(self,window):
        window.blit(self.partilight,(self.x))


                    
white = (250,250,250)
greenbutton2 = button((0,255,0),190,215,100,100, '')

greenbutton3 = button((0,255,0),335,215,100,100, '')

greenbutton4 = button((0,255,0),70,215,100,100, '')

greenbutton5 = button((0,255,0),70,350,100,100, '')

greenbutton6 = button((0,255,0),190,350,100,100, '')

greenbutton7 = button((0,255,0),335,350,100,100, '')


greenbutton8 = button((0,255,0),70,90,100,100, '')

greenbutton9 = button((0,255,0),190,90,100,100, '')

greenbutton10 = button((0,255,0),335,90,100,100, '')



            
font = pygame.font.Font("fos.ttf", 60)
score = 1
cointext = font.render("" + str(score), True, (255,255,255))
coinrect = cointext.get_rect()
coinrect.center = ((100,50))

particles = []


pos = pygame.mouse.get_pos()
def redraw():
    window.fill((174, 214, 241))
    window.blit(bg,(0,0))
    greenbutton2.draw(window)
    greenbutton3.draw(window)
    greenbutton4.draw(window)
    greenbutton5.draw(window)
    greenbutton6.draw(window)
    greenbutton7.draw(window)

    greenbutton8.draw(window)
    greenbutton9.draw(window)
    greenbutton10.draw(window)


    for particle in particles:
        particle.draw(window)
        
    pos = pygame.mouse.get_pos()
    if score >= 0:
        window.blit(MANUAL_CURSOR, MANUAL_CURSOR.get_rect(center = pygame.mouse.get_pos()))
        pygame.mouse.set_visible(False)

        
    if score >= 1:
        window.blit(MANUAL_CURSOR2, MANUAL_CURSOR2.get_rect(center = pygame.mouse.get_pos()))


    if score >= 2:
        window.blit(MANUAL_CURSOR, MANUAL_CURSOR.get_rect(center = pygame.mouse.get_pos()))


    if score >= 3:
        window.blit(MANUAL_CURSOR2, MANUAL_CURSOR2.get_rect(center = pygame.mouse.get_pos()))

        

    if score >= 4:
        window.blit(MANUAL_CURSOR, MANUAL_CURSOR.get_rect(center = pygame.mouse.get_pos()))


    if score >= 5:
        window.blit(MANUAL_CURSOR2, MANUAL_CURSOR2.get_rect(center = pygame.mouse.get_pos()))


    if score >= 6:
        window.blit(MANUAL_CURSOR, MANUAL_CURSOR.get_rect(center = pygame.mouse.get_pos()))



    if score >= 7:
        window.blit(MANUAL_CURSOR2, MANUAL_CURSOR2.get_rect(center = pygame.mouse.get_pos()))



    if score >= 8:
        window.blit(MANUAL_CURSOR, MANUAL_CURSOR.get_rect(center = pygame.mouse.get_pos()))


        
# our main loop
runninggame = True
while runninggame:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type ==  pygame.QUIT:
            runninggame = False


        if event.type == pygame.MOUSEBUTTONDOWN:
            pos = pygame.mouse.get_pos()
            if greenbutton2.isOver(pos):
                score += 1
                cointext = font.render("" + str(score), True, (255,255,255))
                coinrect.center = ((100,50))
                for x in range(4):
                    particles.append(particle(MANUAL_CURSOR.get_rect(center = pygame.mouse.get_pos())))



                    
    redraw()


    pygame.display.update()

pygame.quit()

    



我正在使用的 Assets 请!在测试代​​码时使用 so
enter image description here
enter image description here
enter image description here

最佳答案

类名通常应使用 CapWords 约定。类的名称应该是 Button而不是 button .实例变量应该是小写的。因此,类型为 Button 的对象的名称应该是 button .
此外使用 pygame.Rect对象和 collidepoint .见 How do I detect if the mouse is hovering over a button? PyGame button class is not displaying the text or changing colour on hover .
例如:

class Button():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.over = False

    def draw(self, window, outline=None):
        pygame.draw.rect(window, self.color, self.rect)
        if outline:
            pygame.draw.rect(window, outline, self.rect.inflate(-4, -4), 3)

    def isOver(self, pos):
        return self.rect.collidepoint(pos)
创建 Buttons 的 3x3 网格和 Particle 的 3x3 网格对象。粒子网格的初始值为None :
button_grid = [[Button((0, 128, 0), 70+i*120, 90+j*120, 100, 100, '') for i in range(3)] for j in range(3)]
particle_grid = [[None for i in range(3)] for j in range(3)]
redraw 中绘制网格
def redraw():
    window.fill((32, 32, 32))

    for i in range(len(button_grid)):
        for j in range(len(button_grid[0])):
            b = button_grid[i][j]
            p = particle_grid[i][j]

            is_over = p == None and b.isOver(pygame.mouse.get_pos())
            b.draw(window, (255, 255, 255) if is_over else None)
            if p:
                p.draw(window)
粒子图像应该是类 Particle 的构造函数的参数。 .在类中添加一个方法来设置位置:
class Particle:
    def __init__(self, image):
        self.pos = (0, 0)
        self.image = image
    def set_pos(self, pos):
        self.pos = pos
    def draw(self, window):
        window.blit(self.image, self.image.get_rect(center = self.pos))
创建一个方法,根据当前轮次创建一个新粒子:
def new_particle(turn):
    image = MANUAL_CURSOR if turn % 2 == 0 else MANUAL_CURSOR2
    return Particle(image)
为当前回合添加一个变量并创建一个初始 Particle目的:
turn = 0
particle = new_particle(turn)
设置Particle的位置对象使用当前鼠标位置并在应用程序循环中绘制对象:
runninggame = True
while runninggame:
    # [...]

    particle.set_pos(pygame.mouse.get_pos())

    redraw()
    particle.draw(window)
    pygame.display.update()
单击某个字段时,请检查粒子网格中的相应字段是否为空。将场的中心复制到粒子的位置。将粒子分配给网格。增加转弯并创建一个新粒子:
while runninggame:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type ==  pygame.QUIT:
            runninggame = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            for i in range(len(button_grid)):
                for j in range(len(button_grid[0])):
                    b = button_grid[i][j]
                    if b.isOver(event.pos) and particle_grid[i][j] == None:
                        particle.set_pos(b.rect.center)
                        particle_grid[i][j] = particle
                        turn += 1
                        particle = new_particle(turn)
为双方球员加分:
score1 = 0
score2 = 0
添加一个函数来评估是否连续有 3 个相同的图像:
def has_won(pg):
    pg = particle_grid
    for i in range(3):
        if pg[i][0] and pg[i][1] and pg[i][2]:
            if pg[i][0].image == pg[i][1].image == pg[i][2].image:
                return pg[i][0].image
    for j in range(3):
        if pg[0][j] and pg[1][j] and pg[2][j]:
            if pg[0][j].image == pg[1][j].image == pg[2][j].image:
                return pg[0][j].image
    if pg[0][0] and pg[1][1] and pg[2][2]:
        if pg[0][0].image == pg[1][1].image == pg[2][2].image:
            return pg[0][0].image
    if pg[0][2] and pg[1][1] and pg[2][0]:
        if pg[0][2].image == pg[1][1].image == pg[2][0].image:
            return pg[0][2].image
    return None
测试玩家是否在点击按钮后获胜。当玩家获胜时,增加适当的分数并重置粒子网格:
while runninggame:
    clock.tick(fps)
    for event in pygame.event.get():
        # [...]

        if event.type == pygame.MOUSEBUTTONDOWN:
            [...]

            won = has_won(particle_grid)
            if won:
                if won == MANUAL_CURSOR:
                    score1 += 1
                else:
                    score2 += 1
                print(score1, score2)
                particle_grid = [[None for i in range(3)] for j in range(3)]
添加一个函数来评估网格是否已满:
def grid_is_full(pg):
    return all(cell for row in pg for cell in row)
当网格已满时清除网格:
while runninggame:
    clock.tick(fps)
    for event in pygame.event.get():
        # [...]

        if event.type == pygame.MOUSEBUTTONDOWN:
            [...]

            if grid_is_full(particle_grid):
                particle_grid = [[None for i in range(3)] for j in range(3)]

最小的例子:

import pygame,random
pygame.init()

class Button():
    def __init__(self, color, x, y, width, height, text=''):
        self.color = color
        self.rect = pygame.Rect(x, y, width, height)
        self.text = text
        self.over = False

    def draw(self, window, outline=None):
        pygame.draw.rect(window, self.color, self.rect)
        if outline:
            pygame.draw.rect(window, outline, self.rect.inflate(-4, -4), 3)

    def isOver(self, pos):
        return self.rect.collidepoint(pos)

class Particle:
    def __init__(self, image):
        self.pos = (0, 0)
        self.image = image
    def set_pos(self, pos):
        self.pos = pos
    def draw(self, window):
        window.blit(self.image, self.image.get_rect(center = self.pos))

def new_particle(turn):
    image = MANUAL_CURSOR if turn % 2 == 0 else MANUAL_CURSOR2
    return Particle(image)

def has_won(pg):
    pg = particle_grid
    for i in range(3):
        if pg[i][0] and pg[i][1] and pg[i][2]:
            if pg[i][0].image == pg[i][1].image == pg[i][2].image:
                return pg[i][0].image
    for j in range(3):
        if pg[0][j] and pg[1][j] and pg[2][j]:
            if pg[0][j].image == pg[1][j].image == pg[2][j].image:
                return pg[0][j].image
    if pg[0][0] and pg[1][1] and pg[2][2]:
        if pg[0][0].image == pg[1][1].image == pg[2][2].image:
            return pg[0][0].image
    if pg[0][2] and pg[1][1] and pg[2][0]:
        if pg[0][2].image == pg[1][1].image == pg[2][0].image:
            return pg[0][2].image
    return None

def grid_is_full(pg):
    return all(cell for row in pg for cell in row)

def redraw():
    window.fill((32, 32, 32))
    
    for i in range(len(button_grid)):
        for j in range(len(button_grid[0])):
            b = button_grid[i][j]
            p = particle_grid[i][j]
            
            is_over = p == None and b.isOver(pygame.mouse.get_pos())
            b.draw(window, (255, 255, 255) if is_over else None)
            if p:
                p.draw(window)
        
window = pygame.display.set_mode((500,540))
pygame.display.set_caption("Tic Tac TOE")
fps = 40
clock = pygame.time.Clock()
font =  pygame.font.SysFont(None, 50)

#MANUAL_CURSOR = pygame.image.load('nw.png').convert_alpha()
#MANUAL_CURSOR2 = pygame.image.load('nOW.png').convert_alpha()
size = (60, 60)
MANUAL_CURSOR = pygame.Surface(size)
MANUAL_CURSOR.fill((127, 127, 127))
pygame.draw.line(MANUAL_CURSOR, (0, 127, 255), (5, 5), (size[0]-5, size[1]-5), 3)
pygame.draw.line(MANUAL_CURSOR, (0, 127, 255), (size[0]-5, 5), (5, size[1]-5), 3)
MANUAL_CURSOR2 = pygame.Surface(size)
MANUAL_CURSOR2.fill((127, 127, 127))
pygame.draw.circle(MANUAL_CURSOR2, (127, 0, 255), (size[0]//2, size[1]//2), size[0]//2-5, 3)

score1 = 0
score2 = 0

button_grid = [[Button((0, 128, 0), 70+i*120, 90+j*120, 100, 100, '') for i in range(3)] for j in range(3)]
particle_grid = [[None for i in range(3)] for j in range(3)]
turn = 0
particle = new_particle(turn)
      
runninggame = True
while runninggame:
    clock.tick(fps)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runninggame = False

        if event.type == pygame.MOUSEBUTTONDOWN:
            for i in range(len(button_grid)):
                for j in range(len(button_grid[0])):
                    b = button_grid[i][j]
                    if b.isOver(event.pos) and particle_grid[i][j] == None:
                        particle.set_pos(b.rect.center)
                        particle_grid[i][j] = particle
                        turn += 1
                        particle = new_particle(turn)
        
            won = has_won(particle_grid)
            if won:
                if won == MANUAL_CURSOR:
                    score1 += 1
                else:
                    score2 += 1
                print(score1, score2)
                particle_grid = [[None for i in range(3)] for j in range(3)]

            if grid_is_full(particle_grid):
                particle_grid = [[None for i in range(3)] for j in range(3)]

    particle.set_pos(pygame.mouse.get_pos())
    scoreText1 =  font.render("Player 1   Score: " + str(score1), True, (128, 0, 0))
    scoreText2 =  font.render("Player 2   Score: " + str(score2), True, (128, 0, 0))

    redraw()
    window.blit(scoreText1, (70, 30))
    window.blit(scoreText2, (70, 460))
    particle.draw(window)
    pygame.display.update()

pygame.quit()
exit()

关于python - Pygame 井字游戏逻辑?我该怎么做,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64825967/

相关文章:

python - 在 PyGame (SDL) 中使用 Cairo 时的字节顺序

python - 在幕后 PyGame 游戏可以运行,但图像不会移动

python - 我可以将 Sprite 的 x 位置增加 -0.01,但不是 0.01?

java - 无法让这款井字游戏公平进行

C:已完成 Tic Tac Toe 程序,正在寻找改进的技巧

python - 在 p_error() 中调试 ply 以访问解析器状态/堆栈

python - Scrapy 的 XPath 中的 OR 条件

python - 将嵌套 python 列表简化为结构化树的最佳方法(同时保留顺序)

java - nxn 棋盘上 n 个玩家的 Tic tac Toe - 检查获胜者

python - 由 Trac 动态创建的文件的下载链接 - Wikimacro