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 + } +}