Compare commits

..

No commits in common. "2ee13bb022244cbbdc4a5c98985e4545935f85f0" and "0fed261ac4336d3405569540d4f7d98d38dc5103" have entirely different histories.

10 changed files with 40 additions and 283 deletions

View File

@ -4,12 +4,6 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--
SVG Icons by FontAwesome, no changes have been made to the icons used (bomb, flag)
Licence: https://fontawesome.com/license
-->
<title>Minesweeper 99</title>
</head>
@ -44,6 +38,7 @@
<span>-/-</span>
</div>
</div>
<hr>
</div>
<div id="register">
@ -52,21 +47,12 @@
<label for="username">Username:</label><br>
<input type="text" name="username" placeholder="Username" required="true"><br><br>
<label for="opponents">Number of players:</label><br>
<input type="number" min="2" max="16" name="opponents" value="2"><br>
<label for="opponents">Number of opponents:</label><br>
<input type="number" min="2" max="16" name="opponents" value="2"><br><br>
<h3>Rooms available:</h3>
<span id="query">
<!-- Query output will be pushed here -->
</span>
<br>
<label for="store">Save this username:</label>
<label for="store">Use these settings this session:</label>
<input type="checkbox" name="store"><br>
<label for="session">Use these settings this session:</label>
<input type="checkbox" name="session"><br>
<label for="session" style="color: red">These features use cookies.</label><br><br>
<label for="store" style="color: tomato">This feature uses cookies.</label><br><br>
<button type="submit">Submit</button>
</form>
@ -77,10 +63,6 @@
<div>
<!-- Game log will be pushed here -->
</div>
<div>
<button id="restart" disabled>Restart</button>
<!-- <button>Toggle dark mode</button> -->
</div>
</div>
</div>
</div>
@ -88,7 +70,7 @@
<script src="/main.js"></script>
<footer>
> Coded by <a href="//arnweb.nl" target="new">McArn</a>. (v1.0.7)<br>
> Coded by <a href="//arnweb.nl" target="new">McArn</a>.<br>
> Found bugs? <a href="//arnweb.nl/contact/">Contact me</a>
</footer>

13
package-lock.json generated
View File

@ -511,14 +511,6 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.11.0.tgz",
"integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA=="
},
"axios": {
"version": "0.21.0",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz",
"integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==",
"requires": {
"follow-redirects": "^1.10.0"
}
},
"babel-runtime": {
"version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
@ -5144,11 +5136,6 @@
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
},
"striptags": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/striptags/-/striptags-3.1.1.tgz",
"integrity": "sha1-yMPn/db7S7OjKjt1LltePjgJPr0="
},
"style-loader": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/style-loader/-/style-loader-2.0.0.tgz",

View File

@ -16,7 +16,6 @@
"license": "GPL-3.0-or-later",
"dependencies": {
"@fortawesome/fontawesome-free": "^5.15.1",
"axios": "^0.21.0",
"cookie-storage": "^6.1.0",
"css-loader": "^5.0.1",
"eslint": "^7.12.1",
@ -26,7 +25,6 @@
"sass": "^1.29.0",
"sass-loader": "^10.0.5",
"socket.io-client": "^3.0.0",
"striptags": "^3.1.1",
"style-loader": "^2.0.0",
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="bomb" class="svg-inline--fa fa-bomb fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M440.5 88.5l-52 52L415 167c9.4 9.4 9.4 24.6 0 33.9l-17.4 17.4c11.8 26.1 18.4 55.1 18.4 85.6 0 114.9-93.1 208-208 208S0 418.9 0 304 93.1 96 208 96c30.5 0 59.5 6.6 85.6 18.4L311 97c9.4-9.4 24.6-9.4 33.9 0l26.5 26.5 52-52 17.1 17zM500 60h-24c-6.6 0-12 5.4-12 12s5.4 12 12 12h24c6.6 0 12-5.4 12-12s-5.4-12-12-12zM440 0c-6.6 0-12 5.4-12 12v24c0 6.6 5.4 12 12 12s12-5.4 12-12V12c0-6.6-5.4-12-12-12zm33.9 55l17-17c4.7-4.7 4.7-12.3 0-17-4.7-4.7-12.3-4.7-17 0l-17 17c-4.7 4.7-4.7 12.3 0 17 4.8 4.7 12.4 4.7 17 0zm-67.8 0c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17zm67.8 34c-4.7-4.7-12.3-4.7-17 0-4.7 4.7-4.7 12.3 0 17l17 17c4.7 4.7 12.3 4.7 17 0 4.7-4.7 4.7-12.3 0-17l-17-17zM112 272c0-35.3 28.7-64 64-64 8.8 0 16-7.2 16-16s-7.2-16-16-16c-52.9 0-96 43.1-96 96 0 8.8 7.2 16 16 16s16-7.2 16-16z"></path></svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1 +0,0 @@
<svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="flag" class="svg-inline--fa fa-flag fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M349.565 98.783C295.978 98.783 251.721 64 184.348 64c-24.955 0-47.309 4.384-68.045 12.013a55.947 55.947 0 0 0 3.586-23.562C118.117 24.015 94.806 1.206 66.338.048 34.345-1.254 8 24.296 8 56c0 19.026 9.497 35.825 24 45.945V488c0 13.255 10.745 24 24 24h16c13.255 0 24-10.745 24-24v-94.4c28.311-12.064 63.582-22.122 114.435-22.122 53.588 0 97.844 34.783 165.217 34.783 48.169 0 86.667-16.294 122.505-40.858C506.84 359.452 512 349.571 512 339.045v-243.1c0-23.393-24.269-38.87-45.485-29.016-34.338 15.948-76.454 31.854-116.95 31.854z"></path></svg>

Before

Width:  |  Height:  |  Size: 755 B

View File

@ -22,14 +22,6 @@ body {
h1 {
text-align: center;
img {
fill: white;
filter: invert(1);
height: 1em;
padding-right: 0.3em;
margin-bottom: -0.15em;
}
}
h4.subheader {
@ -49,10 +41,6 @@ body {
column-gap: 1em;
margin: 0 auto;
h2 {
margin-top: 0;
}
div {
padding: 1em;
margin-bottom: 1em;
@ -78,26 +66,16 @@ body {
background-color: #303030;
font-size: large;
img {
fill: white;
filter: invert(1);
height: 1em;
}
&.discovered {
background-color: #424242;
}
&.bomb {
background-color: #e85354;
}
&.added {
background-color: #e89759;
background-color: #FC5130;
}
&.flag {
background-color: #4be3e3;
background-color: #51CB20;
}
}
}
@ -143,19 +121,11 @@ body {
&#register {
display: none;
span#query {
height: 6rem;
display: block;
overflow: auto;
}
}
&#log {
display: none;
font-size: 12px;
position: relative;
min-height: 24rem;
div {
max-height: calc(14 * 1.25rem);
@ -180,12 +150,6 @@ body {
}
}
}
div:nth-of-type(2) {
position: absolute;
bottom: 0;
min-width: unset;
}
}
}
}

View File

@ -3,19 +3,11 @@ import io from "socket.io-client";
import {
CookieStorage
} from "cookie-storage";
import striptags from "striptags";
import axios from "axios";
import log from "./log.js";
import math from "../utilities/math.js";
const cookie = new CookieStorage();
// http://localhost:3000
// http://localhost:2428/tanks
const APIUrl = "https://api.arnweb.nl/tanks";
const GameID = "ms99";
class Multiplayer {
constructor(game) {
// Keep local and external players
@ -23,26 +15,20 @@ class Multiplayer {
this.connected = false;
this.game = game;
this.lastPlaying;
this.game.addListener("sendBomb", () => {
this.sendBomb.call(this);
});
this.game.addListener("cleared", () => {
this.cleared.call(this);
});
this.game.addListener("gameOver", () => {
this.gameOver.call(this);
});
log("Game instance initialized");
var username = cookie.getItem(`${GameID}_user`);
var opponents = sessionStorage.getItem(`${GameID}_settings`);
var username = cookie.getItem("ms99_user");
var opponents = sessionStorage.getItem("ms99_settings");
if (username != null && opponents != null) {
log(`Using previous username ${username} and settings, close this session to reset this.`, "alert");
log(`Using previous username ${username}, delete cookies for this site to reset.`, "alert");
this.connect(username, opponents);
} else {
this.register(username);
@ -55,7 +41,7 @@ class Multiplayer {
// Connect to TanksJS-Server instance
log("Connecting to server...");
this.socket = io(APIUrl, {
this.socket = io("http://localhost:3000/", {
reconnection: false
});
@ -67,7 +53,7 @@ class Multiplayer {
this.socket.emit("identification", {
name: username,
playersMax: opponents,
gameID: GameID
gameID: "ms99"
});
log(`Connected to server as ${username}`, "success");
this.connected = true;
@ -91,56 +77,35 @@ class Multiplayer {
if (data[id] == undefined) {
log(`${this.players[id].username} has left.`, "alert");
delete this.players[id];
if (Object.keys(this.players).length == 0 && this.game.active) {
if (Object.keys(this.players).length == 0) {
log("No other players left", "alert");
this.game.gameOver(true);
this.game.gameOver();
}
}
}
this.opponents = opponents;
this.game.drawStats({
current: Object.keys(this.players).length,
current: Object.keys(this.players).length + 1,
max: opponents
});
});
// Handle player updates
this.socket.on("update", (data) => {
if (data.player.cleared) {
this.game.gameOver();
}
if (data.player.target) {
if (data.player.target.id == this.socket.id) {
this.game.addBomb();
}
} else {
if (!data.player.active) {
log(`${this.players[data.uuid].username} has died`);
if (Object.keys(this.players).length == 1) {
this.lastPlaying = this.players[Object.keys(this.players)[0]];
}
log(`${this.players[data.uuid].username} had died`);
delete this.players[data.uuid];
if (Object.keys(this.players).length == 0) {
if (this.game.active) {
log("No other players left", "alert");
this.game.gameOver(true);
} else {
log(`${this.lastPlaying.username} won`);
this.game.gameOver();
}
}
}
}
this.game.drawStats({
current: Object.keys(this.players).length,
max: opponents
});
});
// Start game
@ -154,84 +119,18 @@ class Multiplayer {
var form = document.querySelectorAll("div#register > form")[0];
form.parentElement.style.display = "block";
axios.get(APIUrl).then((res) => {
var output = document.getElementById("query");
if (res.status == 200) {
var result = res.data.players;
var span = document.createElement("span");
if (Object.keys(result).length == 0) {
span.style.color = "orange";
span.innerHTML = "No players are online :(";
output.appendChild(span);
} else {
var rooms = [];
var counts = {};
for (var player in result) {
var room = result[player].room.split("_");
if (room[0] == GameID) {
rooms.push(room[1]);
}
}
for (var i = 0; i < rooms.length; i++) {
var num = rooms[i];
counts[num] = counts[num] ? counts[num] + 1 : 1;
}
for (const size in counts) {
span.innerHTML += String(`${counts[size]} player(s) in groups of ${size}.<br>`);
}
output.appendChild(span);
}
} else {
span.style.color = "red";
span.innerHTML = "Server is offline!";
output.appendChild(span);
form.querySelector("button").disabled = true;
}
});
var checks = {
session: form.querySelector("input[name=session]"),
store: form.querySelector("input[name=store]"),
};
form.querySelector("input[name=username]").value = username;
if (username != "") {
checks.store.checked = true;
}
checks.session.addEventListener("change", function () {
if (this.checked) {
checks.store.checked = true;
}
});
checks.store.addEventListener("change", function () {
if (!this.checked) {
checks.session.checked = false;
}
});
form.addEventListener("submit", (e) => {
e.preventDefault();
form.parentElement.style.display = "none";
var username = String(striptags(form.querySelector("input[name=username]").value));
var username = String(form.querySelector("input[name=username]").value);
var opponents = form.querySelector("input[name=opponents]").value;
if (form.querySelector("input[name=store]").checked) {
cookie.setItem(`${GameID}_user`, username);
cookie.setItem("ms99_user", username);
sessionStorage.setItem("ms99_settings", opponents);
}
if (form.querySelector("input[name=session]").checked) {
cookie.setItem(`${GameID}_user`, username);
sessionStorage.setItem(`${GameID}_settings`, opponents);
}
this.connect(username, opponents);
});
}
@ -251,28 +150,10 @@ class Multiplayer {
});
}
cleared() {
this.socket.emit("update", {
cleared: true
});
}
gameOver() {
this.socket.emit("update", {
active: this.game.active
});
this.game.drawStats({
current: Object.keys(this.players).length,
max: this.opponents
});
var button = document.getElementById("restart");
button.disabled = false;
button.addEventListener("click", (e) => {
this.socket.disconnect();
window.location.reload();
});
}
}

View File

@ -1,10 +1,11 @@
/* eslint-disable no-unused-vars */
import "../scss/index.scss";
import bomb from "../res/svg/bomb-solid.svg";
// import "../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
import Game from "./screens/game.js";
import Multiplayer from "./helpers/multiplayer.js";
["DOMContentLoaded", "resize"].forEach(evt =>
window.addEventListener(evt, (e) => {
var main = document.getElementById("main");
@ -20,15 +21,7 @@ import Multiplayer from "./helpers/multiplayer.js";
})
);
var img = document.createElement("img");
img.src = bomb;
document.querySelector("body > h1").prepend(img);
var board = document.getElementById("board");
board.addEventListener("contextmenu", (e) => {
e.preventDefault();
});
var game = new Game(board);
var mp = new Multiplayer(game);

View File

@ -4,9 +4,6 @@ import {
EventEmitter
} from "events";
import bomb from "../../res/svg/bomb-solid.svg";
import flag from "../../res/svg/flag-solid.svg";
class Game extends EventEmitter {
constructor(element) {
super();
@ -31,13 +28,11 @@ class Game extends EventEmitter {
this.board.style.gridTemplateColumns = `repeat(${this.sides}, auto)`;
this.generated = false;
this.bombAmount = 50;
this.bombAmount = 60;
this.bombs = [];
this.added = [];
this.discovered = [];
this.time = 60;
this.penalty = 20;
for (let cell = 0; cell < this.size; cell++) {
this.bombs.push(0);
@ -57,6 +52,7 @@ class Game extends EventEmitter {
this.board.appendChild(child);
}
console.log(this.bombs);
}
update() {
@ -97,9 +93,6 @@ class Game extends EventEmitter {
if (players != undefined) {
var playersStats = document.getElementById("players").children[1];
if (this.active || !this.generated) {
players.current++;
}
playersStats.innerHTML = String(players.current + "/" + players.max);
}
}
@ -168,7 +161,7 @@ class Game extends EventEmitter {
let index = 0;
while (index < this.bombAmount) {
var rand = math.rand(0, this.size);
if (rand != cell && !this.bombs[rand] && this.surrounds(cell).indexOf(rand) == -1) {
if (rand != cell && !this.bombs[rand]) {
this.bombs[rand] = 1;
index++;
}
@ -176,14 +169,14 @@ class Game extends EventEmitter {
}
if (this.active && !this.discovered[cell]) {
this.discovered[cell] = 1;
this.children[cell].classList.add("discovered");
if (this.bombs[cell]) {
this.gameOver();
return;
}
this.discovered[cell] = 1;
this.children[cell].classList.add("discovered");
var surrounds = this.surrounds(cell);
var value = 0;
@ -213,12 +206,8 @@ class Game extends EventEmitter {
if (this.bombs[cell]) {
if (!this.discovered[cell]) {
this.discovered[cell] = 1;
var img = document.createElement("img");
img.src = flag;
this.children[cell].appendChild(img);
this.children[cell].innerHTML = "#";
this.children[cell].classList.add("flag");
this.bombAmount--;
this.emit("sendBomb");
@ -228,12 +217,12 @@ class Game extends EventEmitter {
if (this.bombAmount == 0) {
log("You have cleared all bombs!", "success");
this.emit("cleared");
this.active = false;
}
}
} else {
if (!this.discovered[cell]) {
this.time = this.time - this.penalty;
this.time = this.time - 30;
this.drawStats();
this.discover(cell);
@ -243,38 +232,20 @@ class Game extends EventEmitter {
}
addBomb() {
for (let tries = 0; tries < 10; tries++) {
var sum = 0;
var cell = math.rand(0, this.bombs.length);
// var sum = this.surrounds(cell).reduce((a, b) => {
// console.log(this.discovered[a]);
// return this.discovered[a] + this.discovered[b];
// }, 0);
this.surrounds(cell).forEach((e) => {
sum = sum + this.discovered[e];
});
if (sum == 0 && !this.bombs[cell] && !this.discovered[cell]) {
for (let tries = 0; tries < 10; tries++) {
var sum = this.surrounds(cell).reduce((a, b) => this.discovered[a] + this.discovered[b], 0);
if (sum == 0) {
this.bombs[cell] = 1;
this.bombAmount++;
this.added.push(cell);
// this.children[cell].style.background = "#0000ff";
log("A bomb has been added to your field!", "alert");
return;
}
}
}
gameOver(win = false) {
gameOver() {
log("Game over", "error");
if (win) {
log("Congratulations, you win!", "success");
}
this.active = false;
this.drawStats();
@ -282,15 +253,8 @@ class Game extends EventEmitter {
for (let index = 0; index < this.size; index++) {
if (this.bombs[index]) {
if (!this.discovered[index]) {
var img = document.createElement("img");
img.src = bomb;
this.children[index].appendChild(img);
this.children[index].innerHTML = "[]";
this.children[index].classList.add("bomb");
if (this.added.indexOf(index) != -1) {
this.children[index].classList.add("added");
}
}
}
}
}

View File

@ -18,7 +18,7 @@ module.exports = {
],
},
{
test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [{
loader: "file-loader",
options: {
@ -26,16 +26,6 @@ module.exports = {
outputPath: "res/fonts/"
}
}]
},
{
test: /\.(svg)$/,
use: [{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "res/svg/"
}
}]
}
]
}