python "memory puzzle game"
<pre>
<code>    

    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()


</code>
</pre>

<p>I've a problem with this "memory puzzle" game.....
the script is from eBook I've got, I just about try learn the very basic..
I've try to type all of them after I double checked it and never found the typos..
Maybe it was my fault to get the mistake, but I wanna know what mistakes I've made...</p>

<p>So here's a problem..</p>

<p>When I'm done select the first board, of course it'll reveal, but after the second board I had choose and it'll check if it doesn't match the both of board are re-cover again...
while I'd choose another board, the board won't revealed because its stuck with the first board I had choose...
So, the third selection I'd choose as quickly cover and won't revealed..
How do I fix this, please your guidance guys</p>
