UNPKG

deltascrambler

Version:

Scramble and scramble image generator for all WCA and lots of non-WCA puzzles

1,502 lines (1,390 loc) 804 kB
/* * Scrambler for most twisty puzzles. * (c) Frederik Hutfleß * Released under GPL3 */ var scrambler = (function(){function id(x) { return x; } function change_notation(moves, move_gen, img_gen, notation_equiv_class, config) { var cfg = { "222": [id, NNN2yo], "333": [id, NNN2yo], "444": [id, c444], "555": [id, c444], "666": [id, c444], "777": [id, c444], "megam": [id, mega2nolinebr, mega2carrot, mega2oldstyle], "clock": [id], "sq1": [id, karnaukh] }; if (cfg[notation_equiv_class] && cfg[notation_equiv_class][config.notationStyle]) return cfg[notation_equiv_class][config.notationStyle](moves); return id(moves); } function mega2carrot(moves) { moves = moves.join(" ").split("\n").join(" ").split(" "); var out = []; for (var i = 0; i < moves.length; ++i) { if (moves[i][0] == "R") { out.push(moves[i][1] + moves[i + 1][1]); ++i; } else if(moves[i][0] == "U"){ out.push(moves[i]+"\n"); } } return out; } function mega2nolinebr(moves) { return moves.join(" ").split("\n").join(" ").split(" "); } function mega2oldstyle(moves){ var out = []; var sides = ["U","F","R","D","B","L","DR","DL","DBR","DBL","BR","BL"]; function doRPP(sides){ return [sides[7], sides[9], sides[3], sides[10], sides[0], sides[5], sides[8], sides[4], sides[11], sides[2], sides[6], sides[1]] } function doRMM(sides){ return doRPP(doRPP(doRPP(doRPP(sides)))); } function doUPP(sides){ return [sides[0], sides[11], sides[5], sides[3], sides[6], sides[10], sides[9], sides[8], sides[7], sides[4], sides[1], sides[2]] } function doUMM(sides){ return doUPP(doUPP(doUPP(doUPP(sides)))); } for(var i=0;i<moves.length;++i){ switch(moves[i]){ case "R++": sides = doRPP(sides); out.push(sides[5]+"2-"); break; case "R--": sides = doRMM(sides); out.push(sides[5]+"2+"); break; case "D++": sides = doUPP(sides); out.push(sides[0]+"2-"); break; case "D--": sides = doUMM(sides); out.push(sides[0]+"2+"); break; case "U": out.push(sides[0]); break; case "U'": out.push(sides[0]+"-"); break; } } return out; } function NNN2yo(moves){ var out = []; for(var i=0;i<moves.length;++i){ out.push({ "U":"A", "U'":"B", "U2":"C", "D":"D", "D'":"E", "D2":"F", "L":"G", "L'":"H", "L2":"I", "R":"J", "R'":"K", "R2":"L", "M":"M", "M'":"N", "M2":"O", "E":"P", "E'":"Q", "E2":"R", "S":"S", "S'":"T", "S2":"U", "F":"V", "F'":"W", "F2":"X", "B":"Y", "B'":"Z", "B2": "YY" }[moves[i]] || moves[i]); } return out; } function c444(moves){ return moves.join(" ") .split("Fw").join("f").split("Bw").join("b") .split("Rw").join("r").split("Lw").join("l") .split("Uw").join("u").split("Dw").join("d") .split(" "); } function karnaukh(moves){ return moves.join(" ") .split("3,0").join("U") .split("-3,0").join("U'") .split("0,3").join("D") .split("0,-3").join("D'") .split("2,1").join("u") .split("-2,1").join("u'") .split("-1,2").join("d") .split("1,-2").join("d'") .split("(").join("") .split(")").join("") .split(" ") }function megaMoves(n) { var moves = []; if (n % 2 == 1) --n; n /= 2; for (var i = 0; i < n; ++i) { moves.push(i == 0 ? "R" : (i + 1) + "R"); moves.push(i == 0 ? "D" : (i + 1) + "D"); } return moves; } function scrambleMega(turns, rotations, movesPerRow, rows) { var i, j, alg = [], turnsIndex = 0; for (i = 0; i < rows; ++i) { for (j = 0; j < movesPerRow; ++j) { alg.push(turns[turnsIndex++] + rndEl(["++", "--"])); if (turnsIndex > turns.length - 1) turnsIndex = 0; } // Do the 5U 4U 3U ... U alg.push(rndEl(rotations) + "<br/>"); turnsIndex = rn(turns.length); } return alg; }function nncmoves(move, opp, n) { var moves = [], i; if (n == 2) return [move]; for (i = 0; i < ((n % 2) == 0 ? (n / 2) : ((n - 1) / 2)); ++i) { moves.push(i == 0 ? move : (i + 1) + move); if (n % 2 != 0) { moves.push(i == 0 ? opp : (i + 1) + opp); } } return moves; } function rndEl(x) { return x[~~(Math.random() * x.length)]; } function rn(n) { return ~~(Math.random() * n); } function genCuboid(config) { return scrambleNPQ(config.l, config.n, config.m, config.lgth); } function scrambleNPQ(n, p, q, length){ var side, magnitude, suffix, moves=[], prevside = "", prevused = [], doubleprevside = "_"; while(moves.length < length){ side = rndEl(["U","D","R","L","F","B"]); magnitude = rn(Math.ceil({"U":n,"D":n,"R":p,"L":p,"F":q,"B":q}[side]/2-0.5))+1; suffix = ((side=="U"||side=="D")&&q==p)?rndEl(["","2","'"]):rndEl(["2"]); if(prevside != side){ if(!(prevside == {"R":"L","L":"R","U":"D","D":"U","F":"B","B":"F"}[side] && doubleprevside == side)){ doubleprevside = prevside; prevside = side; prevused = [magnitude]; moves.push((magnitude==1?"":magnitude) + side + suffix); } } else if(prevused.indexOf(magnitude) == -1){ prevused.push(magnitude); moves.push((magnitude==1?"":magnitude) + side + suffix); } } return moves; } function scramble(turns, suffixes, length, oppositeTable) { var i, j, moves = [], scrambleMoves = []; if (!oppositeTable) oppositeTable = {}; // Check: We can't generate a scramble with only one move available and more than one move needed // Check: We need at least one suffix. It may be "". if ((turns.length < 2 && length > 1) || suffixes.length < 1) return; // Generate list of all combinations of turns and suffixes for (i = 0; i < turns.length; ++i) for (j = 0; j < suffixes.length; ++j) moves.push("" + turns[i] + suffixes[j]); // Add moves until the needed length is reached while (scrambleMoves.length < length) { scrambleMoves.push(rndEl(moves)); // Don't do A[n] A[m] if (scrambleMoves.length > 1 && scrambleMoves[scrambleMoves.length - 1][0] == scrambleMoves[scrambleMoves.length - 2][0]) scrambleMoves.pop(); // Don't do A[n] B[m] A[o] if A is opposite to B if (scrambleMoves.length > 1 && oppositeTable[scrambleMoves[scrambleMoves.length - 1][0]] == scrambleMoves[scrambleMoves.length - 2][0]) scrambleMoves.pop(); } return scrambleMoves; }function scrambleDumb(moves, length){ var c = []; for(var i=0;i<length;++i){ c.push(rndEl(moves)); } return c; } function genneg1(){ var ret = "", len = 20; for (var i = 0; i < len; i++) { ret += String.fromCharCode(32 + rn(224)); } return ret; } function square2(len){ var i = 0; var ret = []; while (i < len) { var rndu = rn(12) - 5; var rndd = rn(12) - 5; if (rndu != 0 || rndd != 0) { i++; ret.push("(" + rndu + "," + rndd + ") / "); } } return ret; } function state122(){ return rndEl(["R2","R2 U2", "R2 U2 R2", "U2 R2", "U2"]).split(" "); } function state123RU(){ return rndEl(["R2","R2 U2", "R2 U2 R2", "U2 R2", "U2", "U2 R2 U2 R2 U2", "U2 R2 U2 R2", "U2 R2 U2", "R2 U2 R2 U2", "R2 U2 R2 U2 R2", "R2 U2 R2 U2 R2"]).split(" "); } function state111(){ return rndEl(["y","y2","y'","x","x2","x'","z","z'","z y","z y2","z y''","z' y","z' y2","z' y'","z2 y","z2 y2","z2 y'","x y","x y2","x y'","x' y","x' y2","x' y'"]).split(" "); } function r123(){ var scr = []; var dir = Math.random()<.5? 0 : 1; for(var i=0;i<9+Math.random()*2;++i){ if(i%2 == dir) scr.push("R2"); else{ if(Math.random() <.5){ scr.push("U2"); if(Math.random() <.5) scr.push("D2"); } else { scr.push("D2"); } } } return scr; } function megaLSLL(){ var sol = ""; for(var i=0;i<12;++i){ sol += " "+rndEl(["R U R'","R U' R'","R U2 R'","R U2' R'","F' U' F","F' U F","F' U2 F","F' U2' F","R U2' R'","R' F R F'"]); sol += " "+rndEl(["U","U2","U2'","U'"]); } return sol.split(" "); } function genOther(config) { switch(config.type){ case "1x1x1": return scramble(["x","y","z"],["","2","'"],20,{}); break; case "1x1x1optrs": return state111(); break; case "cs-1x-1x-1": return [genneg1(), rndEl(["Error: subscript out of range","Error: superscript out of range"])]; break; case "1x1x2R": return scrambleDumb(["R","R2","R'"],10); break; case "1x1x2U": return scrambleDumb(["U","U2","U'"],10); break; case "1x2x2rs": return state122(); break; case "1x2x3rsru": return state123RU(); break; case "1x2x3": case "1x2x3rs": return r123(); break; case "megaLSLL": return megaLSLL(); break; case "csLOL": return [rndEl(["LOLOLOLOLOLOLOLOLOLOLOLOL","OLOLOLOLOLOLOLOLOLOLOLOLO"])]; break; case "2RU": return scramble(["R","U"],["","2","'"],15,{}); break; case "3RU": return scramble(["R","U"],["","2","'"],25,{}); break; case "3RUF": return scramble(["R","U","F"],["","2","'"],25,{}); break; case "3RUL": return scramble(["R","U","L"],["","2","'"],25,{"R":"L","L":"R"}); break; case "3UL": return scramble(["U","L"],["","2","'"],25,{}); break; case "3MU": return scramble(["M","U"],["","2","'"],25,{}); break; case "3RUFL": return scramble(["R","U","F","L"],["","2","'"],25,{"R":"L","L":"R"}); break; case "3URr": return scramble(["R","U","r"],["","2","'"],30,{"R":"r","r":"R"}); break; case "4URr": return scramble(["R","U","r"],["","2","'"],40,{"R":"r","r":"R"}); break; case "2half": return scramble(halfmoves(2),[""],12,{}); break; case "3half": return scramble(halfmoves(3),[""],22,{}); break; case "4half": return scramble(halfmoves(4),[""],38,{}); break; case "5half": return scramble(halfmoves(5),[""],50,{}); break; case "pyr4tips": return [...puzzles["pyram"].generateScramble().split(" ").filter(function(a){return a.toUpperCase() == a}),rndEl(["r","r'"]),rndEl(["l","l'"]),rndEl(["u","u'"]),rndEl(["b","b'"])]; break; case "pyr0tips": return puzzles["pyram"].generateScramble().split(" ").filter(function(a){return a.toUpperCase() == a}); break; case "MegaRU": return scramble(["R","U"],["","2","2'","'"],35,{}); break; case "Heli": return scramble(["UL","UR","UF","UB","DL","DR","DF","DB","FR","FL","BR","BL"],[""],30,{}); break; case "sq2": return square2(30); break; case "rainbow": return scramble(["R","U","F","D","B","L","P","Q"],["","'"],30,{}); break; //The scramble function currently does not work with so many independent faces, so this is just for testing default: return ["unknown code"]; } } function halfmoves(n){ if(n==2) return ["R2","F2","U2"]; var m = ["R2","F2","U2","D2","L2","B2"]; for(var i=2;i<Math.ceil(n/2);++i){ m.push(i+"R2"); m.push(i+"U2"); m.push(i+"F2"); m.push(i+"D2"); m.push(i+"B2"); m.push(i+"L2"); } if(n%2==0){ i=n/2; m.push(i+"R2"); m.push(i+"U2"); m.push(i+"F2"); } return m; } function genOtherImage(imoves, img_gen, config){ var n = 3; switch(config.type){ case "2RU": case "2half": n=2; break; case "3RU": case "3RUF": case "3RUL": case "3MU": case "3RUFL": case "3URr": case "3half": n=3; break; case "4URr": case "4half": n=4; break; case "5half": n=5; break; case "pyr0tips": case "pyr4tips": return drawWCA("test", "pyram", imoves, config); case "1x1x2R": case "1x1x2U": case "1x2x2rs": case "1x2x3rs": case "1x1x1": case "-cs-1x-1x-1": case "1x1x1optrs": case "sq2": case "rainbow": case "Heli": case "MegaRU": case "megaLSLL": //Rainbow and MegaRU will get images later return; } return nnn_representation.draw("test",nnn_representation.moves(nnn_representation.init_cube(n),nnn_representation.apply_alg(imoves),n),n,config); }function changeNNNImageColors(scrambleSvgCode, config) { var colorScheme = ["#ff0000", "#ffffff", "#00ff00", "#ffff00", "#ff8000", "#0000ff"], colorScheme2 = ["#R", "#U", "#F", "#D", "#B", "#L"], cubicColorScheme = config.colorScheme, i; for (i = 0; i < colorScheme.length; ++i) { scrambleSvgCode = scrambleSvgCode.replace(new RegExp(colorScheme[i], "g"), colorScheme2[i]); } for (i = 0; i < colorScheme.length; ++i) { scrambleSvgCode = scrambleSvgCode.replace(new RegExp(colorScheme2[i], "g"), cubicColorScheme[i]); } return scrambleSvgCode; } function changeClockImageColors(scrambleSvgCode, config) { var colorScheme = ["#000000", "#55ccff", "#3375b2", "#ffff00", "#ff0000"], colorScheme2 = ["#Border", "#Background", "#Foreground", "#Pins", "#Arrows"], cubicColorScheme = config.clockColorScheme, i; for (i = 0; i < colorScheme.length; ++i) { scrambleSvgCode = scrambleSvgCode.replace(new RegExp(colorScheme[i], "g"), colorScheme2[i]); } for (i = 0; i < colorScheme.length; ++i) { scrambleSvgCode = scrambleSvgCode.replace(new RegExp(colorScheme2[i], "g"), cubicColorScheme[i]); } return scrambleSvgCode; }function genColorHTML(color, move){ return "<span style='color:"+color+"'>" + move + "</span>"; } function addColor_(moves, outmoves, config){ var nmoves = []; var colorScheme = config.colorScheme; for(var i=0;i<moves.length;++i){ var index = 0; if(moves[i][0]=="2" || moves[i][0] == "3") index = 1; //unfuck bigger NxNxN switch(moves[i][index]){ case "R": nmoves[i] = genColorHTML(colorScheme[0], outmoves[i]); break; case "U": nmoves[i] = genColorHTML(colorScheme[1]=="#ffffff"?"#dddddd":colorScheme[1], outmoves[i]); break; case "F": nmoves[i] = genColorHTML(colorScheme[2], outmoves[i]); break; case "D": nmoves[i] = genColorHTML(colorScheme[3], outmoves[i]); break; case "B": nmoves[i] = genColorHTML(colorScheme[4], outmoves[i]); break; case "L": nmoves[i] = genColorHTML(colorScheme[5], outmoves[i]); break; default: nmoves[i] = outmoves[i]; } } return nmoves; } function addMegaminxColor_(moves, outmoves, config){ var nmoves = []; var colorScheme = config.colorScheme; for(var i=0;i<moves.length;++i){ var index = 0; switch(moves[i][index]){ case "R": nmoves[i] = genColorHTML(colorScheme[0], outmoves[i]); break; case "D": nmoves[i] = genColorHTML(colorScheme[3], outmoves[i]); break; case "U": nmoves[i] = genColorHTML(colorScheme[1]=="#ffffff"?"#dddddd":colorScheme[1], outmoves[i]); break; default: nmoves[i] = outmoves[i]; } } return nmoves; } function addClockColor_(moves, outmoves, type, config){ var nmoves = []; var colorScheme = config.colorScheme; for(var i=0;i<moves.length;++i){ if(type == 0){ switch(moves[i][moves[i].length-2]){ case "1": nmoves[i] = genColorHTML(colorScheme[0], outmoves[i]); break; case "2": nmoves[i] = genColorHTML(colorScheme[1]=="#ffffff"?"#dddddd":colorScheme[1], outmoves[i]); break; case "3": nmoves[i] = genColorHTML(colorScheme[2], outmoves[i]); break; case "4": nmoves[i] = genColorHTML(colorScheme[3], outmoves[i]); break; case "5": nmoves[i] = genColorHTML(colorScheme[4], outmoves[i]); break; case "6": nmoves[i] = genColorHTML(colorScheme[5], outmoves[i]); break; default: nmoves[i] = outmoves[i]; } } else if(type == 1){ switch(moves[i][moves[i].length-2]){ case "1": nmoves[i] = genColorHTML("#222222", outmoves[i]); break; case "2": nmoves[i] = genColorHTML("#444444", outmoves[i]); break; case "3": nmoves[i] = genColorHTML("#666666", outmoves[i]); break; case "4": nmoves[i] = genColorHTML("#888888", outmoves[i]); break; case "5": nmoves[i] = genColorHTML("#aaaaaa", outmoves[i]); break; case "6": nmoves[i] = genColorHTML("#cccccc", outmoves[i]); break; default: nmoves[i] = outmoves[i]; } } else { switch(moves[i][moves[i].length-2]){ case "y": nmoves[i] = genColorHTML("#777777", outmoves[i]); break; default: nmoves[i] = outmoves[i]; } } } return nmoves; }var pyr_rep = (function(){ var solved = [ [0,0,0,0], //URLB tips [0,0,0,0], //URLB centers [1,1,1],[2,2,2],[3,3,3],[4,4,4] //FLRD Edges ]; function U(state){ return [ [(state[0][0]+1)%3, state[0][1], state[0][2], state[0][3]], [(state[1][0]+1)%3, state[1][1], state[1][2], state[1][3]], [state[4][0], state[2][1], state[2][2]], [state[2][0], state[3][1], state[3][2]], [state[3][0], state[4][1], state[4][2]], state[5] ]; } function move_tip(state, index, amount){ state[0][index] = (state[0][index] + amount)%3; return state; } function move_center(state, index, amount){ state[1][index] = (state[0][index] + amount)%3; return state; } function y(state){ return [ [(state[0][0]+1)%3, state[0][3], state[0][1], state[0][2]], [(state[1][0]+1)%3, state[1][3], state[1][1], state[1][2]], state[4], state[2], state[3], [state[5][2], state[5][0], state[5][1]] ]; } function R(state){ return [ [state[0][0], (state[0][1]+1)%3, state[0][2], state[0][3]], [state[1][0], (state[1][1]+1)%3, state[1][2], state[1][3]], [state[5][0], state[5][1], state[2][2]], state[3], [state[4][0], state[0][0], state[0][1]], [state[3][1], state[3][0], state[5][2]], ]; } })();var nnn_representation = (function() { function rotateA(a) { var tmp; var n = a.length; for (var i = 0; i < n / 2; i++){ for (var j = i; j < n - i - 1; j++){ tmp = a[i][j]; a[i][j] = a[j][n-i-1]; a[j][n-i-1] = a[n-i-1][n-j-1]; a[n-i-1][n-j-1] = a[n-j-1][i]; a[n-j-1][i] = tmp; } } return a; } function tcenter_slice_move(state, face, n, depth, offset=0) { var middle = Math.floor(n/2)-offset; var smiddle = middle+offset+offset; var last = n-1-depth; var first = depth; if(n%2 == 0){ --smiddle; } var moved_faces = [ [1, 2, 3, 4], [0, 4, 5, 2], [1, 5, 3, 0], [0, 2, 5, 4], [1, 0, 3, 5], [1, 4, 3, 2], ][face]; var a = [ [middle, middle, middle, smiddle], [first, first, first, first], [last, middle, first, smiddle], [last, last, last, last], [first, middle, last, smiddle], [smiddle, middle, smiddle, smiddle] ][face]; var b = [ [last, last, last, first], [middle, middle, middle, middle], [smiddle, last, middle, first], [smiddle, smiddle, smiddle, smiddle], [middle, last, smiddle, first], [first, last, first, first] ][face]; var z = state[moved_faces[0]][a[0]][b[0]]; state[moved_faces[0]][a[0]][b[0]] = state[moved_faces[1]][a[1]][b[1]]; state[moved_faces[1]][a[1]][b[1]] = state[moved_faces[2]][a[2]][b[2]]; state[moved_faces[2]][a[2]][b[2]] = state[moved_faces[3]][a[3]][b[3]]; state[moved_faces[3]][a[3]][b[3]] = z; return state; } function init_cube(n) { var pieces = [ [], [], [], [], [], [] ]; for (var i = 0; i < 6; ++i) for (var j = 0; j < n; ++j) { pieces[i][j] = []; for (var k = 0; k < n; ++k) pieces[i][j][k] = i * n * n + j * n + k; } return pieces; } function draw(cid, grstate, n, config) { var c = document.getElementById(cid); var ctx = c.getContext("2d"); var width = c.width; var height = c.height; ctx.clearRect(0, 0, width, height); ctx.font = "12px Arial"; ctx.strokeStyle = config.baseColor; ctx.lineWidth=2; for (var i = 0; i < 6; ++i) for (var j = 0; j < n; ++j) { for (var k = 0; k < n; ++k) draw_cubie(grstate, n, ctx, i, j, k, width, height, config); } } function draw_cubie(grstate, n, ctx, side, x, y, width, height, config) { var unit_size = Math.min(width / 4, height / 3) - 5; var cubie_size = Math.round(unit_size / n); unit_size += 5; var heightoffset = [1, 0, 1, 2, 1, 1][side] * unit_size + 1; var widthoffset = [2, 1, 1, 1, 3, 0][side] * unit_size + 1; var sidecolors = config.colorScheme; ctx.fillStyle = sidecolors[Math.floor(grstate[side][x][y] / n / n)]; ctx.fillRect(widthoffset + y * cubie_size, heightoffset + x * cubie_size, cubie_size, cubie_size); if(config.baseColor != "stickerless"){ ctx.strokeRect(widthoffset + y * cubie_size, heightoffset + x * cubie_size, cubie_size, cubie_size); } //ctx.fillStyle = "#000000"; //ctx.fillText(grstate[side][x][y], widthoffset + y * cubie_size, heightoffset + x * cubie_size + 12); } function draw_mir(cid, grstate, n, config) { var l = n-1; function gssx(s,i,x,y){ if(i==0&&x==0) return s[1][l-y][l]; if(i==0&&x==l) return s[3][y][l]; if(i==1&&x==0) return s[4][0][l-y]; if(i==1&&x==l) return s[2][0][y]; if(i==2&&x==0) return s[1][l][y]; if(i==2&&x==l) return s[3][0][y]; if(i==3&&x==0) return s[2][l][y]; if(i==3&&x==l) return s[4][l][l-y]; if(i==4&&x==0) return s[1][0][l-y]; if(i==4&&x==l) return s[3][0][l-y]; if(i==5&&x==0) return s[1][y][0]; if(i==5&&x==l) return s[3][l-y][0]; return s[i][x][y]; } function gssy(s,i,x,y){ if(i==0&&y==0) return s[2][x][l]; if(i==0&&y==l) return s[4][x][0]; if(i==1&&y==0) return s[5][0][x]; if(i==1&&y==l) return s[0][0][l-x]; if(i==2&&y==0) return s[5][x][l]; if(i==2&&y==l) return s[0][x][0]; if(i==3&&y==0) return s[5][l][l-x]; if(i==3&&y==l) return s[0][l][x]; if(i==4&&y==0) return s[0][x][l]; if(i==4&&y==l) return s[5][x][0]; if(i==5&&y==0) return s[4][x][l]; if(i==5&&y==l) return s[2][x][0]; return s[i][x][y]; } var c = document.getElementById(cid); var ctx = c.getContext("2d"); var width = c.width; var height = c.height; ctx.clearRect(0, 0, width, height); ctx.font = "12px Arial"; ctx.strokeStyle = config.baseColor; ctx.lineWidth=1; var unit_size = Math.min(width / 4, height / 3) - 5; var cubie_size = Math.floor(unit_size / n); var piece_size_x, piece_size_y; var orstate = JSON.parse(JSON.stringify(grstate)); grstate = moves(grstate, apply_alg("U R2 F B R B2 R U2 L B2 R U' D' R2 F R' L B2 U2 F2".split(" ")), 3); for (var i = 0; i < 6; ++i){ var heightoffset = [1, 0, 1, 2, 1, 1][i] * (cubie_size * n + 5) + 1; var widthoffset = [2, 1, 1, 1, 3, 0][i] * (cubie_size * n + 5) + 1; for (var x = 0; x < n; ++x) { for (var y = 0; y < n; ++y){ ctx.fillStyle = config.colorScheme[Math.floor(orstate[i][x][y] / n / n)]; if(y != 1 && x != 1){ piece_size_x = [6,2,4,7,5,3][Math.floor(gssx(grstate,i,x,y) / n / n)]/7*cubie_size; piece_size_y = [6,2,4,7,5,3][Math.floor(gssy(grstate,i,x,y) / n / n)]/7*cubie_size; } else piece_size_x = piece_size_y = [6,2,4,7,5,3][Math.floor(grstate[i][x][y] / n / n)]/7*cubie_size; piece_size_x = Math.round(piece_size_x); piece_size_y = Math.round(piece_size_y); if(x==0) var xoffset = cubie_size - piece_size_x; else xoffset = 0; if(y==0) var yoffset = cubie_size - piece_size_y; else yoffset = 0; if(x==n-1) var x2offset = cubie_size - piece_size_x; else x2offset = 0; if(y==n-1) var y2offset = cubie_size - piece_size_y; else y2offset = 0; ctx.fillRect(widthoffset + yoffset + y * cubie_size, heightoffset + xoffset + x * cubie_size, cubie_size-yoffset-y2offset, cubie_size-xoffset-x2offset); if(config.baseColor != "stickerless") ctx.strokeRect(widthoffset + y * cubie_size, heightoffset + x * cubie_size, cubie_size, cubie_size); } } } } function move(state, side, depth, n) { for (var i = 0; i < depth; ++i) { state = tcenter_slice_move(state, side, n, i); for (var j = 1; j < Math.floor(n / 2)+1; ++j) { state = tcenter_slice_move(state, side, n, i, j); if(n%2!=0 || j<n/2)state = tcenter_slice_move(state, side, n, i, -j); } } state[side] = rotateA(rotateA(rotateA(state[side]))); return state; } function moves(grstate, mvs, n) { for (var i = 0; i < mvs.length; ++i) grstate = move(grstate, mvs[i][0], mvs[i][1], n); return grstate; } function apply_alg(moves){ var mvs = []; for(var i=0;i<moves.length;++i){ var isW = moves[i].indexOf("w")>-1; var face = moves[i].replace(/[0-9w]/g, ""); moves[i] = moves[i].toUpperCase(); moves[i] = moves[i].split("W").join(""); moves[i] = moves[i].replace(/[RUFDBL]/i,"#").split("#"); if(moves[i][0]=="") moves[i][0]=isW?2:1; var mgn = moves[i][1]==""?1:(moves[i][1]=="'"?3:(moves[i][1]=="2"?2:0)); face = face.split("'").join(""); face = {"R":0,"U":1,"F":2,"D":3,"B":4,"L":5}[face]; for(var j=0;j<mgn;++j) mvs.push([face,+moves[i][0]]); } return mvs; } return { draw, draw_mir, move, moves, init_cube, apply_alg } })();var scramble_special_222 = (function() { //Using https://github.com/FrederikHutfless/FastVirtual2x2 const UBL = 0; const UBR = 1; const UFR = 2; const UFL = 3; const DBL = 4; const DBR = 5; const DFR = 6; const DFL = 7; //Solved Cube var cp = [UBL, UBR, UFR, UFL, DBL, DBR, DFR, DFL]; var co = [0, 0, 0, 0, 0, 0, 0, 0]; const moveU = 0; const moveUP = 1; const moveU2 = 2; const moveR = 3; const moveRP = 4; const moveR2 = 5; const moveF = 6; const moveFP = 7; const moveF2 = 8;const movey = 9; const moveyP = 10; const movey2 = 11; const cpMaps = [ [3, 0, 1, 2, 4, 5, 6, 7], [1, 2, 3, 0, 4, 5, 6, 7], [2, 3, 0, 1, 4, 5, 6, 7], [0, UFR, DFR, 3, 4, UBR, DBR, 7], [0, DBR, UBR, 3, 4, DFR, UFR, 7], [0, DFR, DBR, 3, 4, 2, 1, 7], [0, 1, UFL, DFL, 4, 5, UFR, DFR], [0, 1, DFR, UFR, 4, 5, DFL, UFL], [0, 1, DFL, DFR, 4, 5, UFL, UFR], [3,0,1,2,7,4,5,6], [1,2,3,0,5,6,7,4], [2,3,0,1,6,7,4,5] ]; const coMaps = [ [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 2, 1, 0, 0, 1, 2, 0], [0, 2, 1, 0, 0, 1, 2, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 2, 1, 0, 0, 1, 2], [0, 0, 2, 1, 0, 0, 1, 2], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0] ]; const inverseMoves = [1, 0, 2, 4, 3, 5, 7, 6, 8]; function applyCpMove(cp, map) { return [cp[map[0]], cp[map[1]], cp[map[2]], cp[map[3]], cp[map[4]], cp[map[5]], cp[map[6]], cp[map[7]]]; } function applyCoMove(co, map) { return [(co[0] + map[0]) % 3, (co[1] + map[1]) % 3, (co[2] + map[2]) % 3, (co[3] + map[3]) % 3, (co[4] + map[4]) % (2+1), (co[5] + map[5]) % 3, (co[6] + map[6]) % 3, (co[7] + map[7]) % 3]; } function applyMove(co, cp, move) { return [applyCoMove(applyCpMove(co, cpMaps[move]), coMaps[move]), applyCpMove(cp, cpMaps[move])]; } function applyMoves(moves, co, cp) { var i, s; for (i = 0; i < moves.length; ++i) { s = applyMove(co, cp, moves[i]); cp = s[1]; co = s[0]; } return [co, cp]; } function generateOrientations(cube) { return [ cube, applyMoves([moveR, movey2, moveRP, movey2], ...cube), //x applyMoves([moveRP, movey2, moveR, movey2], ...cube), //x' applyMoves([movey], ...cube), //y applyMoves([moveyP], ...cube), //y' applyMoves([movey2], ...cube), //y2 applyMoves([moveF, movey2, moveFP, movey2], ...cube), //z applyMoves([moveFP, movey2, moveF, movey2], ...cube), //z' applyMoves([moveR2, movey2, moveR2], ...cube), //z2 applyMoves([moveR2, movey2, moveR2, movey], ...cube), //z2 y applyMoves([moveR2, movey2, moveR2, movey2], ...cube), //z2 y2 applyMoves([moveR2, movey2, moveR2, moveyP], ...cube), //z2 y' applyMoves([moveF, movey2, moveFP], ...cube), //z y2 applyMoves([moveF, movey2, moveFP, moveyP], ...cube), //z y applyMoves([moveF, movey2, moveFP, movey], ...cube), //z y' applyMoves([moveFP, movey2, moveF, moveyP], ...cube), //z' y applyMoves([moveFP, movey2, moveF, movey], ...cube), //z' y' applyMoves([moveFP, movey2, moveF], ...cube), //z' y2 applyMoves([moveR, movey2, moveRP, movey], ...cube), //x y' applyMoves([moveRP, movey2, moveR, movey], ...cube), //x' y' applyMoves([moveR, movey2, moveRP], ...cube), //x y2 applyMoves([moveRP, movey2, moveR], ...cube), //x' y2 applyMoves([moveR, movey2, moveRP, moveyP], ...cube), //x y applyMoves([moveRP, movey2, moveR, moveyP], ...cube) //x' y ]; } function checkScrambleCharacteristic(cube, fn) { var orientations = generateOrientations(cube); for (var i = 0; i < orientations.length; ++i) { var orientedCube = orientations[i]; if (fn(...orientedCube)) return true; } return false; } function isSideBlock(co, cp) { return pieceToStickers(cp[DFL])[(co[DFL] + 0) % 3] == pieceToStickers(cp[DBL])[(co[DBL] + 0) % 3]; } function is112Block(co, cp) { return isSideBlock(co, cp) && pieceToStickers(cp[DBL])[(co[DBL] + 2) % 3] == pieceToStickers(cp[DFL])[(co[DFL] + 1) % 3]; } function convertMoves(moves) { return moves.split(" ").map(function(a) { return { "U": 0, "U'": 1, "U2": 2, "R": 3, "R'": 4, "R2": 5, "F": 6, "F'": 7, "F2": 8} [a] }); } function movesReadable(moves) { return moves.map(function(a) { return ["U", "U'", "U2", "R", "R'", "R2", "F", "F'", "F2"][a] }).join(" "); } function pieceToStickers(piece) { return ["WOB", "WBR", "WRG", "WGO", "YBO", "YRB", "YGR", "YOG"][piece]; } function cancel(alg) { return alg.split("R R'").join("").split("F F'").join("").split("U U'").join("") .split("R2 R2").join("").split("F2 F2").join("").split("U2 U2").join("") .split("R' R").join("").split("F' F").join("").split("U' U").join(""); } function get112BlockScramble() { var s = puzzles["222"].generateScramble(); s = convertMoves(s); var c = applyMoves(s, co, cp); if (checkScrambleCharacteristic(c, is112Block)) return movesReadable(s).split(" "); for (var i = 0; i < 9; ++i) { if (Math.floor(s[s.length - 1] / 3) != Math.floor(i / 3) || s[s.length - 1] == i) { c = applyMove(c[0], c[1], i); if (checkScrambleCharacteristic(c, is112Block)) return cancel(movesReadable([...s, i])).split(" "); c = applyMove(c[0], c[1], inverseMoves[i]); } } return get112BlockScramble(); } function getNoBarScramble() { var s = puzzles["222"].generateScramble(); s = convertMoves(s); var c = applyMoves(s, co, cp); if (!checkScrambleCharacteristic(c, is112Block)) return movesReadable(s).split(" "); for (var i = 0; i < 9; ++i) { if (Math.floor(s[s.length - 1] / 3) != Math.floor(i / 3) || s[s.length - 1] == i) { c = applyMove(c[0], c[1], i); if (!checkScrambleCharacteristic(c, is112Block)) return cancel(movesReadable([...s, i])).split(" "); c = applyMove(c[0], c[1], inverseMoves[i]); } } return get112BlockScramble(); } function getSideBlockScramble() { var s = puzzles["222"].generateScramble(); s = convertMoves(s); var c = applyMoves(s, co, cp); if (checkScrambleCharacteristic(c, isSideBlock)) return movesReadable(s).split(" "); for (var i = 0; i < 9; ++i) { if (Math.floor(s[s.length - 1] / 3) != Math.floor(i / 3) || s[s.length - 1] == i) { c = applyMove(c[0], c[1], i); if (checkScrambleCharacteristic(c, isSideBlock)) return cancel(movesReadable([...s, i])).split(" "); c = applyMove(c[0], c[1], inverseMoves[i]); } } return getSideBlockScramble(); } function genMoves(config) { if (config.type == "112Block") return get112BlockScramble(); if (config.type == "SideBlock") return getSideBlockScramble(); if (config.type == "NoBar") return getNoBarScramble(); if (config.type == "Any") return randomScramble(); return getSideBlockScramble(); } function genImage(moves, config) { if (moves.join) moves = moves.join(" "); var c = tnoodlejs.scrambleToSvg(moves, puzzles["222"], 0, 0); return scramble_colors.changeImageColors(c); } //Solver attempt var statesfound = {}; function recurse1(c, isdepth, shoulddepth, movesdone) { var lm = movesdone[movesdone.length - 1]; for (var i = 0; i < 9; ++i) { if (movesdone.length == 0 || Math.floor(lm / 3) != Math.floor(i / 3)) { c = applyMove(c[0], c[1], i); statesfound[c[0].join("") + c[1].join("")] = [...movesdone,i].join(""); if (isdepth < shoulddepth) recurse1(c, isdepth + 1, shoulddepth, [...movesdone, i]); c = applyMove(c[0], c[1], inverseMoves[i]); } } } function phase1() { recurse1([co, cp], 1 - 1, 6 - 1, []); } function recurse2(c, isdepth, shoulddepth, movesdone) { var lm = movesdone[movesdone.length - 1], z, i; for (i = 0; i < 9; ++i) { if (movesdone.length == 0 || Math.floor(lm / 3) != Math.floor(i / 3)) { c = applyMove(c[0], c[1], i); if (statesfound[c[0].join("") + c[1].join("")]) { return [statesfound[c[0].join("") + c[1].join("")].split(""), [...movesdone,i]]; } if (isdepth < shoulddepth) z = recurse2(c, isdepth + 1, shoulddepth, [...movesdone, i]); if (z != "no" && z !== undefined) return z; c = applyMove(c[0], c[1], inverseMoves[i]); } } return "no"; } function phase2(s) { if (Object.keys(statesfound).length == 0) phase1(); s = convertMoves(s); var c = applyMoves(s, co, cp); var zz = recurse2([co,cp], 1 - 1, 5 - 1, []); return m2sol(zz[0], zz[1]); } function randomScramble() { if (Object.keys(statesfound).length == 0) phase1(); function shuffleArray(arr) { var i,j; for (i = arr.length - 1; i > 0; --i) { j = Math.floor(Math.random() * (i + 1)); [arr[i], arr[j]] = [arr[j], arr[i]]; } return arr; } var cp = shuffleArray([UBL, UBR, UFR, UFL, DBR, DFR, DFL]); cp = [cp[0], cp[1], cp[2], cp[3], DBL, cp[4], cp[5], cp[6]]; var co = [0, 0, 0, 0, 0, 0, 0, 0]; var parity = 0; for(var i=0;i<7;++i){ var x = Math.floor(Math.random()*3); if(i==4) x=0; co[i]=x; parity += x; } co[7] = [0,2,1][parity%3]; var zz = recurse2([co,cp], 1 - 1, 5 - 1, []); return m2sol(zz[0], zz[1]); } function cancel2(p){ var h = []; for(var i=0;i<p.length;++i){ if((i < p.length && p[i+1] === undefined) || Math.floor(p[i]/3) != Math.floor(p[i+1]/3)){ h.push(p[i]); }else{ var tg = [1,-1,2][p[i]%3]+[1,-1,2][p[i+1]%3]; ++i; if(tg == 1) h.push(Math.floor(p[i]/3)*3); else if(tg == 2) h.push(Math.floor(p[i]/3)*3+2); else if(tg == 3) h.push(Math.floor(p[i]/3)*3+1); } } return h; } function m2sol(m,p){ p = p.reverse(); p = p.map(function(a){return inverseMoves[a]}); p = [...m, ...p]; p=cancel2(p); return movesReadable(p).split(" "); } return { genMoves: genMoves, genImage: genImage, solve: phase2, statesfound: statesfound, randomScramble: randomScramble }; })();var c123 = (function() { function init_cube(n) { return [false, false, 0,1,2,3]; //LFlip, RFlip, UL UR DR DL } function draw(cid, grstate, n, config) { var c = document.getElementById(cid); var ctx = c.getContext("2d"); var width = c.width; var height = c.height; ctx.clearRect(0, 0, width, height); ctx.font = "12px Arial"; ctx.strokeStyle = config.baseColor; ctx.lineWidth=2; draw_cubie(ctx, 0, 1, (grstate[2]<2)?"blue":"green", width, height, config); draw_cubie(ctx, 0, 2, (grstate[3]<2)?"blue":"green", width, height, config); draw_cubie(ctx, 1, 0, (grstate[2]==0||grstate[2]==3)?"orange":"red", width, height, config); draw_cubie(ctx, 1, 1, (grstate[2]==0||grstate[2]==2)?"white":"yellow", width, height, config); draw_cubie(ctx, 1, 2, (grstate[3]==1||grstate[3]==3)?"white":"yellow", width, height, config); draw_cubie(ctx, 1, 3, (grstate[3]==0||grstate[3]==3)?"orange":"red", width, height, config); draw_cubie(ctx, 2, 0, "orange", width, height, config); draw_cubie(ctx, 2, 1, !grstate[0]?"white":"yellow", width, height, config); draw_cubie(ctx, 2, 2, !grstate[1]?"white":"yellow", width, height, config); draw_cubie(ctx, 2, 3, "red", width, height, config); draw_cubie(ctx, 3, 0, (grstate[5]==0||grstate[5]==3)?"orange":"red", width, height, config); draw_cubie(ctx, 3, 1, (grstate[5]==1||grstate[5]==3)?"white":"yellow", width, height, config); draw_cubie(ctx, 3, 2, (grstate[4]==0||grstate[4]==2)?"white":"yellow", width, height, config); draw_cubie(ctx, 3, 3, (grstate[4]==0||grstate[4]==3)?"orange":"red", width, height, config); draw_cubie(ctx, 4, 1, (grstate[2]>1)?"blue":"green", width, height, config); draw_cubie(ctx, 4, 2, (grstate[3]>1)?"blue":"green", width, height, config); } function draw_cubie(ctx, x, y, color, width, height, config) { var unit_size = Math.min(width / 3, height / 5) - 5; var cubie_size = unit_size; var offset = 5; ctx.fillStyle = color; ctx.fillRect(offset + y * cubie_size, offset + x * cubie_size, cubie_size, cubie_size); if(config.baseColor != "stickerless"){ ctx.strokeRect(offset + y * cubie_size, offset + x * cubie_size, cubie_size, cubie_size); } } function move(state, side, depth) { if(side == 0){ state[1] = !state[1]; var x = state[4]; state[4] = state[3]; state[3] = x; } else if(side == 1){ var x = state[2]; state[2] = state[3]; state[3] = x; } else if(side == 2){ var x = state[4]; state[4] = state[5]; state[5] = x; } return state; } function moves(grstate, mvs) { for (var i = 0; i < mvs.length; ++i) grstate = move(grstate, mvs[i][0], mvs[i][1]); return grstate; } function apply_alg(moves){ var mvs = []; for(var i=0;i<moves.length;++i){ face = {"R":0,"U":1,"D":2}[moves[i][0]]; mvs.push([face,2]); } return mvs; } return { draw, move, moves, init_cube, apply_alg } })();function drawWCA(cid, puzzle, moves, config){ var c = document.getElementById(cid); var ctx = c.getContext("2d"); var width = c.width; var height = c.height; var img = /*changeNNNImageColors(*/tnoodlejs.scrambleToSvg(moves.join(" "), puzzles[puzzle], 0, 0)/*, config);*/ if(puzzle == "clock") img = changeClockImageColors(img, config); var imgwidth = +img.substr(12,3); var imgheight = +img.substr(27,3); img = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(img); var img1 = new Image(); img1.src = img; if(width/imgwidth >= height/imgheight){ img1.onload = function() { ctx.clearRect(0, 0, width, height); //if(puzzle == "sq1fast") // ctx.drawImage(img1,0,0,imgwidth*height/imgheight + (width - imgwidth*height/imgheight)/2 + imgwidth*height/imgheight/2,height); ctx.drawImage(img1,0,0,imgwidth*height/imgheight,height); } } else { img1.onload = function() { ctx.clearRect(0, 0, width, height); ctx.drawImage(img1,0,0,width,imgheight*width/imgwidth); } } }var random_move_nnn = (function() { function rndEl(x) { return x[~~(Math.random() * x.length)]; } function rn(n) { return ~~(Math.random() * n); } // If lgth = -1, calculate a good value function genMoves(config) { if(!config.lgth) config.lgth = -1; var l = config.lgth == -1 ? Math.ceil(2*config.n*config.n - 5*config.n + 13) : config.lgth; return scrambleNNN(config.n, l); } function scrambleNNN(n, length){ var side, fn, magnitude, suffix, moves=[], prevside = "", prevused = [], doubleprevside = "_"; while(moves.length < length){ side = rndEl(["R","U","F","D","B","L"]); if(n%2==1) magnitude=rn(n/2-0.5)+1; else if(side =="R" || side == "F" || side == "U") magnitude = rn(n/2)+1; else magnitude = rn(n/2-1)+1; suffix = rndEl(["","2","'"]); if(prevside != side){ if(!(prevside == {"R":"L","L":"R","U":"D","D":"U","F":"B","B":"F"}[side] && doubleprevside == side)){ doubleprevside = prevside; prevside = side; prevused = [magnitude]; moves.push((magnitude<3?"":magnitude) + side + (magnitude==1?"":"w") + suffix); } } else if(prevused.indexOf(magnitude) == -1){ prevused.push(magnitude); moves.push((magnitude<3?"":magnitude) + side + (magnitude==1?"":"w") + suffix); } } return moves; } function genImage(moves, config) { if (config.n >= 2 && config.n <= 5) return scramble_colors.changeImageColors(scrambler_wca.genImage(moves.join(" "), 111 * config.n)); return ""; } return { genMoves: genMoves, genImage: genImage } })(); function getMoves(move_gen, img_gen, notation_equiv_class, config) { switch (move_gen) { case "wca": return puzzles[config.type].generateScramble().split(" "); case "special_222": return scramble_special_222.genMoves(config); case "NNN_moves": return random_move_nnn.genMoves(config); case "subset": scramble_subset.setRandomSource(Math); scramble_subset.initialize(); scramble_subset.setRandomSource(Math); var s = scramble_subset["get" + config.type + "Scramble"]().split(" ").join(" ").split(" "); if (s[s.length - 1] == "") s.pop(); return s; case "minx": return scrambleMega(megaMoves(config.n), ["U", "U'"], config.movesPerRow, config.moves); case "cuboid": return genCuboid(config); case "other": return genOther(config); } } function getImage(imoves, move_gen, img_gen, notation_equiv_class, config) { switch (move_gen) { case "wca": if ([222, 333, 444, "444fast", 555, 666, 777].indexOf(config.type) > -1) { if (img_gen == "mirror") { return nnn_representation.draw_mir("test", nnn_representation.moves(nnn_representation.init_cube(([] + config.type)[0]), nnn_representation.apply_alg(imoves), ([] + config.type)[0]), ([] + config.type)[0], config); } else { return nnn_representation.draw("test", nnn_representation.moves(nnn_representation.init_cube(([] + config.type)[0]), nnn_representation.apply_alg(imoves), ([] + config.type)[0]), ([] + config.type)[0], config); } } return drawWCA("test", config.type, imoves, config); case "special_222": return nnn_representation.draw("test", nnn_representation.moves(nnn_representation.init_cube(2), nnn_representation.apply_alg(imoves), 2), 2, config); case "subset": return nnn_representation.draw("test", nnn_representation.moves(nnn_representation.init_cube(3), nnn_representation.apply_alg(imoves), 3), 3, config); case "NNN_moves": case "cubicWCA": if (img_gen == "normal") return nnn_representation.draw("test", nnn_representation.moves(nnn_representation.init_cube(config.n), nnn_representation.apply_alg(imoves), config.n), config.n, config); else if (img_gen == "mirror") return nnn_representation.draw_mir("test", nnn_representation.moves(nnn_representation.init_cube(config.n), nnn_representation.apply_alg(imoves), config.n), config.n, config); case "minx": return; case "cuboid": return; case "other": if(config.type == "1x2x3" || config.type == "1x2x3rsru" || config.type == "1x2x3rs") return c123.draw("test", c123.moves(c123.init_cube(config.n), c123.apply_alg(imoves), config.n), config.n, config); return genOtherImage(imoves, img_gen, config); } } function joinMoves(moves, move_gen, img_gen, notation_equiv_class, config) { return moves.join(" "); } function changeColor(orig_moves, mod_moves, move_gen, img_gen, notation_equiv_class, config) { if (move_gen == "NNN_moves") return addColor_(orig_moves, mod_moves, config); if (move_gen == "wca" && [222, 333, 444, "444fast", 555, 666, 777, "333ni", "444ni", "555ni", "333fm"].indexOf(config.type) > -1) return addColor_(orig_moves, mod_moves, config); if (move_gen == "wca" && config.type == "clock") return addClockColor_(orig_moves, mod_moves, 1, config); if (move_gen == "wca" && config.type == "minx" && (config.notationStyle == 0 || config.notationStyle == 1)) return addMegaminxColor_(orig_moves, mod_moves, config); return JSON.parse(JSON.stringify(mod_moves)); } return { getMoves: getMoves, getImage: getImage, joinMoves: joinMoves, change_notation: change_notation, changeColor: changeColor } })();//Fake window so tnoodle is happy var window = self; var document = {}; window.document = document; document['write'] = function() {}; window.write = document['write']; document.getElementById = function() {}; document.getElementsByTagName = function() {return [];}; document.readyState = 'loaded'; if(window.location) { // Firefox actually does set self.location for webworkers document.location = window.location; } else { window.location = { href: "", search: "" }; document.location = window.location; } var puzzles; function puzzlesLoaded(puzzls) { window.puzzles = puzzls; self.puzzles = puzzls; puzzles = puzzls; } onmessage = function(event){ console.log(event.data); if(event.data.fn == "setpuzzles"){ puzzles = window.puzzles = {"333":event.data.p333} return; } var out = scrambler[event.data.fn](...event.data.args); console.log(out); postMessage(out); }// The next line will get replaced with the contents of the // gwt-generated tnoodlejs.nocache.js. So don't mess with it unless // you know what you're doing! function TNOODLEJS_GWT() { function tnoodlejs(){ var $wnd_0 = window, $doc_0 = document, gwtOnLoad, bodyDone, base = '', metaProps = {}, values = [], providers = [], answers = [], softPermutationId = 0, onLoadErrorFunc, propertyErrorFunc; if (!$wnd_0.__gwt_stylesLoaded) { $wnd_0.__gwt_stylesLoaded = {}; } if (!$wnd_0.__gwt_scriptsLoaded) { $wnd_0.__gwt_scriptsLoaded = {}; } function isHostedMode(){ var result = false; try { var query = $wnd_0.location.search; return (query.indexOf('gwt.codesvr=') != -1 || (query.indexOf('gwt.hosted=') != -1 || $wnd_0.external && $wnd_0.external.gwtOnLoad)) && query.indexOf('gwt.hybrid') == -1; } catch (e) { } isHostedMode = function(){ return result; } ; return result; } function maybeStartModule(){ if (gwtOnLoad && bodyDone) { gwtOnLoad(onLoadErrorFunc, 'tnoodlejs', base, softPermutationId); } } function computeScriptBase(){ var thisScript, markerId = '__gwt_marker_tnoodlejs', markerScript; $doc_0.write('<script id="' + markerId + '"><\/script>'); markerScript = $doc_0.getElementById(markerId); thisScript = markerScript && markerScript.previousSibling; while (thisScript && thisScript.tagName != 'SCRIPT') { thisScript = thisScript.previousSibling; } function getDirectoryOfFile(path){ var hashIndex = path.lastIndexOf('#'); if (hashIndex == -1) { hashIndex = path.length; } var queryIndex = path.indexOf('?'); if (queryIndex == -1) { queryIndex = path.length; } var slashIndex = path.lastIndexOf('/', Math.min(queryIndex, hashIndex)); return slashIndex >= 0?path.substring(0, slashIndex + 1):''; } ; if (thisScript && thisScript.src) { base = getDirectoryOfFile(thisScript.src); } if (base == '') { var baseElements = $doc_0.getElementsByTagName('base'); if (baseElements.length > 0) { base = baseElements[baseElements.length - 1].href; } else { base = getDirectoryOfFile($doc_0.location.href); } } else if (base.match(/^\w+:\/\//)) { } else { var img = $doc_0.createElement('img'); img.src = base + 'clear.cache.gif'; base = getDirectoryOfFile(img.src); } if (markerScript) { markerScript.parentNode.removeChild(markerScript); } } function processMetas(){ var metas = document.getElementsByTagName('meta'); for (var i = 0, n = metas.length; i < n; ++i) { var meta = metas[i], name_0 = meta.getAttribute('name'), content_0; if (name_0) { if (name_0 == 'gwt:property') { content_0 = meta.getAttribute('content'); if (content_0) { var value, eq = content_0.indexOf('='); if (eq >= 0) { name_0 = content_0.substring(0, eq); value = content_0.substring(eq + 1); } else { name_0 = content_0; value = ''; } metaProps[name_0] = value; } } else if (name_0 == 'gwt:onPropertyErrorFn') { content_0 = meta.getAttribute('content'); if (content_0) { try { propertyErrorFunc = eval(content_0); } catch (e) { alert('Bad handler "' + content_0 + '" for "gwt:onPropertyErrorFn"'); } } } else if (name_0 == 'gwt:onLoadErrorFn') { content_0 = meta.getAttribute('content'); if (content_0) { try { onLoadErrorFunc = eval(content_0); } catch (e) { alert('Bad handler "' + content_0 + '" for "gwt:onLoadErrorFn"'); } } } } } } function unflattenKeylistIntoAnswers(propValArray, value){ var answer = answers; for (var i = 0, n = propValArray.length - 1; i < n; ++i) { answer = answer[propValArray[i]] || (answer[propValArray[i]] = []); } answer[propValArray[n]] = value; } function computePropValue(propName){ var value = providers[propName](), allowedValuesMap = values[propName]; if (value in allowedValuesMap) { return value; } var allowedValuesList = []; for (var k in allowedValuesMap) { allowedValuesList[allowedValuesMap[k]] = k; } if (propertyErrorFunc) { propertyErrorFunc(propName, allowedValuesList, value); } throw null; } providers['user.agent'] = function(){ var ua = navigator.userAgent.toLowerCase(); var makeVersion = function(result){ return parseInt(result[1]) * 1000 + parseInt(result[2]); } ; if (function(){ return ua.indexOf('opera') != -1; } ()) return 'opera'; if (function(){ return ua.indexOf('webkit') != -1; } ()) return 'safari'; if (function(){ return ua.indexOf('msie') != -1 && $doc_0.documentMode >= 9; } ()) return 'ie9'; if (function(){ return ua.indexOf('msie') != -1 && $doc_0.documentMode >= 8; } ()) return 'ie8'; if (function(){ var result = /msie ([0-9]+)\.([0-9]+)/.exec(ua); if (result && result.l