-
Notifications
You must be signed in to change notification settings - Fork 199
Expand file tree
/
Copy pathMineSweeperBoard.kt
More file actions
76 lines (62 loc) · 2.35 KB
/
Copy pathMineSweeperBoard.kt
File metadata and controls
76 lines (62 loc) · 2.35 KB
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
package minesweeper.domain
import minesweeper.domain.block.Block
import minesweeper.domain.block.MineBlock
import minesweeper.domain.block.SafeBlock
import minesweeper.domain.exception.ExceptionReason
import minesweeper.domain.exception.MineSweeperException
import minesweeper.domain.plant_strategy.PlantStrategy
import minesweeper.domain.plant_strategy.RemainderPlantStrategy
class MineSweeperBoard(
private val width: Int,
private val height: Int,
mineCount: Int = 0,
private val strategy: PlantStrategy = RemainderPlantStrategy()
) {
private val _state: MutableMap<Point, Block>
val state: Map<Point, Block>
get() = _state.toMap()
private var _mineCount: Int = 0
val mineCount
get() = _mineCount
init {
if (width * height < mineCount) {
throw MineSweeperException(ExceptionReason.MINE_COUNT_OVER_BLOCKS)
}
_state = buildBoard(width, height).toMutableMap()
plantMines(mineCount)
}
private fun buildBoard(maxXAxis: Int, maxYAxis: Int): Map<Point, Block> {
return (0 until maxXAxis).flatMap { currentXAxis ->
buildLine(currentXAxis, maxYAxis)
}.toMap()
}
private fun buildLine(currentXAxis: Int, maxYAxis: Int): List<Pair<Point, Block>> {
return (0 until maxYAxis).map { y ->
buildBlock(currentXAxis, y)
}
}
private fun buildBlock(currentXAxis: Int, currentYAxis: Int): Pair<Point, Block> {
return Point(currentXAxis, currentYAxis) to SafeBlock()
}
private fun plantMines(plantingMineCount: Int) {
val minePoints = strategy.createMines(width, height, plantingMineCount)
minePoints.forEach {
_state[it] = MineBlock()
}
_mineCount = countMine()
updateSafeBlock()
}
private fun updateSafeBlock() {
val safeBlockPoints = _state.filterValues { block: Block -> block is SafeBlock }.keys
safeBlockPoints.forEach { currentPoint: Point ->
val block = SafeBlock(sumNearPointMines(currentPoint.getNearPoints(width, height)))
_state[currentPoint] = block
}
}
private fun sumNearPointMines(points: List<Point>): Int {
return points.count { _state[it] is MineBlock }
}
private fun countMine(): Int {
return _state.values.count { block: Block -> block is MineBlock }
}
}