IMAGE_SIZE = isNaN(parseInt(getCookie('bestSize'))) ? 48 : parseInt(getCookie('bestSize'))
try {
var images = ['blank.png', 'halfstone.png', 'object.png', 'goal.png', 'manblank.png', 'objectgoal.png', 'mangoal.png'];
for (var i = 0; i < images.length; i++) {
var image = new Image();
image.src = images[i];
}
} catch (e) { }
levelMaps = [
["'''###'''''",
"''## #'####",
"'## ### #",
"## $ #",
"# @$ # #",
"### $### #",
"''# #.. #",
"'## ##.# ##",
"'# ##'",
"'# ##''",
"'#######'''"],
["'##'#####",
"##'## . #",
"#'## $. #",
"'## $ #",
"## $@ ###",
"# $ ##''",
"#.. ##'##",
"# #'##'",
"#####'#''"],
["'''''''''''#####",
"''''''''''## #",
"''''''''''# #",
"''''####''# $ ##",
"''''# ####$ $#'",
"''''# $ $ #'",
"'''## ## $ $ $#'",
"'''# .# $ $ #'",
"'''# .# #'",
"##### #########'",
"#.... @ #''''''",
"#.... #''''''",
"## ######''''''",
"'####'''''''''''"],
["''###########",
"'## # @#",
"### $ $$# #",
"# ##$ $$ #",
"# # $ # #",
"###### ######",
"#.. ..$ #*##'",
"# .. ###''",
"# ..#####'''",
"#########''''"],
["''###########''",
"'## # ##'",
"### $ $#$ $ ###",
"# #$ $ # $ $# #",
"# $ ..#.. $ #",
"# $...#...$ #",
"# $ .. * .. $ #",
"###### @ ######",
"# $ .. .. $ #",
"# $...#...$ #",
"# $ ..#.. $ #",
"# #$ $ # $ $# #",
"### $ $#$ $ ###",
"'## # ##'",
"''###########''"],
["''###########''",
"###. .$. .###",
"'## $ $ $ ##'",
"''## ..$.. ##'''",
"'''##$#$#$##''''",
"''''#.$ $.#'''''",
"''''# @ #'''''",
"''''### ###'''''",
"'''## $ $ ##''''",
"'''#. $ .#''''",
"'''### . ###''''",
"'''''#####''''''"],
["'''''''''''######''",
"''''####''## #''",
"''### #''# ## ###",
"### #### # $ #",
"# $ @ ...*.. $ #",
"# $ $ ## ### ###",
"### ### #'#####''",
"'# ###''''''''",
"'# ####''''''''''",
"'#####'''''''''''''"],
["''''#######''",
"''''# ##'",
"##### ### ##",
"# # ##",
"#@$***. ##$ #",
"# # ## .#",
"## ## # $ #",
"'## ####.$.#",
"''## #",
"'''###### ##",
"''''''''####'"],
["#########",
"#. . #",
"#.$. . #",
"## ###@ #",
"'# $ ##",
"'# $$ ##'",
"'# $ #''",
"'# ###''",
"'####''''"],
["''''''######''''''",
"''''''# #''''''",
"''''''# @ ###''''",
"####''# #''''",
"# ####..#.#$#####",
"# $ $ ##... #",
"# .....#$$ #",
"###### ##$## #####",
"'''''# $ #'''''",
"'''''#### ####'''''",
"'''''''# #''''''''",
"'''''''# #####''''",
"'''''### $ #''''",
"'''''# $ $ #''''",
"'''''# #$# ####''''",
"'''''# #'''''''",
"'''''#######'''''''"],
["''####'''''",
"### ####''",
"# @ ##'",
"# #. .#.###",
"# $$$ $$$ #",
"###.#.#.# #",
"'## #",
"''#### ###",
"'''''####''"],
["''''''''''''''#####''''''''",
"''''''''''''''# #''''''''",
"''''#####'''''# #######''",
"''''# #####'# ..... #''",
"##### # ## #'# # # #''",
"# $ $ $ $ $ #'## ## $ #''",
"# # ##......#### ### $$ ###",
"# ## * # #'# $$ #",
"##########+$$ ##'# #",
"'''''''''#.$ $# #''########",
"'''''''''#.## #''''''''''",
"'''''''''########''''''''''"],
["'''#######''",
"'### ##'",
"'# ### #'",
"'# # #'",
"###$#@ # #'",
"# ##### #'",
"# # *. #'",
"##$$# *.##'",
"'# *..#'",
"'#### #...##",
"''''# #$$$ #",
"''''# $ #",
"''''##### #",
"''''''''####"],
["'#######''",
"## #'#",
"# *.$.#''",
"# *.#.###",
"# #$@$$ #",
"# ## # #",
"###### #",
"'''''#####"],
["'''####''''",
"'''#@ #''''",
"''## ##'''",
"''# .$#####",
"''#$. # #",
"###..$# # #",
"# ..$ $ #",
"# $ $ # ###",
"##### # #''",
"''''# #''",
"''''###.#''",
"''''''###''"],
["''######'''''''",
"'## # ###'''''",
"## # # ##''''",
"# # $.# #''''",
"## $ $.# #''''",
"# #####. ##''''",
"# $. @#''''",
"# $. ####''",
"### # #*# # ###",
"''#### .$ #",
"''''# .$ #",
"''''## .##### #",
"''''# #.$ $ ##",
"''''# #.$ # #",
"''''## # # ##",
"'''''### # ##'",
"'''''''######''"]
]
function init() {
sel = document.getElementsByTagName('select').item(0);
for (var i = 0; i < levelMaps.length; i++) {
var option = document.createElement('option');
option.setAttribute('value', '' + i);
option.appendChild(document.createTextNode('Level ' + i));
sel.appendChild(option);
}
loadLevel();
}
function createImage(id, src) {
var result = document.createElement('img');
result.setAttribute('id', id);
result.setAttribute('width', IMAGE_SIZE);
result.setAttribute('height', IMAGE_SIZE);
result.setAttribute('src', src);
return result;
}
function stripPath(location) {
if (location.indexOf('/') != -1) {
var index = location.indexOf('/');
var prevIndex = index;
while (index != -1) {
prevIndex = index;
index = location.indexOf('/', index + 1);
}
location = location.substring(prevIndex + 1);
}
return location;
}
document.onkeydown = function(e) {
var newX = playerX;
var newY = playerY;
switch (e.keyCode) { // wasd keys: different range for Mozilla and Konqueror
case 38: newY--; break;
case 39: newX++; break;
case 40: newY++; break;
case 37: newX--; break;
default: return;
}
e.preventDefault(); // XXX: Does nothing?
var target = document.getElementById(newX + ',' + newY);
var targetData = stripPath(target.getAttribute('src'));
if (targetData == 'halfstone.png') return false;
if (targetData == 'object.png' || targetData == 'objectgoal.png') {
var pushingTo = document.getElementById((2 * newX - playerX) + ',' + (2 * newY - playerY));
var pushingToData = stripPath(pushingTo.getAttribute('src'));
if (pushingToData != 'blank.png' && pushingToData != 'goal.png') return false;
if (pushingToData == 'goal.png') correctlyPlaced++;
if (targetData == 'objectgoal.png') correctlyPlaced--;
targetData = (targetData == 'objectgoal.png') ? 'goal.png' : 'blank.png';
var pushedTo = createImage((2 * newX - playerX) + ',' + (2 * newY - playerY), (pushingToData == 'goal.png') ? 'objectgoal.png' : 'object.png');
pushingTo.parentNode.replaceChild(pushedTo, pushingTo);
}
var old = document.getElementById(playerX + ',' + playerY);
var newData = 'man' + targetData;
var image = createImage(playerX + ',' + playerY, (stripPath(old.getAttribute('src')) == 'mangoal.png') ? 'goal.png' : 'blank.png');
old.parentNode.replaceChild(image, old);
var image2 = createImage(newX + ',' + newY, newData);
target.parentNode.replaceChild(image2, target);
playerX = newX;
playerY = newY;
if (correctlyPlaced == numberOfObjects) { // Player has finished the game
var name = prompt('Congratulations!\n\nEnter your name for the highscore list:');
var body = document.getElementsByTagName('body')[0];
var form = document.createElement('form');
form.setAttribute('method', 'post');
form.setAttribute('action', '/games/highscore/?game=sokoban');
form.setAttribute('style', 'display: none;');
body.appendChild(form);
var input = document.createElement("input");
input.setAttribute('type', 'text');
input.setAttribute('name', 'name');
input.setAttribute('value', name);
form.appendChild(input);
var scoreInput = document.createElement('input');
scoreInput.setAttribute('type', 'text');
scoreInput.setAttribute('name', 'level');
scoreInput.setAttribute('value', document.forms[0].newLevel.selectedIndex);
form.appendChild(scoreInput);
form.submit();
}
return false;
}
function loadLevel() {
var currentLevel = document.forms[0].newLevel.selectedIndex;
document.forms[0].newLevel.blur(); // remove focus from the level selector so it doesn't scroll when player moves
var tableBody = document.getElementById('tableBody');
while (tableBody.hasChildNodes()) tableBody.removeChild(tableBody.firstChild);
correctlyPlaced = 0;
numberOfObjects = 0;
var levelMap = levelMaps[currentLevel];
for (var row = 0; row < levelMap.length; row++) {
var newRow = document.createElement('tr')
tableBody.appendChild(newRow)
for (var column = 0; column < levelMap[0].length; column++) {
var source = null;
switch (levelMap[row].charAt(column)) {
case '#': source = 'halfstone.png'; break;
case '$': source = 'object.png'; numberOfObjects++; break;
case '.': source = 'goal.png'; break;
case '@': source = 'manblank.png'; playerX = column; playerY = row; break;
case '\'': source = null; break;
case '*': source = 'objectgoal.png'; numberOfObjects++; correctlyPlaced++; break;
case '+': source = 'mangoal.png'; playerX = column; playerY = row; break;
case ' ': source = 'blank.png'; break;
default: alert('Unrecognized map character: "' + levelMap[row].charAt(column) + '"');
}
var newColumn = document.createElement('td')
if (source != null) {
newColumn.appendChild(createImage(column + ',' + row, source));
}
newRow.appendChild(newColumn)
}
}
}
function changeSize(change) {
IMAGE_SIZE += change;
try {
document.cookie = 'bestSize = ' + IMAGE_SIZE + '; expires=' + new Date("January 1, 2006").toGMTString();
} catch (e) {
alert('Could not write cookie!');
}
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
images[i].setAttribute('width', IMAGE_SIZE);
images[i].setAttribute('height', IMAGE_SIZE);
}
}
function getCookie(name) {
var prefix = name + "=";
var begin = document.cookie.indexOf("; " + prefix);
if (begin == -1) {
begin = document.cookie.indexOf(prefix);
if (begin != 0) return null;
} else {
begin += 2;
}
var end = document.cookie.indexOf(";", begin);
if (end == -1) end = document.cookie.length;
return unescape(document.cookie.substring(begin + prefix.length, end));
}
function help() {
alert('Move the man with the arrow keys.\nTry to push the red diamonds onto the green areas without getting stuck.');
}