Skip to content

Instantly share code, notes, and snippets.

@aemkei
Forked from 140bytes/LICENSE.txt
Created November 2, 2011 19:27
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aemkei/1334626 to your computer and use it in GitHub Desktop.
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
Copy link

jed commented Nov 3, 2011

WHAT WILL IT BE!?

@aemkei
Copy link
Author

aemkei commented Nov 3, 2011

... 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
Copy link

atk commented Nov 3, 2011

Rubic's Cube?

@aemkei
Copy link
Author

aemkei commented Nov 3, 2011

@atk: No, it's flat ;)

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

@jed
Copy link

jed commented Nov 4, 2011

OMG, IT'S ANGRY BIRDS!

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

@tsaniel
Copy link

tsaniel commented Nov 4, 2011

I'll guess Pac-man.

@jed
Copy link

jed commented Nov 4, 2011

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
Copy link

subzey commented Nov 4, 2011

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
Copy link

tsaniel commented Nov 4, 2011

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

Magic square?

@subzey
Copy link

subzey commented Nov 4, 2011

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

@aemkei, you're awesome!

@tsaniel
Copy link

tsaniel commented Nov 4, 2011

Wow... It's really amazing.

@aemkei
Copy link
Author

aemkei commented Nov 4, 2011

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

@tsaniel
Copy link

tsaniel commented Nov 4, 2011

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

@aemkei
Copy link
Author

aemkei commented Nov 4, 2011

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

love it!

@aemkei
Copy link
Author

aemkei commented Nov 4, 2011

... 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
Copy link

subzey commented Nov 4, 2011

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
Copy link

atk commented Nov 4, 2011

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
Copy link

tsaniel commented Nov 6, 2011

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
Copy link
Author

aemkei commented Nov 7, 2011

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
Copy link

tsaniel commented Nov 7, 2011

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

@aemkei
Copy link
Author

aemkei commented Nov 7, 2011

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
Copy link

jed commented Nov 7, 2011

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

@aemkei
Copy link
Author

aemkei commented Nov 7, 2011

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
Copy link
Author

aemkei commented Nov 8, 2011

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
Copy link

tsaniel commented Nov 8, 2011

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
Copy link
Author

aemkei commented Nov 8, 2011

@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
Copy link

tsaniel commented Nov 8, 2011

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
Copy link
Author

aemkei commented Nov 8, 2011

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