Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

또 이런저런 질문... #68

Open
Bartleby2718 opened this issue Oct 21, 2018 · 2 comments
Open

또 이런저런 질문... #68

Bartleby2718 opened this issue Oct 21, 2018 · 2 comments
Labels
question Further information is requested

Comments

@Bartleby2718
Copy link
Owner

@gongdo: 벌써 한 달째 코딩 중이지만 한 달 전에 말씀하신 것도 다 소화를 못해서 새로운 조언을 구하기 전에 clarification부터 부탁 드려야 될 것 같아요.

  1. Keyboard Input
  • "어떤 게임이란, 그 게임의 모든 정보인 상태(state)의 변화일 뿐이에요. (중략) 일반적으로 게임에서는 trigger가 될 때마다 변경을 하는 것 보다는 trigger된 이벤트를 기록만 해두고 그 다음 '처리'시 쌓인 이벤트를 한번에 처리하는게 좋아요." : 처리한 이벤트는 flush해야 하나요, 아니면 이것도 기록해야 하나요? 전에 "게임 상태는 게임의 모든 요소를 기술하는 정보로 각 주체가 이 정보를 바탕으로 '재현'이 가능해야" 하고 "이상적인 게임 상태는 임의의 시간에 대해서도 재현이 가능"하다고 하셨는데, 이게 initial state + list of events로 구현하는 게 좋은지, states만으로 구현을 하는 게 좋은지 모르겠어요. 전자를 택할 경우 정확히 어떤 시점에 발생한 어떠한 event가 state의 변화를 trigger했는지 알 수 있는 대신, 기록해야 할 것도 많고 "replay" 재생기(자꾸 스타가 생각나네요)가 state를 표시할 뿐만 아니라 event를 process할 수 있어야 할 것 같거든요. 스타를 보면 후자인 것 같긴 한데...
  1. The Status Quo
  • 지금 상황은 이 상태인데 코딩하는 순서를 잘못 정한 것 같아요. Name, KeySettings, JokerValueStrategy, JokerPositionStrategy 같은 거 다 하고 이제 Action 코딩하려고 보니까 뭔가 이상하네요. (TDD 하듯 process->input의 순으로 했어야 하나 싶어요.) NameTextInput 같은 입력은 입력 주체를 결정한 상태에서 받아야 해서 process 함수에 넣는 게 아니라 player의 메소드로 하거나 emulator.py에서처럼 assign해야 하는 반면에, ActionKeyboardInput 같은 입력은 일단 받고 나서 process 함수에서 입력 주체를 알아내고 필요한 작업을 수행하는 것 같더라고요. 아직 좀 더 고민해 봐야겠지만...
  1. process
  • 제가 이 게임을 기획할 때 Game이 최대 9번의 Duel로 이루어진다고 개념을 잡았는데요. 이 개념에 맞게 모델링하려면 Game.process 메소드는 DuelResult를 처리하고, Duel.process 메소드는 ActionInput을 처리하는 게 맞겠죠?

뭐가 문제인지도 파악을 못하다 보니 질문 쓰는 데도 한참 걸리네요.

p.s. AI 구현은 한국 가서 해야 할 것 같아요. 약 1주 후에 이 도시를 떠나고 그로부터 1주 후에 이 나라를 떠나거든요.

@Bartleby2718 Bartleby2718 added the question Further information is requested label Oct 21, 2018
@gongdo
Copy link

gongdo commented Oct 21, 2018

  1. 정확해요. initial state + events냐 매 state 전체, 혹은 최종 state냐죠. 결국 케바케.
    스타 같은 경우엔 재생이 가능하니 당연히 전자일 수밖에 없지만, 카드게임류는 이미 턴수나 행동 선택의 최대 횟수가 정해져 있으니 모든 상태를 한번에 저장할 수도 있어요.
    예를 들어, game.duels[]가 아니라 game.duels[9] 인거죠. 이러면 게임이 첫 듀얼만에 끝났더라도 듀얼의 개수는 항상 9개이고 다만 아직 시도하지 않은 duel은 '시작하지 않음'이란 상태겠죠.
    이 게임만 본다면 이런식으로 가변 배열이나 동적 요소를 쓰는게 아니라 고정 배열과, 확정적 요소를 사용하는걸 추천해요.

여담으로 파이썬에서 value와 reference에 대한 구분이 있는지 모르겠는데, 대체로 reference가 가변적, 동적 요소이고 value가 고정적, 확정적 요소죠. 내부적으로 reference는 heap 메모리를 사용하여 동적으로 할당/해제가 일어나고 value는 컴파일타임에 이미 사용할 메모리가 stack으로 확보되는 차이가 있고요.

  1. 이제 코드가 길어져서 다 못보겠네요 ㅋㅋ
    암튼, 그래서 TDD가 단지 테스트에 관한게 아니라 디자인에 관한 점검이 되거든요.
    추상적인 인터페이스만으로 뼈대를 구성하고 거기에 대한 가장 단순한 구현으로 기능이 동작하는지 확인하는거죠. 이러면 실제 구현이 복잡해지더라도 전체 뼈대에는 거의 영향을 안주거든요.

어떤 경우는 구현이 너무나도 특이하거나 특정 요소에 의존성이 강해서 그것이 다시 전체 뼈대에 영향을 주기도 하는데, 이건 추상화 수준에 문제가 있었다는 반증이에요. 만약 정말정말 끊을 수 없는 의존성 문제가 있다면 그 의존성이 추상화된 설계에도 반영되어야겠죠.

  1. 이 부분도 케바케인데;;; 세상 만사가 케바케;;;
    만약 processing 로직이 확실히 duel의 state만으로 판정이 된다면 duel이 처리하는게 맞는것 처럼 보이지만, 잘 생각해보면 각기 다른 duel(의 인스턴스) 마다 판정 로직이 달라지는건 아니잖아요? 오히려 판정이란 게임의 룰이고 이 룰에 따라 한 듀얼에 대한 판정이 내려지겠죠.
    세부 구현상으로, duel의 필드를 노출하고 싶지 않다면 반대로 듀얼에 '판정'이란 메서드를 놓고 '룰'이란 파라미터를 전달하는 방법도 있겠죠. 이러면 duel의 정의란, 한 턴의 상태를 관리하고 주어진 게임의 룰을 적용한 결과를 반영한다라고 할 수도 있겠죠. 이 경우에도 게임의 룰이란게 동적으로 바뀌는 요소가 아니므로 굳이 파라미터로 매번 받아야 할 필요는 없어 보이고요.
    따라서 제 직관은 모든 흐름 제어(입력, 판정 등)를 game이 가지고 가는게 맞다고 생각해요.

암튼 마음에 들지 않거나 이상한 부분이 있더라도 일단 완성시키는게 더 중요하니까요.
뭐가 더 나은 방법/구현이냐는 좀 더 나중에 따져도 돼요.
완성해놓고봐야 전체적으로 더 잘 보여서 어떻게 수정해야할지 더 명확해지고요.

건강히 돌아오시길 :)

@Bartleby2718
Copy link
Owner Author

  1. 파이썬은 아마 다 pass by refence일 텐데 list 같은 immutable type과 tuple 같은 mutable type으로 나뉘어요. 굳이 immutable을 쓰지 않아도 기능상으로는 문제가 없어서 습관적으로 mutable인 list를 쓰는 경향이 있지만, 바뀌지 않는 것에 대해서는 이름에 맞게 immutable을 쓰고 싶긴 했는데, 이제 쓸 이유가 하나 더 생겼네요. constants.py 보시면 RANKS 같은 걸 원래도 tuple로 해 놨어요. 역시 로우레벨에 대한 이해가 부족하다 보니 '왜'에 대한 부분이... 흠...

  2. GameDuel의 관계(?)가 이상하다는 생각은 줄곧 했는데, 그러면서도 막상 둘이 코드상에서 '어떻게' 엮여 있는지는 생각해 본 적이 없네요; 지금 보니 DeckCard의 배열+a로 구성되어 있는 반면에, GameDuel은 진행 중인 듀얼만 Game.duel_ongoingDuel로 설정되어 있지 따로 엮여 있지는 않네요. 허허... 그래서 GameDuel의 역할을 혼동했나 봐요.

나중에 리팩토링하는 것보다 기술 부채가 쌓이기 전에 리팩토링하는 게 나을 것 같아서요. 며칠 커밋이 밀리기만 해도 커밋하기 힘든데, 구조가 굳어져 버리면...;

감사합니다!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants