Expectiminimax로 Python에서 2048 게임 깨기
테이블 목차
- 서문
- 게임 소개
- 게임 모델링
- 보드 클래스
- 빈 타일 가져오기
- 타일 추가하기
- 타일 이동하기
- 게임 종료 확인하기
- 게임 플레이
- 게임 보드 출력하기
- 키보드 입력 처리하기
- 게임 루프 실행하기
- AI 알고리즘 설명
- Expecting Minimax 알고리즘
- 휴리스틱 함수
- AI 모듈 구현하기
- AI와 게임 연동하기
- 결과 및 향후 연구 방향
- 결론
알고리즘으로 2048 게임 클리어하기 🎮
서문
안녕하세요! 오늘은 2048 게임을 똑똑한 AI 알고리즘을 사용하여 클리어하는 방법에 대해 얘기해보려고 합니다. 2048 게임은 타일들을 합치면서 최종 목표인 2048 타일을 획득하는 게임입니다. 저는 퍼즐을 푸는 능력에 자부심을 가지고 있지만, 이 게임은 어떻게 해도 클리어를 해본 적이 없는데요. 이번 비디오에서는 이 게임을 해결하는 알고리즘을 소개하고, 해당 알고리즘을 Python으로 구현해보겠습니다. 게임 보드를 모델링하고, 게임을 직접 플레이할 수 있는 기능을 추가한 뒤, Expecting Minimax 알고리즘을 이용하여 AI가 게임을 대신 플레이하도록 할 것입니다. 자세한 내용은 아래에서 차근차근 설명하겠습니다. 시작해봅시다!
2. 게임 소개
2048 게임은 4x4 크기의 게임 보드에서 시작합니다. 보드에는 초기에 2개의 타일이 무작위로 위치해 있습니다. 게임 플레이어는 상하좌우 네 방향 중 하나를 선택하여 타일들을 이동시킬 수 있습니다. 이동된 타일들 중 같은 값을 가지는 두 개의 타일이 충돌하면 합쳐지고, 그 값이 더해진 새로운 타일이 생성됩니다. 게임이 진행될수록 타일들은 점점 더 큰 값으로 합쳐지며, 목표인 2048 타일을 얻을 수 있을까요? 이제 게임을 모델링하고, 플레이하는 방법을 알아보겠습니다.
3. 게임 모델링
3.1. 보드 클래스
게임 보드를 모델링하기 위해 Board
클래스를 만들겠습니다. 이 클래스는 사용자가 지정한 사이즈로 보드를 초기화하고, 보드 위에 있는 빈 타일의 좌표를 가져오는 기능이 있어야 합니다. 또한 턴마다 새로운 타일을 추가하고, 타일들을 상하좌우로 이동시키는 기능도 필요합니다. 게임이 종료되었는지 확인하는 기능 또한 구현할 것입니다.
3.2. 빈 타일 가져오기
게임 보드에서 빈 타일의 좌표를 가져오는 get_empty_tiles()
메서드를 만들겠습니다. 이 메서드는 보드 상의 모든 좌표를 확인하여 값이 0인 빈 타일들의 좌표를 리턴합니다. 이 좌표들은 나중에 새로운 타일을 추가할 때 사용될 것입니다.
3.3. 타일 추가하기
게임 보드에 턴이 끝난 후 새로운 타일을 추가하기 위해 add_tile()
메서드를 구현하겠습니다. 이 메서드는 빈 타일의 좌표 중 하나를 선택하고, 90%의 확률로 값이 2인 타일을 추가하거나 10%의 확률로 값이 4인 타일을 추가합니다. 이를 통해 게임 보드에 새로운 타일을 계속해서 추가할 수 있습니다.
3.4. 타일 이동하기
사용자가 입력한 방향에 따라 타일들을 이동하는 move_tiles()
메서드를 구현하겠습니다. 이를 위해 각각의 방향에 따라 타일들을 순서대로 이동시켜야 합니다. 만약 같은 값의 두 개의 타일이 충돌하면 합쳐지고, 그 값이 더해져서 새로운 타일이 생성됩니다. 이러한 이동과 충돌을 모든 타일에 대해 체크하는 로직을 구현할 것입니다.
3.5. 게임 종료 확인하기
게임이 종료되었는지 확인하기 위해 check_gameover()
메서드를 만들겠습니다. 이 메서드는 보드 상에 더 이상 이동할 수 있는 빈 타일이 없거나, 두 개의 같은 값을 가진 타일이 충돌하지 않는 경우를 확인하여 게임 종료 여부를 판단할 것입니다.
4. 게임 플레이
4.1. 게임 보드 출력하기
게임 보드를 출력하는 draw_board()
함수를 만들겠습니다. 이 함수는 게임 보드를 콘솔에 출력하여 사용자에게 보여줄 것입니다. 타일들은 숫자로 표현되며, 타일의 값에 따라 색상도 조정될 것입니다. 또한 스코어도 화면 아래쪽에 출력하여 사용자에게 정보를 제공할 것입니다.
4.2. 키보드 입력 처리하기
사용자의 키보드 입력을 처리하고, 해당 입력에 따라 게임 보드를 이동시키는 handle_input()
함수를 만들겠습니다. 여기서는 방향키를 입력받아 이동할 방향을 판단하고, 그에 따라 게임 보드를 업데이트할 것입니다. 게임을 종료하거나 게임을 새로 시작할 수 있는 기능도 추가할 예정입니다.
4.3. 게임 루프 실행하기
game_loop()
함수를 만들어 게임 루프를 실행하겠습니다. 이 함수는 게임을 초기화하고, 사용자의 입력을 반복적으로 처리하여 게임 보드를 업데이트하고 출력합니다. 게임이 종료될 때까지 이 반복 과정이 계속될 것입니다.
5. AI 알고리즘 설명
5.1. Expecting Minimax 알고리즘
2048 게임을 대신 플레이하는 AI 알고리즘으로 Expecting Minimax 알고리즘을 사용할 것입니다. Expecting Minimax 알고리즘은 미니맥스 알고리즘의 변형인데, 확률적인 이동에 대한 고려도 추가되어 있습니다. 각 깊이마다 플레이어가 점수를 최대화하려는 경향이 있고, 상대플레이어의 점수를 최소화하려는 경향도 있습니다. 이를 통해 최적의 다음 수를 결정할 수 있는데, 이 알고리즘을 이용하여 게임을 플레이하는 AI를 구현하겠습니다.
5.2. 휴리스틱 함수
Expecting Minimax 알고리즘에서 사용할 휴리스틱 함수는 보드의 패턴을 판단하여 얼마나 좋은 패턴인지를 평가합니다. 이 때 주로 사용하는 패턴은 "뱀 모양" 패턴입니다. 뱀 모양 패턴은 타일들이 이어져 있는 형태로 배치되어 있을 때, 타일들을 쉽게 병합할 수 있고 최대 값은 보드의 가장 아래 모서리에 위치시킬 수 있기 때문에 유리한 상태라고 볼 수 있습니다. 휴리스틱 함수는 이러한 패턴을 고려하여 보드의 가중치를 계산하고 이를 기반으로 점수를 평가할 것입니다.
5.3. AI 모듈 구현하기
AI 모듈에서는 뱀 모양 패턴의 가중치를 반영하는 함수와 Expecting Minimax 알고리즘을 구현할 것입니다. 휴리스틱 함수의 계산 결과에 기반하여 최적의 다음 수를 결정하고, 게임 보드에 새로운 타일을 추가하여 AI가 게임을 대신 플레이하도록 할 것입니다.
5.4. AI와 게임 연동하기
AI 모듈을 게임 모듈과 연동하여 사용자가 스페이스바를 누르면 AI가 게임을 시작하도록 할 것입니다. AI가 보드를 분석하고, Expecting Minimax 알고리즘을 사용하여 최적의 다음 수를 결정합니다. 게임 보드를 이동시키고, 스코어를 업데이트하여 AI가 게임을 대신 플레이하는 과정을 시각적으로 확인할 수 있습니다.
6. 결과 및 향후 연구 방향
이번 프로젝트에서는 Expecting Minimax 알고리즘을 이용하여 2048 게임을 클리어할 수 있는 AI를 구현해보았습니다. AI의 성능은 깊이와 휴리스틱 함수에 따라 달라질 수 있습니다. 게임 종료 조건에 따라 알고리즘의 효율성도 달라지며, 최적의 결과를 얻기 위해서는 향후 더 많은 연구와 실험이 필요합니다. 예를 들어 더 나은 휴리스틱 함수를 찾거나, 패턴이 깨지는 경우에 대한 대응 전략을 고안해야 합니다. 여러분들도 이 분야에서 새로운 아이디어를 제시할 수 있으니, 제게 의견을 보내주시길 바랍니다.
7. 결론
오늘은 Expecting Minimax 알고리즘을 사용하여 2048 게임을 클리어하는 AI를 구현하는 방법에 대해 알아보았습니다. 게임 보드의 모델링부터 실제 게임 플레이, 그리고 AI 알고리즘의 구현까지 차근차근 알려드렸습니다. 이 프로젝트를 통해 알고리즘과 게임 플레이에 대해 더 깊은 이해를 갖게 되었으면 좋겠습니다. 어려운 내용이었지만, 단계별로 진행하면서 스스로도 가능할 거라고 믿습니다. 저는 이런 종류의 프로젝트를 통해 계속해서 새로운 도전을 즐기고 있으며, 여러분들도 도전해보시기를 권장합니다. 끝으로 이 비디오를 시청해주셔서 감사합니다. 질문이나 제안이 있으시면 언제든지 댓글로 남겨주세요. 구독해주시고 앞으로도 제 채널에서 다양한 알고리즘과 AI 관련 프로젝트를 만나보시길 바랍니다. 즐거운 하루 되세요!