Moved files from private to public repo for first release
This commit is contained in:
@ -1,2 +1,6 @@
|
|||||||
# arvutus2-public
|
# arvutus2-public
|
||||||
Public repository for arvutus2
|
Public repository for arvutus2
|
||||||
|
|
||||||
|
# INSTALLATION
|
||||||
|
1. Install dependencies: Run npm install in the directory
|
||||||
|
2. Run it via node main.js
|
80
client/arvutus.html
Normal file
80
client/arvutus.html
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>arvutust - Math</title>
|
||||||
|
<style>
|
||||||
|
body { margin: 0; padding-bottom: 3rem; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
|
||||||
|
|
||||||
|
#form { background: rgba(0, 0, 0, 0.15); padding: 0.25rem; position: fixed; bottom: 0; left: 0; right: 0; display: flex; height: 3rem; box-sizing: border-box; backdrop-filter: blur(10px); }
|
||||||
|
#input { border: none; padding: 0 1rem; flex-grow: 1; border-radius: 2rem; margin: 0.25rem; }
|
||||||
|
#input:focus { outline: none; }
|
||||||
|
#form > button { background: #333; border: none; padding: 0 1rem; margin: 0.25rem; border-radius: 3px; outline: none; color: #fff; }
|
||||||
|
|
||||||
|
#messages { list-style-type: none; margin: 0; padding: 0; }
|
||||||
|
#messages > li { padding: 0.5rem 1rem; }
|
||||||
|
#messages > li:nth-child(odd) { background: #efefef; }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul id="messages"></ul>
|
||||||
|
<form id="form" action="">
|
||||||
|
<input id="input" autocomplete="off" /><button id="sendButton">Send</button><button id="endButton">Home</button>
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
|
<script>
|
||||||
|
var socket = io();
|
||||||
|
|
||||||
|
var messages = document.getElementById('messages');
|
||||||
|
var form = document.getElementById('form');
|
||||||
|
var input = document.getElementById('input');
|
||||||
|
var endButton = document.getElementById('endButton');
|
||||||
|
|
||||||
|
form.addEventListener('submit', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (input.value) {
|
||||||
|
socket.emit('answer', input.value);
|
||||||
|
input.value = '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
endButton.addEventListener('click', function(e) {
|
||||||
|
window.location = '/choice';
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('calculation', function(msg) {
|
||||||
|
var item = document.createElement('li');
|
||||||
|
item.textContent = msg.firstNumber + msg.calculationType + msg.secondNumber;
|
||||||
|
messages.appendChild(item);
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('answerCheck', function(msg) {
|
||||||
|
var item = document.createElement('li');
|
||||||
|
item.textContent = msg.answerType;
|
||||||
|
messages.appendChild(item);
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('errorResponse', function(msg) {
|
||||||
|
var item = document.createElement('li');
|
||||||
|
item.textContent = msg.errorMsg;
|
||||||
|
messages.appendChild(item);
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('gameEndMessage', function(msg) {
|
||||||
|
var item = document.createElement('li');
|
||||||
|
item.textContent = "Game over! You earned " + msg.points + " points and got to level " + msg.currentLevel + "!";
|
||||||
|
messages.appendChild(item);
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('godModeData', function(msg) {
|
||||||
|
var answer = msg.correctAnswerValue;
|
||||||
|
console.log(answer);
|
||||||
|
messages.append(answer);
|
||||||
|
window.scrollTo(0, document.body.scrollHeight);
|
||||||
|
});
|
||||||
|
</script>
|
29
client/choice.html
Normal file
29
client/choice.html
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ARVUTUS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<input type="button" onClick="liitmine()" id="liitmine" value="Liitmine"></input>
|
||||||
|
<input type="button" onClick="lahutamine()" id="liitmine" value="Lahutamine"></input>
|
||||||
|
<input type="button" onClick="logout()" id="logout" value="Logout"></input>
|
||||||
|
<!--<input type="button" onClick="korrutamine()" id="liitmine" value="Korrutamine"></input>
|
||||||
|
<input type="button" onClick="jagamine()" id="liitmine" value="Jagamine"></input>-->
|
||||||
|
</body>
|
||||||
|
<script src="/socket.io/socket.io.js"></script>
|
||||||
|
<script>
|
||||||
|
function liitmine() {
|
||||||
|
window.location = '/liitmine';
|
||||||
|
}
|
||||||
|
function lahutamine() {
|
||||||
|
window.location = '/lahutamine';
|
||||||
|
}
|
||||||
|
function korrutamine() {
|
||||||
|
window.location = '/korrutamine';
|
||||||
|
}
|
||||||
|
function jagamine() {
|
||||||
|
window.location = '/jagamine';
|
||||||
|
}
|
||||||
|
function logout() {
|
||||||
|
window.location = '/';
|
||||||
|
}
|
||||||
|
</script>
|
13
client/index.html
Normal file
13
client/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>ARVUTUS</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<input type="button" onClick="start()" id="start" value="START"></input>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
<script>
|
||||||
|
function start() {
|
||||||
|
window.location = "/choice";
|
||||||
|
}
|
||||||
|
</script>
|
195
main.js
Normal file
195
main.js
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
let firstNumber;
|
||||||
|
let secondNumber;
|
||||||
|
let correctAnswerValue;
|
||||||
|
let responseMessage;
|
||||||
|
let secondMaxTotal;
|
||||||
|
let operator = "+";
|
||||||
|
let maxTotal = 10;
|
||||||
|
let pointLimitPercentage = 0.8;
|
||||||
|
let points = 0;
|
||||||
|
let currentLevel = 1;
|
||||||
|
//Interval's
|
||||||
|
let levelInterval = 40000;
|
||||||
|
let gameEndTimer = 240000;
|
||||||
|
let gameRunning = 0;
|
||||||
|
//IntervalID
|
||||||
|
let setLevelInterval;
|
||||||
|
let stopGameTimeout;
|
||||||
|
//Server config
|
||||||
|
let serverPort = 3000;
|
||||||
|
let debugMode = 0; //1 for enabled 0 for disabled
|
||||||
|
let answerMode = 0; //1 for enabled 0 for disabled (shows the correct answer always)
|
||||||
|
let godMode = 0; //1 for enabled 0 for disabled (shows the correct answer in the web interface)
|
||||||
|
let showClientAnswer = 0 //1 for enabled 0 for disabled (show the answer that the client sent back)
|
||||||
|
const express = require('express');
|
||||||
|
const { fstat } = require('fs');
|
||||||
|
const app = express();
|
||||||
|
const http = require('http');
|
||||||
|
const server = http.createServer(app);
|
||||||
|
const { Server } = require("socket.io");
|
||||||
|
const io = new Server(server);
|
||||||
|
|
||||||
|
app.get('/', (req, res) => {
|
||||||
|
//index.html
|
||||||
|
res.sendFile(__dirname + '/client/index.html');
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/choice', (req, res) => {
|
||||||
|
gameRunning = 0;
|
||||||
|
res.sendFile(__dirname + '/client/choice.html');
|
||||||
|
stopGame();
|
||||||
|
clearUserData();
|
||||||
|
})
|
||||||
|
|
||||||
|
app.get('/liitmine', (req, res) => {
|
||||||
|
//Set correctAnswerValue to use the correct operator and send to arvutus.html
|
||||||
|
operator = "+";
|
||||||
|
res.sendFile(__dirname + '/client/arvutus.html');
|
||||||
|
gameRunning = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/lahutamine', (req, res) => {
|
||||||
|
//Set correctAnswerValue to use the correct operator and send to arvutus.html
|
||||||
|
operator = "-";
|
||||||
|
res.sendFile(__dirname + '/client/arvutus.html');
|
||||||
|
gameRunning = 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(serverPort, () => {
|
||||||
|
console.log('Server started on port', serverPort);
|
||||||
|
});
|
||||||
|
|
||||||
|
io.on('connection', (socket) => {
|
||||||
|
|
||||||
|
//Only start math if user is on the correct page (gameRunning = 1)
|
||||||
|
console.log("Connection made");
|
||||||
|
if (gameRunning == 1) {
|
||||||
|
if (debugMode == 1) {console.log("gameset to 1");};
|
||||||
|
getNewCalculation();
|
||||||
|
io.emit('calculation', { firstNumber: firstNumber, secondNumber: secondNumber, calculationType: operator});
|
||||||
|
if (godMode == 1) { io.emit('godModeData', correctAnswerValue); };
|
||||||
|
if (debugMode == 1) {console.log(socket.id);};
|
||||||
|
//Answers the answer for the calculation
|
||||||
|
socket.on('answer', (msg) => {
|
||||||
|
if (showClientAnswer == 1) {
|
||||||
|
console.log(msg);
|
||||||
|
}
|
||||||
|
if (msg == correctAnswerValue) {
|
||||||
|
calculatePoints(true);
|
||||||
|
responseMessage = "Correct answer! You currently have " + points + " points. Current level: " + currentLevel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
calculatePoints(false);
|
||||||
|
responseMessage = "Incorrect answer! You currently have " + points + " points. Current level: " + currentLevel;
|
||||||
|
}
|
||||||
|
io.emit('answerCheck', { answerType: responseMessage});
|
||||||
|
getNewCalculation();
|
||||||
|
io.emit('calculation', { firstNumber: firstNumber, secondNumber: secondNumber, calculationType: operator});
|
||||||
|
});
|
||||||
|
setLevelInterval = setInterval(setLevel, levelInterval);
|
||||||
|
stopGameTimeout = setTimeout(stopGame, gameEndTimer);
|
||||||
|
if (debugMode == 1) {console.log("timeout and interval set");};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getNewCalculation() {
|
||||||
|
//Generates correct answer with the correct operator
|
||||||
|
if (operator == "+") {
|
||||||
|
if (currentLevel == 1 || currentLevel == 2) {
|
||||||
|
firstNumber = Math.floor(Math.random() * maxTotal);
|
||||||
|
secondMaxTotal = maxTotal - firstNumber;
|
||||||
|
secondNumber = Math.floor(Math.random() * secondMaxTotal);
|
||||||
|
if (secondNumber < (firstNumber / 2)) {console.info("secondnumber smaller than firstnumber div 2")}
|
||||||
|
}
|
||||||
|
//Needed for eliminating the calculations from the previous levels
|
||||||
|
else if (currentLevel > 2) {
|
||||||
|
firstNumber = Math.floor(Math.random() * (maxTotal - (maxTotal * 0.1)) + (maxTotal * 0.1));
|
||||||
|
secondMaxTotal = maxTotal - firstNumber;
|
||||||
|
secondNumber = Math.floor(Math.random() * (secondMaxTotal - (secondMaxTotal * 0.5)) + (secondMaxTotal * 0.2));
|
||||||
|
if (secondNumber < (firstNumber / 2)) {console.info("secondnumber smaller than firstnumber div 2")}
|
||||||
|
} //TODO: fix secondMaxRandom being too low (777 - 23)
|
||||||
|
correctAnswerValue = firstNumber + secondNumber;
|
||||||
|
if (answerMode == 1) {console.log(correctAnswerValue);};
|
||||||
|
}
|
||||||
|
else if (operator == "-") {
|
||||||
|
if (currentLevel == 1 || currentLevel == 2) {
|
||||||
|
firstNumber = Math.floor(Math.random() * maxTotal);
|
||||||
|
secondNumber = Math.floor(Math.random() * firstNumber);
|
||||||
|
}
|
||||||
|
//Needed for eliminating the calculations from the previous levels
|
||||||
|
else if (currentLevel > 2) {
|
||||||
|
firstNumber = Math.floor(Math.random() * (maxTotal - (maxTotal * 0.1)) + (maxTotal * 0.1));
|
||||||
|
secondNumber = Math.floor(Math.random() * (firstNumber - (maxTotal * 0.1)) + (maxTotal * 0.1));
|
||||||
|
}
|
||||||
|
correctAnswerValue = firstNumber - secondNumber;
|
||||||
|
if (answerMode == 1) {console.log(correctAnswerValue);};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculatePoints(correct) {
|
||||||
|
//Calculate points (correct = true means that answer was correct and vice versa)
|
||||||
|
if (correct == true) {
|
||||||
|
if (firstNumber <= maxTotal * 0.1 || secondNumber <= maxTotal * 0.1 ) {
|
||||||
|
points += 2;
|
||||||
|
}
|
||||||
|
else if (correctAnswerValue <= maxTotal * pointLimitPercentage) {
|
||||||
|
points += 4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
points += 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
points -= 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendErrorInfo(data) {
|
||||||
|
//Unused (Error messages)
|
||||||
|
io.emit('errorResponse', "ERROR: ", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLevel() {
|
||||||
|
//Constantly updates/sets level
|
||||||
|
currentLevel += 1;
|
||||||
|
switch (currentLevel) {
|
||||||
|
case 2:
|
||||||
|
maxTotal = 20;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
maxTotal = 100;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
maxTotal = 1000;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
maxTotal = 10000;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
maxTotal = 100000;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
maxTotal = 10;
|
||||||
|
currentLevel = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopGame() {
|
||||||
|
//Ends/Stops the game
|
||||||
|
gameRunning = 0;
|
||||||
|
clearInterval(setLevelInterval);
|
||||||
|
setLevelInterval = 0;
|
||||||
|
clearTimeout(stopGameTimeout)
|
||||||
|
stopGameTimeout = 0;
|
||||||
|
console.log("Cleared timeout and interval data.");
|
||||||
|
io.emit('gameEndMessage', { points: points, currentLevel: currentLevel });
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearUserData() {
|
||||||
|
//Used to clear user data variables
|
||||||
|
points = 0;
|
||||||
|
currentLevel = 1;
|
||||||
|
gameRunning = 0;
|
||||||
|
setLevelInterval = 0;
|
||||||
|
}
|
1387
package-lock.json
generated
Normal file
1387
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
package.json
Normal file
16
package.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "arvutus",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"init": "node main.js"
|
||||||
|
},
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.18.2",
|
||||||
|
"socket.io": "^4.5.1"
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user