';
+}
+
+/**
+ * checks if the puzzle has been solved
+ *
+ * @returns {boolean} true if complete, false if not
+ */
+function checkComplete(){
+ for(let i=1;i<=25;i++){
+ let elem = document.querySelector('#cell-'+i+' input');
+ console.log(elem.value + ' '+possibleDones[currentPuzzle][i-1]);
+ if(parseInt(elem.value) !== possibleDones[currentPuzzle][i-1]) {
+ console.log('not solved');
+ return false;
+ }
+ }
+ console.log('solved');
+ stopTimer();
+ document.getElementById('win').style.display='block';
+ document.getElementById('playAgain').style.display='block';
+
+ const scoreModel = $("#gameScoreFormModal");
+ attachHeading(`Time: ${time} seconds`);
+ //scoreModel.on("hidden.bs.modal", load);
+ attachSubmit({score: time}, () => {
+ scoreModel.modal("hide");
+ });
+ scoreModel.modal("show"); // user jQuery to show the modal
+
+ return true;
+}
+
+let time = 0;
+/**
+ * increases the timer
+ */
+let seconds = setInterval(function(){
+ time += 1;
+
+ let minutes = Math.floor(time/60);
+ let seconds = Math.floor(time%60);
+
+ if(seconds > 9){
+ document.getElementById('timer').innerText = "Time " + minutes + ":" + seconds;
+ }else {
+ document.getElementById('timer').innerText = "Time " + minutes + ":0" + seconds;
+ }
+},1000);
+
+
+/**
+ * stops the timer
+ */
+function stopTimer(){
+ clearTimeout(seconds);
+}
+
+/**
+ * validates keyboard input,
+ * only allows numbers 1-5
+ *
+ * @param {e} the keyboard event
+ */
+function validate(e){
+ var theEvent = e || window.e;
+ // Handle key press
+ var key = theEvent.keyCode || theEvent.which;
+ key = String.fromCharCode(key);
+ var regex = /[1-5]|\./;
+ if( !regex.test(key) ) {
+ theEvent.returnValue = false;
+ if(theEvent.preventDefault) theEvent.preventDefault();
+ }
+}
+
+/**
+ * reloads the page
+ */
+function playAgain(){
+ location.reload();
+}
\ No newline at end of file
diff --git a/public/js/luck/main.js b/public/js/luck/main.js
new file mode 100644
index 00000000..15d1a170
--- /dev/null
+++ b/public/js/luck/main.js
@@ -0,0 +1,153 @@
+const config = {
+ type: Phaser.AUTO,
+ width: 800,
+ height: 600,
+ parent: "game-area",
+ scene: {
+ preload,
+ create,
+ update
+ }
+};
+
+const game = new Phaser.Game(config);
+const mean = Math.pow(2, 12);
+const max = mean * 2;
+const min = 0;
+const stddev = mean / 4;
+const startReadings = 10;
+let readingsLeft = startReadings;
+let totalLuck = 0;
+
+/**
+ * Load game assets.
+ * @author: jk
+ */
+function preload() {
+ // assets from www.flaticon.com
+ this.load.image("potOfGold", "/assets/luck/pot-of-gold.svg");
+}
+
+/**
+ * Create the game objects. The game logic is written here though event callbacks.
+ * @author: jk
+ */
+function create() {
+ const scene = this;
+ const playBtn = scene.add.image(250, 300, "potOfGold").setInteractive();
+ const startText = scene.add.text(226, 330, "Start");
+ const readingsContainer = scene.add.container(5, 5);
+ readingsContainer.add(scene.add.text(0, 0, `Readings Left: ${readingsLeft}`, {fontSize: 28}));
+ readingsContainer.add(scene.add.text(0, 40, `Luck: ${getAvgLuck()}`, {fontSize: 28}));
+ const textContainer = scene.add.container(350, 260);
+ playBtn.setScale(0.2, 0.2);
+ playBtn.on("pointerdown", function (pointer) {
+ this.setTint(0xffff00);
+ });
+ playBtn.on("pointerout", function (pointer) {
+ this.clearTint();
+ });
+ playBtn.on("pointerup", function (pointer) {
+ if (readingsLeft === 0) return;
+ this.clearTint();
+ startText.visible = false;
+ const num = getNumber();
+ const luck = getLuck(num);
+ textContainer.removeAll();
+ textContainer.add(scene.add.text(0, 0, `Your number is ${num.toFixed(0)}!`));
+ textContainer.add(scene.add.text(0, 60, `Your luck is at ${luck.toFixed(3)}%`));
+ readingsLeft--;
+ totalLuck += luck;
+ readingsContainer.removeAll();
+ readingsContainer.add(scene.add.text(0, 0, `Readings Left: ${readingsLeft}`, {fontSize: 28}));
+ readingsContainer.add(scene.add.text(0, 40, `Luck: ${getAvgLuck().toFixed(3)}%`, {fontSize: 28}));
+ if (readingsLeft === 0) {
+ const score = getAvgLuck();
+ const scoreModel = $("#gameScoreFormModal");
+ const resetGame = data => {
+ readingsLeft = startReadings;
+ totalLuck = 0;
+ textContainer.removeAll();
+ readingsContainer.removeAll();
+ readingsContainer.add(scene.add.text(0, 0, `Readings Left: ${readingsLeft}`, {fontSize: 28}));
+ readingsContainer.add(scene.add.text(0, 40, `Luck: ${getAvgLuck()}`, {fontSize: 28}));
+ startText.visible = true;
+ };
+ attachHeading(`Score: ${score.toFixed(3)}%`);
+ scoreModel.on("hidden.bs.modal", resetGame);
+ attachSubmit({score: score}, () => {
+ scoreModel.modal("hide");
+ });
+ scoreModel.modal("show"); // user jQuery to show the modal
+ }
+ });
+}
+
+function update() {
+
+}
+
+/**
+ * Returns a number between min and max following a normal distibution
+ * @author: jk
+ * @returns {Number}
+ */
+function getNumber() {
+ return createMemberInNormalDistribution(mean, stddev);
+}
+
+
+/**
+ * Returns member of set with a given mean and standard deviation
+ * @author: https://stackoverflow.com/a/196941
+ * @param {Number} mean
+ * @param {Number} std_dev
+ * @returns {Number}
+ */
+function createMemberInNormalDistribution(mean, std_dev) {
+ let diff = (gaussRandom() * std_dev);
+ let adj = mean + diff; // adjusted for range
+ if (adj > max) {
+ adj = max;
+ } else if (adj < min) {
+ adj = min;
+ }
+ return adj;
+}
+
+/**
+ * Returns random number in normal distribution centering on 0.
+ * ~95% of numbers returned should fall between -2 and 2
+ * ie within two standard deviations
+ * @author: https://stackoverflow.com/a/196941
+ */
+function gaussRandom() {
+ const u = 2 * Math.random() - 1;
+ const v = 2 * Math.random() - 1;
+ const r = u * u + v * v;
+ /*if outside interval [0,1] start over*/
+ if (r === 0 || r >= 1) return gaussRandom();
+ const c = Math.sqrt(-2 * Math.log(r) / r);
+ return u * c;
+}
+
+/**
+ * Calculate the percentage from the mean linearly.
+ * @param number The number generated.
+ * @returns {number} The luck percentage.
+ */
+function getLuck(number) {
+ return (100 * Math.abs(mean - number) / mean);
+}
+
+/**
+ * Average the luck over the number of readings.
+ * @returns {number} The average Luck percentage.
+ */
+function getAvgLuck() {
+ if (readingsLeft !== startReadings) {
+ return totalLuck / (startReadings - readingsLeft);
+ } else {
+ return 0;
+ }
+}
diff --git a/public/js/rockpaperscissors/rps.js b/public/js/rockpaperscissors/rps.js
new file mode 100644
index 00000000..c17dd054
--- /dev/null
+++ b/public/js/rockpaperscissors/rps.js
@@ -0,0 +1,161 @@
+let wins = 0;
+let round = 1;
+yourOptions = [];
+aiOptions = [];
+
+/**
+ * Fired when the user makes a choice
+ * Decides who won the round and progresses
+ * the game
+ *
+ * @param {option} what the player
+ * chose: rock, paper, or scissors
+ */
+function makeChoice(option){
+ let aiOption = aiChoice();
+ yourOptions.push(option);
+ aiOptions.push(aiOption);
+ let status = '';
+ if(option === 'rock'){
+ if(aiOption === 'rock'){ //tie
+ status = 'tie';
+ }else if(aiOption === 'paper'){ //lose
+ wins--;
+ status = 'lose';
+ }else{ //win
+ wins++;
+ status = 'win';
+ }
+ }else if(option === 'paper'){
+ if(aiOption === 'rock'){ //win
+ wins++;
+ status = 'win';
+ }else if(aiOption === 'paper'){ //tie
+ status = 'tie';
+ }else{ //lose
+ wins--;
+ status = 'lose';
+ }
+ }else{
+ if(aiOption === 'rock'){ //lose
+ wins--;
+ status = 'lose';
+ }else if(aiOption === 'paper'){ //win
+ wins++;
+ status = 'win';
+ }else{ //tie
+ status = 'tie';
+ }
+ }
+ document.getElementById('wins').innerText='Score: '+wins;
+ updateGameArea(option, aiOption, status);
+}
+
+/**
+ * Randomly decides what the AI will choose
+ *
+ * @returns {string} rock paper or scissors
+ */
+function aiChoice(){
+ let choice = Math.floor((Math.random()*3));
+ if(choice === 0){
+ return 'rock';
+ }else if(choice === 1){
+ return 'paper';
+ }else{
+ return 'scissors';
+ }
+}
+
+/**
+ * updates the game area to display who won a round
+ *
+ * @param {option} what you chose to play
+ * @param {aiOption} what the ai chose
+ * @param {status} if you won, lost, or drew the round
+ */
+function updateGameArea(option, aiOption,status){
+ let response = '';
+ if(status === 'win'){
+ response = 'You won!';
+ }else if(status === 'lose'){
+ response = "You lost :'^(";
+ }else{
+ response = "It's a tie!"
+ }
+ document.getElementById('game-area').innerHTML = '
\n' +
+ '
'+response+'
\n' +
+ '
\n' +
+ '
\n' +
+ ' ' +
+ '
VS
'+
+ ' \n' +
+ '
'+
+ ' ';
+
+}
+
+/**
+ * Changes the result back to the choice
+ * Also ends the game if 10 rounds have been played
+ */
+function nextRound(){
+ round++;
+ if(round === 11){
+ finalResults();
+
+ const scoreModel = $("#gameScoreFormModal");
+ attachHeading(`Score: ${wins} wins`);
+ //scoreModel.on("hidden.bs.modal", load);
+ attachSubmit({score: wins}, () => {
+ scoreModel.modal("hide");
+ });
+ scoreModel.modal("show"); // user jQuery to show the modal
+ }else {
+ document.getElementById('rounds').innerText = 'Round: ' + round;
+ document.getElementById('game-area').innerHTML = '
\n' +
+ '
Choose your move!
\n' +
+ '
\n' +
+ '
\n' +
+ ' \n' +
+ ' \n' +
+ ' \n' +
+ '
';
+ }
+}
+
+/**
+ * displays the final results
+ * whether you have won, lost, or drawn
+ * and what each player played.
+ * Also gives the user the option to play again.
+ */
+function finalResults(){
+ let gameArea = document.getElementById('game-area');
+ if(wins === 0){
+ gameArea.innerHTML = '
+
+{{#section 'js'}}
+
+
+{{/section}}
+
+{{#> layouts/modal-layout type="gameScore" title="Submit Score" submitText="Submit" }}
+ {{#*inline "form-content"}}
+ {{> includes/game-submit-default }}
+ {{/inline}}
+{{/layouts/modal-layout}}
+
+
+{{#> layouts/modal-layout type="help" title="Gompei Run Help" }}
+ {{#*inline "form-content"}}
+ {{> includes/help/gompei }}
+ {{/inline}}
+{{/layouts/modal-layout}}
\ No newline at end of file
diff --git a/views/helpers.js b/views/helpers.js
new file mode 100644
index 00000000..8697ee98
--- /dev/null
+++ b/views/helpers.js
@@ -0,0 +1,16 @@
+const helpers = {
+ // allow any section to be defined in hbs using {{{_sections.section_name}}}
+ // this can then be fulfilled using {{#section 'css'}}Section html{{/section}}
+ section: function(name, options) {
+ if (!this._sections) this._sections = {};
+ this._sections[name] = options.fn(this);
+ return null;
+ },
+ // Take in a expression and dont return it as is. Allows have {{ }} in a rendered document without being evaluated
+ noeval: function(expression) {
+ return expression;
+ },
+};
+
+
+module.exports.helpers = helpers;
\ No newline at end of file
diff --git a/views/index.hbs b/views/index.hbs
new file mode 100644
index 00000000..085d39e2
--- /dev/null
+++ b/views/index.hbs
@@ -0,0 +1,21 @@
+
diff --git a/views/partials/includes/auth-sign-in.hbs b/views/partials/includes/auth-sign-in.hbs
new file mode 100644
index 00000000..308c965e
--- /dev/null
+++ b/views/partials/includes/auth-sign-in.hbs
@@ -0,0 +1,9 @@
+
+ Login Failed
+
+
+
+
+
+
+
diff --git a/views/partials/includes/auth-sign-up.hbs b/views/partials/includes/auth-sign-up.hbs
new file mode 100644
index 00000000..33ffbf65
--- /dev/null
+++ b/views/partials/includes/auth-sign-up.hbs
@@ -0,0 +1,13 @@
+
+ Sign Up Failed
+
+
+
+
+
+
+
+
+
+
+
diff --git a/views/partials/includes/game-submit-default.hbs b/views/partials/includes/game-submit-default.hbs
new file mode 100644
index 00000000..cd8f9506
--- /dev/null
+++ b/views/partials/includes/game-submit-default.hbs
@@ -0,0 +1,11 @@
+
+ Submission Failed
+
+
+
+ Score: {{ score }}
+
+
+ Do you wish to submit this score?
+
+
diff --git a/views/partials/includes/help/bdest.hbs b/views/partials/includes/help/bdest.hbs
new file mode 100644
index 00000000..5766c5d6
--- /dev/null
+++ b/views/partials/includes/help/bdest.hbs
@@ -0,0 +1,12 @@
+
+ Brick Destroyer is a game where you destroy bricks with a ball. When the ball
+ reaches the bottom of the screen, a life will be lost. If the number of lives
+ reaches zero the game is over.
+
+
Controls:
+
+
Space: serves the ball and restarts the game
+
Left Arrow Key: moves the paddle left
+
Right Arrow Key: moves the paddle right
+
+
\ No newline at end of file
diff --git a/views/partials/includes/help/ex.hbs b/views/partials/includes/help/ex.hbs
new file mode 100644
index 00000000..7b798875
--- /dev/null
+++ b/views/partials/includes/help/ex.hbs
@@ -0,0 +1 @@
+
You can submit whatever score you want, please be nice
\ No newline at end of file
diff --git a/views/partials/includes/help/flappygoat.hbs b/views/partials/includes/help/flappygoat.hbs
new file mode 100644
index 00000000..e391d9d0
--- /dev/null
+++ b/views/partials/includes/help/flappygoat.hbs
@@ -0,0 +1,4 @@
+
The game works the same way as regular old flappy bird.
+ Press space to initiate the game and also to jump through the pipes.
+ Get the highest score you can!
+
\ No newline at end of file
diff --git a/views/partials/includes/help/gompei.hbs b/views/partials/includes/help/gompei.hbs
new file mode 100644
index 00000000..305f49fa
--- /dev/null
+++ b/views/partials/includes/help/gompei.hbs
@@ -0,0 +1,13 @@
+
+ This game is inspired by the Google Chrome T-Rex game that you
+ can play when your browser cannot connect to the internet.
+ The point of the game is to help Gompei jump over rocks as long
+ you can to get the most points!
+
Controls
+
+
UP -> Jump (you can double jump!)
+
DOWN -> Fall faster when in midair
+
p -> Pause/resume game
+
+ Enjoy!
+
\ No newline at end of file
diff --git a/views/partials/includes/help/index.hbs b/views/partials/includes/help/index.hbs
new file mode 100644
index 00000000..2d9306eb
--- /dev/null
+++ b/views/partials/includes/help/index.hbs
@@ -0,0 +1,6 @@
+
+ Welcome to AJAJA Games!! Click any game you like to start playing.
+ If you hover over the game it will show a brief description.
+ If you wish to submit your scores please sign in.
+ You can make an account with us sign in with Google or GitHub.
+
\ No newline at end of file
diff --git a/views/partials/includes/help/kenken.hbs b/views/partials/includes/help/kenken.hbs
new file mode 100644
index 00000000..d0066b43
--- /dev/null
+++ b/views/partials/includes/help/kenken.hbs
@@ -0,0 +1,7 @@
+
+
The only numbers you may write are 1, 2, 3, 4, or 5.
+
No numbers may appear more than once in any row or column. (That is, all required numbers must appear once in every row and column.)
+
Each "cage" (region bounded by a heavy border) contains a "target number." If there's more than one cell in the cage, the target is also accompanied by an arithmetic operation. You must fill that cage with numbers that produce the target number, using only the specified arithmetic operation. Numbers may be repeated within a cage, if necessary, as long as they do not repeat within a single row or column.
+
In a one-cell cage, just write the target number in that cell.
+
The puzzle is constantly checked, you will be notified
+once the correct board state is filled in.
\ No newline at end of file
diff --git a/views/partials/includes/help/luck.hbs b/views/partials/includes/help/luck.hbs
new file mode 100644
index 00000000..4639a2d2
--- /dev/null
+++ b/views/partials/includes/help/luck.hbs
@@ -0,0 +1,7 @@
+
+ Click on the pot of gold to start the game.
+ Each click will take a reading of your current luck percentage.
+ The game will end after ten readings.
+ After you can submit your score if you wish.
+ And also start a new game.
+
\ No newline at end of file
diff --git a/views/partials/includes/help/rockpaperscissors.hbs b/views/partials/includes/help/rockpaperscissors.hbs
new file mode 100644
index 00000000..15e51f63
--- /dev/null
+++ b/views/partials/includes/help/rockpaperscissors.hbs
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/views/partials/includes/help/sudoku.hbs b/views/partials/includes/help/sudoku.hbs
new file mode 100644
index 00000000..0fca401c
--- /dev/null
+++ b/views/partials/includes/help/sudoku.hbs
@@ -0,0 +1,5 @@
+
+ Sudoku is a number placing puzzle based on a 9x9 grid with several given numbers. The object is to place the numbers 1 to 9 in the empty squares so that each row, each column and each 3x3 box contains the same number only once.
+
The puzzle is constantly checked, you will be notified
+ once the correct board state is filled in.
+
\ No newline at end of file
diff --git a/views/partials/includes/help/tower-defence.hbs b/views/partials/includes/help/tower-defence.hbs
new file mode 100644
index 00000000..57ef7870
--- /dev/null
+++ b/views/partials/includes/help/tower-defence.hbs
@@ -0,0 +1,5 @@
+
+ Use the Sandbag, Machine Gun and Cannon towers to thwart the invading army. Dont let them reach the base!
+ Each tower costs money. You can earn money by destroying the enemy.
+ You can pause by pressing P.
+
\ No newline at end of file
diff --git a/views/partials/includes/help/user.hbs b/views/partials/includes/help/user.hbs
new file mode 100644
index 00000000..4a287ee7
--- /dev/null
+++ b/views/partials/includes/help/user.hbs
@@ -0,0 +1,4 @@
+
+ This page has information about a specific user.
+ If you would like to get info about a user simply click on their name.
+
\ No newline at end of file
diff --git a/views/partials/includes/nav-bar.hbs b/views/partials/includes/nav-bar.hbs
new file mode 100644
index 00000000..f1b3f6e1
--- /dev/null
+++ b/views/partials/includes/nav-bar.hbs
@@ -0,0 +1,41 @@
+{{!-- TODO: fix problem with realy thin windows and scrolling right --}}
+
diff --git a/views/partials/includes/scores-body-global.hbs b/views/partials/includes/scores-body-global.hbs
new file mode 100644
index 00000000..d14569a0
--- /dev/null
+++ b/views/partials/includes/scores-body-global.hbs
@@ -0,0 +1,7 @@
+
+
+ {{#noeval "{{#each scoresData as |score|}}"}}{{/noeval}}
+
\ No newline at end of file
diff --git a/views/partials/includes/scores-body-user.hbs b/views/partials/includes/scores-body-user.hbs
new file mode 100644
index 00000000..49907185
--- /dev/null
+++ b/views/partials/includes/scores-body-user.hbs
@@ -0,0 +1,7 @@
+
+
+ {{#noeval "{{#each scoresData as |score|}}"}}{{/noeval}}
+
\ No newline at end of file
diff --git a/views/partials/includes/scores.hbs b/views/partials/includes/scores.hbs
new file mode 100644
index 00000000..c9c9a859
--- /dev/null
+++ b/views/partials/includes/scores.hbs
@@ -0,0 +1,54 @@
+
+ {{#each this.scoresGameDropdownData as |game|}}
+
+ {{/each}}
+
+
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/partials/layouts/modal-layout.hbs b/views/partials/layouts/modal-layout.hbs
new file mode 100644
index 00000000..e54691b9
--- /dev/null
+++ b/views/partials/layouts/modal-layout.hbs
@@ -0,0 +1,32 @@
+
+
+
+
+
{{ title }}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/views/rockpaperscissors.hbs b/views/rockpaperscissors.hbs
new file mode 100644
index 00000000..27c2f352
--- /dev/null
+++ b/views/rockpaperscissors.hbs
@@ -0,0 +1,67 @@
+
The only numbers you may write are 1, 2, 3, 4, or 5.
+
No numbers may appear more than once in any row or column. (That is, all required numbers must appear once in every row and column.)
+
Each "cage" (region bounded by a heavy border) contains a "target number." If there's more than one cell in the cage, the target is also accompanied by an arithmetic operation. You must fill that cage with numbers that produce the target number, using only the specified arithmetic operation. Numbers may be repeated within a cage, if necessary, as long as they do not repeat within a single row or column.
+
In a one-cell cage, just write the target number in that cell.
+
The puzzle is constantly checked, you will be notified
+ once the correct board state is filled in.
+
+