diff --git a/frontend/static/js/api/game/tictactoe/TicTacToeGame.js b/frontend/static/js/api/game/tictactoe/TicTacToeGame.js index 9312e22..b8a1cc0 100644 --- a/frontend/static/js/api/game/tictactoe/TicTacToeGame.js +++ b/frontend/static/js/api/game/tictactoe/TicTacToeGame.js @@ -37,7 +37,6 @@ class TicTacToe async onReceive(messageData) { - console.log(messageData) switch (messageData.detail) { case 'x': @@ -48,16 +47,20 @@ class TicTacToe case 'game_start': this.game.started = true; + this.game.finished = false; if (this.turn) this.setOutline(4, false); + this.printTimer(); break; case 'game_move': + if (messageData.targetMorpion === undefined || messageData.targetCase === undefined) this.map[messageData.targetMorpion][messageData.targetCase] = (this.sign == "x") ? 1 : 0; this.printSign(messageData.targetMorpion, messageData.targetCase, (this.sign == "x") ? "o" : "x"); this.setOutline(this.currentMorpion, false); + this.printTimer(); break; - + case 'game_end': this.game.finished = true; this.canvas.removeEventListener("mousedown", (event, morpion = this) => this.onClick(event, morpion)); @@ -89,7 +92,37 @@ class TicTacToe this.context.beginPath(); this.context.fillStyle = (winning_sign == "o") ? "red" : "green"; this.context.fillText((winning_sign == "o") ? lang.get("morpionWin") + "O" : lang.get("morpionWin") + "X", this.width / 2 - 30, this.height - this.gap / 2, 140); - this.context.closePath(); + } + + printTimer() + { + let sec = 20; + let turn = this.turn + let id = setInterval(() => + { + this.context.beginPath(); + this.context.fillStyle = "#1a1a1d"; + this.context.fillRect(this.width / 2 - 40, 0, this.width / 2 + 40, this.gap - 10) + this.context.closePath(); + if (sec == 0 || turn != this.turn || this.game.finished) + { + clearInterval(id); + if (sec == 0 && !this.turn && this.game.finished == false) + this.game.send(JSON.stringify({"timerIsDue" : this.sign})) + return; + } + if (this.turn) + { + this.context.beginPath(); + this.context.fillStyle = "white"; + this.context.font = `40px Verdana`; + this.context.fillText(sec, this.width / 2, this.gap / 2); + this.context.font = `inherit`; + this.context.closePath(); + } + sec--; + }, 1000 + ) } checkWin() { @@ -131,6 +164,7 @@ class TicTacToe { morpion.setOutline(this.currentMorpion, true); morpion.sendCase(targetMorpion, targetCase); + morpion.printTimer() } else morpion.incorrectCase(); diff --git a/games/consumers.py b/games/consumers.py index 08ba4d4..bdfc0b3 100644 --- a/games/consumers.py +++ b/games/consumers.py @@ -40,18 +40,19 @@ class TicTacToeWebSocket(WebsocketConsumer): if (self.game is None): return + self.member = self.game.join(self.user.pk, self) - if (isinstance(self.member, TicTacToePlayer)): + if (isinstance(self.member, TicTacToePlayer)): # Send player sign (x or o) to the player self.member.send(self.member.sign) - if (self.game._everbody_is_here() and self.game.model.started == True and self.game.model.finished == False): + if (self.game._everbody_is_here() and self.game.model.started == True and self.game.model.finished == False): # if an user disconnected and joined back self.member.send("catchup", {"morpion" : self.game._map, "turn" : self.game.turn, "currentMorpion": self.member.currentMorpion}) return - if (self.game._everbody_is_here() and self.game.model.started == False): - if (self.game.time != -1): - self.game.broadcast("opponent_joined") + + if (self.game._everbody_is_here() and self.game.model.started == False): # Launch the game if the two players are connected self.game.broadcast("game_start") + self.game.time = time.time() self.game.model.start() def receive(self, text_data=None, bytes_data=None): @@ -60,12 +61,18 @@ class TicTacToeWebSocket(WebsocketConsumer): if (data.get("targetMorpion") is not None and data.get("targetCase") is not None): if (self.game.add(data, self.member) == False): return + + if (data.get("timerIsDue") is not None and self.game.time + 20 < time.time()): + self.winner = 'x' if self.game.turn == 'o' else 'o' + self.game.model.finish(self.user) + self.game.broadcast("game_end", {"winning_sign": self.winner}) + if (self.game.checkWin() != False): self.winner = self.game.checkWin() self.game.model.finish(self.user) self.game.broadcast("game_end", {"winning_sign": self.winner}) + self.game.broadcast("game_move", data, [self.member]) - pass def disconnect(self, event): try: diff --git a/games/objects/tictactoe/TicTacToeGame.py b/games/objects/tictactoe/TicTacToeGame.py index 769d51c..d8ea06b 100644 --- a/games/objects/tictactoe/TicTacToeGame.py +++ b/games/objects/tictactoe/TicTacToeGame.py @@ -47,6 +47,7 @@ class TicTacToeGame(AGame): self._map[newmove.get("targetMorpion")][newmove.get("targetCase")] = newmove.get("sign") player.currentMorpion = int(newmove.get("targetCase")) self.changeTurn() + self.time = time.time() return True return False