From 8ec936babfdf9232ca012d35c84fae579ef017f6 Mon Sep 17 00:00:00 2001 From: "Felix W. Dekker" Date: Tue, 5 May 2020 21:59:03 +0200 Subject: [PATCH] Migrate to npm, use template package --- .gitattributes | 1 + .gitignore | 117 ++++++++++++++++ Gruntfile.js | 123 +++++++++++++++++ README.md | 28 ++++ index.html | 310 ------------------------------------------- package-lock.json | Bin 0 -> 236360 bytes package.json | 34 +++++ src/main/index.html | 78 +++++++++++ src/main/js/index.js | 238 +++++++++++++++++++++++++++++++++ 9 files changed, 619 insertions(+), 310 deletions(-) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Gruntfile.js delete mode 100644 index.html create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/main/index.html create mode 100644 src/main/js/index.js diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1a6bd45 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +package-lock.json binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e7ea1e8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,117 @@ +## Node +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.pnp.* diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..b8c8a77 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,123 @@ +const path = require("path"); + +module.exports = grunt => { + grunt.initConfig({ + pkg: grunt.file.readJSON("package.json"), + clean: { + default: ["dist/"], + }, + copy: { + html: { + files: [{expand: true, cwd: "src/main/", src: "**/*.html", dest: "dist/"}] + }, + css: { + files: [{expand: true, cwd: "src/main/", src: "**/*.css", dest: "dist/"}] + }, + }, + focus: { + dev: { + include: ["css", "html", "js", "link"], + }, + }, + replace: { + dev: { + src: ["./dist/*.html", "./dist/*.js"], + replacements: [ + { + from: "%%VERSION_NUMBER%%", + to: "<%= pkg.version %>+" + new Date().toISOString().slice(0, 19).replace(/[-:T]/g, "") + } + ], + overwrite: true + }, + deploy: { + src: ["./dist/*.html", "./dist/*.js"], + replacements: [ + { + from: "%%VERSION_NUMBER%%", + to: "<%= pkg.version %>" + } + ], + overwrite: true + }, + }, + webpack: { + options: { + entry: "./src/main/js/index.js", + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + }, + ], + }, + resolve: { + extensions: [".js"], + }, + output: { + filename: "bundle.js", + path: path.resolve(__dirname, "dist/"), + }, + }, + dev: { + mode: "development", + devtool: "inline-source-map", + }, + deploy: { + mode: "production", + }, + }, + watch: { + css: { + files: ["src/main/**/*.css"], + tasks: ["copy:css"], + }, + html: { + files: ["src/main/**/*.html"], + tasks: ["copy:html"], + }, + js: { + files: ["src/main/**/*.js"], + tasks: ["webpack:dev", "replace:dev"], + }, + link: { + files: ["node_modules/@fwdekker/*/dist/**"], + tasks: ["webpack:dev", "replace:dev"], + }, + }, + }); + + grunt.loadNpmTasks("grunt-contrib-clean"); + grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-contrib-watch"); + grunt.loadNpmTasks("grunt-focus"); + grunt.loadNpmTasks("grunt-text-replace"); + grunt.loadNpmTasks("grunt-webpack"); + + grunt.registerTask("dev", [ + // Pre + "clean", + // Copy files + "copy:html", + "copy:css", + // Compile + "webpack:dev", + // Post + "replace:dev" + ]); + grunt.registerTask("dev:server", ["dev", "focus:dev"]); + grunt.registerTask("deploy", [ + // Pre + "clean", + // Copy files + "copy:html", + "copy:css", + // Compile JS + "webpack:deploy", + // Post + "replace:deploy" + ]); + + grunt.registerTask("default", ["dev"]); +}; diff --git a/README.md b/README.md index c1e62c7..1d5a49f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,30 @@ # Dice Given a set of dice, calculates the probability density graph of each value that can be rolled. + +## Development +### Requirements +* [npm](https://www.npmjs.com/) + +### Setting up +```shell script +# Install dependencies (only needed once) +$> npm ci +``` + +### Building +```shell script +# Build the template in `dist/` for development +$> npm run dev +# Same as above, but automatically rerun it whenever files are changed +$> npm run dev:server +# Build the template in `dist/` for deployment +$> npm run deploy +``` + +### Publishing +```shell script +# Log in to npm +$> npm login +# Push to npm +$> npm publish --access public +``` diff --git a/index.html b/index.html deleted file mode 100644 index ebb3f01..0000000 --- a/index.html +++ /dev/null @@ -1,310 +0,0 @@ - - - - - - - - - - - Dice probabilities | FWDekker - - - - - -
- -
-
-

Dice probabilities

- -
-

Calculates the probability of rolling a value given a combination of dice.

-
-
-
- - - -
-
-
-
-
- - - - - - - - - - - - - -
Sides per dieNumber of rolls
- -
- - -
-
-
-
-
- - - -
-

Probabilities

-
-
- -
-
-
- - - - -
- - - - - - - - diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..889b318eafb5af7c043ca707fd81569f9c94367e GIT binary patch literal 236360 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 + + + + + + + + + + Dice probabilities | FWDekker + + + + + +
+ +
+ + + + +
+
+
+
+
+ + + + + + + + + + + + + +
Sides per dieNumber of rolls
+ +
+ + +
+
+
+
+
+ + +
+

Probabilities

+
+
+ +
+
+
+
+ +
+ + + + + + diff --git a/src/main/js/index.js b/src/main/js/index.js new file mode 100644 index 0000000..7005b0f --- /dev/null +++ b/src/main/js/index.js @@ -0,0 +1,238 @@ +import {$, doAfterLoad, footer, header, nav} from "@fwdekker/template"; +import Chart from "chart.js" + + +////// +/// +/// Helper functions +/// +////// + +const repeat = (value, length) => { + const zeroArray = []; + for (let i = 0; i < length; i++) + zeroArray.push(value); + return zeroArray; +}; + +const rangeExclusive = (from, to) => { + const rangeArray = []; + for (let i = from; i < to; i++) + rangeArray.push(i); + return rangeArray; +}; + +const rangeInclusive = (from, to) => { + const rangeArray = rangeExclusive(from, to); + rangeArray.push(to); + return rangeArray; +}; + +const iterateNodeList = (nodeList, fun) => { + for (let i = 0; i < nodeList.length; i++) { + const node = nodeList.item(i); + fun(node); + } +}; + + +////// +/// +/// Template +/// +////// + +doAfterLoad(() => { + $("#nav").appendChild(nav()); + $("#header").appendChild(header({ + title: "Dice", + description: "Calculate the probability of rolling a value given a combination of dice" + })); + $("#footer").appendChild(footer({ + author: "Felix W. Dekker", + authorURL: "https://fwdekker.com/", + license: "MIT License", + licenseURL: "https://git.fwdekker.com/FWDekker/dice/src/branch/master/LICENSE", + vcs: "git", + vcsURL: "https://git.fwdekker.com/FWDekker/dice/", + version: "v%%VERSION_NUMBER%%" + })); + $("main").style.display = null; +}); + + +////// +/// +/// Input +/// +////// + +const inputTable = {}; + + +// Functions +inputTable.getTable = () => $("#dieSettings tbody"); + +inputTable.dieRowCount = () => inputTable.getTable().querySelectorAll(".dieEyes").length; + +inputTable.highestDieRowIndex = () => { + const table = inputTable.getTable(); + + let highestDieRowIndex = -1; + iterateNodeList(table.getElementsByTagName("tr"), (node) => { + if ("index" in node.dataset) + highestDieRowIndex = Math.max(highestDieRowIndex, +node.dataset.index); + }); + + return highestDieRowIndex; +}; + +inputTable.addDieRow = () => { + const createNumberInput = (index, className, value) => { + const input = document.createElement("input"); + input.id = className + index; + input.className = className; + input.type = "number"; + input.min = "1"; + input.step = "1"; + input.value = value; + input.addEventListener("keypress", (e) => { + if (e.key === "Enter") + outputChart.updateProbGraph(); + }); + input.focus(); + return input; + }; + + const createRemoveLink = (index, className) => { + const link = document.createElement("button"); + link.id = className + index; + link.className = className + " button-clear"; + link.type = "button"; + link.innerHTML = "Remove"; + link.onclick = (() => inputTable.removeDieRow(index)); + return link; + }; + + + const table = inputTable.getTable(); + const newIndex = inputTable.highestDieRowIndex() + 1; + + const row = table.insertRow(inputTable.dieRowCount()); + row.dataset.index = "" + newIndex; + + row.insertCell().appendChild(createNumberInput(newIndex, "dieEyes", 6)); + row.insertCell().appendChild(createNumberInput(newIndex, "dieCount", 2)); + row.insertCell().appendChild(createRemoveLink(newIndex, "dieRemove")); +}; + +inputTable.removeDieRow = index => { + if (inputTable.highestDieRowIndex() > 0) { + const table = inputTable.getTable(); + const row = table.querySelector("tr[data-index=\"" + index + "\"]"); + row.parentElement.removeChild(row); + } +}; + +inputTable.getDice = () => { + const dice = []; + + const eyesInputs = document.getElementsByClassName("dieEyes"); + const countInputs = document.getElementsByClassName("dieCount"); + for (let i = 0; i < eyesInputs.length; i++) { + const count = parseInt(countInputs.item(i).value); + + for (let j = 0; j < count; j++) + dice.push(parseInt(eyesInputs.item(i).value)); + } + + return dice; +}; + + +// Init +doAfterLoad(() => { + const button = $("#addDieRowButton"); + button.onclick = inputTable.addDieRow; + button.click() +}); + + +////// +/// +/// Output +/// +////// + +const outputChart = {}; +let probChart; + + +// Functions +outputChart.calculateDiceFrequencies = dice => { + if (dice.length === 0) + return []; + + + // Roll dice + let rollFreqs = [0].concat(repeat(1, dice[0])); + dice.slice(1).forEach(die => { + const dieRollFreqs = rollFreqs.concat(repeat(0, die)); + rollFreqs = repeat(0, dieRollFreqs.length); + + rangeInclusive(1, die).forEach(rollValue => { + rangeExclusive(1, dieRollFreqs.length - die).forEach(i => { + rollFreqs[rollValue + i] += dieRollFreqs[i]; + }); + }); + }); + rollFreqs.shift(); + + + // Calculate frequencies + const totalRolls = rollFreqs.reduce((a, b) => a + b, 0); + rangeExclusive(0, rollFreqs.length).forEach(roll => { + rollFreqs[roll] = rollFreqs[roll] / totalRolls; + }); + + + return rollFreqs; +}; + +outputChart.updateProbGraph = () => { + const dice = inputTable.getDice(); + const rollFreqs = outputChart.calculateDiceFrequencies(dice); + + probChart.data.labels = rangeInclusive(1, rollFreqs.length); + probChart.data.datasets = [{ + data: rollFreqs, + backgroundColor: "rgb(0, 51, 204, 0.4)" + }]; + probChart.update(); +}; + + +// Init +doAfterLoad(() => { + probChart = new Chart($("#probChart").getContext("2d"), { + type: "line", + data: {}, + options: { + legend: { + display: false + }, + scales: { + yAxes: [{ + display: true, + ticks: { + suggestedMin: 0 + } + }] + } + } + }); + + const submit = $("#submit"); + submit.onclick = outputChart.updateProbGraph; + submit.click() +});