使用2D数组创建跳棋碎片 - Pygame

时间:2018-03-17 21:50:07

标签: python multidimensional-array pygame geometry iteration

我正在使用我相对较新的库pygame在python中制作一个跳棋游戏。但是我遇到了程序问题,其中创建了太多的红色和黑色部分并且它们的布局不正确。

这些碎片只是用红色或黑色绘制的圆圈。为了获得碎片的布局,我在函数newGameBoard()中创建了一个2D数组,它放置了碎片的位置,但是当我在函数drawPieces()中遍历游戏板时,会创建一个24块的块在棋盘的每一面,而不是在游戏板的位置创建。

以下是当前代码:

import pygame

newGame=True
loggedIn=False
miniGame=False

black=(0,0,0)
white=(255,255,255)
red=(255,0,0)
greyBackground =(203, 206, 203)

# This sets the WIDTH and HEIGHT of each grid location
width=65
height=65
radius=30

margin=0# This sets the margin between each cell

xDistanceFromEdge=220

pygame.init()

gameBoard=[[None]*8]*8

windowSize= [960, 640]
screen = pygame.display.set_mode(windowSize)

pygame.display.set_caption("Draughts Game")

done = False

clock = pygame.time.Clock()



# -------- Main Program Loop -----------
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:

            pos = pygame.mouse.get_pos()

            # Change the x/y screen coordinates to grid coordinates
            column = (pos[0]-xDistanceFromEdge) // (width+margin)
            row = pos[1] // (height+margin)


    screen.fill(greyBackground)

    def boardGui(black,white):
        for boardRow in range(8):
            for boardColumn in range(8):
                xCoordinate=((margin+width) * boardColumn + margin)+xDistanceFromEdge
                yCoordinate=(margin+height) * boardRow + margin
                if boardRow%2==0 and boardColumn%2==0:
                    currentColour = black
                if boardRow%2!=0 and boardColumn%2==0:
                    currentColour = white
                if boardRow%2==0 and boardColumn%2!=0:
                    currentColour = white
                if boardRow%2!=0 and boardColumn%2!=0:
                    currentColour = black
                pygame.draw.rect(screen,currentColour,[xCoordinate,yCoordinate, width, height])

    def piecesGameBoard(gameBoard):
        if newGame==True:
            newGameBoard(gameBoard)

    def newGameBoard(gameBoard):
        for x in range(8):
            for y in range(3):
                if ((x%2!=0) and (y%2==0)) or ((x%2==0) and (y%2!=0)):
                    gameBoard[x][y]="NormalBlack"

            for y in range(5,8):
                if ((x%2==0) and (y%2==0)) or ((x%2!=0) and (y%2!=0)):
                    gameBoard[x][y]="NormalRed"
        print(gameBoard)

        drawPieces(gameBoard,black,red)

    def drawPieces(gameBoard,black,red):
        for x in range(8):
            for y in range(8):
                xCoordinate=((margin+width) * x + margin+32)+xDistanceFromEdge
                yCoordinate=(margin+height) * y + margin+33
                if gameBoard[x][y]=="NormalBlack":
                    pygame.draw.circle(screen,black,(xCoordinate,yCoordinate),radius)

                if gameBoard[x][y]=="kingBlack":
                    pygame.draw.circle(screen,black,(xCoordinate,yCoordinate),radius)
                    #-----put letter k in the middle-----#
                if gameBoard[x][y]=="NormalRed":
                    pygame.draw.circle(screen,red,(xCoordinate,yCoordinate),radius)

                if gameBoard[x][y]=="KingRed":
                    pygame.draw.circle(screen,red,(xCoordinate,yCoordinate),radius)
                    #----put letter k in the middle---#

    boardGui(black,white)
    piecesGameBoard(gameBoard)

    clock.tick(60)

    pygame.display.flip()

pygame.quit()

我试图在newGameBoard()函数中创建但确实有效的部分。使用此程序,gameBoard在每次移动后都会发生变化,这就是为什么我希望程序以gameBoard变量的格式创建碎片。

1 个答案:

答案 0 :(得分:1)

这是我认为你的代码的一个版本。我认为主要问题在于您如何初始化gameboard变量:

gameBoard=[[None]*8]*8

我改为:

gameBoard=[[None]*8 for _ in range(8)]  # Proper initialization.

因此,它会为每一行创建一个None值的新列,而不是在每一行中放置相同的列表。这是一个常见的Python新手“gotcha”。

我还尝试在某种程度上清理,简化和组织代码结构。一个值得注意的变化是我将所有这些函数定义移到了主循环之外 - 因为没有理由不止一次这样做,它只会减慢执行速度。

还有许多其他优化措施可以完成,但是因为你没有要求进行完整的代码审查(无论如何这都不合适 - 还有另一个名为Code Review的网站事情),我没有实施任何一个......

import pygame

newGame=True
loggedIn=False
miniGame=False

black=(0,0,0)
white=(255,255,255)
red=(255,0,0)
greyBackground=(203, 206, 203)

# This sets the WIDTH and HEIGHT of each grid location
width=65
height=65
radius=30

margin=0# This sets the margin between each cell
xDistanceFromEdge=220
#gameBoard=[[None]*8]*8
gameBoard=[[None]*8 for _ in range(8)]  # Proper initialization.
windowSize=[960, 640]

pygame.init()
screen = pygame.display.set_mode(windowSize)
pygame.display.set_caption("Draughts Game")
done = False
clock = pygame.time.Clock()

# Added helper function.
def square_colour(row, col):
    """ Determine colour of game board square from its position. """
    return white if (row + col) % 2 == 0 else black  # Makes upper-left corner white.

def boardGui(black,white):
    for boardRow in range(8):
        for boardColumn in range(8):
            xCoordinate=((margin+width) * boardColumn + margin)+xDistanceFromEdge
            yCoordinate=(margin+height) * boardRow + margin
            currentColour = square_colour(boardRow, boardColumn)
            pygame.draw.rect(screen,currentColour,[xCoordinate,yCoordinate, width, height])

def piecesGameBoard(gameBoard):
    if newGame:
        newGameBoard(gameBoard)

def newGameBoard(gameBoard):
    gameBoard[:] = [[None]*8 for _ in range(8)]  # Empty the game board.

    for x in range(8):
        for y in range(8):
            if square_colour(x, y) == black:
                if y in range(3):
                    gameBoard[x][y]="NormalBlack"
                if y in range(5,8):
                    gameBoard[x][y]="NormalRed"

    drawPieces(gameBoard,black,red)

def drawPieces(gameBoard,black,red):
    for x in range(8):
        for y in range(8):
            xCoordinate=((margin+width) * x + margin+32)+xDistanceFromEdge
            yCoordinate=(margin+height) * y + margin+33
            if gameBoard[x][y]=="NormalBlack":
                pygame.draw.circle(screen,black,(xCoordinate,yCoordinate),radius)
                # Draw a white outline around edge of black pieces so they are visible
                # when placed on black game board squares.
                pygame.draw.circle(screen,white,(xCoordinate,yCoordinate),radius, 1)
            if gameBoard[x][y]=="KingBlack":
                pygame.draw.circle(screen,black,(xCoordinate,yCoordinate),radius)
                #-----put letter k in the middle-----#
            if gameBoard[x][y]=="NormalRed":
                pygame.draw.circle(screen,red,(xCoordinate,yCoordinate),radius)
            if gameBoard[x][y]=="KingRed":
                pygame.draw.circle(screen,red,(xCoordinate,yCoordinate),radius)
                #----put letter k in the middle---#

# -------- Main Program Loop -----------
while not done:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            done = True
        elif event.type == pygame.MOUSEBUTTONDOWN:

            pos = pygame.mouse.get_pos()

            # Change the x/y screen coordinates to grid coordinates
            column = (pos[0]-xDistanceFromEdge) // (width+margin)
            row = pos[1] // (height+margin)

    screen.fill(greyBackground)
    boardGui(black,white)
    piecesGameBoard(gameBoard)
    clock.tick(60)
    pygame.display.flip()

pygame.quit()

显示棋盘:

screenshot of checkerboard displayed