소프티어 부트캠프 2기 체스 프로젝트
- PawnTest 클래스 생성
- create() 테스트 메소드 작성
- 흰색 폰 생성
- 검은색 폰 생성
- create() 테스트 메소드 작성
- Pawn 클래스 구현
- 리팩토링
- 문자열 값 중복 제거를 위해 local variable 추가
- Pawn 생성 및 결과 확인 코드의 중복 제거를 위해 메소드 추가
- Board 클래스 구현
- ArrayList로 여러 개의 Pawn 관리
- Pawn 추가 기능
- PawnTest에 색이 없는 Pawn 생성 테스트 추다
- 색을 상수로
- BoardTest 추가
- Pawn를 체스 판에 추가
- 패키지 분리
- Pawn 외의 객체 추가시 에러 발생시키기
- 중복제거
-
Pawn에 색, 출력할 값을 받는 생성자 추가
-
Pawn에 출력할 값을 리턴하는 getRepresentation 함수 추가
-
Board에 8 * 8로 구성된 체스판을 초기화하는 함수 initialize를 추가
-
Board의 초기화 결과를 출력할 수 있도록, String을 리턴하는 print() 함수 구현
- 검은색 Pawn은 대문자 'P', 흰색은 소문자 'p', 빈칸은 '.'으로 표시
-
Board에 흰색 Pawn과 검은색 Pawn을 저장하는 List를 추가
-
Board 중복 코드 제거 리팩토링
- Pawn 목록의 representation들을 하나의 string으로 만들어주는 부분을 함수로 구현
-
main() 구현
- start 입력시 Board init 후 print되어야 함
- end 입력시 종료되어야 함
- "\n" 반복코드 제거 => System.getProperty("line.separator") 사용
- new line 문자는 운영체제마다 달라질 수 있음!!
- utils.StringUtils 클래스를 추가해 해당 기능을 유틸리티 메소드로 분리한다.
- Pawn 클래스 명을 좀 더 일반적인 이름인 Piece로 rename
- 색상, 이름(기물 종류: pawn, knight,...)을 가짐
- private 생성자를 가져야 하며 인스턴스 생성 후에는 상태를 변경할 수 없어야함(값 객체)
- 색과 이름을 받아 Piece 객체를 생성하는 팩토리 메소드를 구현
- 전체 기물 상태를 볼 수 있는 체스판 구현 및 테스트
- 검은색 말과 흰색 말을 구분할 수 있는 메소드 추가
- 리팩토링
-
기물의 색(Color), 기물의 종류(Type)에 따른 enum 구현
- Color.None -> Color.NO_COLOR로 수정
- Type.None -> Type.NO_PIECE로 수정
- Color, Type을 Piece 클래스 내부로 옮기기
- getRepresentation 대신 getWhiteRepresentation, getBlackRepresentation
-
팩토리 메소드에서 enum 사용
- 기물이 존재하지 않는 Piece도 생성할 수 있도록 Piece.createBlank() 메소드 구현
- Piece.getType() 함수 구현
-
팩토리 메소드 리팩토링
- createWhite(initialType), createBlack(initialType) 구현을 통해 중복 제거
-
체스판의 모든 칸을 Piece로 초기화 -> ArrayList<ArrayList>
- ArrayList 구조로 변경하기 (cf) 체스판에서 row를 Rank라고 부름)
-
기물 종류, 색에 해당하는 기물 개수를 반환하는 로직 구현 (호출 시에 개수를 계산하게)
-
주어진 위치의 기물을 가져오는 메소드 구현 (체스판 좌표 구성)
- 위치를 xy 좌표로 변환하는 작업의 중복을 제거하기 위해 Position class 구현
-
임의의 기물을 체스판에 추가하는 기능
- 빈 체스판을 초기화하는 함수 추가
-
체스 프로그램 점수 계산 기능 추가
- 한 번에 한 쪽의 점수만을 계산해야함
- 현재까지 남아있는 기물에 따라 점수 계산
- 같은 file에 폰이 여러 개 있는 경우 0.5점으로 계산
-
기물의 점수가 높은 순으로 정렬하는 기능 추가
- 검은색과 흰색 각각을 높은순서/낮은 순서로 정렬해보기
- java collection의 정렬 기능을 활용해 점수가 높은 순서에서 낮은 순으로 정렬한다.
-
리팩토링
- 인터페이스 추출
- 요구사항을 만족하는 "최소한의 클래스, 메소드, 중복을 없애는 것"이 중요
-
기물의 이동 구현
- 현재 위치에서 다른 위치로 이동할 수 있는 기능 구현
- 일단 기물 종류 별 이동 원칙은 무시하고, 입력받은 위치로 무조건 이동 가능하게 구현할 것
-
main() 메소드에 move 명령 추가
- 콘솔에서 move 명령을 실행하면 기물이 이동할 수 있어야 함.
- 이동 완료 후 체스판 상태를 콘솔 화면에 출력
-
Board 클래스의 역할 분담
- Board 클래스는 너무 많은 역할을 가지고 있음 -> 여기에 기물 움직임까지 추가하면 너무 복잡 -> 구조를 개선하자
- 8 * 8 체스판을 구현하는 부분 : Board
- 8 * 8 체스판의 구성 관리
- 체스 게임 규칙에 따라 로직을 구현하는 부분 : ChessGame
- 체스판 출력 로직도 별도의 클래스로 분리할 수 있음 : ChessView
-
King 기물의 이동 구현
- king은 어느방향이든 한 칸 움직일 수 있음
- king이 체스판 밖으로 이동하는 경우 등 예외 상황 고려
-
Queen 기물의 이동 구현
- Queen은 직선이라면 몇 칸이라도 이동할 수 있음
- 재귀호출을 써보는것도 괜찮을지도? (종료조건 명확히 할 것!)
-
if문을 제거 하기 위한 다형성
- Piece를 상속하여 각 기물 종류별 class를 구현
-
기물 이동가능 여부 파악을 위해 Direction enum 추가
-
자식 클래스 내에서 중복이 발생하는 부분은 부모로 옮겨보자!
-
상속 구조에 따른 전체 코드 리팩토링
-
위치 예외 처리
- "a1" ~ "h8" 범위를 벗어나는 위치 예외 처리
-
기물이 유효하지 않은 위치로 이동
- 현재 위치에 기물이 존재하지 않음
- 이동하려는 위치가 현재 위치와 같음
- 이동하려는 위치가 기물의 이동 규칙을 따르지 않음
- Pawn은 첫번째 움직일 때는 2칸까지, 이후에는 1칸만 움직일 수 있음
- Pawn이 대각선 방향으로 움직이려면 해당 위치에 상대편 기물이 존재해야 함.
- 이동 위치가 유효하나 같은 편의 기물이 이미 존재함
-
다른 편의 기물을 이동하려고 할 때