Skip to content

Instantly share code, notes, and snippets.

@aemkei
Forked from 140bytes/LICENSE.txt
Created November 2, 2011 19:27
Show Gist options
  • Select an option

  • Save aemkei/1334626 to your computer and use it in GitHub Desktop.

Select an option

Save aemkei/1334626 to your computer and use it in GitHub Desktop.
minesweeper - 140byt.es

Minesweeper - 140byt.es

Minesweeper is a single-player game. The object of the game is to clear an abstract minefield without detonating a mine.

This version uses less than 140 bytes pure JavaScript to compile the main game logic.

Play the Demo and feel free to bomb some bytes!

For more information

See the 140byt.es site for a showcase of entries (built itself using 140-byte entries!), and follow @140bytes on Twitter.

To learn about byte-saving hacks for your own code, or to contribute what you've learned, head to the wiki.

140byt.es is brought to you by Jed Schmidt, with help from Alex Kloss. It was inspired by work from Thomas Fuchs and Dustin Diaz.

function f(
a, // input
b, // position
c, // output
d, // placeholder
e // interator index
){
for (
e = // loop though cells if
1/a[b] && // ... input cell is not a border
c[b] == e && // ... current cell was not set
16; // call loop twice (2 x 8 cells)
e--;
e > 7 ? // first:
c[b] = a[b] ? // check if input cell has a bomb
9 : // "9" is used to indicate a bomb
~~c[b] + ~~a[d] // otherwise sum up bombs around
: c[b] || f( // second: if cell is empty
a, // ... analyse sourrounding cells
d, // ... with new position
c
)
)
d = "1789"[ // list of coords around cell
e % 4 // make sure we are in range
] * ( // generate negative values
e / 4 & 1 || -1 // ... but only for the first 4 chars
// (will return: -1,-7,-8,-9, 9, 8, 7, 1)
) + b // and shift from current position
}
function a(b,c,d,e,f,g,h){if(b[d]===h||e[d]!==h)return;e[d]=0;for(g in f=[-c-1,-c,-c+1,-1,1,c-1,c,c+1])e[d]+=~~b[d+f[g]];b[d]?e[d]="X":1;for(g in f)e[d]||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h){if(b[d]===h||e[d]!==h)return;for(g in f=[-c-1,-c,-c+1,-1,1,c-1,c,c+1])e[d]=~~e[d]+~~b[d+f[g]];b[d]?e[d]="X":1;for(g in f)e[d]||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){if(b[d]===h||e[d]!==h)return;for(g in f=[-c-1,-c,-c+1,-1,1,c-1,c,c+1])i=~~i+~~b[d+f[g]];b[d]?i="X":1;for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){if(b[d]!==h&&e[d]===h){for(g in f=[-c-1,-c,-c+1,-1,1,c-1,c,c+1])i=~~i+~~b[d+f[g]],b[d]?i="X":1;for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}}
function a(b,c,d,e,f,g,h,i){if(b[d]!==h&&e[d]===h){for(g in f=[-c-1,-c,-c+1,-1,1,c-1,c,c+1])i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}}
function a(b,c,d,e,f,g,h,i){f=b[d]!==h&&e[d]===h?[-c-1,-c,-c+1,-1,1,c-1,c,c+1]:[];for(g in f)i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){f=b[d]!==h&&e[d]===h?[-c-1,-c,-c+1,-1,1,c-1,c,c+1]:0;for(g in f)i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){for(g in f=b[d]!==h&&e[d]===h?[-c-1,-c,-c+1,-1,1,c-1,c,c+1]:[])i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){for(g in f=b[d]!==h&&e[d]===h?[-c-1,-c,-c+1,-1,1,c-1,c,c+1]:0)i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){for(g in f=b[d]!==h&&e[d]===h&&[-c-1,-c,-c+1,-1,1,c-1,c,c+1])i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h,i){for(g in f=b[d]!==h&&e[d]===h&&[-c-1,-c,1-c,-1,1,c-1,c,c+1])i=b[d]?"X":~~i+~~b[d+f[g]];for(g in f)(e[d]=i)||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h){for(g in f=b[d]!==h&&e[d]===h&&[-c-1,-c,1-c,-1,1,c-1,c,c+1])e[d]=b[d]?"X":~~e[d]+~~b[d+f[g]];for(g in f)e[d]||a(b,c,d+f[g],e)}
function a(b,c,d,e,f,g,h){for(g in f=b[d]!==h&&e[d]===h&&[-10,-9,-8,-1,1,8,9,10])e[d]=b[d]?"X":~~e[d]+~~b[d+f[g]];for(g in f)e[d]||a(b,9,d+f[g],e)}
function a(b,c,d,e,f,g){for(f in e=b[c]!==g&&d[c]===g&&[-10,-9,-8,-1,1,8,9,10])d[c]=b[c]?"X":~~d[c]+~~b[c+e[f]];for(f in e)d[c]||a(b,c+e[f],d)}
function a(b,c,d,e,f,g){for(f in e=b[c]!==g&&d[c]===g&&[-9,-8,-7,-1,1,7,8,9])d[c]=b[c]?"X":~~d[c]+~~b[c+e[f]];for(f in e)d[c]||a(b,c+e[f],d)}
function f(a,b,c,d,e,g){for(e in d=a[b]!==g&&c[b]===g&&[1,7,8,9,-1,-7,-8,-9])c[b]=a[b]?"X":~~c[b]+~~a[b+d[e]];for(e in d)c[b]||f(a,b+d[e],c)}
function f(a,b,c,d,e,g){for(e in d=a[b]!==g&&c[b]===g&&[1,7,8,9,-1,-7,-8,-9])c[b]=a[b]?9:~~c[b]+~~a[b+d[e]];for(e in d)c[b]||f(a,b+d[e],c)} // 139: aemkei
function f(a,b,c,d,e){for(e in d=1/a[b]&&!(1/c[b])&&[-9,-8,-7,-1,1,7,8,9])c[b]=a[b]?9:~~c[b]+~~a[b+d[e]];for(e in d)c[b]||f(a,b+d[e],c)} // 136: subzey
function f(a,b,c,d,e){for(e in d=1/a[b]&&c[b]==e&&[-9,-8,-7,-1,1,7,8,9])e=c[b]=a[b]?9:~~c[b]+~~a[b+d[e]];for(e in e||d)f(a,b+d[e],c)} // 133 tsaniel
function f(a,b,c,d,e,g){d=1/a[b]&&!(1/c[b])&&"82109871";for(e in d+=d)g=d[e]-9*(e%8<4)+b,e<8?c[b]=a[b]?9:~~c[b]+~~a[g]:c[b]||f(a,g,c)} // 134 aemkei
function f(a,b,c,d,e){for(e=1/a[b]&&!(1/c[b])&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="82109871"[e%8]-9*(e%8<4)+b} // 129 aemkei
function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="82109871"[e%8]-9*(e%8<4)+b} // 127 tsaniel
function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="1789"[e%4]*(e>>2&1||-1)+b} // 126 tsaniel
function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="1789"[e%4]*(e/4&1||-1)+b} // 125 tsaniel
function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="1789"[e%4]*(e/4&1||-1)+b}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 YOUR_NAME_HERE <YOUR_URL_HERE>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "minesweeper",
"description": "A game where you have to clear a field without detonating a mine.",
"keywords": [
"game",
"algorithm",
"fun"
]
}
<!DOCTYPE html>
<head>
<title>Minesweeper - 140byt.es</title>
<style type="text/css" media="screen">
body {
font-family: Arial;
font-size: 16px;
}
div {
width: 240px;
margin: 20px;
border: 1px solid #000;
display: inline-block;
}
span {
display: inline-block;
float: left;
text-align: center;
width: 30px;
height: 30px;
margin: 2px 2px;
line-height: 30px;
background-color: #EEE;
}
span.save {
background-color: #CFC;
}
span.bomb {
background-color: #FCC;
}
</style>
</head>
<body>
<div id="game"></div>
<br>
Minesweeper in 140byt.es - <a href="https://gist.github.com/1334626">Source</a>
<script>
var sweep = function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="1789"[e%4]*(e/4&1||-1)+b}
var current = [];
var input = [
, , , , , , , ,
, 0, 0, 0, 0, 0, 0, 0,
, 0, 1, 0, 0, 0, 0, 0,
, 0, 0, 0, 0, 1, 0, 0,
, 0, 0, 0, 0, 0, 0, 0,
, 1, 0, 0, 0, 0, 0, 0,
, 0, 0, 1, 0, 0, 0, 0,
, 0, 0, 0, 0, 0, 1, 0,
, , , , , , ,
];
function click(i){
sweep(input, i, current);
render(current);
}
function render(array){
var elem = document.getElementById("game");
elem.innerHTML = "";
for (var i=8; i<8*8; i++){
var span = document.createElement("span"),
value = array[i];
elem.appendChild(span);
span.innerHTML = value || 0;
if (value == undefined) {
span.innerHTML = "";
} else {
span.className = "save";
}
if (value == 9) {
span.innerHTML = "#";
span.className = "bomb";
}
(function(i){
span.onclick = function(){
click(i);
}
})(i);
span.style.display = i%8 ? "" : "none";
}
}
render("current", current);
</script>
</body>
@jed

jed commented Nov 3, 2011

Copy link
Copy Markdown

WHAT WILL IT BE!?

@aemkei

aemkei commented Nov 3, 2011

Copy link
Copy Markdown
Author

... a well known game. The source might be something between my Game of Life and Sudoku solver, but simpler.
Currently at ~180 bytes and some logic missing.

Stay tuned!

@atk

atk commented Nov 3, 2011

Copy link
Copy Markdown

Rubic's Cube?

@aemkei

aemkei commented Nov 3, 2011

Copy link
Copy Markdown
Author

@atk: No, it's flat ;)

... and it's down to 139 bytes, so read the description and leave your bets!

@jed

jed commented Nov 4, 2011

Copy link
Copy Markdown

OMG, IT'S ANGRY BIRDS!

just kidding. my first thought was "chutes and ladders", and then "battleship", but neither seems to fit.

@tsaniel

tsaniel commented Nov 4, 2011

Copy link
Copy Markdown

I'll guess Pac-man.

@jed

jed commented Nov 4, 2011

Copy link
Copy Markdown

so we know that it takes (1) an input array, (2) an output array, and (3) a position, and (while blocking) recurses until the position exists in the output. possible array values seem to range from -9 to 9. so it's definitely "solving" something, no?

@subzey

subzey commented Nov 4, 2011

Copy link
Copy Markdown

These offsets may be coords shift on 8×8 board flattened into 1-dimensional array.

┌────┬────┬────┐
│ -9 │ -8 │ -7 │
├────┼────┼────┤
│ -1 │    │  1 │
├────┼────┼────┤
│  7 │  8 │  9 │
└────┴────┴────┘

Eh… but in that case the whole function looks rather like image flood filling snippet than a game.

@tsaniel

tsaniel commented Nov 4, 2011

Copy link
Copy Markdown
┌────┬────┬────┐
│ 8  │ 1  │ 6  │
├────┼────┼────┤
│ 3  │ 5  │ 7  │
├────┼────┼────┤
│ 4  │ 9  │ 2  │
└────┴────┴────┘

Magic square?

@subzey

subzey commented Nov 4, 2011

Copy link
Copy Markdown

Hell yeah! I know that game! :) http://jsfiddle.net/NPqcn/

@aemkei, you're awesome!

@tsaniel

tsaniel commented Nov 4, 2011

Copy link
Copy Markdown

Wow... It's really amazing.

@aemkei

aemkei commented Nov 4, 2011

Copy link
Copy Markdown
Author

Congrats @subzey, you swept the field with only two (correct) answers! I'm impressed!
Going to compile the test.html and game.html

@tsaniel

tsaniel commented Nov 4, 2011

Copy link
Copy Markdown

We'll start golfing right after you're ready :)

@aemkei

aemkei commented Nov 4, 2011

Copy link
Copy Markdown
Author

Okay, demo is.

Hint: To quickly see if the code is broken or not, simply add click(12) to the end of test.html

@aronwoost

Copy link
Copy Markdown

love it!

@aemkei

aemkei commented Nov 4, 2011

Copy link
Copy Markdown
Author

... added some more comments to annotated.js

Thinks that still blow up the code:

  • double for(e in d) loop
  • [-9,-8,-7,-1,1,7,8,9] (might be written as "9871" and than inverting the values)

@subzey

subzey commented Nov 4, 2011

Copy link
Copy Markdown

Undefined check a[b]!==g can be replaced with 1/a[b]. Any finite number yields “truthy” value and undefined is coerced to NaN. So we can get rid of g.

function f(a,b,c,d,e){for(e in d=1/a[b]&&!(1/c[b])&&[-9,-8,-7,-1,1,7,8,9])c[b]=a[b]?9:~~c[b]+~~a[b+d[e]];for(e in d)c[b]||f(a,b+d[e],c)}

@atk

atk commented Nov 4, 2011

Copy link
Copy Markdown

I tried to use [1,7,8,9] and call the function twice, once with b+d[e] and once with b-d[e], but it got longer this way.

@tsaniel

tsaniel commented Nov 6, 2011

Copy link
Copy Markdown

What about

function f(a,b,c,d,e){for(e in d=1/a[b]&&c[b]==e&&[-9,-8,-7,-1,1,7,8,9])e=c[b]=a[b]?9:~~c[b]+~~a[b+d[e]];for(e in e||d)f(a,b+d[e],c)}

?

Save 3 bytes and more efficient.

@aemkei

aemkei commented Nov 7, 2011

Copy link
Copy Markdown
Author

Nice we are down to 133 bytes now!

And my best approach to reduce d=[-9,-8,-7,-1,1,7,8,9] (21b) was setting it to d="82109871" (10b) and later subtract -9 from the first characters: -9*(e<4) (8b) But unfortunately we have to do this twice, so still longer than before.

@tsaniel

tsaniel commented Nov 7, 2011

Copy link
Copy Markdown

By the way, would you mind using some ES5 features to shave the bytes off?

@aemkei

aemkei commented Nov 7, 2011

Copy link
Copy Markdown
Author

Hmm I would keep ES5 out of this. You know, it's just for fun to play with a small subset of language features.
But we might ask @jed about the official features!

@jed

jed commented Nov 7, 2011

Copy link
Copy Markdown

seems the consensus to me is to keep things to "old school" for now.

@aemkei

aemkei commented Nov 7, 2011

Copy link
Copy Markdown
Author

I got rid of the second for in loop and used a string instead of the array:

function f(a,b,c,d,e,g){d=1/a[b]&&!(1/c[b])&&"82109871";for(e in d+=d)g=d[e]-9*(e%8<4)+b,e<8?c[b]=a[b]?9:~~c[b]+~~a[g]:c[b]||f(a,g,c)}

Okay, this version will add one more byte (134b), but maybe we can use it to further shrink the code.

@aemkei

aemkei commented Nov 8, 2011

Copy link
Copy Markdown
Author

How about: (129 bytes)

function f(a,b,c,d,e){for(e=1/a[b]&&!(1/c[b])&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="82109871"[e%8]-9*(e%8<4)+b}

@tsaniel

tsaniel commented Nov 8, 2011

Copy link
Copy Markdown

You can still use c[b]==e, so it's 127 bytes.

function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="82109871"[e%8]-9*(e%8<4)+b}

@aemkei

aemkei commented Nov 8, 2011

Copy link
Copy Markdown
Author

@tsaniel: Sure, you're right! I've updated the files and now think about adding some more logic to the 13 left bytes.

I'd love to uncover the full board when a bomb was hit. So whenever a[b] is "truthy" it should not stop the second loop.

@tsaniel

tsaniel commented Nov 8, 2011

Copy link
Copy Markdown

Save 2 bytes.

function f(a,b,c,d,e){for(e=1/a[b]&&c[b]==e&&16;e--;e>7?c[b]=a[b]?9:~~c[b]+~~a[d]:c[b]||f(a,d,c))d="1789"[e%4]*(e/4&1||-1)+b}

Updated.

@aemkei

aemkei commented Nov 8, 2011

Copy link
Copy Markdown
Author

Nice one: Now it's 125 bytes only!
I tried to use "1789" too, but was not able to get the comparator down to 10 bytes :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment