[pygame] 메모리 퍼즐 - 2

서희찬·2021년 4월 6일
0

메모리 퍼즐 - 1 을 이어서 계속하겠다.
이제 메인에서 쓰이는 함수들을 정의해야한다.

generateRevealedBoxesData(val)

#열린 상자에 대한 데이터 구조만들기
def generateRevealedBoxesData(val): #구성요소의 값을 Val로 한다
    revealedBoxes = []   
    for i in range(BOARDWIDTH):
        revealedBoxes.append([val]*BOARDHEIGHT) #불리언 값을 가지는 2차원 리스트를 만든다. 
    return revealedBoxes #revealedBoxes[x][y]가 된다. 

불리언 값을 가지는 2차원 리스트를 만드는 함수이다.

getRandomizedBoard()

def getRandomizedBoard():
    #모든 가능한 색에서 가능한 모양의 목록을 모두 얻어낸다.
    icons = []
    for color in ALLCOLORS:
        for shape in ALLSHAPES:
            icons.append((shape,color))
            

모든 형태와 색깔로 가능한 모든 조합을 가진 리스트를 만든다.

random.shuffle(icons)#아이콘 리스트의 순서를 랜덤으로한다.
    numIconsUsed = int(BOARDWIDTH*BOARDHEIGHT/2) # 얼마나 많은 아이콘이 필요한지 계산
    icons = icons[:numIconsUsed] * 2 #각각의 짝을 만든다
    random.shuffle(icons)

이를 통해 게임판에 필요한 상자의 개수를 구한후 아이콘이 2개씩 있어야 하므로곱한 값을 2로 나눈 수를 numIconUsed에 저장한다.
그리고, icons 를 numIconUsed 만큼 잘라내어 새로운 리스트를 *2 를 통해 두개를 만든다.
이후 shuffle 을 써서 섞는다.

    #랜덤하게 아이콘이 놓여 있는 게임판의 데이터 구조를 만든다.
    board = []
    for x in range(BOARDWIDTH):
        column=[]
        for y in range(BOARDHEIGHT):
            column.append(icons[0])
            del icons[0] # 방금 추가한 아이콘을 지운다.
        board.append(column)
    return board

icons list에 있는 값들을 column에 넣고 icons를 지워가며 icons[0]은 계속 새로운 값을 가지면서 길이가 짧아지게 만들었다.
-> 리스트 맨 앞부분에서 아이템을 지우고 다른 아이템은 앞으로 한 칸씩 자리를 옮기므로 지운 아이템의 바로 뒤 아이템이 바로 첫 번째 아이템이 되는 방식을 이용 !

이를 통해서 다시 한번 getRandomizedBoard()

    #모든 가능한 색에서 가능한 모양의 목록을 모두 얻어낸다.
    icons = []
    for color in ALLCOLORS:
        for shape in ALLSHAPES:
            icons.append((shape,color))
    
    random.shuffle(icons)#아이콘 리스트의 순서를 랜덤으로한다.
    numIconsUsed = int(BOARDWIDTH*BOARDHEIGHT/2) # 얼마나 많은 아이콘이 필요한지 계산
    icons = icons[:numIconsUsed] * 2 #각각의 짝을 만든다
    random.shuffle(icons)

    #랜덤하게 아이콘이 놓여 있는 게임판의 데이터 구조를 만든다.
    board = []
    for x in range(BOARDWIDTH):
        column=[]
        for y in range(BOARDHEIGHT):
            column.append(icons[0])
            del icons[0] # 방금 추가한 아이콘을 지운다.
        board.append(column)
    return board 

splitIntoGroupsOf(groupSize,theList)

def splitIntoGroupsOf(groupSize,theList):
    #리스트를 2차원 리스트로 만든다. 안쪽의 리스트는 최대로 groupSize개만큼의 아이템이 있다.
    result = []
    for i in range(0,len(theList),groupSize):
        result.append(theList[i:i+groupSize])
    return result

range(0,20,8) 형태 : for문을 3번 돌게되고 i는 0,8,16이 된다.
이를 통해 therList(0:8)->(8:16)->(16:24)가 된다.
.... 이를 통해2차원 리스트로 가를 수 있다..
아직 이해가... 크흑...

leftTopCoordsOfBox(boxx,boxy)

def leftTopCoordsOfBox(boxx,boxy):
    #게임판 좌표계를 픽셀 좌표계로 변환한다.
    left = boxx * (BOXSIZE + GAPSIZE) + XMARGIN
    top = boxy * (BOXSIZE + GAPSIZE )+ YMARGIN
    return (left, top)

이를 통해서 윈도우 안에 카드마다 좌표를 새로 줄 수 있어서 더 좌표를 쉽게 찾을 수 있다.
상자를 그릴 떄 픽셀 좌표계가 필요한 곳에서 함수를 호출한다.

getBoxAtPixel(x,y)

#픽셀 좌표계에서 게임판 좌표계로 변환하기
def getBoxAtPixel(x,y):
    for boxx in range(BOARDWIDTH):
        for boxy in range(BOARDHEIGHT):
            left, top = leftTopCoordsOfBox(boxx,boxy)
            boxRect = pygame.Rect(left,top,BOXSIZE,BOXSIZE)
            if boxRect.collidepoint(x,y):
                return (boxx,boxy)
    return (None,None)

앞서 정의한 함수와는 반대로 픽셀 좌표계로 변환할 함수이다.

drawIcon(shape,color,boxx,boxy)

def drawIcon(shape,color,boxx,boxy):
#그리기 함수에서는 대부분 상자의 중간위치와 1/4위치를 필요 하는 경우가 많아서 미리정의
    quarter = int(BOXSIZE*0.25) #syntactic sugar
    half = int(BOXSIZE*0.5) 

    left,top = leftTopCoordsOfBox(boxx,boxy) #보드의 좌표에서 픽셀의 좌표를 얻는다. 
    #형태를 그린다. 
    if shape == DONUT:
        pygame.draw.circle(DISPLAYSURF, color, (left + half, top + half), half - 5)
        pygame.draw.circle(DISPLAYSURF, BGCOLOR, (left + half, top + half), quarter - 5)
    elif shape == SQUARE:
        pygame.draw.rect(DISPLAYSURF, color, (left + quarter, top + quarter, BOXSIZE - half, BOXSIZE - half))
    elif shape == DIAMOND:
        pygame.draw.polygon(DISPLAYSURF, color, ((left + half, top), (left + BOXSIZE - 1, top + half), (left + half, top + BOXSIZE - 1), (left, top + half)))
    elif shape == LINES:
        for i in range(0, BOXSIZE, 4):
            pygame.draw.line(DISPLAYSURF, color, (left, top + i), (left + i, top))
            pygame.draw.line(DISPLAYSURF, color, (left + i, top + BOXSIZE - 1), (left + BOXSIZE - 1, top + i))
    elif shape == OVAL:
        pygame.draw.ellipse(DISPLAYSURF, color, (left, top + quarter, BOXSIZE, half))

리기 함수에서는 대부분 상자의 중간위치와 1/4위치를 필요 하는 경우가 많아서 미리정의해두는 것이 좋다
이 와 같은것을 신택틱 슈가 라고 한다.

3편에서 계속...

profile
부족한 실력을 엉덩이 힘으로 채워나가는 개발자 서희찬입니다 :)

0개의 댓글