- 변형된 규칙의 체스 게임을 구현하는 미션
- DB: JDBC, 이벤트 소싱을 통한 MySQL 데이터베이스 관리
- WEB: Spark.java, Mustache 템플릿 엔진
- Docker 컨테이너를 통한 개발환경 공유
-
전통적인 데이터 관리 방법: 생존한 체스말들의 현재 위치를 DB에 저장하고 체스말의 움직임에 따라 체스말 데이터를 변경.
- 매번 일일이 현재 최종 상태에 부합하도록 개별 데이터를 변경해줘야 함.
-
이벤트 소싱: 체스게임 시작 여부, 체스말의 움직임 등의 이벤트를 DB에 저장.
- 여태까지 발생한 모든 이벤트를 조회함으로써 현재 상태를 재구현 가능. 이때 상태패턴/오토마타 활용하면 용이함.
- 앙파상, 캐슬링 등은 이전에 폰이 두 칸을 움직였는가, 킹/룩이 움직이지 않았는가 등의 정보를 요구함.
- 현재 위치 정보만으로는 이러한 기능을 구현할 수 없지만 기록 자체를 저장함으로써 쉽게 구현할 수 있게 됨.
-
DB/웹 연동 없이 터미널 입출력만을 통해 게임 진행
-
start를 입력받으면 즉시 새로운 체스 게임을 시작한다. 기존 게임이 존재하는 경우 보드를 초기화한다. -
게임이 진행 중인 경우,
move source target를 입력받으면source에 위치한 체스말을target으로 이동시킨다. -
게임 종료 후
status를 입력받으면 각 진영의 점수와 승리자 정보를 출력한다. -
end를 입력받으면 즉시 프로그램을 종료한다. -
명령어 형식이 잘못된 경우, 다시 입력을 요구한다.
-
현재 게임 상태에 적용될 수 없는 명령어인 경우, 다시 입력을 요구한다.
- 웹/DB 연동을 통해 복수의 게임을 저장하며 진행
- 새로운 게임 시작 버튼을 누르면 신규 게임 시작 후
/game/:id라우트로 이동한다.- 버튼을 누르면
/new-game으로 POST 요청 전송. /new-game에서는 서버에서는 게임 생성 후 해당 게임에 할당된id값을 JSON으로 반환.- 해당 게임에 할당된
id값을 라우트에 담아/game/:id로 이동.
- 버튼을 누르면
- 기존 게임 재개 버튼을 누르면
/search라우트로 이동한다.
- form에서
id값을 입력받아 그에 대응되는 게임을 찾는다.-
id값에 대응되는 게임이 존재하는 경우/game/:id라우트로 이동한다. -
id값에 대응되는 게임이 존재하지 않는 경우 알람으로 예외 메시지를 보여주며 페이지는 변하지 않는다. -
id값에 숫자 이외의 값이 입력되는 경우 알람으로 예외 메시지를 보여주며 페이지는 변하지 않는다.
-
-
id값에 대응되는 게임의 현재 체스말 위치 정보에 따른 체스보드와 게임 상태 정보가 화면에 제시된다.- 이동/공격 명령은 체스말 클릭을 통해 입력받는다.
- 각 턴이 종료될 때마다 해당 게임의 상태와 모든 체스말에 대한 정보는 DB에 저장된다.
- DB 저장 작업이 종료되었을 때 게임이 진행 중인 경우, 같은
/game/:id화면을 보여준다. - 이동과 공격 관련 세부 로직은 콘솔 애플리케이션과 동일하다.
- 이동/공격 명령은 체스말 클릭을 통해 입력받는다.
-
id값에 대응되는 게임이 종료된 경우/result/:id라우트로 이동하는 버튼을 제공한다.- 게임 결과 조회 이외의 작업은 불가능하도록 팝업으로 화면을 가린다.
-
id값은 숫자이며, 아직 대응되는 게임이 생성되지 않은 경우 게임을 실행할 수 없도록 한다.
- 종료된 게임에 대한 점수, 승자, 최종적인 보드 정보를 화면에 보여준다.
- 체스 게임이 시작되면 체스판을 초기화한다.
- 각 행은 아래부터 1~8행으로 구성된다.
- 각 열은 좌측부터 a~h열로 구성된다.
- 백색 진영은 아래쪽에, 흑색 진영은 위쪽에 위치한다.
- 2행과 7행은 각각 8개의 폰(Pawn)들로 구성된다.
- 1행과 8행은 각각 2개의 룩(Rook), 2개의 나이트(Knight), 2개의 비숍(Bishop), 퀸(Queen)과 킹(King)으로 구성된다.
- 체스 게임이 진행되는 동안 백색과 흑색 진영이 1번씩 순서대로 돌아가며 체스 말을 이동시킨다.
- 현재 차례인 진영의 색깔이 아닌 체스 말을 이동시키려는 경우 예외가 발생한다.
-
move source target형식으로 입력받았을 때target에 체스 말이 없는 경우 해당 위치로 이동시킨다. -
source와target이 존재하지 않는 위치인 경우 예외가 발생한다. -
source에 해당되는 체스 말이 없는 경우 예외가 발생한다. -
체스 말의 이동 가능 범위에
target이 포함되어 있지 않은 경우 예외가 발생한다.- 기본적으로 해당 체스 말의 이동 규칙에 부합하지 않는 경우 예외가 발생한다.
- 이동하려는 위치에 도달하기까지 다른 체스 말이 가로막고 있는 경우 예외가 발생한다.
-
move source target형식으로 입력받았을 때target에 다른 색의 체스 말이 존재하는 경우 해당 체스 말을 공격한다. -
체스 말의 공격 가능 범위에 상대방 체스 말이 해당되지 않는 경우 예외가 발생한다.
- 기본적으로 해당 체스 말의 공격 규칙에 부합하지 않는 경우 예외가 발생한다.
- 공격하려는 위치에 도달하기까지 다른 체스 말이 가로막고 있는 경우 예외가 발생한다.
-
target에 같은 색의 체스 말이 존재하는 경우 예외가 발생한다. -
예외가 발생하는 경우 다시 입력을 받는다.
-
킹이 잡히는 경우 즉시 게임이 종료된다.
- 점수와는 별개로 킹을 먼저 잡은 쪽이 승자다.
-
게임 종료 후
status를 입력받으면 각 진영의 점수와 승리자 정보를 출력한다.- 퀸은 9점, 룩은 5점, 비숍은 3점, 나이트는 2.5점, 폰은 1점으로 계산한다.
- 같은 색의 폰이 복수로 존재하는 경우, 해당 폰은 전부 0.5점으로 계산한다.
♜♞♟♛♚♟♞♜ 8 (rank 8)
♝♝♝♝♝♝♝♝ 7
........ 6
........ 5
........ 4
........ 3
♗♗♗♗♗♗♗♗ 2
♖♘♙♕♔♙♘♖ 1 (rank 1)
abcdefgh (files)
- 기본적으로 각 체스 말은 자신만의 방식으로만 이동/공격할 수 있다.
- 체스 말은 현재 위치와 이동하려는 위치 사이에 다른 체스 말이 존재하는 경우, 해당 위치로 이동할 수 없다. (나이트 제외)
- 대부분의 체스 말은 자신이 이동하려는 위치에 다른 색의 체스 말이 있는 경우, 해당 말을 잡을 수 있다. (폰 제외. 킹 부분적 제외)
- 체크 당한 상태에서는 킹이 공격 범위로부터 벗어나게 하는 행동 외에는 행할 수 없다.
- 이동: 기본적으로 앞으로 한 칸만 전진한다.
- 다만, 최초 위치에서 단 한 번 2칸 전진할 수 있다.
- 공격: 전진하는 방향의 대각선으로 한 칸 이동하여 공격한다.
- 상하좌우 1칸을 건너뛰고 해당 방향의 대각선으로 한 칸 이동한다.
- 대각선으로 n칸 이동한다.
- 상하좌우로 n칸 이동한다.
- 상하좌우 혹은 대각선으로 n칸 이동한다.
- 상하좌우 혹은 대각선으로 1칸만 이동한다.
- 이동하려는 위치가 다른 체스 말의 공격범위인 경우, 해당 위치로 이동할 수 없다.