From 4c4c1b2cd7e18386c68ddc060332db3c0dad11c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?yoonnyeong=28=EC=B5=9C=EC=9C=A4=EB=85=95=29?= Date: Fri, 1 Dec 2023 23:33:36 +0900 Subject: [PATCH] =?UTF-8?q?STEP=201=20:=20=EC=A7=80=EB=A2=B0=EC=B0=BE?= =?UTF-8?q?=EA=B8=B0(=EA=B7=B8=EB=A6=AC=EA=B8=B0)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 +++++- src/main/kotlin/.gitkeep | 0 src/main/kotlin/minesweeper/domain/Cell.kt | 10 +++++++ .../kotlin/minesweeper/domain/GameBoard.kt | 15 ++++++++++ .../minesweeper/domain/MineGenerator.kt | 16 ++++++++++ .../kotlin/minesweeper/domain/MineSweeper.kt | 19 ++++++++++++ src/main/kotlin/minesweeper/domain/Point.kt | 3 ++ src/main/kotlin/minesweeper/main.kt | 7 +++++ src/main/kotlin/minesweeper/view/InputView.kt | 30 +++++++++++++++++++ .../kotlin/minesweeper/view/ResultView.kt | 20 +++++++++++++ src/test/kotlin/.gitkeep | 0 .../minesweeper/domain/GameBoardTest.kt | 28 +++++++++++++++++ .../minesweeper/domain/MineGeneratorTest.kt | 18 +++++++++++ 13 files changed, 174 insertions(+), 1 deletion(-) delete mode 100644 src/main/kotlin/.gitkeep create mode 100644 src/main/kotlin/minesweeper/domain/Cell.kt create mode 100644 src/main/kotlin/minesweeper/domain/GameBoard.kt create mode 100644 src/main/kotlin/minesweeper/domain/MineGenerator.kt create mode 100644 src/main/kotlin/minesweeper/domain/MineSweeper.kt create mode 100644 src/main/kotlin/minesweeper/domain/Point.kt create mode 100644 src/main/kotlin/minesweeper/main.kt create mode 100644 src/main/kotlin/minesweeper/view/InputView.kt create mode 100644 src/main/kotlin/minesweeper/view/ResultView.kt delete mode 100644 src/test/kotlin/.gitkeep create mode 100644 src/test/kotlin/minesweeper/domain/GameBoardTest.kt create mode 100644 src/test/kotlin/minesweeper/domain/MineGeneratorTest.kt diff --git a/README.md b/README.md index 4c354962f..f04e8f609 100644 --- a/README.md +++ b/README.md @@ -1 +1,8 @@ -# kotlin-minesweeper \ No newline at end of file +# kotlin-minesweeper + +## 지뢰 찾기(그리기) +- [X] 높이, 너비, 지뢰 갯수를 입력받는다. +- [X] 높이, 너비, 지뢰 갯수는 자연수이여야한다. +- [X] 지뢰는 "*"로 표시되고 지뢰가 아닌 곳은 "C"로 표시된다. +- [X] 지뢰는 랜덤으로 배치된다. + diff --git a/src/main/kotlin/.gitkeep b/src/main/kotlin/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/main/kotlin/minesweeper/domain/Cell.kt b/src/main/kotlin/minesweeper/domain/Cell.kt new file mode 100644 index 000000000..c4b9ba25b --- /dev/null +++ b/src/main/kotlin/minesweeper/domain/Cell.kt @@ -0,0 +1,10 @@ +package minesweeper.domain + +class Cell(var isMine: Boolean = false) { + override fun toString(): String { + return when { + isMine -> "*" + else -> "C" + } + } +} diff --git a/src/main/kotlin/minesweeper/domain/GameBoard.kt b/src/main/kotlin/minesweeper/domain/GameBoard.kt new file mode 100644 index 000000000..f34c80b0c --- /dev/null +++ b/src/main/kotlin/minesweeper/domain/GameBoard.kt @@ -0,0 +1,15 @@ +package minesweeper.domain + +data class GameBoard(private val _height: Int, private val _width: Int) { + val height get() = _height + val width get() = _width + + val board: Array> + + init { + require(_height > 0 && _width > 0) { + "자연수를 입력해주세요." + } + board = Array(_height) { Array(_width) { Cell() } } + } +} diff --git a/src/main/kotlin/minesweeper/domain/MineGenerator.kt b/src/main/kotlin/minesweeper/domain/MineGenerator.kt new file mode 100644 index 000000000..4272b1842 --- /dev/null +++ b/src/main/kotlin/minesweeper/domain/MineGenerator.kt @@ -0,0 +1,16 @@ +package minesweeper.domain + +import kotlin.random.Random + +class MineGenerator(private val gameBoard: GameBoard, private val mineCount: Int) { + fun generateRandomPoints(): List { + val minePoints = mutableSetOf() + + while (minePoints.size < mineCount) { + val randomPoint = Point(Random.nextInt(gameBoard.height), Random.nextInt(gameBoard.width)) + minePoints.add(randomPoint) + } + + return minePoints.toList() + } +} diff --git a/src/main/kotlin/minesweeper/domain/MineSweeper.kt b/src/main/kotlin/minesweeper/domain/MineSweeper.kt new file mode 100644 index 000000000..c2a885828 --- /dev/null +++ b/src/main/kotlin/minesweeper/domain/MineSweeper.kt @@ -0,0 +1,19 @@ +package minesweeper.domain + +class MineSweeper(val gameBoard: GameBoard, mineCount: Int) { + private val mineGenerator = MineGenerator(gameBoard, mineCount) + private val minePoints = mineGenerator.generateRandomPoints() + + init { + require(mineCount > 0) { + "자연수를 입력해주세요." + } + placeMines(gameBoard) + } + + private fun placeMines(gameBoard: GameBoard) { + for (point in minePoints) { + gameBoard.board[point.x][point.y].isMine = true + } + } +} diff --git a/src/main/kotlin/minesweeper/domain/Point.kt b/src/main/kotlin/minesweeper/domain/Point.kt new file mode 100644 index 000000000..b36b14821 --- /dev/null +++ b/src/main/kotlin/minesweeper/domain/Point.kt @@ -0,0 +1,3 @@ +package minesweeper.domain + +data class Point(val x: Int, val y: Int) diff --git a/src/main/kotlin/minesweeper/main.kt b/src/main/kotlin/minesweeper/main.kt new file mode 100644 index 000000000..a8a997f67 --- /dev/null +++ b/src/main/kotlin/minesweeper/main.kt @@ -0,0 +1,7 @@ +import minesweeper.view.InputView +import minesweeper.view.ResultView + +fun main() { + val mineSweeper = InputView.prepareMineSweeper() + ResultView.startMineSweeper(mineSweeper) +} diff --git a/src/main/kotlin/minesweeper/view/InputView.kt b/src/main/kotlin/minesweeper/view/InputView.kt new file mode 100644 index 000000000..58d18d3b0 --- /dev/null +++ b/src/main/kotlin/minesweeper/view/InputView.kt @@ -0,0 +1,30 @@ +package minesweeper.view + +import minesweeper.domain.GameBoard +import minesweeper.domain.MineSweeper + +object InputView { + + fun prepareMineSweeper() : MineSweeper{ + val gameBoard = GameBoard(getHeight(), getWidth()) + return MineSweeper(gameBoard, getMine()) + } + + private fun getHeight() : Int{ + println("높이를 입력하세요.") + return readln().toInt() + } + + private fun getWidth() : Int{ + println("너비를 입력하세요.") + return readln().toInt() + } + + + private fun getMine() : Int{ + println("지뢰는 몇 개인가요?") + return readln().toInt() + } + + +} diff --git a/src/main/kotlin/minesweeper/view/ResultView.kt b/src/main/kotlin/minesweeper/view/ResultView.kt new file mode 100644 index 000000000..5cabc6fc2 --- /dev/null +++ b/src/main/kotlin/minesweeper/view/ResultView.kt @@ -0,0 +1,20 @@ +package minesweeper.view + +import minesweeper.domain.GameBoard +import minesweeper.domain.MineSweeper + +object ResultView { + fun startMineSweeper(mineSweeper: MineSweeper){ + println("지뢰찾기 게임 시작") + printMineSweeper(mineSweeper.gameBoard) + } + + private fun printMineSweeper(gameBoard : GameBoard) { + for (row in gameBoard.board) { + for (cell in row) { + print("$cell ") + } + println() + } + } +} diff --git a/src/test/kotlin/.gitkeep b/src/test/kotlin/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/test/kotlin/minesweeper/domain/GameBoardTest.kt b/src/test/kotlin/minesweeper/domain/GameBoardTest.kt new file mode 100644 index 000000000..8bb22c0a3 --- /dev/null +++ b/src/test/kotlin/minesweeper/domain/GameBoardTest.kt @@ -0,0 +1,28 @@ +package minesweeper.domain + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.assertThrows + +class GameBoardTest { + @Test + fun `자연수로 높이와 너비를 입력하면 게임보드를 만든다`() { + val height = 3 + val width = 4 + val gameBoard = GameBoard(height, width) + + height shouldBe gameBoard.height + width shouldBe gameBoard.width + } + + @Test + fun `지뢰찾기 보드의 높이와 너비는 자연수여야 한다`() { + assertThrows { + GameBoard(0, 5) + } + + assertThrows { + GameBoard(3, -1) + } + } +} diff --git a/src/test/kotlin/minesweeper/domain/MineGeneratorTest.kt b/src/test/kotlin/minesweeper/domain/MineGeneratorTest.kt new file mode 100644 index 000000000..44aac98fe --- /dev/null +++ b/src/test/kotlin/minesweeper/domain/MineGeneratorTest.kt @@ -0,0 +1,18 @@ +package minesweeper.domain + +import io.kotest.matchers.shouldBe +import org.junit.jupiter.api.Test + +class MineGeneratorTest { + + @Test + fun `입력받은 지뢰 개수 만큼 무작위로 지뢰가 위치할 좌표를 만든다`() { + val mineCount = 5 + val gameBoard = GameBoard(5, 5) + val mineGenerator = MineGenerator(gameBoard, mineCount) + + val minePoints = mineGenerator.generateRandomPoints() + + mineCount shouldBe minePoints.size + } +}