From 704ef006a824ed554fc7f2bd52dbc04fd186dc35 Mon Sep 17 00:00:00 2001 From: simon Date: Sun, 26 Jan 2020 15:51:16 -0500 Subject: [PATCH] restart game & fixes --- app.py | 68 +++++++++++++++++++++++++++++++++++++------------- models.py | 11 ++++++-- static/net.js | 24 +++++++++++++++--- static/room.js | 20 ++++++++++++--- 4 files changed, 97 insertions(+), 26 deletions(-) diff --git a/app.py b/app.py index 5adae5b..589edc0 100644 --- a/app.py +++ b/app.py @@ -7,7 +7,8 @@ from common import config, db from models import BingoGame, GameState, GameMode, User from util import is_valid_id -INVALID_ID_ERR = "Invalid identifier" +ERR_INVALID_ID = "Invalid identifier" +ERR_BAD_REQUEST = "Bad request" app = Flask(__name__) app.config['SECRET_KEY'] = config["FLASK_SECRET"] @@ -39,11 +40,27 @@ class BingoNamespace(Namespace): def __init__(self): super().__init__("/socket") - def on_get_end_message(self): - log("get_end_message", {}) - emit("end_message", { - "text": "Game has ended, replay?" - }) + def on_get_end_message(self, message): + room = message["room"] if "room" in message else None + log("get_end_message", message, room=room) + + if room is None or "oid" not in message: + emit("create_game_rsp", { + "error": ERR_BAD_REQUEST + }) + return + + game = db.get_game(room) + if game.admin == message["oid"]: + emit("end_message", { + "text": "Game has ended, replay?", + "replay": True, + }) + else: + emit("end_message", { + "text": "Waiting for %s to restart game..." % (db.get_user(game.admin).name, ), + "replay": False, + }) def on_cell_click(self, message): room = message["room"] @@ -52,6 +69,9 @@ class BingoNamespace(Namespace): user = db.get_user(message["oid"]) card = db.get_card(message["card"]) cell = card.cells[message["cidx"]] + game = db.get_game(room) + + # if game.mode == GameMode.FREE or game.mode: if not cell.checked or card.last_cell == message["cidx"]: card.check_cell(message["cidx"]) @@ -84,16 +104,16 @@ class BingoNamespace(Namespace): db.save_card(card) db.save_user(user) - emit("card_state", { - "card": card.serialize(), - "parent": user.name - }, room=room) - emit("get_card_rsp", { "card": card.serialize(), "parent": user.name }) + emit("card_state", { + "card": card.serialize(), + "parent": user.name + }, room=room) + for player in game.players: if player != user.oid: other_user = db.get_user(player) @@ -102,21 +122,35 @@ class BingoNamespace(Namespace): emit("card_state", {"card": other_card.serialize(), "parent": other_user.name}) def on_create_game(self, message): - room = message["room"] + room = message["room"] if "room" in message else None log("create_game", message, room) + if "oid" not in message or room is None or "mode" not in message or "pool" not in message: + emit("create_game_rsp", { + "created": False, + "error": ERR_BAD_REQUEST + }) + return + if not is_valid_id(room): emit("create_game_rsp", { "created": False, - "error": INVALID_ID_ERR - }, room=room) + "error": ERR_INVALID_ID + }) return game = db.get_game(room) - if game.state is GameState.CREATING: + if game.state is GameState.CREATING or (game.state is GameState.ENDED and game.admin == message["oid"]): + for oid in game.players: + player = db.get_user(oid) + if room in player.cards: + del player.cards[room] + db.save_user(player) + game.state = GameState.PLAYING game.mode = GameMode[message["mode"]] game.pool = message["pool"] + game.admin = message["oid"] db.save_game(game) emit("game_state", {"state": game.state.name, }, room=room) @@ -129,11 +163,11 @@ class BingoNamespace(Namespace): log("join", message) room = message["room"] - name = message["room"] + name = message["name"] if not is_valid_id(room) or not is_valid_id(name): emit("join_rsp", { - "error": INVALID_ID_ERR + "error": ERR_INVALID_ID }, room=room) return diff --git a/models.py b/models.py index c76407a..f8a80c2 100644 --- a/models.py +++ b/models.py @@ -102,6 +102,8 @@ class BingoCard: class GameMode(Enum): FREE = "free" + ADMIN = "admin" + CPU = "cpu" class GameState(Enum): @@ -124,11 +126,11 @@ class BingoGame: }, "background": 0x282A36, "message": 0xF8F8F2, - "font": "'Roboto Mono', 'Lucida Console'" + "font": "Hack, 'Roboto Mono', 'Lucida Console'" } def __init__(self, room, admin, mode=GameMode.FREE, pool=None, state=GameState.CREATING, - players=None, winners=None, style=None): + players=None, winners=None, style=None, valid_cells=None): self.room = room self.mode = mode self.admin = admin @@ -145,6 +147,9 @@ class BingoGame: if style is None: style = BingoGame._default_style self.style = style + if valid_cells is None: + valid_cells = [] + self.valid_cells = valid_cells def should_end(self): # TODO: add winner count @@ -166,6 +171,7 @@ class BingoGame: "players": list(self.players), "winners": self.winners, "style": self.style, + "valid_cells": self.valid_cells, } @staticmethod @@ -179,6 +185,7 @@ class BingoGame: players=set(j["players"]), winners=j["winners"], style=j["style"], + valid_cells=j["valid_cells"], ) diff --git a/static/net.js b/static/net.js index e96bbe3..24b0e45 100644 --- a/static/net.js +++ b/static/net.js @@ -21,7 +21,11 @@ function initNet() { }) SOCKET.on("end_message", msg => { - alert(msg.text) + if (msg.replay) { + createGameModal(); + } else { + TEXT.text = msg.text; + } }) SOCKET.on("game_state", msg => { @@ -33,7 +37,10 @@ function initNet() { "room": ROOM, }) } else if (msg.state === "ENDED") { - SOCKET.emit("get_end_message") + SOCKET.emit("get_end_message", { + "oid": selfOid(), + "room": ROOM, + }) } }) @@ -53,8 +60,14 @@ function initNet() { SOCKET.on("get_card_rsp", msg => { // Add self card let card = new BingoCard(msg.card.oid, msg.parent); - card._self = msg.card; + + Object.keys(CARDS).forEach(key => { + if (key !== "SELF") { + CARDS[key]._destroy(); + } + }); + CARDS = {}; CARDS[msg.card.oid] = card; CARDS["SELF"] = card; updateCards(); @@ -81,7 +94,10 @@ function initNet() { "room": ROOM, }) } else if (msg.state === "ENDED") { - SOCKET.emit("get_end_message") + SOCKET.emit("get_end_message", { + "oid": selfOid(), + "room": ROOM, + }) } }); diff --git a/static/room.js b/static/room.js index 16d33fa..de07699 100644 --- a/static/room.js +++ b/static/room.js @@ -63,7 +63,7 @@ function onCreateGameSubmit() { "mode": gameMode, "maximum_size": maximumSize, "middle_free": middleFree, - "pool": pool.split(/\s+/).map(w => w.trim()) + "pool": pool.split(/\n+/).map(w => w.trim()) }) return false; } @@ -255,6 +255,20 @@ function BingoCard(oid, parent, small = false) { } } + g._destroy = function () { + let toDestroy = []; + g.children.forEach(child => { + if (child !== this._text) { + toDestroy.push(child); + } + }) + toDestroy.forEach(x => { + x._destroy(); + }) + + g.destroy({texture: true, baseTexture: true, children: true}); + } + return g; } @@ -265,8 +279,7 @@ function makeText() { const t = new PIXI.Text("", { fontFamily: STYLE.font, fontSize: 38, - fill: STYLE.cell.text, - strokeThickness: 2, + fill: STYLE.message, align: "left", breakWords: true, wordWrap: true, @@ -360,6 +373,7 @@ function updateCards() { } window.onresize = function () { + calculateDimensions(); updateCards(); }