Last active
July 28, 2018 16:20
-
-
Save Guevara-chan/88c7478b180cb0c34540ce32ae5f2add to your computer and use it in GitHub Desktop.
Barebone minesweeper core.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# ~>Minesweeper core logic. | |
# ==Extnesion methods== | |
Function::getter = (name, proc) -> Object.defineProperty @prototype, name, {get: proc, configurable: true} | |
Function::setter = (name, proc) -> Object.defineProperty @prototype, name, {set: proc, configurable: true} | |
Boolean::either = (true_val, false_val = '') -> if @valueOf() then true_val else false_val | |
#.{ [Classes] | |
class Cell | |
shroud = (alert = 0b1111) << 4 | |
bomb = flag = alert # Nibble max. | |
# --Methods goes here. | |
constructor: (@pack = 0, @shroud = @shroud) -> | |
@getter 'alert', () -> @pack & alert | |
@setter 'alert', (val) -> (@pack = (@pack & shroud) + val) | |
@getter 'shroud', () -> (@pack & shroud) >> 4 | |
@setter 'shroud', (val) -> @pack = (@pack & alert) + (val << 4) | |
@getter 'explosive', () -> @alert is bomb | |
@setter 'explosive', (val) -> @alert = val.either bomb, 0 | |
@getter 'flagged', () -> @shroud is flag | |
@setter 'flagged', (val) -> @shroud = val.either flag, 1 | |
# -------------------- # | |
class Minefield | |
around = [[-1, -1], [-1, 0], [0, -1], [0, 0], [0, 1], [1, 0], [1, 1], [-1, 1], [1, -1]] | |
# --Methods goes here. | |
constructor: (@width, @height, vacancy = 0.7) -> | |
@sampler = new Cell 0, true | |
@cells = Array.from Array(@height), => new Uint8Array(@width).map => | |
@sampler.explosive = Math.random() > vacancy; return @sampler.pack | |
@markup() | |
get: (x, y) -> | |
@cache = @sampler if 1+ @sampler.pack = @cells[y]?[x] | |
set: (x, y, cell = @cache) -> | |
return cell if 1+ @cells[y]?[x] = cell?.pack | |
mark: (x, y, state) -> | |
@set(x, y) if @get(x, y)?.flagged = state ? (not @cache.flagged) | |
probe: (x, y, caution = false) -> | |
return if (not @get x, y) or (@cache.flagged and caution) | |
@cache.shroud = false | |
return @set(x, y).explosive | |
detect: (x, y) -> | |
(@probe(x + offset[0], y + offset[1], true) for offset in around).includes true | |
markup: () -> | |
for row, y in @cells | |
for bits, x in row | |
unless (cell = new Cell bits).explosive | |
cell.alert++ for [tx, ty] in around when @get(x + tx, y + ty)?.explosive | |
@set x, y, cell | |
return @ | |
#.} [Classes] | |
# Some mandatory export. | |
try [window.Cell, window.Minefield] = [Cell, Minefield] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment