드디어 마지막 미션입니다.
마지막 미션은 다리 건너기입니다.
요구 사항은 다음과 같습니다.
기능 요구 사항
위아래 둘 중 하나의 칸만 건널 수 있는 다리를 끝까지 건너가는 게임이다.
- 위아래 두 칸으로 이루어진 다리를 건너야 한다.
- 다리는 왼쪽에서 오른쪽으로 건너야 한다.
- 위아래 둘 중 하나의 칸만 건널 수 있다.
- 다리의 길이를 숫자로 입력받고 생성한다.
- 다리를 생성할 때 위 칸과 아래 칸 중 건널 수 있는 칸은 0과 1 중 무작위 값을 이용해서 정한다.
- 위 칸을 건널 수 있는 경우 U, 아래 칸을 건널 수 있는 경우 D값으로 나타낸다.
- 무작위 값이 0인 경우 아래 칸, 1인 경우 위 칸이 건널 수 있는 칸이 된다.
- 다리가 생성되면 플레이어가 이동할 칸을 선택한다.
- 이동할 때 위 칸은 대문자 U, 아래 칸은 대문자 D를 입력한다.
- 이동한 칸을 건널 수 있다면 O로 표시한다. 건널 수 없다면 X로 표시한다.
- 다리를 끝까지 건너면 게임이 종료된다.
- 다리를 건너다 실패하면 게임을 재시작하거나 종료할 수 있다.
- 재시작해도 처음에 만든 다리로 재사용한다.
- 게임 결과의 총 시도한 횟수는 첫 시도를 포함해 게임을 종료할 때까지 시도한 횟수를 나타낸다.
- 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다.
- Exception이 아닌 IllegalArgumentException, IllegalStateException 등과 같은 명확한 유형을 처리한다.
출력 요구 사항
- 게임 시작 문구
다리 건너기 게임을 시작합니다.
- 게임 종료 문구
최종 게임 결과
[ O | | ]
[ | O | O ]
게임 성공 여부: 성공
총 시도한 횟수: 2
- 사용자가 이동할 때마다 다리 건너기 결과의 출력 형식은 실행 결과 예시를 참고한다.
- 이동할 수 있는 칸을 선택한 경우 O 표시
- 이동할 수 없는 칸을 선택한 경우 X 표시
- 선택하지 않은 칸은 공백 한 칸으로 표시
- 다리의 시작은 [, 다리의 끝은 ]으로 표시
- 다리 칸의 구분은 |(앞뒤 공백 포함) 문자열로 구분
- 현재까지 건넌 다리를 모두 출력
- 예외 상황 시 에러 문구를 출력해야 한다. 단, 에러 문구는 "[ERROR]"로 시작해야 한다.
추가된 요구 사항
- 함수(또는 메서드)의 길이가 10라인을 넘어가지 않도록 구현한다.
- 함수(또는 메서드)가 한 가지 일만 잘하도록 구현한다.
- 메서드의 파라미터 개수는 최대 3개까지만 허용한다.
- 아래 있는 InputView, OutputView, BridgeGame, BridgeMaker, BridgeRandomNumberGenerator 클래스의 요구사항을 참고하여 구현한다.
- 각 클래스의 제약 사항은 아래 클래스별 세부 설명을 참고한다.
- 이외 필요한 클래스(또는 객체)와 메서드는 자유롭게 구현할 수 있다.
- InputView 클래스에서만 camp.nextstep.edu.missionutils.Console 의 readLine() 메서드를 이용해 사용자의 입력을 받을 수 있다.
- BridgeGame 클래스에서 InputView, OutputView 를 사용하지 않는다.
3주차 미션에서는 마지막에 MVC 패턴을 적용하느라 힘들었지만, 이번에는 시작부터 MVC 패턴을 적용하였습니다. 그래도 지난번에 한 번 해봤다고 이번에는 조금 수월했던 것 같습니다. 그래도 여전히 제가 작성한 것이 맞는지 알 수가 없었고, 다른 분들이 피어리뷰를 하는 이유를 깨달았습니다. 저는 아직 코드 리뷰가 두려워해보지 못했는데요, 이렇게 혼자 답답해하고 있을 바에 코드 팩폭 당하는 게 낫겠습니다..ㅠㅠ
저는 그동안 제가 코드 포맷팅을 열심히 하고 있다고 생각했는데, 전혀 아니었습니다. IntelliJ에서의 코드 포맷팅은 Ctrl + Alt + L을 사용하는데요, 전체적으로 포맷팅 되는 것이 아니라 제가 작성 중인 코드 내에서만 포맷팅이 된다는 것을 깨달았습니다. 변경사항이 생기고 바로 포맷팅을 했으면 되는 일인데, 아직 습관이 되지 않아 '아! 포맷팅 안 했지'하고 한 번에 처리하곤 했습니다. 모니터 앞에 Ctrl + S처럼 메모지로 붙여놓아야 할지도 모르겠습니다.
지난번에 enum 클래스 활용하여 로또 미션을 수행했었는데요, 이번에는 그런 요구사항은 없었으나 복습하는 의미에서 이번에도 enum 클래스를 사용하고자 했습니다. 현재까지 다리를 건넌 진행 상황을 출력할 때, 다리 건너기의 게임 결과가 enum 클래스로 관리되면 단순하게 기능을 구현할 수 있을 것 같아 여기에 적용해보았습니다.
파라미터로는 게임 결과에 따라 위 칸, 아래 칸 별로 출력해야 할 문자열을 담아두었습니다.
/*
* UP_WIN - 플레이어: U, 다리 상태: U 인 경우
* UP_LOSE - 플레이어: U, 다리 상태: D 인 경우
* DOWN_WIN - 플레이어: D, 다리 상태: D 인 경우
* DOWN_LOSE - 플레이어: D, 다리 상태: U 인 경우
* */
enum class BridgeResult(
val upState: String,
val downState: String
) {
UP_WIN("O", " "),
UP_LOSE("X", " "),
DOWN_WIN(" ", "O"),
DOWN_LOSE(" ", "X")
}
로또 미션에서 테스트 코드를 작성할 때 파라미터만 바뀔 뿐 동일한 테스트 메서드가 있었습니다. 2주 차 숫자 야구 피드백 영상에서 마지막 부분에 이를 애노테이션을 활용하여 변경한 부분이 있어 적용하려고 했는데요, 미처 적용하지 못해 아쉬움이 남았었습니다. 이번에는 파라미터만 바뀌고 반복적으로 테스트해야 할 메서드는 @ValueSource와 @ParameterizedTest 애노테이션을 사용하여 작성해보았습니다.
유튜브에 [10분 테코 톡, 바다의 JUnit5] 강의가 있길래 보다가, @DisplayName 애노테이션을 알게 되어 함께 적용해보았습니다. assertAll도 적용하여 끝까지 중간에 테스트가 실패해도 마지막 assert까지 실행할 수 있도록 하려고 했는데요, 오류가 나서 실패했습니다.ㅠㅠ 다음에는 고치고, 실행하고, 고치고, 실행하고 반복하는 일이 없길 바라며 assertAll을 사용할 수 있으면 좋겠네요.
@DisplayName("다리의 길이가 숫자 형태가 아니면 예외 발생")
@ValueSource(strings = [" ", "a", " 1"])
@ParameterizedTest
fun testBridgeSize(input: String) {
assertThrows<IllegalArgumentException> {
Validator.checkBridgeSize(input)
}
}
이렇게 4주차 마지막 미션도 끝이 났습니다. 프리코스 모두 고생하셨습니다.
최종 코딩테스트 자격은 거의 한 달 뒤쯤 결과가 나오더라구요! 자격이 주어질지는 모르겠지만 주어진다면 바로 3일뒤가 최종 코테이기 때문에 미리 준비해둬야 할 것 같습니다.
리스트 문자열 출력
joinToString
- 리스트의 요소를 문자열로 출력
예제1
fun main(args: Array<String>) {
val numbers = listOf<String>("H", "E", "L", "L", "O")
println(numbers.joinToString(""))
}
separator (구분자)를 jointToString("") 처럼 준다면 위와 같이 리스트의 요소가 붙어서 문자열로 출력됩니다.
예제2
fun main(args: Array<String>) {
val numbers = listOf<String>("H", "E", "L", "L", "O")
println(numbers.joinToString(" * "))
}
만약 다른 구분자를 준다면 아래와 같이 출력됩니다.
예제3
fun main(args: Array<String>) {
val numbers = listOf<String>("H", "E", "L", "L", "O")
println(numbers.joinToString(prefix = "<< ", separator = " * ", postfix = " >>"))
}
prefix와 postfix를 사용하면 문자열의 시작과 끝에 사용할 문자열을 입력할 수 있습니다.
'Android > 우아한테크코스 5기' 카테고리의 다른 글
[우아한테크코스 5기 프리코스] 안드로이드 3주차 회고록 (0) | 2022.11.23 |
---|---|
[우아한테크코스 5기 프리코스] 안드로이드 2주차 회고록 (0) | 2022.11.16 |
[우아한테크코스 5기 프리코스] 안드로이드 1주차 회고록 (0) | 2022.11.08 |