아두이노 터치스크린 틱택토 게임 만들기: 단계별 튜토리얼
부품 및 소모품
| 부품 |
수량 |
| 아두이노 우노 (Arduino UNO) |
1 |
| 2.8인치 터치스크린 |
1 |
앱 및 온라인 서비스
프로젝트 소개
여러분 안녕하세요! 또 다른 아두이노 튜토리얼에 오신 것을 환영합니다. 이번 상세 튜토리얼에서는 아두이노 틱택토 게임을 만들어보겠습니다. 보시는 것처럼 터치스크린을 사용하며 컴퓨터와 대결하게 됩니다. 틱택토 같은 간단한 게임은 게임 프로그래밍과 인공지능 입문에 훌륭한 교재가 됩니다. 이번 프로젝트에서는 인공지능 알고리즘을 사용하지 않지만, 더 복잡한 게임에서 왜 AI 알고리즘이 필요한지 이해할 수 있을 것입니다.
아두이노용 게임 개발은 쉽지 않고 많은 시간이 필요합니다. 하지만 재미도 있고 인공지능 같은 고급 프로그래밍 주제를 탐구할 수 있어 간단한 게임 정도는 만들어볼 만합니다. 훌륭한 학습 경험이 될 것이고, 마지막엔 아이들을 위한 멋진 게임이 하나 생길 것입니다!
이제 프로젝트를 시작해봅시다.
1단계: 모든 부품 준비하기
이 프로젝트에 필요한 부품은 다음과 같습니다:
- 아두이노 우노 1개
- 2.8인치 터치스크린 1개
프로젝트 비용은 매우 저렴합니다. 약 15달러(약 2만 원)면 충분합니다.
이 프로젝트를 시작하기 전에 제가 준비한 터치 디스플레이 관련 영상을 시청하시길 권장합니다. 코드 이해와 터치스크린 캘리브레이션에 도움이 됩니다.
2단계: 아두이노용 2.8인치 터치 컬러 디스플레이
이 터치스크린은 banggood.com에서 발견했는데, 가격이 약 11달러로 매우 저렴해서 테스트 삼아 구매했습니다.
구매 링크
해상도는 320x240 픽셀이며, 쉴드 형태로 제공되어 아두이노 우노와 연결이 매우 간편합니다. 다만 이 쉴드를 사용하면 아두이노 우노의 디지털 핀과 아날로그 핀을 거의 모두 차지하게 되어, 남은 핀은 디지털 2개, 아날로그 1개뿐입니다. 다행히 아두이노 메가와도 호환되므로 핀이 더 필요하면 메가를 사용하면 됩니다. 아두이노 두(Due)나 Wemos D1 ESP8266 보드에서는 작동하지 않습니다. 또 다른 장점은 마이크로 SD 카드 슬롯이 내장되어 있어 사용이 쉽다는 점입니다.
3단계: 프로젝트 조립 및 테스트
스크린을 아두이노 우노에 연결한 후 코드를 업로드하면 바로 플레이할 수 있습니다.
먼저 "게임 시작" 버튼을 누르면 게임이 시작되고, 아두이노가 먼저 둡니다. 그런 다음 화면을 터치해 내 수를 둘 수 있습니다. 아두이노가 수를 두고, 이를 반복합니다. 가로, 세로, 대각선 중 한 줄에 세 개의 표시를 먼저 완성하는 쪽이 승리합니다. 게임이 끝나면 "게임 오버" 화면이 뜨고, "다시 하기" 버튼으로 새 게임을 시작할 수 있습니다.
아두이노는 이 게임을 매우 잘합니다. 대부분의 게임에서 이기거나, 플레이어가 아주 잘해도 무승부로 끝납니다. 저는 인간 플레이어에게도 승리할 기회를 주기 위해 알고리즘이 의도적으로 실수하도록 설계했습니다. 코드에 두 줄만 추가하면 아두이노가 절대 지지 않게 만들 수 있습니다. 그런데 2달러짜리 칩인 아두이노 CPU가 어떻게 인간의 두뇌를 이길 수 있을까요? 우리가 만든 프로그램이 인간의 두뇌보다 더 똑똑한 걸까요?
4단계: 게임 알고리즘
이 질문에 답하려면 제가 구현한 알고리즘을 살펴봐야 합니다.
컴퓨터가 항상 먼저 둡니다. 이 결정만으로도 아두이노가 이기기 훨씬 쉬워집니다. 첫 수는 항상 모서리 중 하나입니다. 두 번째 수도 남은 모서리 중 무작위로 선택하며, 플레이어의 수는 전혀 고려하지 않습니다. 그 이후부터는 아두이노가 먼저 플레이어가 다음 수에 이길 수 있는지 확인하고, 그렇다면 그 수를 막습니다. 플레이어가 한 번에 이길 수 없다면, 가능한 모서리에 두거나 남은 칸 중 무작위로 둡니다. 이게 전부입니다. 이 간단한 알고리즘만으로도 인간 플레이어를 매번 이기거나, 최악의 경우 무승부로 끝낼 수 있습니다. 이건 최적의 틱택토 알고리즘은 아니지만, 가장 단순한 것 중 하나입니다.
이 알고리즘은 틱택토가 매우 간단한 게임이라 쉽게 분석하고 해결할 수 있어 아두이노에서 구현하기 쉽습니다. 게임 트리를 설계하면 승리 전략을 발견해 코드로 구현하거나, CPU가 실시간으로 게임 트리를 계산해 최적의 수를 선택하게 할 수도 있습니다. 물론 이번에 쓴 알고리즘은 게임이 간단하니 아주 단순합니다. 체스 같은 게임에서 승리 알고리즘을 설계하려면, 가장 빠른 컴퓨터로도 게임 트리를 계산하는 데 천 년이 걸릴 겁니다! 그런 게임엔 다른 접근법, 즉 인공지능 알고리즘과 막대한 연산 능력이 필요합니다. 이에 대해선 나중에 자세히 다루겠습니다.
5단계: 프로젝트 코드
프로젝트 코드를 간단히 살펴보겠습니다. 컴파일하려면 세 가지 라이브러리가 필요합니다.
- 수정된 Adafruit TFTLCD
- Adafruit GFX
- Touchscreen
보시다시피 이런 간단한 게임도 600줄이 넘는 코드가 필요합니다. 코드가 복잡해 짧은 튜토리얼에서 전부 설명하긴 어렵습니다. 아두이노의 수를 결정하는 알고리즘 구현 부분만 보여드리겠습니다.
먼저 두 번의 무작위 모서리 수를 둡니다.
int firstMoves[]={0,2,6,8}; // 첫 수로 사용할 위치들
for(counter=0; counter<4; counter++) { // 둔 첫 수 개수 세기
if(board[firstMoves[counter]]!=0) { // 누군가 첫 수를 뒀다면
movesPlayed++;
}
}
do {
if(moves<=2) {
int randomMove = random(4);
int c = firstMoves[randomMove];
if (board[c]==0) {
delay(1000);
board[c]=2;
Serial.print(firstMoves[randomMove]);
Serial.println();
drawCpuMove(firstMoves[randomMove]);
b=1;
}
}
}
매 라운드마다 플레이어가 다음 수에 이길 수 있는지 확인합니다.
int checkOpponent() {
if(board[0]==1 && board[1]==1 && board[2]==0) return 2;
else if(board[0]==1 && board[1]==0 && board[2]==1) return 1;
else if (board[1]==1 && board[2]==1 && board[0]==0) return 0;
else if (board[3]==1 && board[4]==1 && board[5]==0) return 5;
else if (board[4]==1 && board[5]==1 && board[3]==0) return 3;
else if (board[3]==1 && board[4]==0 && board[5]==1) return 4;
else if (board[1]==0 && board[4]==1 && board[7]==1) return 1;
else return 100;
}
이길 수 있다면 그 수를 막습니다(대부분의 경우). 인간에게 기회를 주기 위해 모든 수를 막지는 않습니다. 어떤 수를 안 막는지 찾아보세요. 막은 후에는 남은 모서리에 두거나 무작위 수를 둡니다. 코드를 연구해 자신만의 필승 알고리즘을 구현해보세요. 언제나처럼 프로젝트 코드는 이 튜토리얼에 첨부되어 있습니다.
참고: Banggood에서 같은 디스플레이를 두 가지 다른 드라이버로 판매하므로, 위 코드가 작동하지 않으면 initDisplay 함수를 다음과 같이 변경하세요:
void initDisplay() {
tft.reset();
tft.begin(0x9341);
tft.setRotation(3);
}
6단계: 마무리 생각과 개선점
보시다시피 아두이노 우노만으로도 간단한 게임의 필승 알고리즘을 구현할 수 있습니다. 이 프로젝트는 만들기 쉽고, 동시에 인공지능과 게임 프로그래밍 입문으로 훌륭합니다. 앞으로 더 강력한 라즈베리파이를 이용해 더 고급 AI 프로젝트를 시도해볼 예정이니 기대해 주세요! 여러분의 의견도 들려주세요.
아래에 댓글 남겨주시고, 재미있으셨다면 좋아요도 부탁드립니다. 감사합니다!