Skip to content

Instantly share code, notes, and snippets.

@RuyiLi
Created December 9, 2019 03:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RuyiLi/ff9db280d107136134fc47b7fbdc5c02 to your computer and use it in GitHub Desktop.
Save RuyiLi/ff9db280d107136134fc47b7fbdc5c02 to your computer and use it in GitHub Desktop.
Soldier simulator application for my Math Extended Essay.
<canvas></canvas>
<button onclick="josephus()"> Start </button>
<button onclick="eliminate()"> Kill </button>
<script>
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const SIZE = 640;
canvas.width = canvas.height = SIZE;
ctx.font = '20px Arial';
function drawSoldier(x, y, dead, deadIndex) {
const s = 32;
const r = s / 2;
ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI, false);
ctx.fillStyle = dead ? '#ff3300' : '#11f23e';
ctx.fill();
ctx.strokeStyle = '#181818';
ctx.lineWidth = 7;
ctx.stroke();
if (!dead) return;
ctx.fillStyle = '#ededed';
ctx.fillText(deadIndex, x - ctx.measureText('' + deadIndex).width / 2, y + 7);
}
// alive = list(range(1, n + 1))
// dead = []
// rounds = 0
// step -= 1
// i = step
// while len(alive) > 1:
// rounds += 1
// dead.append(alive.pop(i))
// i = (i + step) % len(alive)
let s = +prompt('S:'), n = +prompt('N:');
let alive, dead;
let rounds = 0
const step = s - 1;
let c = step;
function eliminate() {
rounds += 1
dead.push(alive[ c ]);
alive.splice(c, 1)
c = (c + step) % alive.length;
render();
}
function josephus() {
alive = Object.keys([ ...new Array(n).fill(n) ]).map(_ => +_);
dead = []
render();
}
function render() {
ctx.clearRect(0, 0, SIZE, SIZE);
for (let i = 0; i < n; i++) {
const deg = (360 / n * i - 90) * Math.PI / 180
const x = SIZE / 2 + Math.cos(deg) * 300// * n / 100;
const y = SIZE / 2 + Math.sin(deg) * 300;
drawSoldier(x, y, dead.includes(i), dead.indexOf(i) + 1, i);
ctx.fillStyle = dead.includes(i) ? '#ff3300' : '#11f23e';
ctx.fillText(i + 1, (SIZE / 2 + Math.cos(deg) * 260) - ctx.measureText('' + (i + 1)).width / 2, (SIZE / 2 + Math.sin(deg) * 260) + 7);
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment