Created
December 9, 2019 03:14
-
-
Save RuyiLi/ff9db280d107136134fc47b7fbdc5c02 to your computer and use it in GitHub Desktop.
Soldier simulator application for my Math Extended Essay.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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