Skip to content

Commit e6ddcf7

Browse files
authored
Merge pull request #40 from ndrsllwngr/feature/quick-reveal
QuickReveal
2 parents 9bf4b8f + 3680405 commit e6ddcf7

4 files changed

Lines changed: 51 additions & 16 deletions

File tree

src/Game/Board.hs

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
module Game.Board
44
( generateBoard,
5-
revealCell,
5+
reveal,
66
revealAllNonFlaggedCells,
77
flagCell,
88
checkLost,
@@ -22,23 +22,23 @@ module Game.Board
2222
)
2323
where
2424

25-
import Control.Lens
26-
import Data.List
27-
import Data.Matrix
28-
import Data.Matrix.Lens (elemAt, flattened, size)
29-
import System.Random
30-
import System.Random.Shuffle
25+
import Control.Lens
26+
import Data.List
27+
import Data.Matrix
28+
import Data.Matrix.Lens (elemAt, flattened, size)
29+
import System.Random
30+
import System.Random.Shuffle
3131

3232
type Dimension = (Int, Int)
3333

3434
type Coordinate = (Int, Int)
3535

3636
data Cell = Cell
37-
{ _isFlagged :: Bool,
38-
_isRevealed :: Bool,
39-
_hasBomb :: Bool,
37+
{ _isFlagged :: Bool,
38+
_isRevealed :: Bool,
39+
_hasBomb :: Bool,
4040
_neighboringBombs :: Int,
41-
_coordinate :: Coordinate
41+
_coordinate :: Coordinate
4242
}
4343
deriving (Show, Eq)
4444

@@ -79,6 +79,10 @@ generateBoard (h, w) bombCount seed =
7979
setCellToRevealed :: Board -> Coordinate -> Board
8080
setCellToRevealed board c = board & elemAt c . isRevealed .~ True
8181

82+
-- wrapper for the reveal actions, if a cell is not revealed yet, reveal it, otherwise try a quick reveal
83+
reveal :: Board -> Coordinate -> Board
84+
reveal board c = if board ^. (elemAt c . isRevealed) then quickReveal board c else revealCell board c
85+
8286
-- Reveals a cell at a given coordinate for a given Board
8387
-- Rule explanation: will also reveal any direct neighbouring Cells which have no bomb and their neighbour cells if the have 0 neighboring bombs
8488
revealCell :: Board -> Coordinate -> Board
@@ -102,6 +106,23 @@ revealCell board c = resultBoard
102106
-- In any other case just reveal the cell at (i,j)
103107
_ -> setCellToRevealed board c
104108

109+
-- Quick reveal
110+
-- If a cell is revealed, has more than one neighboring bomb and the bomb count matches the amount of flagged neighbors all non flagged neighbours can bo quick revealed
111+
quickReveal :: Board -> Coordinate -> Board
112+
quickReveal board c = resultBoard
113+
where
114+
dim = getDimensionsForBoard board
115+
cellIsRevealed = board ^. (elemAt c . isRevealed)
116+
neighbourCoordinates = neighbourCells c dim
117+
neighbours = filter (\cell -> cell ^. coordinate `elem` neighbourCoordinates) (toList board)
118+
bombNeighbourCount = board ^. (elemAt c . neighboringBombs)
119+
nonFlaggedNeighboursCoordinates = map _coordinate $ filter (\x -> not (x ^. isFlagged)) neighbours
120+
flaggedNeighboursCount = length $ filter (^. isFlagged) neighbours
121+
-- move is only valid if c is revealed, has neighboring bombs and if the neighboringBombs match the number of flagged neighbours
122+
isValidMove = cellIsRevealed && bombNeighbourCount > 0 && bombNeighbourCount == flaggedNeighboursCount
123+
--if the move is valid reveal all neighbour cells otherwise return the initial board
124+
resultBoard = if isValidMove then foldl setCellToRevealed board nonFlaggedNeighboursCoordinates else board
125+
105126
-- Reveals all cells which have not been flagged
106127
revealAllNonFlaggedCells :: Board -> Board
107128
revealAllNonFlaggedCells board = board & flattened . filtered (not . _isFlagged) . isRevealed .~ True

src/Game/Game.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ makeMove state m =
8383
where
8484
(boardAfterMove, time) = case m of
8585
(Flag c t) -> (flagCell (state ^. board) c, t)
86-
(Reveal c t) -> (revealCell (state ^. board) c, t)
86+
(Reveal c t) -> (reveal (state ^. board) c, t)
8787
(RevealAllNonFlagged t) -> (revealAllNonFlaggedCells (state ^. board), t)
8888
finishGame = calculateTimeElapsed (state ^. lastStartedAt) (state ^. timeElapsed) time
8989
st = checkStatus boardAfterMove

templates/game.hamlet

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
Left Click
3434
to reveal a cell.
3535
<span .font-mono .font-semibold .bg-gray-200 .text-sm .sm:text-base .text-gray-700 .subpixel-antialiased .px-2 .py-2 .rounded>
36-
Alt + Click
36+
Right Click
3737
to flag a cell.
3838
<li .mt-2>
3939
Click the face to restart. A new seed will be chosen.
@@ -62,7 +62,7 @@
6262
$forall cellEntity <- row ^. rowCells
6363
<td #x#{(cellEntity ^. cellEntityCoordX)}y#{(cellEntity ^. cellEntityCoordY)}>
6464
$if (gameStateEntity ^. gameStateEntityStatus) == "Ongoing"
65-
<div .div onclick="makeMove(#{cellEntity ^. cellEntityCoordX}, #{cellEntity ^. cellEntityCoordY}, '#{gameStateEntity ^. gameStateEntityGameId}', event)">
65+
<div .div onclick="makeMove(#{cellEntity ^. cellEntityCoordX}, #{cellEntity ^. cellEntityCoordY}, '#{gameStateEntity ^. gameStateEntityGameId}', event)" oncontextmenu="makeMove(#{cellEntity ^. cellEntityCoordX}, #{cellEntity ^. cellEntityCoordY}, '#{gameStateEntity ^. gameStateEntityGameId}', event)">
6666
<img .img src="/static/assets/#{(cellEntity ^. cellEntityAssetId)}.svg" width="24" height="24">
6767
$else
6868
<div .div>

templates/game.julius

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,28 @@ var src;
1818
const makeMove = (x, y, gameId, event) => {
1919
event.preventDefault();
2020

21-
console.log("MAKE MOVE", { x, y, gameId, event });
21+
console.log("MAKE MOVE", { x, y, gameId }, "EVENT", {
22+
button: event.button,
23+
event,
24+
});
25+
26+
var action = null;
27+
if (event.button === 0) {
28+
action = "Reveal";
29+
} else if (event.button === 2) {
30+
action = "Flag";
31+
}
32+
33+
if (action === null) {
34+
return;
35+
}
2236

2337
$.ajax({
2438
url: "/game/" + gameId,
2539
type: "PUT",
2640
contentType: "application/json",
2741
data: JSON.stringify({
28-
action: event.altKey ? "Flag" : "Reveal",
42+
action: action,
2943
coordX: x,
3044
coordY: y,
3145
}),

0 commit comments

Comments
 (0)