#MonthOfCode - Day 18: search

My entry for the 18th day of the month of code. The theme for today is: search.

This is a search game. You are looking for a hidden X in the grid. When you click on a cell, an arrow pointing in the general direction of the X is revealed. ←↑→↓ if the X is in the same row/column, ↖↗↘↙ otherwise.

But it’s too late, the X has already moved! After each click, it moves on one of the unrevealed adjacent cells. At the end of the game, all the cells that the X has visited are shown.

And it has horrible colors.

Code after the break.

search.jsview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
document.addEventListener('DOMContentLoaded', function() {

var gameover = false;

var symbols = {
l: '←',
u: '↑',
r: '→',
d: '↓',
ul: '↖',
ur: '↗',
dr: '↘',
dl: '↙'
}

var $table = $('#moc-18');
for (var i = 0; i < 10; i++) {
var $row = $('<tr>');
for (var j = 0; j < 10; j++) {
$row.append($('<td>'));
}
$table.append($row);
}

// random first position
var hiddenX = rand(10);
var hiddenY = rand(10);

var indexOf = Array.prototype.indexOf;
indexOf = indexOf.call.bind(indexOf);

$table.on('click', 'td', function (ev) {
$td = $(ev.target);
if (gameover) {
return;
}
var p = this.parentNode;
var x = indexOf(p.childNodes, this);
var y = indexOf(p.parentNode.childNodes, p);

if (x === hiddenX && y === hiddenY) {
// found!
$td.addClass('found').text('X');
$table.addClass('gameover');
gameover = true;
return;
}

var indication = '';
if (y !== hiddenY) {
indication += (y < hiddenY ? 'd' : 'u');
}
if (x !== hiddenX) {
indication += (x < hiddenX ? 'r' : 'l');
}

$td.addClass('discovered').html(symbols[indication]);
move();
});

function move() {
var td = $($table.find('tr')[hiddenY]).find('td')[hiddenX];
$(td).addClass('was-here');

var available = [
[-1, -1], [-1, 0], [-1, 1],
[ 0, -1], [ 0, 1],
[ 1, -1], [ 1, 0], [ 1, 1]
];
// identify possible moves
available = available.filter(function (m) {
var x = hiddenX + m[0];
var y = hiddenY + m[1];
var td = $($table.find('tr')[y]).find('td')[x];

return x >= 0 && x < 10 &&
y >= 0 && y < 10 &&
! $(td).hasClass('discovered');
});
console.log(available)
if (available.length) {
var pick = available[rand(available.length)];
console.log(pick)
hiddenX += pick[0];
hiddenY += pick[1];
}
}

function rand(min, max) {
if (max == null) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min));
}
});
search.cssview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#moc-18 {
border-collapse: collapse;
border-spacing: 0;
border-width: 0 0 1px 1px;
border-style: solid;
margin: 30px auto;

text-align: center;
font-family: monospace;
font-size: 18px;

}


#moc-18 td {
width: 30px;
height: 30px;
vertical-align: middle;

border-width: 1px 1px 0 0;
border-style: solid;

background-color: #DEADED;
}


#moc-18 td:hover {
background-color: #C84AF0;
cursor: pointer;
}


#moc-18 td.discovered,
#moc-18 td.discovered:hover {
background-color: #D47BF0;
cursor: normal;
}


#moc-18.gameover td.was-here {
background-color: #FFB800;
}


#moc-18.gameover td.found {
background-color: yellow;
}