## ~piotr-machura/sweep-ai

2d45d6c985d47c35380b88016477b013670f1e58 — Piotr Machura 10 months ago
```Fix random bomb placement
```
```2 files changed, 17 insertions(+), 11 deletions(-)

M sweep_ai/logic.py
M tests/test_logic.py
```
`M sweep_ai/logic.py => sweep_ai/logic.py +13 -11`
```@@ 6,6 6,7 @@ import numpy as np

#pylint: disable=invalid-name

+
class State:
"""Represents game state at any point in time.

@@ 31,7 32,7 @@ class State:
bombs: percentage of bombs to place
bomb_positions: exact bomb positions

-        If `bomb_positions` are provided the `bombs` are ignored.
+        If `bomb_positions` are provided the `bombs` percentage is ignored.
"""
self.size = size
self.bomb = np.zeros((self.size, self.size), dtype=int)

@@ 40,21 41,23 @@ class State:
self.near = np.copy(self.bomb)
self.won: Optional[bool] = None

-        # If the positions were not explicitly provided randomise them.
+        # If the positions were not explicitly provided randomise them
if bomb_positions is None:
-            bomb_positions = list(
-                zip(
-                    sample(range(self.size), k=int(self.size**2 * bombs)),
-                    sample(range(self.size), k=int(self.size**2 * bombs)),
-                ))
-
-        # Create the board based on the positions
+            # Reduce 'bombs' to [0, 1]
+            bombs = np.max([bombs, 0.])
+            bombs = np.min([bombs, 1.])
+            # Choose from all the possible positions
+            possible = [
+                (x, y) for x in range(self.size) for y in range(self.size)
+            ]
+            bomb_positions = sample(possible, k=round(self.size**2 * bombs))
+
+        # Place bombs
for x, y in bomb_positions:
self.bomb[x, y] = 1
for n_x, n_y in self.neighbors(x, y):
self.near[n_x, n_y] += 1

-
@property
def not_bomb(self):
"""The inverse of `self.bombs`."""

@@ 65,7 68,6 @@ class State:
"""The inverse of `self.revealed`."""
return (self.revealed + 1) % 2

-
def click(self, x: int, y: int):
"""Simulate a click on the `(x, y)` position.

```
`M tests/test_logic.py => tests/test_logic.py +4 -0`
```@@ 23,6 23,10 @@ def test_bombs():
[1, 1, 0, 1],
]))

+    for size, percentage in [(4, 0.25), (10, 0.1), (12, 0.34), (20, 0.1),]:
+        state = logic.State(size, percentage)
+        assert np.sum(state.bomb) == round(size**2 * percentage)
+

def test_neighbors():
state = logic.State(4)

```