var mineGui_mine = false, mineGui_curmap, mineGui_curndx, mineGui_moves = "", mineGui_mapname = ''; var mineGui_movesBackup = []; var mineGui_customNdx = 1; var mineGui_canvas = true; var mineGui_imgSources = { 'sprites': 'sprites.png' }; var mineGui_spriteOffset = { 'R': 5, '#': 7, '*': 6, '\\': 2, 'L': 3, 'O': 4, '.': 0, ' ': 1, 'A': 8,'B': 9,'C':10,'D':11,'E':12,'F':13,'G':14,'H':15,'I':16, '1':17,'2':18,'3':19,'4':20,'5':21,'6':22,'7':23,'8':24,'9':25, 'W':26, '!':27, '@':30 }; var mineGui_spriteOffset_Lost = { 'R': 28, '#': 7, '*': 6, '\\': 2, 'L': 3, 'O': 4, '.': 0, ' ': 1, 'A': 8,'B': 9,'C':10,'D':11,'E':12,'F':13,'G':14,'H':15,'I':16, '1':17,'2':18,'3':19,'4':20,'5':21,'6':22,'7':23,'8':24,'9':25, 'W':26, '!':27, '@':30 }; var mineGui_spriteOffset_Won = { 'R': 29, '#': 7, '*': 6, '\\': 2, 'L': 3, 'O': 29, '.': 0, ' ': 1, 'A': 8,'B': 9,'C':10,'D':11,'E':12,'F':13,'G':14,'H':15,'I':16, '1':17,'2':18,'3':19,'4':20,'5':21,'6':22,'7':23,'8':24,'9':25, 'W':26, '!':27, '@':30 }; var mineGui_images = {}; var mineGui_imagesNeed = 0; function mineGui_loadImg(key, src) { var img; ++mineGui_imagesNeed; mineGui_images[key] = img = new Image(); img.onload = function() { if (0 == --mineGui_imagesNeed) { mineGui_show(); } }; img.src = src; } function mineGui_start() { var div = document.getElementById("mineGui"); var selMap = document.getElementById("mineGui_selectMap"); var inpMoves = document.getElementById("mineGui_moves"); var customMapInput = document.getElementById("mineGui_data") var validMoves = {L:1,U:1,R:1,D:1,A:1,W:1,S:1}; var k; document.getElementById("mineGui_addData").onclick = mineGui_addCustomMap; selMap.onchange = function() { var k = selMap.options[selMap.selectedIndex].text; mineGui_setMap(k, selMap.selectedIndex); selMap.blur(); }; var inpValidate = function() { if (inpMoves.value == mineGui_moves) return; mineGui_moves = ""; var txt = inpMoves.value.toUpperCase(), i; for (i = 0; i < txt.length; ++i) { if (validMoves[txt[i]]) mineGui_moves += txt[i]; } mineGui_updateMine(); }; var delayInpValidate = function(event) { // console.log("input", event, event.type); window.setTimeout(inpValidate, 0); }; inpMoves.onchange = delayInpValidate; inpMoves.onpaste = delayInpValidate; inpMoves.onkeypress = delayInpValidate; document.body.onkeydown = function (event) { // console.log("body", event); // console.log("isChar", event.isChar, // "; char '"+String.fromCharCode(event.charCode)+ // "'; key '"+String.fromCharCode(event.keyCode)+"'") if (document.activeElement === customMapInput) return; if (event.ctrlKey || event.altKey || event.metaKey) return; var handled = true; // ascii keys are reported as uppercase ascii code var cmd = String.fromCharCode(event.keyCode); if (validMoves[cmd]) { mineGui_move(cmd); } else if (cmd == 'C') { // clear mineGui_moves = ""; mineGui_updateMine(); } else if (cmd == 'T') { // toggle text/canvas mineGui_canvas = !mineGui_canvas; console.log("canvas show", mineGui_canvas); mineGui_show(); } else switch (event.keyCode) { case 8: // backspace -> undo mineGui_moves = mineGui_moves.slice(0,-1); mineGui_updateMine(); break; case 33: // page up if (selMap.selectedIndex > 0) { selMap.selectedIndex--; selMap.onchange(); } break; case 34: // page down if (selMap.selectedIndex+1 < selMap.options.length) { selMap.selectedIndex++; selMap.onchange(); } break; case 37: // left if (mineGui_mine.validMove('L')) mineGui_move('L'); break; case 38: // up if (mineGui_mine.validMove('U')) mineGui_move('U'); break; case 39: // right if (mineGui_mine.validMove('R')) mineGui_move('R'); break; case 40: // down if (mineGui_mine.validMove('D')) mineGui_move('D'); break; default: handled = false; break; } if (handled) { // console.log("body handled", event, event.type); event.preventDefault(); return true; } }; for (k in mineGui_imgSources) { if (mineGui_imgSources.hasOwnProperty(k)) { mineGui_loadImg(k, mineGui_imgSources[k]); } } var fragment = window.location.hash.slice(1).split(';'); var searchMap = fragment[0]; var loadMoves = ''; var selectIndex = 0; for (k in mineMaps) { if (mineMaps.hasOwnProperty(k)) { var entry = document.createElement("option"); entry.textContent = k; if (k === searchMap) { // console.log("selected map " + k); selectIndex = selMap.options.length; if (fragment.length > 1) loadMoves = fragment[1]; } selMap.appendChild(entry); } //entry.add } selMap.selectedIndex = selectIndex; selMap.onchange(); if (loadMoves !== '') { // console.log("preset moves: " + loadMoves); inpMoves.value = loadMoves; inpMoves.onchange(); } } function mineGui_addCustomMap() { var map = document.getElementById("mineGui_data").value; var mine; var selMap = document.getElementById("mineGui_selectMap"); document.getElementById("mineGui_addDataResult").textContent = ""; try { mine = new Mine(map); } catch (e) { document.getElementById("mineGui_addDataResult").textContent = "Adding map failed: " + e; return; } mineMaps["custom" + mineGui_customNdx] = map; var entry = document.createElement("option"); entry.textContent = "custom" + mineGui_customNdx; selMap.appendChild(entry); mineGui_customNdx++; window.setTimeout(function() { selMap.selectedIndex = selMap.options.length - 1; selMap.onchange(); }, 0); } function mineGui_move(cmd) { for (i = 0; i < cmd.length; ++i) { if (mineGui_mine.state != Mine.ALIVE) break; mineGui_moves += cmd[i]; mineGui_mine.move(cmd[i]); } mineGui_show(); } function mineGui_setMap(map, ndx) { mineGui_mapname = map; mineGui_movesBackup[mineGui_curndx] = mineGui_moves; mineGui_curmap = mineMaps[map]; mineGui_curndx = ndx; mineGui_moves = mineGui_movesBackup[mineGui_curndx]; if (!mineGui_moves) mineGui_moves = ""; location.href = '#' + mineGui_mapname + ';' + mineGui_moves; mineGui_updateMine(); } function mineGui_updateMine() { // redo moves mineGui_mine = new Mine(mineGui_curmap); var cmd = mineGui_moves; mineGui_moves = ""; for (i = 0; i < cmd.length; ++i) { if (mineGui_mine.state != Mine.ALIVE) break; mineGui_moves += cmd[i]; mineGui_mine.move(cmd[i]); } mineGui_show(); } var mineGui_drawQueued = false; function mineGui_draw() { if (!mineGui_drawQueued) { mineGui_drawQueued = true; window.setTimeout(mineGui_draw_queued, 0); } } function mineGui_draw_queued() { mineGui_drawQueued = false; var spriteOffset = mineGui_spriteOffset; switch (mineGui_mine.state) { case Mine.ALIVE: break; case Mine.LOST: spriteOffset = mineGui_spriteOffset_Lost; break; case Mine.ABORTED: break; case Mine.WON: spriteOffset = mineGui_spriteOffset_Won; break; } var waterLevel = Math.max(mineGui_mine.water_level, 0); var map = mineGui_mine.toString().split(/\n/); var canv = document.getElementById("mineGui_mineCanvas"); var mapNode = document.getElementById("mineGui_mineMap"); if (mineGui_canvas && 0 == mineGui_imagesNeed) { canv.style.display = ''; canv.style.visibility = 'visible'; mapNode.style.display = 'none'; mapNode.style.visibility = 'hidden'; canv.width = 16*mineGui_mine.width; canv.height = 16*mineGui_mine.height; var ctx = canv.getContext("2d"); ctx.globalAlpha=1.0; ctx.fillStyle = "black"; ctx.fillRect(0,0,canv.width, canv.height); var sprites = mineGui_images.sprites; for (var y = 0; y < mineGui_mine.height; ++y) { for (var x = 0; x < mineGui_mine.width; ++x) { ctx.drawImage(sprites, 0, spriteOffset[map[y][x]] * 16, 16, 16, 16*x, 16*y, 16, 16); } } ctx.fillStyle = "#0000FF"; ctx.globalAlpha = 0.3; y = 16*(mineGui_mine.height - waterLevel); ctx.fillRect(0,y,canv.width, canv.height-y); } else { canv.style.display = 'none'; canv.style.visibility = 'hidden'; mapNode.style.display = ''; mapNode.style.visibility = 'visible'; } } var mineGui_fragmentQueued = false; function mineGui_updateFragment() { if (false !== mineGui_fragmentQueued) window.clearTimeout(mineGui_fragmentQueued); mineGui_fragmentQueued = window.setTimeout(mineGui_updateFragment_queued, 100); } function mineGui_updateFragment_queued() { mineGui_fragmentQueued = false; location.href = '#' + mineGui_mapname + ';' + mineGui_moves; } function mineGui_show(queued) { if (!mineGui_mine) return; mineGui_updateFragment(); var state = ""; switch (mineGui_mine.state) { case Mine.ALIVE: state = "Still mining"; break; case Mine.LOST: state = "Robot broken - " + mineGui_mine.reason; break; case Mine.ABORTED: state = "Aborted"; break; case Mine.WON: state = "Won - " + mineGui_mine.reason; break; } var waterLevel = Math.max(mineGui_mine.water_level, 0); var map = mineGui_mine.toString().split(/\n/); mineGui_draw(); if (waterLevel > 0) { document.getElementById("mineGui_mineMapWater").textContent = map.splice(-waterLevel).join("\n"); } else { document.getElementById("mineGui_mineMapWater").textContent = ""; } document.getElementById("mineGui_mineMapDry").textContent = map.join("\n"); document.getElementById("mineGui_moves").value = mineGui_moves; document.getElementById("mineGui_meta").textContent = mineGui_mine.metaText(); document.getElementById("mineGui_state").textContent = state; document.getElementById("mineGui_score").textContent = mineGui_mine.score; document.getElementById("mineGui_scoreMoves").textContent = mineGui_mine.moves; document.getElementById("mineGui_scoreLambdas").textContent = mineGui_mine.found_lambdas + "/" + (mineGui_mine.lambdas+mineGui_mine.found_lambdas); document.getElementById("mineGui_razors").textContent = mineGui_mine.razors; document.getElementById("mineGui_belowWater").textContent = mineGui_mine.moves_below_water; }