Browse Source

v0.2.0 Roll multiple Asphodice

Uses default Asphodice class, rolls sets of 1..10 dice 100000 times for
stats.

Future work will need minor extensions of base Asphodice class, such as:
	- class short name (for HTML element ids)
	- class description (to explain what mechanics are implemented-
	  eg different successCutoff)

FE will also need adapted:
	- ids will need to use class short names (as above)
		- result cards
		- chart canvases
		- tables
	- anchors for 'jump to' navigation (see next item)
	- grouping of dice class results with show/hide groups (or
	  tabs or some other means of selecting results, eg dropdown), eg:
		- Asphodice
			- d=1
			- d=2
			- ...
			- d=10
		- AsphodiceCutoff8
			- d=1
			- d=2
			- ...
			- d=10
		- AsphodiceCrits
			- d=1
			- d=2
			- ...
			- d=10
		 (etc)
tags/v0.2.0^0
bertieb 3 years ago
parent
commit
74fc86d913
2 changed files with 77 additions and 25 deletions
  1. +1
    -1
      package.json
  2. +76
    -24
      src/ts/frontend.ts

+ 1
- 1
package.json View File

@@ -1,6 +1,6 @@
{ {
"name": "asphodice", "name": "asphodice",
"version": "0.1.3",
"version": "0.2.0",
"description": "Dice roller for Asphodel. Includes statistical information", "description": "Dice roller for Asphodel. Includes statistical information",
"devDependencies": { "devDependencies": {
"@types/chai": "^4.2.14", "@types/chai": "^4.2.14",


+ 76
- 24
src/ts/frontend.ts View File

@@ -16,10 +16,8 @@ let barChartOptions = { scales: {
} }
} }


let rollstats = new RollStats();

function hexColours(numColours: number): Array<string> { function hexColours(numColours: number): Array<string> {
return palette("cb-Set1", numColours).map( function (hex: string) {
return palette(["cb-Set1", "tol-dv"], numColours).map( function (hex: string) {
return `#${String(hex)}`; }) return `#${String(hex)}`; })
} }
/** /**
@@ -83,6 +81,7 @@ function subsubTitle(text:string): string {
*/ */


function rerollReport(rollstats: RollStats): string { function rerollReport(rollstats: RollStats): string {
let rerollsChartId = `rerollsChart-${rollstats.numDice}`;
// Column structure // Column structure
let output = `<div class="col" id="rerollCol">`; let output = `<div class="col" id="rerollCol">`;
// Heading // Heading
@@ -90,7 +89,7 @@ function rerollReport(rollstats: RollStats): string {
// Preamble (ie it looks super confusing) // Preamble (ie it looks super confusing)
//output += "<p>This is super confusing because the colours are swapped on the legend and the chart, then the data below swaps back.</p>"; //output += "<p>This is super confusing because the colours are swapped on the legend and the chart, then the data below swaps back.</p>";
// Chart // Chart
output += `<canvas id="rerollsChart"></canvas>`
output += `<canvas id="${rerollsChartId}"></canvas>`


// Numbers // Numbers


@@ -111,6 +110,8 @@ function rerollReport(rollstats: RollStats): string {
} }


function outcomesReport(rollstats: RollStats): string { function outcomesReport(rollstats: RollStats): string {
let outcomesChartId = `outcomesChart-${rollstats.numDice}`;
let outcomesTableId = `outcomesTable-${rollstats.numDice}`;
// Column structure // Column structure
let output = `<div class="col" id="outcomesCol">`; let output = `<div class="col" id="outcomesCol">`;
// Heading // Heading
@@ -118,16 +119,18 @@ function outcomesReport(rollstats: RollStats): string {
// Preamble // Preamble


// Chart // Chart
output += `<canvas id="outcomesChart"></canvas>`;
output += `<canvas id="${outcomesChartId}"></canvas>`;


// Table // Table
output += makeTableSkeleton("outcomeTable", ["Outcome", "Count", "Percentage"]);
output += makeTableSkeleton(outcomesTableId, ["Outcome", "Count", "Percentage"]);


output += `</div>`; output += `</div>`;
return output; return output;
} }


function outcomeBalancesReport(rollstats: RollStats): string { function outcomeBalancesReport(rollstats: RollStats): string {
let balanceChartId = `balanceChart-${rollstats.numDice}`;
let balanceTableId = `balanceTable-${rollstats.numDice}`;
// Column structure // Column structure
let output = `<div class="col" id="balancesCol">`; let output = `<div class="col" id="balancesCol">`;
// Heading // Heading
@@ -135,10 +138,10 @@ function outcomeBalancesReport(rollstats: RollStats): string {
// Preamble // Preamble


// Chart // Chart
output += `<canvas id="balanceChart"></canvas>`;
output += `<canvas id="${balanceChartId}"></canvas>`;


// Table // Table
output += makeTableSkeleton("balanceTable", ["Balance", "Count", "Percentage"]);
output += makeTableSkeleton(balanceTableId, ["Balance", "Count", "Percentage"]);
output += `</div>`; output += `</div>`;
return output; return output;
} }
@@ -149,12 +152,15 @@ function outcomeBalancesReport(rollstats: RollStats): string {
* The more javascripty way of doing this would be a callback or a custom event (TODO?) * The more javascripty way of doing this would be a callback or a custom event (TODO?)
*/ */
function generateCharts(rollstats: RollStats): void { function generateCharts(rollstats: RollStats): void {
let rerollsChartId = `rerollsChart-${rollstats.numDice}`;
let outcomesChartId = `outcomesChart-${rollstats.numDice}`;
let balanceChartId = `balanceChart-${rollstats.numDice}`;


/* /*
* Rerolls * Rerolls
*/ */


let rerollsCanvas: any = $("#rerollsChart");
let rerollsCanvas: any = $(`#${rerollsChartId}`);
let rerollsChart = new Chart(rerollsCanvas, { let rerollsChart = new Chart(rerollsCanvas, {
type: "doughnut", type: "doughnut",
data: { data: {
@@ -181,7 +187,7 @@ function generateCharts(rollstats: RollStats): void {
* Outcomes * Outcomes
*/ */


let outcomesCanvas: any = $("#outcomesChart");
let outcomesCanvas: any = $(`#${outcomesChartId}`);
let outcomesChart = new Chart(outcomesCanvas, { let outcomesChart = new Chart(outcomesCanvas, {
type: "bar", type: "bar",
data: { data: {
@@ -189,7 +195,7 @@ function generateCharts(rollstats: RollStats): void {
datasets: [{ datasets: [{
label: "Outcome Counts", label: "Outcome Counts",
data: Object.values(rollstats.outcomeCounts), data: Object.values(rollstats.outcomeCounts),
backgroundColor: hexColours(Object.values(rollstats.balanceCounts).length),
backgroundColor: hexColours(Object.values(rollstats.outcomeCounts).length),
}], }],
}, },
options: barChartOptions, options: barChartOptions,
@@ -208,7 +214,7 @@ function generateCharts(rollstats: RollStats): void {
values.push(rollstats.balanceCounts[keys[i]]); values.push(rollstats.balanceCounts[keys[i]]);
} }


let balanceCanvas: any = $("#balanceChart");
let balanceCanvas: any = $(`#${balanceChartId}`);
let balanceChart = new Chart(balanceCanvas, { let balanceChart = new Chart(balanceCanvas, {
type: "bar", type: "bar",
data: { data: {
@@ -233,11 +239,12 @@ function generateTables(rollstats: RollStats): void {
/* /*
* Outcomes * Outcomes
*/ */
let outcomesTableId = `outcomesTable-${rollstats.numDice}`;


let oc = rollstats.outcomeCounts; let oc = rollstats.outcomeCounts;
let okeys = Object.keys(oc); let okeys = Object.keys(oc);
for (var i = 0; i < okeys.length; i++) { for (var i = 0; i < okeys.length; i++) {
let tb = $("#outcomeTable").find("tbody");
let tb = $(`#${outcomesTableId}`).find("tbody");
let outcome: Outcomes = okeys[i] as Outcomes; let outcome: Outcomes = okeys[i] as Outcomes;
let outcomeCount = rollstats.outcomeCounts[outcome]; let outcomeCount = rollstats.outcomeCounts[outcome];
let outcomePercent: string = ""; let outcomePercent: string = "";
@@ -254,12 +261,13 @@ function generateTables(rollstats: RollStats): void {
/* /*
* Outcome Balance Counts * Outcome Balance Counts
*/ */
let balanceTableId = `balanceTable-${rollstats.numDice}`;


let bc = rollstats.balanceCounts; let bc = rollstats.balanceCounts;
let keys = Object.keys(bc); let keys = Object.keys(bc);
keys.sort(function(a: string, b: string){return Number(a) - Number(b)}); keys.sort(function(a: string, b: string){return Number(a) - Number(b)});
for (var i = 0; i < keys.length; i++) { for (var i = 0; i < keys.length; i++) {
let tb = $("#balanceTable").find("tbody");
let tb = $(`#${balanceTableId}`).find("tbody");
tb.append(`<tr> <td>${keys[i]}</td> tb.append(`<tr> <td>${keys[i]}</td>
<td>${rollstats.balanceCounts[keys[i]]}</td> <td>${rollstats.balanceCounts[keys[i]]}</td>
<td>${(rollstats.balanceCounts[keys[i]] / rollstats.numRolls * 100).toFixed(2)}</td> <td>${(rollstats.balanceCounts[keys[i]] / rollstats.numRolls * 100).toFixed(2)}</td>
@@ -291,10 +299,11 @@ function describeRolls(rollstats: RollStats): string {
function resultsCard(rollstats: RollStats): JQuery<HTMLElement>{ function resultsCard(rollstats: RollStats): JQuery<HTMLElement>{
// <div id="results"> is the general results div to append results to // <div id="results"> is the general results div to append results to
// TODO: include class shortname in id (?) // TODO: include class shortname in id (?)
$("#results").append(`<div class="card my-4" id="results-aspho-${rollstats.numDice}">`);
let resultsCard = $("#results").find("div.card");
let cardId = `results-aspho-${rollstats.numDice}`;
$("#results").append(`<div class="card my-4" id="${cardId}">`);
let resultsCard = $("#results").find(`#${cardId}`);
resultsCard.append(`<div class="card-body">`); resultsCard.append(`<div class="card-body">`);
let resultsCardBody: JQuery<HTMLElement> = $("#results").find("div.card-body");
let resultsCardBody: JQuery<HTMLElement> = $(`#${cardId}`).find("div.card-body");
return resultsCardBody; return resultsCardBody;
} }


@@ -304,6 +313,7 @@ function resultsCard(rollstats: RollStats): JQuery<HTMLElement>{


function resultsHeader(rollstats: RollStats): string { function resultsHeader(rollstats: RollStats): string {
// Use flexbox (d-flex) for LHS/RHS justification // Use flexbox (d-flex) for LHS/RHS justification
let resultsBodyId = `resultsBody-${rollstats.numDice}`;
let resultsTitle = `<div class="d-flex justify-content-between">` let resultsTitle = `<div class="d-flex justify-content-between">`
resultsTitle += `<div>` resultsTitle += `<div>`
+ bigTitle(`Asphodice Results + bigTitle(`Asphodice Results
@@ -312,7 +322,11 @@ function resultsHeader(rollstats: RollStats): string {
</small>`) </small>`)
+ `</div>`; + `</div>`;
resultsTitle += `<div> resultsTitle += `<div>
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="collapse" data-bs-target="#resultsBody" aria-expanded="true" aria-controls="collapse-resultsBody">(hide/show)</button>
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="collapse"
data-bs-target="#${resultsBodyId}"
aria-expanded="true" aria-controls="collapse-resultsBody">
(hide/show)
</button>
</div>` </div>`
resultsTitle += `</div>`; resultsTitle += `</div>`;
return resultsTitle; return resultsTitle;
@@ -324,9 +338,12 @@ function resultsHeader(rollstats: RollStats): string {
*/ */


function resultsBody(rollstats: RollStats): string { function resultsBody(rollstats: RollStats): string {
let resultsBody = `<div id="resultsBody" class="show row resultsToggle">`;
let resultsBodyId = `resultsBody-${rollstats.numDice}`;
let resultsBody = `<div id="${resultsBodyId}" class="show row resultsToggle">`;
resultsBody += describeRolls(rollstats); resultsBody += describeRolls(rollstats);
resultsBody += rerollReport(rollstats) + outcomesReport(rollstats) + outcomeBalancesReport(rollstats);
resultsBody += rerollReport(rollstats)
+ outcomesReport(rollstats)
+ outcomeBalancesReport(rollstats);
resultsBody += `</div>`; resultsBody += `</div>`;
return resultsBody; return resultsBody;
} }
@@ -356,15 +373,50 @@ function addResults(rollstats: RollStats): void {
generateCharts(rollstats); generateCharts(rollstats);
} }


/**
* Card with status and hide-show all control
*/
function resultsControlCard(): string {
let resultsControl = `<div id="resultsControl" class="card my-3 mx-2 border border-2 border-info">`;
resultsControl += `<h2 class="card-title mx-3 my-2">Results</h5>`;
resultsControl += `<div class="progress mx-3">
<div class="progress-bar" id="resultsProgress"></div>
</div>`;
resultsControl += `<div class="card-body">
<button class="btn btn-primary" type="button"
data-bs-toggle="collapse" data-bs-target=".resultsToggle"
aria-expanded="true" aria-controls="resultsToggleAll">
Hide / Show All
</button>
</div>`;

resultsControl += `</div>`;
return resultsControl
}



function getResults():void { function getResults():void {
// Disable 'roll' button (TODO: multiple sets of rolls)
// Disable 'roll' button
$("#mainRoll").prop("disabled", true); $("#mainRoll").prop("disabled", true);
console.log("Getting results..."); // TODO: progress bar when we have multiple sets of rolls
console.log("Getting results...");


$("#results").empty(); $("#results").empty();
rollstats.doRolls();
addResults(rollstats);

$("#results").append(resultsControlCard);

let maxDice = 10;
for (let i = 1; i < maxDice; i++) {
let rollstats = new RollStats(i);
rollstats.doRolls();
addResults(rollstats);
$("#resultsProgress").width(`${i/maxDice*100}%`);
$("#resultsProgress").text(`${i/maxDice*100}%`);
}
console.log("Results done!");
$("#resultsProgress").width("100%");
$("#resultsProgress").text("100%");
} }






Loading…
Cancel
Save