1주차 과제를 끝내고 벨로그에 열심히 블로깅을 하면서 코틀린의 기본적인 함수 지식들을 습득할 수 있었다. 솔직히 내가 작성한 코드를 이렇게까지 세세하게 뜯어본 적은 처음이라 내심 뭔가 뿌듯했다,, 이 뿌듯함을 계속 가져가기 위해 앞으로도 노력할 것이다!😉
2주차 과제는 이틀동안 설계 및 코드 작성을 완료했다! 이번에는 MVC패턴
을 지키기 위해 많이 찾아보면서 설계를 진행했다. 또한 테스트 코드도 적용해보기도 하고 커밋 메세지도 카테고리를 나눠서 작성해봤다! 저번에 지키지 못한 몇 가지를 이번에 만회할 수 있도록 노력했다. 하지만 내가 한 방식이 맞는지는 잘 모르겠지만...! 혹시 틀린 부분이 있다면 알려주시면 감사하겠습니다,,🙇♀️
이번 과제의 기능 요구사항에 대해서 알아보자.
초간단 자동차 경주 게임을 구현한다.
- 주어진 횟수 동안 n대의 자동차는 전진 또는 멈출 수 있다.
- 각 자동차에 이름을 부여할 수 있다. 전진하는 자동차를 출력할 때 자동차 이름을 같이 출력한다.
- 자동차 이름은 쉼표(,)를 기준으로 구분하며 이름은 5자 이하만 가능하다.
- 사용자는 몇 번의 이동을 할 것인지를 입력할 수 있어야 한다.
- 전진하는 조건은 0에서 9 사이에서 무작위 값을 구한 후 무작위 값이 4 이상일 경우이다.
- 자동차 경주 게임을 완료한 후 누가 우승했는지를 알려준다. 우승자는 한 명 이상일 수 있다.
- 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분한다.
- 사용자가 잘못된 값을 입력할 경우 IllegalArgumentException을 발생시킨 후 애플리케이션은 종료되어야 한다.
이번 과제의 목표 중 하나인 여러 역할을 수행하는 큰 함수를 단일 역할을 수행하는 작은 함수로 분리한다.
에 걸맞게 프로그래밍 요구 사항이 하나 더 생겼다.
- indent(인덴트, 들여쓰기) depth를 3이 넘지 않도록 구현한다. 2까지만 허용한다.
- 예를 들어 while문 안에 if문이 있으면 들여쓰기는 2이다.
- 힌트: indent(인덴트, 들여쓰기) depth를 줄이는 좋은 방법은 함수(또는 메서드)를 분리하면 된다.
- 함수(또는 메서드)가 한 가지 일만 하도록 최대한 작게 만들어라.
이 요구 사항 덕분에 생각할 거리가 굉장히 많아졌었다! 전에는 for문 안에 if문 넣고 또 for문 넣고 그랬었는데 이러한 더러운 코드가 사라질 수 있게 해주었다!!!😉
먼저 내가 초기에 작성한 기능들과 최종 코드의 기능들이 많이 달라져서 기능 리스트를 계속해서 수정해야했다 ..ㅎㅎ 최종은 다음과 같다!
Model
- 입력받은 자동차 문자열 구분 함수(쉼표로 구분 / 5자 이하)
- 결과 리스트 초기화 함수
- 랜덤 숫자 반환 함수(Randoms.pickNumberInRange(0, 9) 사용)
- 랜덤 숫자가 4이상인지 판별하는 함수
- 결과 리스트의 각 자동차 인덱스에 '-' 문자 추가 함수
- 자동차 전진 함수(0~9 사이의 무작위 값 / 4이상일 때 전진)
- 우승자 판별 함수
View
- 자동차 이름 입력 함수
- 시도 횟수 입력 함수
- 실행 결과 출력 함수
- 최종 우승자 출력 함수
Controller
예외 (IllegalArgumentException)
- 공백을 입력한 경우
- 같은 이름의 자동차를 입력한 경우
- 자동차 이름을 5자 초과한 경우
- 이동횟수에 양수가 아닌 0이나 음수를 입력한 경우
- 이동횟수에 양수가 아닌 다른 타입을 입력한 경우
- 자동차를 하나만 입력한 경우
-> 예외로 처리(레이싱은 두 명 이상일 때 시작 가능)
이런식으로 작성을 해봤는데 이게 MVC패턴
에 적합한지 잘 모르겠다! 또한 Controller
에는 어떠한 내용을 작성해야하는지 잘 모르겠다,, 그냥 Model
과 View
에서 함수를 가져와서 합쳐놓은 것 뿐.. 그리고 파일을 따로 나누지 않고 하나의 파일에 다 때려넣었다...! 어떤식으로 나눠야할지 감을 못잡아서 다른 분들 코드보고 다음에 참고해서 나눠봐야겠다!
제가 작성한 코드 git주소입니다!
보시고.. 고칠점 있으면 다 말해주시면 감사하겠습니다!!!! 모든 피드백 환영이에요!!
이번 과제를 진행하면서 새로 알게된 기능이나 함수들에 대해서 정리를 해보려한다!
저번 과제에서 MutableList
에 대해서 처음 접하고 사용까지 해봤었다. 그 때는 리스트 안에 값을 넣어서 선언을 했었는데, 이번에는 리스트를 먼저 공란으로 만들고 나중에 값을 추가했어야 했다. 그런데 MutableList
을 초기화하는 방법을 알지 못해 살짝 헤맸었다.
내가 사용한 방법은 두 번째 방법이다. 자동차의 대 수에 따라 리스트의 크기를 정하고 싶어서 공백으로 되어있는 리스트를 하나 만들었다. 그리고 바로바로 출력할 수 있도록 리스트에 -
문자를 추가하고자 했다.
비어있는 MutableList
로 초기화하는 방법은 세 가지 정도 있다.
mutableListOf()
사용
val emptyList = mutableListOf()
MutableList
생성자 사용
val emptyList = MutableList(0) { }
emptyList().toMutableList()
사용
val emptyList = emptyList().toMutableList()
이번에 반복문을 쓰게 되면서 발견한(?) 기능이다. 코틀린에서 반복문을 작성할 때, 원래는 for
문 안에 (i in 0..val)
이런식으로 작성했었는데, 이게 0
이상 val
이하여서 진짜 딱 val
전까지 돌리려면 이 방법은 사용할 수가 없어서 val-1
을 넣었더니 intellij
가 대신에 <val
을 사용하라고 했다. 그래서 사용했는데 여기서 또 indices
로 바꾸라고 권유해줬다. 그래서 indices
에 대해서 찾아봤다.
indices
는 컬렉션의 유효한 인덱스 범위를IntRange
형태로 반환한다. 첫 번째 인덱스부터 마지막 인덱스까지의 범위를 제공한다.
for (i in list.indices) {
println("$i: ${list[i]}")
}
for (i in list.indices) {
if (i % 2 == 0) {
// 짝수 인덱스 처리
}
}
나는 랜덤 숫자가 4 이상인 것을 리스트에 추가할 때나, 리스트의 -
을 출력할 때 등 정말 많은 곳에서 사용했다. 앞으로 정말 유용하게 쓸 기능인 것 같다!
사용자가 입력한 자동차 이름들 중 중복되는 이름이 있으면 예외로 처리하도록 하기 위해 사용한 기능이다.
distinct()
는 컬렉션에서 중복된 요소를 제거하고 고유한 요소만 포함하는 새로운 리스트를 반환한다. 원본 컬렉션은 변경되지 않고 유지된다.
val list = listOf(1, 2, 2, 3, 4, 4, 5)
val distinctList = list.distinct()
println(distinctList) // 출력: [1, 2, 3, 4, 5]
사용자가 처음 입력한 자동차 리스트의 요소 개수와 중복을 제거한 리스트의 요소 개수가 다르면 예외를 처리하도록 함수를 구현했다.
함수들을 일일이 다 나누다보니 매개변수와 반환형을 정하는 게 조금 헷갈렸지만 나누고나니 내가 작성한 코드가 뭔가 이해하기가 더 쉬워진 느낌이 들었다. 함수 이름 정하는 것도.. 좀 힘들었다. 함수명이 너무 긴 것들도 있어서 수정해야할까... 생각이 들면서도 봤을 때 어떤 기능을 하는지 딱 알 수 있어서 바꿔야할까 싶었다.
이번 과제를 수행하는 시간이 저번 과제 수행 시간보다 훨씬 적게 들었다. 그만큼 성장했다는 거겠지?! 앞으로도 열심히 해보겠다. 끝까지 포기하지 않고 열심히 가보자🫵🫵🔥🔥
이번 우테코 과제에는 소감을 적는 것도 포함되어 있었다. 다음과 같은 질문에 대한 중간 회고를 진행하라고 했다!
- 지원서에 작성한 목표를 얼마나 달성하고 있다고 생각하나요? 그 이유는 무엇인가요?
- 지원서에 작성한 목표를 변경해야 한다고 생각하시나요? 그렇다면 그 이유와 어떤 목표로 변경하고 싶으신가요?
- 프리코스를 진행하면서 눈에 띄는 변화나 깨달은 점이 있나요?