import random, pygame, sys
from pygame.locals import *
FPS = 30 # general speed of the program
WinW = 640 # size width of window
WinH = 480 # size height of window
RevSpd = 8 # reveals and covers speed
BxSz = 40 # size of box both of H & W px
GapSz = 10 # size between boxes in px
BrdW = 4 # number of columns of icons
BrdH = 3 # rows
assert (BrdW * BrdH) % 2 == 0, 'Board needs to have an even number of boxes for pairs of matches.'
XMarg = int((WinW - (BrdW * (BxSz + GapSz))) / 2)
YMarg = int((WinH - (BrdH * (BxSz + GapSz))) / 2)
# R G B
Gray = (100, 100, 100)
NavyBlu = (60, 60, 100)
Whi = (255, 255, 255)
Rd = (255, 0, 0)
Grn = (0, 255, 0)
Blu = (0, 0, 255)
Yllw = (255, 255, 0)
Org = (255, 128, 0)
Prpl = (255, 0, 255)
Cyan = (0, 255, 255)
BgClr = NavyBlu
LghtBgClr = Gray
BxClr = Whi
HighlightClr = Blu
Donut = 'donut'
Square = 'square'
Diamond = 'diamond'
Lines = 'lines'
Oval = 'oval'
AllClr = (Rd, Grn, Blu, Yllw, Org, Prpl, Cyan)
AllShps = (Donut, Square, Diamond, Lines, Oval)
assert len(AllClr) * len(AllShps) * 2 >= BrdW * BrdH, "Board is too big for the number of shapes/colors defined."
def main():
global FpsClk, DiS
pygame.init()
FpsClk = pygame.time.Clock()
DiS = pygame.display.set_mode((WinW, WinH))
msx = 0 # used to store x coordinate of mouse event
msy = 0 # y coordinate
pygame.display.set_caption('Memory Game')
mainBoard = getRandomizedBoard()
revealedBoxes = generateRevealedBoxesData(False)
firstSelection = None # stores the (x, y) of the first box clicked
DiS.fill(BgClr)
startGameAnimation(mainBoard)
while True:
mouseClicked = False
DiS.fill(BgClr) # draw the window
drawBoard(mainBoard, revealedBoxes)
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE):
pygame.quit()
sys.exit()
elif event.type == MOUSEMOTION:
msx, msy = event.pos
elif event.type == MOUSEBUTTONUP:
msx, msy = event.pos
mouseClicked = True
boxx, boxy = getBoxAtPixel(msx, msy)
if boxx != None and boxy != None:
# the mouse is currently over a box
if not revealedBoxes[boxx][boxy]:
drawHighlightBox(boxx, boxy)
if not revealedBoxes[boxx][boxy] and mouseClicked:
revealBoxesAnimation(mainBoard, [(boxx, boxy)])
revealedBoxes[boxx][boxy] = True # set the box as revealed
if firstSelection == None: # the current box was the first box clicked
firstSelection = (boxx, boxy)
else: # the current box was the second box clicked
# check if there's a match between the two icons
ishp1, iclr1 = getShapeAndColor(mainBoard, firstSelection[0], firstSelection[1])
ishp2, iclr2 = getShapeAndColor(mainBoard, boxx, boxy)
if ishp1 != ishp2 or iclr1 != iclr2:
# icons don't match re-cover up both selection
pygame.time.wait(1000) # 1000 ml/s = 1 s
coverBoxesAnimation(mainBoard, [(firstSelection[0], firstSelection[1]), (boxx, boxy)])
revealedBoxes[firstSelection[0]][firstSelection[1]] = False
revealedBoxes[boxx][boxy] = False
elif hasWon(revealedBoxes): # check if all pairs found
gameWonAnimation(mainBoard)
pygame.time.wait(2000)
# reset the board
mainBoard = getRandomizedBoard()
revealedBoxes = generateRevealedBoxesData(False)
# show the fully unrevealed board for a second
drawBoard(mainBoard, revealedBoxes)
pygame.display.update()
pygame.time.wait(1000)
# replay the start game animation
startGameAnimation(mainBoard)
firstSelection = None # reset firstSelect variable
# redraw the screen and wait a clock tick
pygame.display.update()
FpsClk.tick(FPS)
def generateRevealedBoxesData(val):
revealedBoxes = []
for i in range(BrdW):
revealedBoxes.append([val] * BrdH)
return revealedBoxes
def getRandomizedBoard():
# get a list of every possible shape in every possible color
icons = []
for color in AllClr:
for shape in AllShps:
icons.append((shape, color))
random.shuffle(icons) # randomize the order of the icons list
numIcnUsd = int(BrdW * BrdH / 2) # calculate how many icons are needed
icons = icons[:numIcnUsd] * 2 # make two of each
random.shuffle(icons)
# create the board data structure, with randomly placed icons
board = []
for x in range(BrdW):
column = []
for y in range(BrdH):
column.append(icons[0])
del icons[0] # remove the icons as we assign them
board.append(column)
return board
def splitIntoGroupsOf(groupSize, theList):
# splits a list into a list of list, where the inner lists have at
# most groupSize number of items
result = []
for i in range(0, len(theList), groupSize):
result.append(theList[i:i + groupSize])
return result
def leftTopCoordsOfBox(boxx, boxy):
# convert board coordinates to px coordinates
left = boxx * (BxSz + GapSz) + XMarg
top = boxy * (BxSz + GapSz) + YMarg
return (left, top)
def getBoxAtPixel(x, y):
for boxx in range(BrdW):
for boxy in range(BrdH):
left, top = leftTopCoordsOfBox(boxx, boxy)
boxRect = pygame.Rect(left, top, BxSz, BxSz)
if boxRect.collidepoint(x, y):
return (boxx, boxy)
return (None, None)
def drawIcon(shape, color, boxx, boxy):
quarter = int(BxSz * 0.25) # syntactic sugar
half = int(BxSz * 0.5) # syntactic sugar
left, top = leftTopCoordsOfBox(boxx, boxy) # get pixel coords from board coords
# draw the shapes
if shape == Donut:
pygame.draw.circle(DiS, color, (left + half, top + half), half - 5)
pygame.draw.circle(DiS, BgClr, (left + half, top + half), quarter - 5)
elif shape == Square:
pygame.draw.rect(DiS, color, (left + quarter, top + quarter, BxSz - half, BxSz - half))
elif shape == Diamond:
pygame.draw.polygon(DiS, color, ((left + half, top), (left + BxSz - 1, top + half), (left + half, top + BxSz - 1), (left, top + half)))
elif shape == Lines:
for i in range(0, BxSz, 4):
pygame.draw.line(DiS, color, (left, top + i), (left + i, top))
pygame.draw.line(DiS, color, (left + i, top + BxSz - 1), (left + BxSz - 1, top + i))
elif shape == Oval:
pygame.draw.ellipse(DiS, color, (left, top + quarter, BxSz, half))
def getShapeAndColor(board, boxx, boxy):
# shape value for x, y spot is stored in board[x][y][0]
# color value for x, y spot is stored in board[x][y][1]
return board[boxx][boxy][0], board[boxx][boxy][1]
def drawBoxCovers(board, boxes, coverage):
# draws boxes being covered/revealed. "boxes" is a list
# of two-item lists, which have the x & y spot of the box
for box in boxes:
left, top = leftTopCoordsOfBox(box[0], box[1])
pygame.draw.rect(DiS, BgClr, (left, top, BxSz, BxSz))
shape, color = getShapeAndColor(board, box[0], box[1])
drawIcon(shape, color, box[0], box[1])
if coverage > 0: # only draw the cover if there's an coverage
pygame.draw.rect(DiS, BxClr, (left, top, coverage, BxSz))
pygame.display.update()
FpsClk.tick(FPS)
def revealBoxesAnimation(board, boxesToReveal):
# do the "box reveal" animation
for coverage in range (BxSz, (-RevSpd) - 1, - RevSpd):
drawBoxCovers(board, boxesToReveal, coverage)
def coverBoxesAnimation(board, boxesToCover):
# do the "box cover" animation
for coverage in range(0, BxSz + RevSpd, RevSpd):
drawBoxCovers(board, boxesToCover, coverage)
def drawBoard(board, revealed):
# draws all of the boxes in their covered or revealed state
for boxx in range(BrdW):
for boxy in range(BrdH):
left, top = leftTopCoordsOfBox(boxx, boxy)
if not revealed[boxx][boxy]:
# draw a covered box
pygame.draw.rect(DiS, BxClr, (left, top, BxSz, BxSz))
else:
# draw the (revealed) icon
shape, color = getShapeAndColor(board, boxx, boxy)
drawIcon(shape, color, boxx, boxy)
def drawHighlightBox(boxx, boxy):
left, top = leftTopCoordsOfBox(boxx, boxy)
pygame.draw.rect(DiS, HighlightClr, (left - 5, top - 5, BxSz + 10, BxSz + 10), 4)
def startGameAnimation(board):
# randomly reveal the boxes 8 at a time
coveredBoxes = generateRevealedBoxesData(False)
boxes = []
for x in range(BrdW):
for y in range(BrdH):
boxes.append((x, y))
random.shuffle(boxes)
boxGroups = splitIntoGroupsOf(8, boxes)
drawBoard(board, coveredBoxes)
for boxGroup in boxGroups:
revealBoxesAnimation(board, boxGroup)
coverBoxesAnimation(board, boxGroup)
def gameWonAnimation(board):
# flash the background color when the player has won
coveredBoxes = generateRevealedBoxesData(True)
color1 = LghtBgClr
color2 = BgClr
for i in range(13):
color1, color2 = color2, color1 # swap color
DiS.fill(color1)
drawBoard(board, coveredBoxes)
pygame.display.update()
pygame.time.wait(3000)
def hasWon(revealedBoxes):
# returns True if all the boxes have been revealed, otherwisw False
for i in revealedBoxes:
if False in i:
return False # return False if any boxes are covered
return True
if __name__ == '__main__':
main()
我对这款“记忆拼图”游戏有疑问..... 该脚本来自我所拥有的电子书,我只是尝试学习非常基础的.. 在我仔细检查之后我尝试输入所有这些并且从未找到错别字。 也许错误是我的错,但我想知道我犯了什么错......
所以这是一个问题..
当我完成后选择第一块板,当然它会显示,但在我选择的第二块板之后,它会检查它是否与两块板都不匹配再次重新覆盖.. 。 当我选择另一块电路板时,电路板不会显示,因为它卡在我选择的第一块电路板上...... 所以,我选择的第三个选择快速覆盖,不会透露.. 我该如何解决这个问题,请你的指导人员