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",
"version": "0.1.3",
"version": "0.2.0",
"description": "Dice roller for Asphodel. Includes statistical information",
"devDependencies": {
"@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> {
return palette("cb-Set1", numColours).map( function (hex: string) {
return palette(["cb-Set1", "tol-dv"], numColours).map( function (hex: string) {
return `#${String(hex)}`; })
}
/**
@@ -83,6 +81,7 @@ function subsubTitle(text:string): string {
*/

function rerollReport(rollstats: RollStats): string {
let rerollsChartId = `rerollsChart-${rollstats.numDice}`;
// Column structure
let output = `<div class="col" id="rerollCol">`;
// Heading
@@ -90,7 +89,7 @@ function rerollReport(rollstats: RollStats): string {
// 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>";
// Chart
output += `<canvas id="rerollsChart"></canvas>`
output += `<canvas id="${rerollsChartId}"></canvas>`

// Numbers

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

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

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

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

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

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

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

// Table
output += makeTableSkeleton("balanceTable", ["Balance", "Count", "Percentage"]);
output += makeTableSkeleton(balanceTableId, ["Balance", "Count", "Percentage"]);
output += `</div>`;
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?)
*/
function generateCharts(rollstats: RollStats): void {
let rerollsChartId = `rerollsChart-${rollstats.numDice}`;
let outcomesChartId = `outcomesChart-${rollstats.numDice}`;
let balanceChartId = `balanceChart-${rollstats.numDice}`;

/*
* Rerolls
*/

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

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

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

let oc = rollstats.outcomeCounts;
let okeys = Object.keys(oc);
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 outcomeCount = rollstats.outcomeCounts[outcome];
let outcomePercent: string = "";
@@ -254,12 +261,13 @@ function generateTables(rollstats: RollStats): void {
/*
* Outcome Balance Counts
*/
let balanceTableId = `balanceTable-${rollstats.numDice}`;

let bc = rollstats.balanceCounts;
let keys = Object.keys(bc);
keys.sort(function(a: string, b: string){return Number(a) - Number(b)});
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>
<td>${rollstats.balanceCounts[keys[i]]}</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>{
// <div id="results"> is the general results div to append results to
// 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">`);
let resultsCardBody: JQuery<HTMLElement> = $("#results").find("div.card-body");
let resultsCardBody: JQuery<HTMLElement> = $(`#${cardId}`).find("div.card-body");
return resultsCardBody;
}

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

function resultsHeader(rollstats: RollStats): string {
// Use flexbox (d-flex) for LHS/RHS justification
let resultsBodyId = `resultsBody-${rollstats.numDice}`;
let resultsTitle = `<div class="d-flex justify-content-between">`
resultsTitle += `<div>`
+ bigTitle(`Asphodice Results
@@ -312,7 +322,11 @@ function resultsHeader(rollstats: RollStats): string {
</small>`)
+ `</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>`
resultsTitle += `</div>`;
return resultsTitle;
@@ -324,9 +338,12 @@ function resultsHeader(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 += rerollReport(rollstats) + outcomesReport(rollstats) + outcomeBalancesReport(rollstats);
resultsBody += rerollReport(rollstats)
+ outcomesReport(rollstats)
+ outcomeBalancesReport(rollstats);
resultsBody += `</div>`;
return resultsBody;
}
@@ -356,15 +373,50 @@ function addResults(rollstats: RollStats): void {
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 {
// Disable 'roll' button (TODO: multiple sets of rolls)
// Disable 'roll' button
$("#mainRoll").prop("disabled", true);
console.log("Getting results..."); // TODO: progress bar when we have multiple sets of rolls
console.log("Getting results...");

$("#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