diff options
Diffstat (limited to 'mines.kt')
| -rw-r--r-- | mines.kt | 36 |
1 files changed, 21 insertions, 15 deletions
@@ -1,5 +1,8 @@ data class Tile(val adjacentMines: Int = 0, val mine: Boolean = false, val masked: Boolean = true) +/** + * The Minesweeper "grid", containing instances of [Tile]. + */ class Grid(val width: Int, val height: Int, val tiles: Array<Tile>) { constructor(width: Int = 8, height: Int = 8, mines: Int = 10) : this(width, height, Array<Tile>(width * height) { Tile() }) { @@ -11,8 +14,7 @@ class Grid(val width: Int, val height: Int, val tiles: Array<Tile>) { } private fun index(x: Int, y: Int) = y * width + x - private fun coordinatesValid(x: Int, y: Int) = y >= 0 && y < height && x >= 0 && x < width - + private fun valid(x: Int, y: Int) = y in 0 until height && x in 0 until width private fun place(x: Int, y: Int, tile: Tile) { tiles[index(x, y)] = tile } @@ -24,7 +26,7 @@ class Grid(val width: Int, val height: Int, val tiles: Array<Tile>) { * the range of [0, width), or if the Y coordinate is outside the * range of [0, height). */ - fun tile(x: Int, y: Int) = if (coordinatesValid(x, y)) { + operator fun get(x: Int, y: Int) = if (valid(x, y)) { tiles[index(x, y)] } else { throw IllegalArgumentException("Invalid coordinates (${x}, ${y})") @@ -38,16 +40,20 @@ class Grid(val width: Int, val height: Int, val tiles: Array<Tile>) { * range of [0, height). */ fun placeMine(x: Int, y: Int) { - if (!coordinatesValid(x, y)) { + if (!valid(x, y)) { throw IllegalArgumentException("Invalid coordinates (${x}, ${y})") } + if (this[x, y].mine) { + return; + } + place(x, y, Tile(mine = true)) - val xMin = if (x - 1 < 0) { x } else { x - 1 } - val xMax = if (x + 1 >= width) { x } else { x + 1 } - val yMin = if (y - 1 < 0) { y } else { y - 1 } - val yMax = if (y + 1 >= height) { y } else { y + 1 } + val xMin = (x - 1).coerceAtLeast(0) + val xMax = (x + 1).coerceAtMost(width - 1) + val yMin = (y - 1).coerceAtLeast(0) + val yMax = (y + 1).coerceAtMost(height - 1) for (y in yMin..yMax) { for (x in xMin..xMax) { @@ -68,18 +74,18 @@ class Grid(val width: Int, val height: Int, val tiles: Array<Tile>) { * range of [0, height). */ fun reveal(x: Int, y: Int) { - if (!coordinatesValid(x, y) || !tile(x, y).masked) { + if (!valid(x, y) || !this[x, y].masked) { return; } - with (tile(x, y)) { + with (this[x, y]) { place(x, y, copy(masked = false)) if (!mine && adjacentMines == 0) { - val xMin = if (x - 1 < 0) { x } else { x - 1 } - val xMax = if (x + 1 >= width) { x } else { x + 1 } - val yMin = if (y - 1 < 0) { y } else { y - 1 } - val yMax = if (y + 1 >= height) { y } else { y + 1 } + val xMin = (x - 1).coerceAtLeast(0) + val xMax = (x + 1).coerceAtMost(width - 1) + val yMin = (y - 1).coerceAtLeast(0) + val yMax = (y + 1).coerceAtMost(height - 1) for (y in yMin..yMax) { for (x in xMin..xMax) { @@ -93,7 +99,7 @@ class Grid(val width: Int, val height: Int, val tiles: Array<Tile>) { override fun toString(): String = buildString { for (y in 0 until height) { for (x in 0 until width) { - val tile = tile(x, y) + val tile = this@Grid[x, y] append(when { tile.masked -> "." tile.mine -> "M" |