Door Puzzle
https://www.reddit.com/r/dnd/comments/4y4t7l/_/d6l2l6g?context=1000
by jcubed111
HTML
<div id="diskArea"></div>
<br/>
<button onclick="rotate(0, 1)">+ A</button>
<button onclick="rotate(1, 1)">+ B</button>
<button onclick="rotate(2, 1)">+ C</button> <br/>
<button onclick="rotate(0, -1)">- A</button>
<button onclick="rotate(1, -1)">- B</button>
<button onclick="rotate(2, -1)">- C</button>
<br/><br/>
Steps: <span id="steps">0</span>
<br/><br/>
<div id="status"></div>
<br/>
<button onclick="showSolution()">Show Solution</button>
<div id="solution" class="hidden"></div>
<script>
setup();
render();
check();
</script>
CSS
#diskArea{
position: relative;
width: 250px;
height: 250px;
background: #eee;
}
.disk{
position: absolute;
width: 250px;
height: 250px;
transform-origin: 50% 50%;
border-radius: 50%;
overflow: hidden;
transition: transform 0.5s;
}
.number{
position: absolute;
left: 75px;
top: 150px;
width: 100px;
height: 100px;
transform-origin: 50px -25px;
font-size: 40px;
text-align: center;
box-sizing: border-box;
padding-top: 35px;
border-top-left-radius: 50px 100px;
border-top-right-radius: 50px 100px;
}
.n0{
color: transparent;
}
button{ cursor: pointer;}
button,
#solution,
#status{
font-family: monospace;
}
.hidden{
display: none;
}
JavaScript
"use strict";
var size = 5; // how many numbers there are per disk
// 3: easy
// 5: moderate
// 7: hard
// 11: harder
var method = 1; // determines how the buttons work
// 0: buttons always work the same
// 1: buttons are randomized when the puzzle is generated,
// but each button always moves two diska the same amount.
switch(method) {
case 0:
var rotAmounts = [ // always works for size >= 3 if size is prime.
[0, 1, 1],
[2, 0, 2],
[2, 2, 0],
];
break;
case 1:
var f = [
((Math.random()*(size>>1))|0)+1,
((Math.random()*(size>>1))|0)+1,
((Math.random()*(size>>1))|0)+1,
];
var rotAmounts = _.shuffle([
[1*f[0], 1*f[0], 0*f[0]],
[0*f[1], 1*f[1], 1*f[1]],
[1*f[2], 0*f[2], 1*f[2]],
]);
break;
}
var offsets = [0, 0, 0];
while(offsets.join('') == '000') { // ensure we never start with a solved puzzle
offsets = [
(Math.random()*size)|0,
(Math.random()*size)|0,
(Math.random()*size)|0
];
}
function setup() {
var colors = ['#ccc', '#bbb', '#aaa'];
for(var i=2; i>=0; i--) {
var el = document.createElement('div');
el.className='disk';
el.id = ['a', 'b', 'c'][i];
var angle = 360/size;
el.style.backgroundImage = `
linear-gradient(${ +90+angle/2 }deg, ${ colors[i] } 50%, transparent 50%),
linear-gradient(${ -90-angle/2 }deg, ${ colors[i] } 50%, transparent 50%),
linear-gradient(${ +90+angle/2 }deg, #000 50.5%, transparent 50.5%),
linear-gradient(${ -90-angle/2 }deg, #000 50.5%, transparent 50.5%)
`;
document.getElementById('diskArea').appendChild(el);
for(var j=0; j<size; j++) {
var num = document.createElement('div');
num.className='number' + (j ? '' : ' n0');
num.style.transform = 'rotate(-' + j/size*360 + 'deg)';
num.innerHTML = ['a', 'b', 'c'][i] + j;
el.appendChild(num);
}
}
}
function rotate(n, sign) {
document.getElementById('steps').innerHTML++;
var amounts = rotAmounts[n];
offsets[0] = offsets[0] +...