summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob L. Kreuze <jakob@memeware.net>2018-12-15 07:26:23 -0500
committerJakob L. Kreuze <jakob@memeware.net>2018-12-15 07:26:23 -0500
commit76fd5eaa9707ed423d442b594ec31997901ce2e6 (patch)
treee26b03c171ea4fb2a92f5c3e934fda3540f6248f
parentb9348a41231a4578f0d69c335a5409ec8559f92e (diff)
Further refactoring.
-rw-r--r--mines.kt36
1 files 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<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"