From 76fd5eaa9707ed423d442b594ec31997901ce2e6 Mon Sep 17 00:00:00 2001 From: "Jakob L. Kreuze" Date: Sat, 15 Dec 2018 07:26:23 -0500 Subject: Further refactoring. --- mines.kt | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/mines.kt b/mines.kt index b4d7d77..ae8415d 100644 --- a/mines.kt +++ b/mines.kt @@ -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) { constructor(width: Int = 8, height: Int = 8, mines: Int = 10) : this(width, height, Array(width * height) { Tile() }) { @@ -11,8 +14,7 @@ class Grid(val width: Int, val height: Int, val tiles: Array) { } 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) { * 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) { * 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) { * 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) { 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" -- cgit v1.3