티스토리 뷰

Game with Python

16퍼즐 제작 - (5)

Conkara 2017. 6. 12. 18:58

'''추후에 모아서 개선하기 위해 일부러 이상하게 짠 부분도 있고

필자의 실력과 식견이 부족해서 이상하게 짜 진 부분 도 있습니다.

만드는 방법은 여러가지 입니다. 다만 효율적인 코드를 정답이라고 한다면 

필자의 코드는 절대로 정답이 아닙니다.

필자는 일단 정답을 만들어 낼 정도의 실력이 있는 사람도 아니지만

아래에 있는 코드는 일부러 오답을 낸 코드입니다. 추후에 수정과 보수하는것까지

블로그에 등록을 할것이기 때문에요'''


코드가 돌아가는것 자체에는 문제가 없지만 단지 그뿐인 코드.... 들에 관한 내용이 중간중간 들어가있습니다


다만 초심자분들도 제 게시물을 보게 될때 그런 내용이 산재해있다면 읽기 오히려 불편해질것같아서 일부러 하얀 글씨 처리 했습니다. 제 코드를 보고 엉망진창 엉터리로 짯구나 라는걸 알아보실 실력이시면 이미 저보다 프로그래밍을 잘하시겠지만 드래그 하시면 볼 수는 있습니다. 이 허접이 어떤 이유가 있어서 이렇게 했나.



네 우선 잘못된 정보가 있어서 정정 하나 하고 갈게요... 게임 이름이 16퍼즐이 아니라 15 퍼즐이라고 합니다... 아....


일단 16퍼즐로 글을 쓰고 있으니 16퍼즐로 계속 쓰겠지만 정식 게임 이름은 15퍼즐이라고 하네요.... ㅠㅠ


네 오늘은 우선 16퍼즐의 판을 자동 생성하는것, 클리어를 판별하는 함수를 만들겁니다.


판을 자동 생성하려면 숫자를 그냥 섞으면 됩니다. 그런데 제가 이전에 단일 리스트를 쓰지 않고 이중 리스트를 써서 문제가 몇가지 생겼습니다. 이런걸 해결할때는 코드를 덕지덕지 더 붙여 이중 리스트에 맞게 쓰느냐, 아니면 단일 리스트로 개조하느냐 하는 방법이 있습니다. 저는 이 코드 설계가 얼마나 안좋게 됬나 보여드리기 위해 일부러 이중 리스트를 계속해서 사용했습니다.

리스트의 원소를 섞는 함수를 직접 만들어도 되지만 왜 그런걸 굳이 해야해(?) 라고 생각하고 필자도 그렇게 생각합니다. 만들려고 하면 만들 수는 있죠. 하지만 파이썬의 random class 에는 이미 shuffle 이라는 훌륭한 함수를 제공합니다. 이걸 사용해서 깔끔하게 정리하죠.

위쪽에 import random 을 적어주시고

네 이런식으로 섞어 줍니다


라고 낚이시면 안됩니다. 제가 해놓았던 설계에 제가 발목을 잡히게 되는데요

이렇게 섞으면 단일 리스트에 대해서만 바뀌는 것 입니다.

제가 짯던 gameBoard 는 명백하게 이중 리스트였죠

[[" 1 "," 2 "," 3 "," 4 "],[" 5 "," 6 "," 7 "," 8 "], [" 9 "," 10"," 11"," 12"],[" 13"," 14"," 15"," 0 "]]


애시당초 이런식으로 초기화가 되어있기 때문에 바뀌어도 1 2 3 4가 한 조가 되어 움직이고

5 6 7 8 이 한조가 되어 움직입니다. 이런걸 판을 섞는다 라고 하지 않습니다 적어도 저에게는요.


자 그럼 이걸 해결하려면 리스트 안에 리스트를 섞어 주면 되는거 아냐? 라고 저는 먼저 떠올렸습니다

그리고 1초만에 기각했습니다

왜냐하면 리스트 내에서 리스트를 섞게 되면 1,2,3,4 가 내부에서 섞이고 5,6,7,8 이 내부에서 섞이고 하는 식으로 되서 

14 13 0 15

7 5 8 6

3 4 1 2

11 10 12 9


등과 같이 섞이게 됩니다. 이런걸 원하신건가요. 이것도 섞인것이라고 보기에는 문제가 있습니다.


결국 단일 리스트로 만들지 않은 화근을 여기서 봅니다. 

이중 리스트에 바로 쓰기 위해서는 다른 단일 리스트에서 미리 섞어서 앞에서 4개씩 끊어서 넣어주는 방법을 생각해 볼 수 있겠네요. 필자는 이게 가장 먼저 떠올라서 이걸 사용했습니다 


저보다 잘 하시는 분들을 다른 방식을 생각해 내실 수 있겠지요. 저는(변명이지만) 아직 대학생이고... 공부가 부족해서 이런 방식밖에 잘 모르겠어요.


네 위와 같이 다른 리스트를 만들어서 셔플 한 뒤 4개씩 끊어서 이중 배열에 삽입하고 있습니다


numberList 를 너무 불편하게 쭉 늘여놓았는데 


numberList = [i for i in range(16)]


이 코드로 생성하게 되면 안되? 라고 물어보실 수 있어요. 제가 예전에 짜 놓았던 코드를 들여다 보면 가독성 문제로 0 이 아니라 " 0 " " 1 " 과 같은 식으로 저장을 해 놓았죠. 이게 문제가 됩니다. 숫자가 아니라 문자이고 두자리 숫자와 한자리 숫자의 경우 끝부분에 공백이 붙고 안붙고가 차이가 납니다.


만약 100까지의 숫자였다면 저런식으로 초기화를 하기보단 리스트에서 숫자를 꺼내서 검사를 해서 공백을 붙여서 문자열로 저장하는게 훨씬 깔끔했겠지요.


다만 필자가 생각하기 16개정도는 그냥 적는게 훨씬 빠르고 깔끔하다고 생각해서

(추후에 게임을 확장할 일이 생기면 또 난리나겠지요.)


이런식으로 초기화를 하게 되었습니다.


코드 자체는 간단하니 설명할건 딱히 없겠네요. 저렇게 섞고 저장하면 깔끔하게 섞인 판이 출력됩니다.


다음에는 완료함수를 설계해야하는데요. 


또 여러가지 방법이 있습니다. 숫자가 순서대로 정렬되었는지 계산해봐도 되고. 각 칸에는 번호가 있습니다. 이것과 숫자간의 관계를 생각해도 됩니다, 예를들어 0,0, 번째칸에는 당연히 1이 들어있어야합니다. 4*0 + 0 + 1 == 1 인지


4*y + x +1 == gameBoard[x][y] 에대해 모든 칸을 검사해도 됩니다.


다만 필자는 잔꾀가 많아서 미리 완성된 보드판과 비교를 하기로 했습니다



새로운 판을 준비하고 움직일때마다 이 판과 같은지 검사만 하면 되겠네요.



위와 같은 코드를 GameBoard class 내에 삽입해주고, 이 함수를 이동 할때마다 호출해서 만약 true(1) 이라면 즉시 break 후 congraturation 을 화면에 띄워주도록 만들었습니다. 그 결과 잘 작동 되네요. 이제 이 콘솔게임은 거의 끝났습니다


다음 포스팅에서는 코딩 이야기보단 이 게임이 나아갈 방향, 설계시 문제가 됬던 점, 사실 저 섞는거에도 문제가 있는데 그것까지 

가볍게 다루고 넘어가겠습니다. 대학교 2학년 지식 이거저거 끌어다 쓰니 부족한게 많이 느껴지네요. 아...


'Game with Python' 카테고리의 다른 글

pygame에 대해서 간단히 알아봅시다. -(1)  (0) 2017.06.15
16퍼즐 제작 - (6)  (0) 2017.06.13
16퍼즐 제작 - (4)  (0) 2017.06.02
16퍼즐 제작 - (3)  (0) 2017.05.31
16퍼즐 제작 - (2)  (0) 2017.05.29
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/02   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
글 보관함