From abf6e6aa0236af4c7f4fa83b76873d77fc833d79 Mon Sep 17 00:00:00 2001 From: Zutatensuppe Date: Tue, 27 Apr 2021 21:43:53 +0200 Subject: [PATCH] add different score modes --- common/GameCommon.js | 39 ++++++++++++++++++++++++++--- common/Util.js | 2 ++ game/index.js | 58 ++++++++++++++++++++++++++++++-------------- game/style.css | 4 +++ server/Game.js | 14 +++++++---- server/index.js | 14 ++++++++--- 6 files changed, 101 insertions(+), 30 deletions(-) diff --git a/common/GameCommon.js b/common/GameCommon.js index 743af69..42d7944 100644 --- a/common/GameCommon.js +++ b/common/GameCommon.js @@ -3,6 +3,9 @@ import Protocol from './Protocol.js' import Time from './Time.js' import Util from './Util.js' +const SCORE_MODE_FINAL = 0 +const SCORE_MODE_ANY = 1 + // Map const GAMES = {} @@ -10,13 +13,14 @@ function exists(gameId) { return (!!GAMES[gameId]) || false } -function __createGameObject(id, rng, puzzle, players, evtInfos) { +function __createGameObject(id, rng, puzzle, players, evtInfos, scoreMode) { return { id: id, rng: rng, puzzle: puzzle, players: players, evtInfos: evtInfos, + scoreMode: scoreMode, } } @@ -34,8 +38,8 @@ function __createPlayerObject(id, ts) { } } -function newGame({id, rng, puzzle, players, evtInfos}) { - const game = __createGameObject(id, rng, puzzle, players, evtInfos) +function newGame({id, rng, puzzle, players, evtInfos, scoreMode}) { + const game = __createGameObject(id, rng, puzzle, players, evtInfos, scoreMode) setGame(id, game) return game } @@ -158,6 +162,10 @@ function setImageUrl(gameId, imageUrl) { GAMES[gameId].puzzle.info.imageUrl = imageUrl } +function getScoreMode(gameId) { + return GAMES[gameId].scoreMode || SCORE_MODE_FINAL +} + function isFinished(gameId) { return getFinishedTileCount(gameId) === getTileCount(gameId) } @@ -654,8 +662,23 @@ function handleInput(gameId, playerId, input, ts) { // Snap the tile to the final destination moveTilesDiff(gameId, tileIdxs, diff) finishTiles(gameId, tileIdxs) - changePlayer(gameId, playerId, { points: getPlayerPoints(gameId, playerId) + tileIdxs.length }) _tileChanges(tileIdxs) + + if (getScoreMode(gameId) === SCORE_MODE_FINAL) { + changePlayer(gameId, playerId, { + points: getPlayerPoints(gameId, playerId) + tileIdxs.length, + }) + _playerChange() + } else if (getScoreMode(gameId) === SCORE_MODE_ANY) { + changePlayer(gameId, playerId, { + points: getPlayerPoints(gameId, playerId) + 1, + }) + _playerChange() + } else { + // no score mode... should never occur, because there is a + // fallback to SCORE_MODE_FINAL in getScoreMode function + } + // check if the puzzle is finished if (getFinishedTileCount(gameId) === getTileCount(gameId)) { changeData(gameId, { finished: ts }) @@ -685,6 +708,12 @@ function handleInput(gameId, playerId, input, ts) { const zIndex = getMaxZIndexByTileIdxs(gameId, tileIdxs) setTilesZIndex(gameId, tileIdxs, zIndex) _tileChanges(tileIdxs) + if (getScoreMode(gameId) === SCORE_MODE_ANY) { + changePlayer(gameId, playerId, { + points: getPlayerPoints(gameId, playerId) + 1, + }) + _playerChange() + } return true } return false @@ -751,4 +780,6 @@ export default { getStartTs, getFinishTs, handleInput, + SCORE_MODE_FINAL, + SCORE_MODE_ANY, } diff --git a/common/Util.js b/common/Util.js index 6a87275..f83404e 100644 --- a/common/Util.js +++ b/common/Util.js @@ -166,6 +166,7 @@ function encodeGame(data) { data.puzzle, data.players, data.evtInfos, + data.scoreMode, ] } @@ -182,6 +183,7 @@ function decodeGame(data) { puzzle: data[3], players: data[4], evtInfos: data[5], + scoreMode: data[6], } } diff --git a/game/index.js b/game/index.js index 5d92d78..5f3ef8c 100644 --- a/game/index.js +++ b/game/index.js @@ -1,3 +1,4 @@ +import GameCommon from '../common/GameCommon.js'; import Time from '../common/Time.js' const Upload = { @@ -105,23 +106,39 @@ export default {

New game

-
- - -
-
- - - - or - - - - - (or select from below) - -
- Start new game + + + + + + + + + + + + + + + + +
+ +
+ +
+ + + or + + + + + (or select from below) + +
+ Start new game +

Image lib

@@ -137,6 +154,7 @@ export default { return { tiles: 1000, image: '', + scoreMode: GameCommon.SCORE_MODE_ANY, } }, methods: { @@ -157,7 +175,11 @@ export default { 'Accept': 'application/json', 'Content-Type': 'application/json' }, - body: JSON.stringify({tiles: this.tiles, image: this.image}), + body: JSON.stringify({ + tiles: this.tiles, + image: this.image, + scoreMode: parseInt(this.scoreMode, 10), + }), }) if (res.status === 200) { const game = await res.json() diff --git a/game/style.css b/game/style.css index 7dfee68..92ac3ce 100644 --- a/game/style.css +++ b/game/style.css @@ -25,6 +25,10 @@ h1, h2, h3, h4 { a { color: var(--link-color); text-decoration: none; } a:hover { color: var(--link-hover-color); } +td, th { + vertical-align: top; +} + .scores { position: absolute; right: 0; diff --git a/server/Game.js b/server/Game.js index df09de3..610fd1e 100644 --- a/server/Game.js +++ b/server/Game.js @@ -48,12 +48,13 @@ function loadGame(gameId) { }, puzzle: game.puzzle, players: game.players, - evtInfos: {} + evtInfos: {}, + scoreMode: game.scoreMode || GameCommon.SCORE_MODE_FINAL, }) } const changedGames = {} -async function createGameObject(gameId, targetTiles, image, ts) { +async function createGameObject(gameId, targetTiles, image, ts, scoreMode) { const seed = Util.hash(gameId + ' ' + ts) const rng = new Rng(seed) return GameCommon.__createGameObject( @@ -64,12 +65,13 @@ async function createGameObject(gameId, targetTiles, image, ts) { }, await createPuzzle(rng, targetTiles, image, ts), [], - {} + {}, + scoreMode ) } -async function createGame(gameId, targetTiles, image, ts) { +async function createGame(gameId, targetTiles, image, ts, scoreMode) { GameLog.create(gameId) - GameLog.log(gameId, Protocol.LOG_HEADER, 1, targetTiles, image, ts) + GameLog.log(gameId, Protocol.LOG_HEADER, 1, targetTiles, image, ts, scoreMode) const seed = Util.hash(gameId + ' ' + ts) const rng = new Rng(seed) @@ -82,6 +84,7 @@ async function createGame(gameId, targetTiles, image, ts) { puzzle: await createPuzzle(rng, targetTiles, image, ts), players: [], evtInfos: {}, + scoreMode, }) changedGames[gameId] = true @@ -130,6 +133,7 @@ function persistGame(gameId) { }, puzzle: game.puzzle, players: game.players, + scoreMode: game.scoreMode, })) log.info(`[INFO] persisted game ${game.id}`) } diff --git a/server/index.js b/server/index.js index 2cb4ba3..ebf174f 100644 --- a/server/index.js +++ b/server/index.js @@ -20,6 +20,7 @@ import { GAME_DIR, TEMPLATE_DIR, } from './Dirs.js' +import GameCommon from '../common/GameCommon.js' const log = logger('index.js') @@ -85,7 +86,13 @@ app.post('/newgame', bodyParser.json(), async (req, res) => { const gameId = Util.uniqId() if (!Game.exists(gameId)) { const ts = Time.timestamp() - await Game.createGame(gameId, req.body.tiles, req.body.image, ts) + await Game.createGame( + gameId, + req.body.tiles, + req.body.image, + ts, + req.body.scoreMode + ) } res.send({ url: `/g/${gameId}` }) }) @@ -151,11 +158,12 @@ wss.on('message', async ({socket, data}) => { throw `[gamelog ${gameId} does not exist... ]` } const log = GameLog.get(gameId) - let game = await Game.createGameObject( + const game = await Game.createGameObject( gameId, log[0][2], log[0][3], - log[0][4] + log[0][4], + log[0][5] || GameCommon.SCORE_MODE_FINAL ) notify( [Protocol.EV_SERVER_INIT_REPLAY, Util.encodeGame(game), log],