Skip to content

Instantly share code, notes, and snippets.

@rhulha
Created December 10, 2018 12:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rhulha/3bedc98972477eb917a1815a836b5741 to your computer and use it in GitHub Desktop.
Save rhulha/3bedc98972477eb917a1815a836b5741 to your computer and use it in GitHub Desktop.
Minesweeper implemented in ~100 lines of TypeScript
function ac(type_: string, father: HTMLElement): HTMLElement {
return father.appendChild(document.createElement(type_));
}
function getById(id: string): HTMLElement {
return document.getElementById(id);
}
function shuffle<T>(a: Array<T>) {
for (var i = 81; i >= 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
[a[i], a[j]] = [a[j], a[i]];
}
return a;
}
class Tile {
td: HTMLElement;
checkTime: number;
constructor(public type_: string) { }
}
var msboard = new Array<Tile>();
for (var i = 0; i <= 81; i++) {
msboard.push(new Tile(i < 10 ? '*' : ''));
}
shuffle(msboard);
function isBomb(x: number, y: number): boolean {
return (x < 0 || x > 8 || y < 0 || y > 8) ? false : msboard[x + y * 9].type_ == '*';
}
function reveal(x: number, y: number, bombsAround: number) {
if (x < 0 || x > 8 || y < 0 || y > 8)
return;
var tile = msboard[x + y * 9];
tile.td.style.backgroundColor = 'white';
tile.td.style.borderStyle = 'inset';
if (bombsAround > 0)
tile.td.innerHTML = "" + bombsAround;
}
function countBombsAround(x: number, y: number): number {
var found = 0;
for (var xx = x - 1; xx <= x + 1; xx++) {
for (var yy = y - 1; yy <= y + 1; yy++) {
if (isBomb(xx, yy))
found++;
}
}
return found;
}
function revealAround(x: number, y: number) {
if (x < 0 || x > 8 || y < 0 || y > 8)
return;
var tile = msboard[x + y * 9];
if (tile.checkTime == checkTime)
return; // don't double check a tile
else
tile.checkTime = checkTime;
for (var xx = x - 1; xx <= x + 1; xx++) {
for (var yy = y - 1; yy <= y + 1; yy++) {
if (xx == x && yy == y) { }
else if (isBomb(xx, yy)) { }
else {
check(xx,yy);
}
}
}
}
function check(x: number, y: number) {
if (isBomb(x, y)) {
var tile = msboard[x + y * 9];
tile.td.innerHTML = '*';
tile.td.style.backgroundColor = 'red';
} else {
var bombs = countBombsAround(x, y);
reveal(x, y, bombs);
if (bombs == 0)
revealAround(x, y);
}
}
class GridGame {
mstab: HTMLElement;
constructor(xx: number, yy: number) {
this.mstab = ac("table", getById("tableBorder"));
for (var y = 0; y < yy; y++) {
var mstr = ac("tr", this.mstab);
for (var x = 0; x < xx; x++) {
var mstd = ac("td", mstr);
mstd.tabIndex = x + y * 9;
msboard[x + y * 9].td = mstd;
}
}
}
}
var gg = new GridGame(9, 9);
var checkTime = 0;
gg.mstab.addEventListener("mousedown", function (event: MouseEvent) {
checkTime++;
var td = event.target as HTMLElement;
if (td.tabIndex >= 0) {
if(event.button == 2)
td.innerHTML = "!";
else
check(td.tabIndex % 9, td.tabIndex / 9 | 0);
}
});
@rhulha
Copy link
Author

rhulha commented Dec 10, 2018

HTML:

<body oncontextmenu="return false;">
  <div id="tableBorder"></div>
</body>

CSS:

td { border:1px solid orange;
    width: 25px;
    height: 25px;
    color: black;
    background-color: orange;
    border-style: outset;
    text-align: center;
    vertical-align: middle;
   }

@rhulha
Copy link
Author

rhulha commented Dec 10, 2018

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