summaryrefslogtreecommitdiff
path: root/minesweeper.kt
blob: ee4c575c2ee0002b4b04786ccaf847204531662d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
data class Tile(val minesAdjacent: Int, val mine: Boolean, val masked: Boolean)

data class Grid(val tiles: Array<Tile>, val width: Int, val height: Int)

fun Grid.valid(x: Int, y: Int) = x >= 0 && x < width && y >= 0 && y < height
fun Grid.index(x: Int, y: Int) = y * width + x
fun Grid.tile(x: Int, y: Int) = tiles[index(x, y)]
fun Grid.get(x: Int, y: Int) = Pair(tile(x, y), index(x, y))

fun Grid.put(x: Int, y: Int, tile: Tile) {
    tiles[index(x, y)] = tile
}

fun addMine(grid: Grid, x: Int, y: Int) {
    if (!grid.valid(x, y)) {
        throw IllegalArgumentException()
    }

    grid.put(x, y, Tile(minesAdjacent = 0, mine = true, masked = true))

    for (i in -1..1) {
        for (j in -1..1) {
            if (!(i == 0 && j == 0) && grid.valid(x + i, y + j)) {
                val old = grid.tile(x + i, y + j)
                val minesAdjacent = if (old.mine) { 0 } else { old.minesAdjacent + 1 }
                grid.put(x + i, y + j, Tile(minesAdjacent, old.mine, old.masked))
            }
        }
    }
}

fun revealTile(grid: Grid, x: Int, y: Int) {
    if (!grid.valid(x, y)) {
        return
    }
    
    val tile = grid.tile(x, y)
    
    if (!tile.masked) {
        return
    }

    grid.put(x, y, Tile(tile.minesAdjacent, tile.mine, masked = false))

    if (tile.minesAdjacent == 0) {
        revealTile(grid, x - 1, y - 1)
        revealTile(grid, x,     y - 1)
        revealTile(grid, x + 1, y - 1)
        revealTile(grid, x - 1, y    )
        revealTile(grid, x + 1, y    )
        revealTile(grid, x - 1, y + 1)
        revealTile(grid, x,     y + 1)
        revealTile(grid, x + 1, y + 1)
    }
}

// TODO: Turn this into a toString?

fun printTiles(grid: Grid) {
    for (y in 0..grid.height-1) {
        for (x in 0..grid.width-1) {
            val tile = grid.tile(x, y)
            val display = when {
                tile.masked -> "."
                tile.mine -> "M"
                tile.minesAdjacent == 0 -> " "
                else -> tile.minesAdjacent.toString()
            }

            print("${display} ")
        }
        println()
        println()
    }
}

fun main(args: Array<String>) {
    val width = 10
    val height = 10
    val tiles: Array<Tile> = Array(width * height, { Tile(0, mine = false, masked = true) })

    val grid = Grid(tiles, width, height)

    addMine(grid, 0, 0)
    addMine(grid, 1, 0)
    addMine(grid, 2, 0)
    addMine(grid, 3, 0)
    revealTile(grid, 5, 5)

    printTiles(grid)
}