My personal website's games section
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

252 lines
16 KiB

{% include 'header.html' %}
<div id="app" class="gameArea extraSpace"><form method="{{ formMethod }}">
<div class="singleCol">
<form method="{{ formMethod }}">
<input type="hidden" name="username" value="{{ username }}"/>
<input type="hidden" name="page" value="{{ prev }}"/>
<input style="position: relative; top: 0; left: 0; float: left;" class="greenButton" type="submit" value="Back"/>
<form method="{{ formMethod }}">
<input type="hidden" name="page" value="json"/>
<input style="position: relative; top: 0; left: 0; float: left; margin-left: 10px" class="purpleButton" type="submit" value="JSON Data"/>
<input style="position: relative; top: 0; left: 0; float: left; margin-left: 10px" class="grayButton" type="button" value="Reload" onclick="window.location.reload();"/>
<h1 class="scale">Boggle 2.0 - Stats</h1>
<div class="leftCol highscores">
<p class="scale" style="margin: 10px;">
{% if has5x5 %}
<div class="grayBox">
<h3>5x5, 4 letters, 3 min</h3>
<a href="?id={{ winScore5x5._id }}&username={{ username }}&page=view&prev=stats">high score</a>: {{ winScore5x5.winScore }}<br/>
<a href="?id={{ numWordsPlayersFound5x5._id }}&username={{ username }}&page=view&prev=stats">most words found</a>: {{ numWordsPlayersFound5x5.numWordsPlayersFound }}<br/>
<a href="?id={{ percentFound5x5._id }}&username={{ username }}&page=view&prev=stats">highest % found</a>: {{ ((percentFound5x5.percentFound*100)|round)/100 }}%<br/>
<a href="?id={{ maxScore5x5._id }}&username={{ username }}&page=view&prev=stats">high possible score</a>: {{ maxScore5x5.maxScore }}<br/>
<a href="?id={{ maxWords5x5._id }}&username={{ username }}&page=view&prev=stats">most words available</a>: {{ maxWords5x5.maxWords }}<br/>
<a href="?id={{ low_maxScore5x5._id }}&username={{ username }}&page=view&prev=stats">low possible score</a>: {{ low_maxScore5x5.maxScore }}<br/>
<a href="?id={{ low_maxWords5x5._id }}&username={{ username }}&page=view&prev=stats">least words available</a>: {{ low_maxWords5x5.maxWords }}<br/>
<a href="?id={{ duplicates5x5._id }}&username={{ username }}&page=view&prev=stats">most duplicates</a>: {{ duplicates5x5.duplicates }}<br/>
{% endif %}
{% if has4x4 %}
<div class="grayBox">
<h3>4x4, 3 letters, 3 min</h3>
<a href="?id={{ winScore4x4._id }}&username={{ username }}&page=view&prev=stats">high score</a>: {{ winScore4x4.winScore }}<br/>
<a href="?id={{ numWordsPlayersFound4x4._id }}&username={{ username }}&page=view&prev=stats">most words found</a>: {{ numWordsPlayersFound4x4.numWordsPlayersFound }}<br/>
<a href="?id={{ percentFound4x4._id }}&username={{ username }}&page=view&prev=stats">highest % found</a>: {{ ((percentFound4x4.percentFound*100)|round)/100 }}%<br/>
<a href="?id={{ maxScore4x4._id }}&username={{ username }}&page=view&prev=stats">high possible score</a>: {{ maxScore4x4.maxScore }}<br/>
<a href="?id={{ maxWords4x4._id }}&username={{ username }}&page=view&prev=stats">most words available</a>: {{ maxWords4x4.maxWords }}<br/>
<a href="?id={{ low_maxScore4x4._id }}&username={{ username }}&page=view&prev=stats">low possible score</a>: {{ low_maxScore4x4.maxScore }}<br/>
<a href="?id={{ low_maxWords4x4._id }}&username={{ username }}&page=view&prev=stats">least words available</a>: {{ low_maxWords4x4.maxWords }}<br/>
<a href="?id={{ duplicates4x4._id }}&username={{ username }}&page=view&prev=stats">most duplicates</a>: {{ duplicates4x4.duplicates }}<br/>
{% endif %}
{% if hasSel %}
<div class="grayBox">
<h3>Games Selected</h3>
<a href="?id={{ winScoreSel._id }}&username={{ username }}&page=view&prev=stats">high score</a>: {{ winScoreSel.winScore }}<br/>
<a href="?id={{ numWordsPlayersFoundSel._id }}&username={{ username }}&page=view&prev=stats">most words found</a>: {{ numWordsPlayersFoundSel.numWordsPlayersFound }}<br/>
<a href="?id={{ percentFoundSel._id }}&username={{ username }}&page=view&prev=stats">highest % found</a>: {{ ((percentFoundSel.percentFound*100)|round)/100 }}%<br/>
<a href="?id={{ maxScoreSel._id }}&username={{ username }}&page=view&prev=stats">high possible score</a>: {{ maxScoreSel.maxScore }}<br/>
<a href="?id={{ maxWordsSel._id }}&username={{ username }}&page=view&prev=stats">most words available</a>: {{ maxWordsSel.maxWords }}<br/>
<a href="?id={{ low_maxScoreSel._id }}&username={{ username }}&page=view&prev=stats">low possible score</a>: {{ low_maxScoreSel.maxScore }}<br/>
<a href="?id={{ low_maxWordsSel._id }}&username={{ username }}&page=view&prev=stats">least words available</a>: {{ low_maxWordsSel.maxWords }}<br/>
<a href="?id={{ duplicatesSel._id }}&username={{ username }}&page=view&prev=stats">most duplicates</a>: {{ duplicatesSel.duplicates }}<br/>
{% endif %}
{% if hasAll %}
<div class="grayBox">
<h3>All Games</h3>
<a href="?id={{ winScoreAll._id }}&username={{ username }}&page=view&prev=stats">high score</a>: {{ winScoreAll.winScore }}<br/>
<a href="?id={{ numWordsPlayersFoundAll._id }}&username={{ username }}&page=view&prev=stats">most words found</a>: {{ numWordsPlayersFoundAll.numWordsPlayersFound }}<br/>
<a href="?id={{ percentFoundAll._id }}&username={{ username }}&page=view&prev=stats">highest % found</a>: {{ ((percentFoundAll.percentFound*100)|round)/100 }}%<br/>
<a href="?id={{ maxScoreAll._id }}&username={{ username }}&page=view&prev=stats">high possible score</a>: {{ maxScoreAll.maxScore }}<br/>
<a href="?id={{ maxWordsAll._id }}&username={{ username }}&page=view&prev=stats">most words available</a>: {{ maxWordsAll.maxWords }}<br/>
<a href="?id={{ low_maxScoreAll._id }}&username={{ username }}&page=view&prev=stats">low possible score</a>: {{ low_maxScoreAll.maxScore }}<br/>
<a href="?id={{ low_maxWordsAll._id }}&username={{ username }}&page=view&prev=stats">least words available</a>: {{ low_maxWordsAll.maxWords }}<br/>
<a href="?id={{ duplicatesAll._id }}&username={{ username }}&page=view&prev=stats">most duplicates</a>: {{ duplicatesAll.duplicates }}<br/>
{% endif %}
<div class="ct-chart ct-perfect-fourth" id="scoreChart"></div>
<div class="ct-chart ct-perfect-fourth" id="possibleScoreChart"></div>
<div class="ct-chart ct-perfect-fourth" id="wordsFoundChart"></div>
<div class="ct-chart ct-perfect-fourth" id="wordsPossibleChart"></div>
<div class="ct-chart ct-perfect-fourth" id="percentFoundChart"></div>
<div class="ct-chart ct-perfect-fourth" id="duplicatesChart"></div>
<!-- <div class="ct-chart ct-perfect-fourth" id="Chart"></div>
<div class="ct-chart ct-perfect-fourth" id="Chart"></div>
<div class="ct-chart ct-perfect-fourth" id="Chart"></div>
<div class="ct-chart ct-perfect-fourth" id="Chart"></div> -->
<div class="ct-chart ct-perfect-fourth" id="boardSizeChart"></div>
<div class="ct-chart ct-perfect-fourth" id="solveTimeChart"></div>
<!-- <div class="ct-chart ct-perfect-fourth" id="numPlayersChart"></div> -->
<div class="rightCol gamesTable">
<h2>Past Games</h2>
<div class="compactText" style="margin: 10px;">
<form id="selectedForm">
<input type="hidden" name="username" value="{{ username }}"/>
<input type="hidden" name="page" value="stats"/>
<input type="hidden" name="selectedUsed" value="true"/>
<input type="hidden" id="sortCol" name="sortCol" value="{{ sortCol }}"/>
<input type="hidden" id="isAscending" name="isAscending" value="{{ isAscending }}"/>
show sizes:
<input type="checkbox" name="show2x2" {{ show2x2 }}>2x2
<input type="checkbox" name="show3x3" {{ show3x3 }}>3x3
<input type="checkbox" name="show4x4" {{ show4x4 }}>4x4
<input type="checkbox" name="show5x5" {{ show5x5 }}>5x5
<input type="checkbox" name="show6x6" {{ show6x6 }}>6x6
<input type="checkbox" name="show7x7" {{ show7x7 }}>7x7
<input type="checkbox" name="showOtherSizes" {{ showOtherSizes }}>other sizes<br/>
show letters:
<input type="checkbox" name="show2L" {{ show2L }}>2
<input type="checkbox" name="show3L" {{ show3L }}>3
<input type="checkbox" name="show4L" {{ show4L }}>4
<input type="checkbox" name="show5L" {{ show5L }}>5
<input type="checkbox" name="show6L" {{ show6L }}>6
<input type="checkbox" name="show7L" {{ show7L }}>7
<input type="checkbox" name="showOtherL" {{ showOtherL }}>other letters<br/>
show minutes:
<input type="checkbox" name="show30Sec" {{ show30Sec }}>0.5
<input type="checkbox" name="show1Min" {{ show1Min }}>1
<input type="checkbox" name="show2Min" {{ show2Min }}>2
<input type="checkbox" name="show3Min" {{ show3Min }}>3
<input type="checkbox" name="show4Min" {{ show4Min }}>4
<input type="checkbox" name="show5Min" {{ show5Min }}>5
<input type="checkbox" name="show6Min" {{ show6Min }}>6
<input type="checkbox" name="show7Min" {{ show7Min }}>7
<input type="checkbox" name="show8Min" {{ show8Min }}>8
<input type="checkbox" name="show9Min" {{ show9Min }}>9
<input type="checkbox" name="show10Min" {{ show10Min }}>10
<input type="checkbox" name="showOtherMin" {{ showOtherMin }}>other times<br/>
<input class="greenButton" type="submit" value="Apply"/>
<input class="grayButton" type="button" value="Reset" onclick="document.getElementById('resetForm').submit();"/>
select all/none: <input type="checkbox" name="selectAll" {{ selectAll }} onclick="document.querySelectorAll('input[type=checkbox]').forEach((c)=>c.checked = this.checked);"/>
<form id="resetForm">
<input type="hidden" name="username" value="{{ username }}"/>
<input type="hidden" name="page" value="stats"/>
Click on columns headers to sort the table.<br/>
sortCol = {{ sortCol }};
isAscending = "{{ isAscending }}" == "True";
function sortTable(newSortCol, isNumber) {
if (newSortCol == sortCol) {
isAscending = !isAscending;
} else {
sortCol = newSortCol;
isAscending = !isNumber; //numbers default to descending, text defaults to ascending
document.getElementById("sortCol").value = sortCol;
document.getElementById("isAscending").value = isAscending;
<table id="pastGames" class="grayTable">
<th onclick="sortTable(0, true)">Game #</th>
<th onclick="sortTable(1, false)">Host</th>
<th onclick="sortTable(2, true)">Players</th>
<th onclick="sortTable(3, true)">Size</th>
<th onclick="sortTable(4, true)">Letters</th>
<th onclick="sortTable(5, true)">Time (Min)</th>
<th onclick="sortTable(6, true)">Total # of Words</th>
<th onclick="sortTable(7, true)"># of Words Found</th>
<th onclick="sortTable(8, true)">% of Words Found</th>
<th onclick="sortTable(9, true)">Max Score</th>
<th onclick="sortTable(10, true)">Winning Score</th>
<th onclick="sortTable(11, false)">Winners</th>
{% for game in games %}
<td><a href="?id={{ game._id }}&username={{ username }}&page=view&prev=stats">{{ game._id }}</a></td>
<td>{% if game.players|length > 0 %}{{ game.players[0] }}{% endif %}</td>
<td>{{ game.players|length }}</td>
<td>{{ game.size }}x{{ game.size }}</td>
<td>{{ game.letters }}</td>
<td>{{ game.minutes }}</td>
<td>{{ game.maxWords }}</td>
<td>{{ game.numWordsPlayersFound }}</td>
<td>{{ ((game.percentFound*100)|round)/100 }}%</td>
<td>{{ game.maxScore }}</td>
<td>{{ game.winScore }}</td>
<td>{% for winner in %}{{ winner }}{{ ", " if not loop.last }}{% endfor %}</td>
{% endfor %}
<div class="singleCol"></div>
<link rel="stylesheet" href="/static/chartist.min.css">
<script src="/static/chartist.min.js"></script>
<script src="/static/chartist-plugin-axistitle.min.js"></script>
//have to wait for the page to load to access the footer
window.onload = function() {
// hide the footer since it gets in the way
document.getElementsByTagName('footer')[0].style.display = "none";
function settings (xlabel, ylabel) {
return {
chartPadding: {
top: 20,
right: 0,
bottom: 30,
left: 20
axisY: {
onlyInteger: true
plugins: [
axisX: {
axisTitle: xlabel,
axisClass: 'ct-axis-title',
offset: {
x: 0,
y: 50
textAnchor: 'middle'
axisY: {
axisTitle: ylabel,
axisClass: 'ct-axis-title',
offset: {
x: 0,
y: -15
textAnchor: 'middle',
flipTitle: false
{% if hasSel %}
new Chartist.Bar('#scoreChart', {{ winScoreChart|safe }}, settings("winning score", "# of games"));
new Chartist.Bar('#possibleScoreChart', {{ maxScoreChart|safe }}, settings("possible score", "# of games"));
new Chartist.Bar('#wordsFoundChart', {{ maxWordsChart|safe }}, settings("# of words found", "# of games"));
new Chartist.Bar('#wordsPossibleChart', {{ maxWordsChart|safe }}, settings("# of words possible", "# of games"));
new Chartist.Bar('#percentFoundChart', {{ percentFoundChart|safe }}, settings("% of words found", "# of games"));
new Chartist.Bar('#duplicatesChart', {{ duplicatesChart|safe }}, settings("# of duplicate words", "# of games"));
new Chartist.Bar('#boardSizeChart', {{ sizeChart|safe }}, settings("board size", "# of games"));
// new Chartist.Bar('#numPlayersChart', histogram(app., "players".length), settings("# of players", "# of games"));
new Chartist.Bar('#solveTimeChart', {{ secondsToSolveChart|safe }}, settings("computer solve time (sec)", "# of games"));
{% endif %}
{% include 'footer.html' %}