parent
6a6dac7b01
commit
dab1ed15c1
7 changed files with 198 additions and 0 deletions
|
@ -110,6 +110,12 @@ Sticker by [djuan](https://linktr.ee/mkiiisystem)!
|
||||||
|
|
||||||
**[Braceless JS](https://github.com/nycki93/braceless-javascript/), 2018.** You can do a lot with 'one-line' functions. Let's play with that!
|
**[Braceless JS](https://github.com/nycki93/braceless-javascript/), 2018.** You can do a lot with 'one-line' functions. Let's play with that!
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="card">
|
||||||
|
<a href="./mathdice/"><img src="/a/card-mathdice.png"></a>
|
||||||
|
|
||||||
|
**[Mathdice](./mathdice/), 2017.** Practice your number skills with random puzzles. Check with the auto-solver!
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<a href="https://museumofzzt.com/file/p/PortalZZT_v0_5.zip"><img src="/a/card-portal-zzt.png"></a>
|
<a href="https://museumofzzt.com/file/p/PortalZZT_v0_5.zip"><img src="/a/card-portal-zzt.png"></a>
|
||||||
|
|
BIN
static/a/card-mathdice.png
Normal file
BIN
static/a/card-mathdice.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 2.3 KiB |
29
static/mathdice/index.html
Normal file
29
static/mathdice/index.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Mathdice Solver 1.0</title>
|
||||||
|
<!-- By Nick "Nupa" Lamicela, 2018 -->
|
||||||
|
<meta charset="utf-8"/>
|
||||||
|
<link rel="stylesheet" href="mathdice.css"/>
|
||||||
|
<script src="mathdice.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<p>Your numbers are:</p>
|
||||||
|
<form>
|
||||||
|
<input type="text" name="die1" class="scoring dice" />
|
||||||
|
<input type="text" name="die2" class="scoring dice" />
|
||||||
|
<input type="text" name="die3" class="scoring dice" />
|
||||||
|
<input type="text" name="target" id="target" class="dice" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<button id="roll-button">Roll dice</button>
|
||||||
|
<button id="solve-button">Solve the puzzle</button>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<div id="solution"/>
|
||||||
|
</body>
|
||||||
|
</html>
|
19
static/mathdice/mathdice.css
Normal file
19
static/mathdice/mathdice.css
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
body {
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dice {
|
||||||
|
display: inline-block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: gray outset 6px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
font-size: 80px;
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#target {
|
||||||
|
border-color: gold;
|
||||||
|
width: 200px;
|
||||||
|
}
|
143
static/mathdice/mathdice.js
Normal file
143
static/mathdice/mathdice.js
Normal file
|
@ -0,0 +1,143 @@
|
||||||
|
"use strict";
|
||||||
|
const OPERATORS = {
|
||||||
|
add: {
|
||||||
|
apply(a, b) {return a + b},
|
||||||
|
toString() {return "+"}
|
||||||
|
},
|
||||||
|
subtract: {
|
||||||
|
apply(a, b) {return a - b},
|
||||||
|
toString() {return "-"}
|
||||||
|
},
|
||||||
|
multiply: {
|
||||||
|
apply(a, b) {return a * b},
|
||||||
|
toString() {return "*"}
|
||||||
|
},
|
||||||
|
divide: {
|
||||||
|
apply(a, b) {return a / b},
|
||||||
|
toString() {return "/"}
|
||||||
|
},
|
||||||
|
power: {
|
||||||
|
apply(a, b) {return a ** b},
|
||||||
|
toString() {return "^"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign event handlers.
|
||||||
|
document.getElementById("roll-button").onclick = generateProblem;
|
||||||
|
document.getElementById("solve-button").onclick = showSolution;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Roll dice and generate a mathdice problem. There are three "key" values
|
||||||
|
* (d6), and one "target" roll (1d12 * 1d12).
|
||||||
|
*/
|
||||||
|
function generateProblem () {
|
||||||
|
// mouse:mice :: douse:dice
|
||||||
|
const diceList = document.querySelectorAll('.scoring');
|
||||||
|
Array.prototype.forEach.call(diceList, douse => {
|
||||||
|
douse.value = roll_d(6);
|
||||||
|
})
|
||||||
|
|
||||||
|
const target = document.getElementById('target');
|
||||||
|
target.value = roll_d(12) * roll_d(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solve the problem! Read in the values on screen and run them through the
|
||||||
|
* solution algorithm.
|
||||||
|
*/
|
||||||
|
function showSolution () {
|
||||||
|
const diceList = document.querySelectorAll('.scoring');
|
||||||
|
const diceValues = Array.prototype.map.call(diceList, douse =>
|
||||||
|
Number(douse.value)
|
||||||
|
)
|
||||||
|
const targetValue = Number(document.getElementById('target').value);
|
||||||
|
const solution = solve(diceValues, targetValue);
|
||||||
|
document.getElementById('solution').innerHTML = solution;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random number between 1 and n, inclusive.
|
||||||
|
* @param {number} n
|
||||||
|
*/
|
||||||
|
function roll_d (n) {
|
||||||
|
const roll = Math.floor(n * Math.random()) + 1;
|
||||||
|
return roll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate an expression! An expression is either
|
||||||
|
* 1) a number, or
|
||||||
|
* 2) two expressions connected with an operator.
|
||||||
|
* @param {number | Array} expr
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function evaluateExpression (expr) {
|
||||||
|
if (!Array.isArray(expr)) return expr;
|
||||||
|
|
||||||
|
const [a, op, b] = expr;
|
||||||
|
const valueA = evaluateExpression(a);
|
||||||
|
const valueB = evaluateExpression(b);
|
||||||
|
return op.apply(valueA, valueB);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an expression as a string.
|
||||||
|
* @param {number | Array} expr
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
function writeExpression (expr) {
|
||||||
|
if (!Array.isArray(expr)) return expr;
|
||||||
|
|
||||||
|
const [a, op, b] = expr;
|
||||||
|
let strA = writeExpression(a);
|
||||||
|
if (Array.isArray(a)) {strA = `(${strA})`}
|
||||||
|
let strB = writeExpression(b);
|
||||||
|
if (Array.isArray(b)) {strB = `(${strB})`}
|
||||||
|
return `${strA} ${op.toString()} ${strB}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solve a mathdice problem!
|
||||||
|
* @param {number[]} scoringDice An array of "key" values used in the puzzle.
|
||||||
|
* @param {number} target The "target" value to try and produce.
|
||||||
|
* @returns {string} A string representation of the optimal answer.
|
||||||
|
*/
|
||||||
|
function solve(scoringDice, target) {
|
||||||
|
// Possible solutions: 2 * 3! * 5^2 = 300. Reasonable to brute force.
|
||||||
|
const [a, b, c] = scoringDice;
|
||||||
|
const dicePermutations = [
|
||||||
|
[a, b, c],
|
||||||
|
[a, c, b],
|
||||||
|
[b, a, c],
|
||||||
|
[b, c, a],
|
||||||
|
[c, a, b],
|
||||||
|
[c, b, a]
|
||||||
|
];
|
||||||
|
const templates = [
|
||||||
|
(a, b, c, x, y) => [a, x, [b, y, c]],
|
||||||
|
(a, b, c, x, y) => [[a, x, b], y, c]
|
||||||
|
];
|
||||||
|
|
||||||
|
// I don't even care how brutally hard-coded this is, I don't NEED the
|
||||||
|
// general case right now.
|
||||||
|
const guesses = [];
|
||||||
|
for (const keyX in OPERATORS) {
|
||||||
|
const x = OPERATORS[keyX];
|
||||||
|
for (const keyY in OPERATORS) {
|
||||||
|
const y = OPERATORS[keyY];
|
||||||
|
dicePermutations.forEach( ([a, b, c]) => {
|
||||||
|
templates.forEach( f => {
|
||||||
|
guesses.push(f(a, b, c, x, y));
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the best guess.
|
||||||
|
const scores = guesses.map( guess =>
|
||||||
|
Math.abs(target - evaluateExpression(guess))
|
||||||
|
)
|
||||||
|
const bestScore = Math.min(...scores);
|
||||||
|
const bestGuess = guesses[scores.indexOf(bestScore)];
|
||||||
|
return `${writeExpression(bestGuess)} = ${evaluateExpression(bestGuess)}`;
|
||||||
|
}
|
1
static/mathdice/readme.md
Normal file
1
static/mathdice/readme.md
Normal file
|
@ -0,0 +1 @@
|
||||||
|
An html mathdice game.
|
Loading…
Add table
Reference in a new issue