Skip to content

Commit

Permalink
Merge pull request #40 from ndrsllwngr/feature/quick-reveal
Browse files Browse the repository at this point in the history
QuickReveal
  • Loading branch information
ndrsllwngr authored Sep 28, 2020
2 parents 9bf4b8f + 3680405 commit e6ddcf7
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 16 deletions.
43 changes: 32 additions & 11 deletions src/Game/Board.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

module Game.Board
( generateBoard,
revealCell,
reveal,
revealAllNonFlaggedCells,
flagCell,
checkLost,
Expand All @@ -22,23 +22,23 @@ module Game.Board
)
where

import Control.Lens
import Data.List
import Data.Matrix
import Data.Matrix.Lens (elemAt, flattened, size)
import System.Random
import System.Random.Shuffle
import Control.Lens
import Data.List
import Data.Matrix
import Data.Matrix.Lens (elemAt, flattened, size)
import System.Random
import System.Random.Shuffle

type Dimension = (Int, Int)

type Coordinate = (Int, Int)

data Cell = Cell
{ _isFlagged :: Bool,
_isRevealed :: Bool,
_hasBomb :: Bool,
{ _isFlagged :: Bool,
_isRevealed :: Bool,
_hasBomb :: Bool,
_neighboringBombs :: Int,
_coordinate :: Coordinate
_coordinate :: Coordinate
}
deriving (Show, Eq)

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

-- wrapper for the reveal actions, if a cell is not revealed yet, reveal it, otherwise try a quick reveal
reveal :: Board -> Coordinate -> Board
reveal board c = if board ^. (elemAt c . isRevealed) then quickReveal board c else revealCell board c

-- Reveals a cell at a given coordinate for a given Board
-- Rule explanation: will also reveal any direct neighbouring Cells which have no bomb and their neighbour cells if the have 0 neighboring bombs
revealCell :: Board -> Coordinate -> Board
Expand All @@ -102,6 +106,23 @@ revealCell board c = resultBoard
-- In any other case just reveal the cell at (i,j)
_ -> setCellToRevealed board c

-- Quick reveal
-- 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
quickReveal :: Board -> Coordinate -> Board
quickReveal board c = resultBoard
where
dim = getDimensionsForBoard board
cellIsRevealed = board ^. (elemAt c . isRevealed)
neighbourCoordinates = neighbourCells c dim
neighbours = filter (\cell -> cell ^. coordinate `elem` neighbourCoordinates) (toList board)
bombNeighbourCount = board ^. (elemAt c . neighboringBombs)
nonFlaggedNeighboursCoordinates = map _coordinate $ filter (\x -> not (x ^. isFlagged)) neighbours
flaggedNeighboursCount = length $ filter (^. isFlagged) neighbours
-- move is only valid if c is revealed, has neighboring bombs and if the neighboringBombs match the number of flagged neighbours
isValidMove = cellIsRevealed && bombNeighbourCount > 0 && bombNeighbourCount == flaggedNeighboursCount
--if the move is valid reveal all neighbour cells otherwise return the initial board
resultBoard = if isValidMove then foldl setCellToRevealed board nonFlaggedNeighboursCoordinates else board

-- Reveals all cells which have not been flagged
revealAllNonFlaggedCells :: Board -> Board
revealAllNonFlaggedCells board = board & flattened . filtered (not . _isFlagged) . isRevealed .~ True
Expand Down
2 changes: 1 addition & 1 deletion src/Game/Game.hs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ makeMove state m =
where
(boardAfterMove, time) = case m of
(Flag c t) -> (flagCell (state ^. board) c, t)
(Reveal c t) -> (revealCell (state ^. board) c, t)
(Reveal c t) -> (reveal (state ^. board) c, t)
(RevealAllNonFlagged t) -> (revealAllNonFlaggedCells (state ^. board), t)
finishGame = calculateTimeElapsed (state ^. lastStartedAt) (state ^. timeElapsed) time
st = checkStatus boardAfterMove
Expand Down
4 changes: 2 additions & 2 deletions templates/game.hamlet
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
Left Click
to reveal a cell.
<span .font-mono .font-semibold .bg-gray-200 .text-sm .sm:text-base .text-gray-700 .subpixel-antialiased .px-2 .py-2 .rounded>
Alt + Click
Right Click
to flag a cell.
<li .mt-2>
Click the face to restart. A new seed will be chosen.
Expand Down Expand Up @@ -62,7 +62,7 @@
$forall cellEntity <- row ^. rowCells
<td #x#{(cellEntity ^. cellEntityCoordX)}y#{(cellEntity ^. cellEntityCoordY)}>
$if (gameStateEntity ^. gameStateEntityStatus) == "Ongoing"
<div .div onclick="makeMove(#{cellEntity ^. cellEntityCoordX}, #{cellEntity ^. cellEntityCoordY}, '#{gameStateEntity ^. gameStateEntityGameId}', event)">
<div .div onclick="makeMove(#{cellEntity ^. cellEntityCoordX}, #{cellEntity ^. cellEntityCoordY}, '#{gameStateEntity ^. gameStateEntityGameId}', event)" oncontextmenu="makeMove(#{cellEntity ^. cellEntityCoordX}, #{cellEntity ^. cellEntityCoordY}, '#{gameStateEntity ^. gameStateEntityGameId}', event)">
<img .img src="/static/assets/#{(cellEntity ^. cellEntityAssetId)}.svg" width="24" height="24">
$else
<div .div>
Expand Down
18 changes: 16 additions & 2 deletions templates/game.julius
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,28 @@ var src;
const makeMove = (x, y, gameId, event) => {
event.preventDefault();

console.log("MAKE MOVE", { x, y, gameId, event });
console.log("MAKE MOVE", { x, y, gameId }, "EVENT", {
button: event.button,
event,
});

var action = null;
if (event.button === 0) {
action = "Reveal";
} else if (event.button === 2) {
action = "Flag";
}

if (action === null) {
return;
}

$.ajax({
url: "/game/" + gameId,
type: "PUT",
contentType: "application/json",
data: JSON.stringify({
action: event.altKey ? "Flag" : "Reveal",
action: action,
coordX: x,
coordY: y,
}),
Expand Down

0 comments on commit e6ddcf7

Please sign in to comment.