-
Notifications
You must be signed in to change notification settings - Fork 199
Step2 #232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jpoh281
wants to merge
40
commits into
next-step:jpoh281
Choose a base branch
from
jpoh281:step2
base: jpoh281
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Step2 #232
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
6ce91cc
docs: 요구사항 정리
288f98a
feat: 높이와 너비, 지뢰의 개수를 반영해 보드를 생성할 수 있다.
420c9f2
refactor: 블록 문자열을 블록 객체로 수정
13926cd
feat:유저로부터 요구사항을 입력받기 위한 InputView 생성
d9b1a77
feat: Main 및 컨트롤러를 생성해서 유저의 요구사항을 받아 보드 생성
563b905
feat: ResultView를 생성해서 생성된 보드 유저에게 보여주기
cdbdfb7
docs: 피드백 목록 정리
de0089e
refactor: View에서 처리해야할 로직들 이동
90f6ef0
refactor: OrNull 제거
b196d6a
feat: 좌표를 나타내는 Point 객체 생성
70b8fda
refactor: 이차원 배열 -> 맵으로 수정
257b76b
feat: CustomException 사용
4133782
refactor: View를 Interface로 변경
e7e1a31
refactor: 지뢰의 수를 측정하는 메소드와 변수 정리
ada31aa
refactor: ResultView의 매직 리터럴 companion object로 이동
cb645f4
refactor: forEach -> flatMap으로 변경
77a340b
refactor: 에러 문구 ResultView에게 책임 부여 및 Known, Unknown의 처리 분류
19bdc2c
refactor: 보드 자체를 반환하도록 변경
9820e71
docs: 2단계 요구사항 작성
3d033cd
feat: SafeBlock에 nearMineCount 프로퍼티 추가
f9e24c6
feat: 시작할 때 SAFEBLOCK -> EMPTYBLOCK으로 변경
b9b28d3
feat: InputView의 가짜 객체를 만들어서 컨트롤러 테스트 추가
eea4988
feat: Point - 근처의 포인트 객체들 받아오기 기능 추가
15dee1e
feat: - 지뢰를 심은 뒤에 지뢰의 수를 반영하는 메소드 생성
f5b8a13
feat: - SafeBlock 표기 방식 변경
e1aace3
refactor: 변수명 수정
b37a91c
Merge branch 'jpoh281' into step2
943e4d5
refactor: Controller에서 그대로 터뜨리기
jpoh281 0e68951
feat: 지뢰를 심는 전략패턴 인터페이스와 클래스들 생성
jpoh281 74acd9a
refactor: 열 수 있는 블록과 열 수 없는 블록 분리
28edd9d
refactor: 전략패턴 적용 및 응집도 높이기
b8babef
refactor: Empty Block 다시 삭제
322b8ca
refactor: try-catch를 안쓰고 로직을 변경
001d298
refactor: block, exception 패키지 생성
75508fc
refactor: 타입이 나오도록 변경 및 공백 삭제, 임포트 수정
8e04e5f
refactor: ResultViewImpl -> ConsoleResultView 변경
520a042
feat: 열린 블록과 열리지 않은 블록 클래스를 만들어 open 메소드를 필요한 클래스에만 할당
1c4ee11
refactor: 지뢰가 0일 때 0 나누기 에러 나오는 현상 수정
e95a24c
refactor: ResultViewImpl -> ConsoleReulstView로 더 명확하게변경
11ac2ce
refactor: 코드 정리
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,28 +1,36 @@ | ||
| package minesweeper.controller | ||
|
|
||
| import minesweeper.domain.Block | ||
| import minesweeper.domain.MineSweeperBoard | ||
| import minesweeper.domain.Point | ||
| import minesweeper.domain.exception.MineSweeperException | ||
| import minesweeper.domain.plant_strategy.RemainderPlantStrategy | ||
| import minesweeper.view.ConsoleResultView | ||
| import minesweeper.view.InputView | ||
| import minesweeper.view.InputViewImpl | ||
| import minesweeper.view.ResultView | ||
| import minesweeper.view.ResultViewImpl | ||
|
|
||
| class GameController( | ||
| private val inputView: InputView = InputViewImpl(), | ||
| private val resultView: ResultView = ResultViewImpl() | ||
| private val resultView: ResultView = ConsoleResultView() | ||
| ) { | ||
| fun run(): Map<Point, Block> { | ||
| val gameBoard = setUp() | ||
| resultView.renderInitialBoard(gameBoard.state) | ||
| return gameBoard.state | ||
| fun run(): MineSweeperBoard? { | ||
| return try { | ||
| val gameBoard: MineSweeperBoard = setUp() | ||
| resultView.renderInitialBoard(gameBoard.state) | ||
| gameBoard | ||
| } catch (e: MineSweeperException) { | ||
| resultView.printKnownException(e) | ||
| throw e | ||
| } catch (e: Exception) { | ||
| resultView.printUnknownException(e) | ||
| throw e | ||
| } | ||
| } | ||
|
|
||
| private fun setUp(): MineSweeperBoard { | ||
| val height = inputView.readHeight() | ||
| val width = inputView.readWidth() | ||
| val mineCount = inputView.readMineCount() | ||
|
|
||
| return MineSweeperBoard(height, width, mineCount) | ||
| return MineSweeperBoard(height, width, mineCount, RemainderPlantStrategy()) | ||
| } | ||
| } |
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,8 @@ | ||
| package minesweeper.domain | ||
|
|
||
| import minesweeper.domain.exception.ExceptionReason | ||
| import minesweeper.domain.exception.MineSweeperException | ||
|
|
||
| data class Point(val x: Int, val y: Int) : Comparable<Point> { | ||
|
|
||
| init { | ||
|
|
@@ -8,5 +11,38 @@ data class Point(val x: Int, val y: Int) : Comparable<Point> { | |
| } | ||
| } | ||
|
|
||
| fun getNearPoints(width: Int, height: Int): List<Point> { | ||
| val nearPoints = nearPoints.toList() | ||
| return nearPoints.mapNotNull { plusOrNull(it.first, it.second, width, height) } | ||
| } | ||
|
|
||
| override fun compareTo(other: Point) = compareValuesBy(this, other, { it.y }, { it.x }) | ||
|
|
||
| private fun plusOrNull(x: Int, y: Int, maxX: Int, maxY: Int): Point? { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 연산자 오버로딩을 해도 괜찮겠네요~ |
||
| if (isValidateX(x, maxX) && isValidateY(y, maxY)) { | ||
| return Point(this.x + x, this.y + y) | ||
| } | ||
| return null | ||
| } | ||
|
|
||
| private fun isValidateX(x: Int, maxX: Int): Boolean { | ||
| return (this.x + x) in 0 until maxX | ||
| } | ||
|
|
||
| private fun isValidateY(y: Int, maxY: Int): Boolean { | ||
| return (this.y + y) in 0 until maxY | ||
| } | ||
|
|
||
| companion object { | ||
| private val nearPoints = listOf( | ||
| -1 to -1, | ||
| -1 to 0, | ||
| -1 to 1, | ||
| 0 to -1, | ||
| 0 to 1, | ||
| 1 to -1, | ||
| 1 to 0, | ||
| 1 to 1 | ||
| ) | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package minesweeper.domain.block | ||
|
|
||
| sealed class Block |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package minesweeper.domain.block | ||
|
|
||
| class MineBlock : OpenedBlock() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package minesweeper.domain.block | ||
|
|
||
| sealed class OpenedBlock : Block() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package minesweeper.domain.block | ||
|
|
||
| import minesweeper.domain.exception.ExceptionReason | ||
| import minesweeper.domain.exception.MineSweeperException | ||
|
|
||
| class SafeBlock(val nearMineCount: Int = 0) : OpenedBlock() { | ||
|
|
||
| init { | ||
| if (nearMineCount !in nearMineRange) throw MineSweeperException(ExceptionReason.ILLEGAL_NEAR_MINE_RANGE) | ||
| } | ||
|
|
||
| companion object { | ||
| private val nearMineRange = (0..8) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| package minesweeper.domain.block | ||
|
|
||
| open class UnOpenedBlock : Block() |
8 changes: 8 additions & 0 deletions
8
src/main/kotlin/minesweeper/domain/exception/ExceptionReason.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| package minesweeper.domain.exception | ||
|
|
||
| enum class ExceptionReason { | ||
| ILLEGAL_POINT, | ||
| NEGATIVE_POINT_VALUE, | ||
| MINE_COUNT_OVER_BLOCKS, | ||
| ILLEGAL_NEAR_MINE_RANGE | ||
| } |
2 changes: 1 addition & 1 deletion
2
...inesweeper/domain/MineSweeperException.kt → .../domain/exception/MineSweeperException.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| package minesweeper.domain | ||
| package minesweeper.domain.exception | ||
|
|
||
| class MineSweeperException(val reason: ExceptionReason) : Exception() |
7 changes: 7 additions & 0 deletions
7
src/main/kotlin/minesweeper/domain/plant_strategy/PlantStrategy.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package minesweeper.domain.plant_strategy | ||
|
|
||
| import minesweeper.domain.Point | ||
|
|
||
| interface PlantStrategy { | ||
| fun createMines(width: Int, height: Int, mineCount: Int): Set<Point> | ||
| } |
16 changes: 16 additions & 0 deletions
16
src/main/kotlin/minesweeper/domain/plant_strategy/RandomPlantStrategy.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package minesweeper.domain.plant_strategy | ||
|
|
||
| import minesweeper.domain.Point | ||
| import java.util.* | ||
|
|
||
| class RandomPlantStrategy : PlantStrategy { | ||
| override fun createMines(width: Int, height: Int, mineCount: Int): Set<Point> { | ||
| val minePoints = mutableSetOf<Point>() | ||
| while (minePoints.size < mineCount) { | ||
| val currentWidth = Random().nextInt(width) | ||
| val currentHeight = Random().nextInt(height) | ||
| minePoints.add(Point(currentWidth, currentHeight)) | ||
| } | ||
| return minePoints | ||
| } | ||
| } |
23 changes: 23 additions & 0 deletions
23
src/main/kotlin/minesweeper/domain/plant_strategy/RemainderPlantStrategy.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| package minesweeper.domain.plant_strategy | ||
|
|
||
| import minesweeper.domain.Point | ||
|
|
||
| class RemainderPlantStrategy : PlantStrategy { | ||
|
|
||
| override fun createMines(width: Int, height: Int, mineCount: Int): Set<Point> { | ||
| val minePoints = mutableSetOf<Point>() | ||
|
|
||
| if (mineCount == 0) return minePoints | ||
|
|
||
| val term = width * height / mineCount | ||
| val maxNumber = term * mineCount | ||
| for (i: Int in 0 until maxNumber step term) { | ||
| val currentWidth = i % width | ||
| val currentHeight = i / width | ||
|
|
||
| minePoints.add(Point(currentWidth, currentHeight)) | ||
| } | ||
|
|
||
| return minePoints | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,65 @@ | ||
| package minesweeper.view | ||
|
|
||
| import minesweeper.domain.Point | ||
| import minesweeper.domain.block.Block | ||
| import minesweeper.domain.block.MineBlock | ||
| import minesweeper.domain.block.SafeBlock | ||
| import minesweeper.domain.block.UnOpenedBlock | ||
| import minesweeper.domain.exception.ExceptionReason | ||
| import minesweeper.domain.exception.MineSweeperException | ||
|
|
||
| class ConsoleResultView : ResultView { | ||
| override fun renderInitialBoard(state: Map<Point, Block>) { | ||
| println() | ||
| println("지뢰찾기 게임 시작") | ||
| renderBoard(state) | ||
| } | ||
|
|
||
| override fun printKnownException(exception: MineSweeperException) { | ||
| println(parseException(exception)) | ||
| } | ||
|
|
||
| private fun parseException(exception: MineSweeperException): String { | ||
| return when (exception.reason) { | ||
| ExceptionReason.NEGATIVE_POINT_VALUE -> NEGATIVE_POINT_VALUE_TEXT | ||
| ExceptionReason.MINE_COUNT_OVER_BLOCKS -> MINE_COUNT_OVER_BLOCKS_TEXT | ||
| ExceptionReason.ILLEGAL_NEAR_MINE_RANGE -> ILLEGAL_NEAR_MINE_RANGE_TEXT | ||
| ExceptionReason.ILLEGAL_POINT -> CANT_CREATE_BLOCK | ||
| } | ||
| } | ||
|
|
||
| override fun printUnknownException(exception: Exception) { | ||
| print(exception.message) | ||
| } | ||
|
|
||
| private fun renderBoard(state: Map<Point, Block>) { | ||
| val yList = state.toList().groupBy { it.first.y } | ||
| yList.forEach { | ||
| renderRow(it.value.map { pair -> pair.second }) | ||
| } | ||
| } | ||
|
|
||
| private fun renderRow(row: List<Block>) { | ||
| row.forEach(::renderBlock) | ||
| println() | ||
| } | ||
|
|
||
| private fun renderBlock(block: Block) { | ||
| when (block) { | ||
| is UnOpenedBlock -> print(UNOPENED_BLOCK_CHARACTER) | ||
| is MineBlock -> print(DEFAULT_MINE_CHARACTER) | ||
| is SafeBlock -> print(block.nearMineCount) | ||
| } | ||
| print(BLANK_CHARACTER) | ||
| } | ||
|
|
||
| companion object { | ||
| private const val DEFAULT_MINE_CHARACTER = "*" | ||
| private const val UNOPENED_BLOCK_CHARACTER = "C" | ||
| private const val BLANK_CHARACTER = " " | ||
| private const val NEGATIVE_POINT_VALUE_TEXT = "좌표 값은 음수가 될 수 없습니다." | ||
| private const val MINE_COUNT_OVER_BLOCKS_TEXT = "지뢰의 개수는 총 블록의 개수보다 많을 수 없습니다." | ||
| private const val ILLEGAL_NEAR_MINE_RANGE_TEXT = "근처의 지뢰 범위는 0 이상 8 이하입니다." | ||
| private const val CANT_CREATE_BLOCK = "현재 보드에 없는 지점에 지뢰를 설치할 수 없습니다." | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,11 @@ | ||
| package minesweeper.view | ||
|
|
||
| import minesweeper.domain.Block | ||
| import minesweeper.domain.Point | ||
| import minesweeper.domain.block.Block | ||
| import minesweeper.domain.exception.MineSweeperException | ||
|
|
||
| interface ResultView { | ||
| fun renderInitialBoard(state: Map<Point, Block>) | ||
| fun printKnownException(exception: MineSweeperException) | ||
| fun printUnknownException(exception: Exception) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
전략을 바꿀 수 있으니, 여러 장점이 있을것 같아요.
테스트코드에서 전략을 한개 만들어서, 그 전략만큼 지뢰가 잘 심겼는지 등 테스트 할 수 있겠죠? 나중에 게임 실행하면서 원하는 위치에 지뢰를 심고, 터트리는 등 테스트를 더욱 쉽게 가능할거에요.