개요
2048 은 가장 처음으로 떠올린 순수 javascript
로 수월하게 만들 수 있는 게임이다. 게임의 상태가 항상 정적인 보드판 안에서 진행되고 조작 또한 4 방향 키 움직임이 전부이기 때문이다. 그리고 2048 이 떠오른 결정적인 사건은 코딩테스트 공부 중에 있었다. 백준에서 삼성 SW 역량테스트 기출문제를 풀다가 이 문제 를 보고나서 이왕 문제를 풀 겸 2048 자체도 만들어보자는 생각이 들었다.
제작
외관
우선 가장 처음으로 만들어야 할 것은 게임의 전체적인 외관이었다. 이 게임은 간단한 4x4 격자 형식의 보드판이 전부였고 추가해야 할 것은 점수판 정도였다. 4x4 격자는 html
의 table
태그를 이용해 구현했고 css
로 모양을 만들어주었다.
칸 하나하나를 id
를 통해 접근할 수 있도록 각 칸의 id
를 좌표
로 설정하여 구분하였다.
로직
게임에 들어가는 로직은 다음과 같이 크게 4가지로 구분된다.
- 숫자의 생성
- 숫자의 이동
- 게임 오버
- 점수 판정
숫자의 생성
숫자가 생성되는 타이밍은 다음과 같이 2가지 경우이다.
- 게임 시작 시
- 플레이어가 유효한 숫자이동을 했을 시
숫자 생성 확률은 원작 2048
을 여러번 실행해보며 깨달은 확률적 수치를 적용하였다.
10번 중 4
는 1번 꼴로 등장하고 나머지는 전부 2
가 생성됨을 확인해서 90% 확률로 2
, 10% 확률로 4
가 새로 생성되게끔 하였다. 확률 관련 내용은 모두 랜덤 함수를 통해 구현하였다.
숫자의 이동
숫자의 이동은 2048
게임의 핵심 로직이다. 또한 위에서 언급한 삼성 SW 역량테스트 문제의 해답이기도 하다. 이 게임에서 숫자의 이동 규칙은 다음과 같다.
- 보드판 위의 숫자를 상 하 좌 우 로 이동할 수 있으며 한 번 이동 시 모든 숫자들이 같은 방향으로 갈 수 있는 만큼 최대한 이동한다.
- 숫자들이 이동할 때 같은 숫자끼리 충돌 시 둘이 합쳐져 하나의 블록이 되고 블록의 숫자는 두 블록의 합이 된다.
- 한 번의 이동으로 하나의 블록이 연쇄적으로 여러번 합쳐질 수 없다.
그리고 상하좌우 4방향에 대해 모두 따로 구현하는 방법도 있지만 필자는 숫자의 이동을 한 방향에 대해서만 구현한 후, 나머지 방향은 보드판 자체를 회전시킴으로써 해결했다. 예를 들어 위
방향에 대해서만 구현한 경우 왼쪽
으로 이동하려는 경우 보드판을 시계방향
으로 회전한 후 위로
이동시키고 다시 반시계방향
으로 보드판을 돌려주면 왼쪽
으로 이동시킨 것과 동일하다. 이 때 보드판의 회전 과정에서 성능상의 문제가 언급될 수 있지만 보드판은 4x4 사이즈로 매우 작으므로 수십번을 회전시킨다 해도 무리가 없기 때문에 성능 이슈는 사실상 없다.
숫자의 이동 시 보드판에 변화가 있었다면 새로운 숫자를 생성하고 그렇지 않다면 게임 오버인지 체크한다.
게임 오버
게임 오버가 되는 경우는 다음과 같은 조건을 만족할 때이다.
- 보드판의 숫자가 모두 꽉차있다.
- 숫자를 이동시켜 합칠 수 있는 숫자가 아무것도 없다.
게임 오버 시에는 최종 점수를 alert
를 이용해 표시하도록 하였다.
점수 반영
게임에서 점수는 다음과 같이 계산된다.
숫자를 합하여 만든 숫자들의 합
따라서 점수는 숫자의 이동
시 만들어진 숫자를 누적시켜주기만 하면 된다.
관련 코드는 숫자의 이동 함수에서 score
변수에 값을 더해주는 것에서 확인할 수 있다.
마무리
실제로 만들어 플레이 해 본 바로는 간단하게 구현한 것 치고는 꽤 완성도가 높다는 것이다. 애초에 2048
게임 자체가 간단하고 중독성 있었던 만큼 거의 그대로 완전히 구현해냈기 때문에 꽤 만족스러운 결과물이 나왔다. 자바스크립트로 만든 HTML
형식의 게임은 github
블로그에 직접 삽입이 가능해서 아래 링크를 통해 직접 플레이 할 수 있게 하였다.
직접 플레이 해보기: https://yjyoon-dev.github.io/games/2048.html
전체 코드는 github
저장소를 참고해주기 바란다.
https://github.com/yjyoon-dev/vanilla-javascript-game/tree/master/2048
- Post link: https://blog.yjyoon.dev/project/2020/11/13/jsgame-2048/
- Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.