add: tictactoe: timers on catchup

This commit is contained in:
Namonay 2024-05-14 16:46:16 +02:00
parent aa01405988
commit 995a808974
5 changed files with 50 additions and 25 deletions

View File

@ -1,4 +1,4 @@
import { client, lang } from "../../../index.js";
import { client, lang, navigateTo } from "../../../index.js";
import { AGame } from "../AGame.js";
@ -50,7 +50,7 @@ class TicTacToe
this.game.finished = false;
if (this.turn)
this.setOutline(4, false);
this.printTimer();
this.printTimer(20);
break;
case 'game_move':
@ -59,7 +59,7 @@ class TicTacToe
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();
this.printTimer(20);
break;
case 'game_end':
@ -68,6 +68,7 @@ class TicTacToe
this.printWin(messageData.winning_sign);
break;
case 'catchup':
this.game.finished = messageData.finished
this.map = messageData.morpion;
for (let i = 0; i < 9; i++)
{
@ -81,6 +82,7 @@ class TicTacToe
this.currentMorpion = messageData.currentMorpion;
if (this.turn)
this.setOutline(this.currentMorpion, false);
this.printTimer(Math.floor(messageData.timer));
}
}
@ -96,10 +98,15 @@ class TicTacToe
this.context.fillText((winning_sign == "o") ? lang.get("morpionWin") + "O" : lang.get("morpionWin") + "X", this.width / 2 - 85, this.height - this.gap / 2 + 10, 180);
}
printTimer()
printTimer(sec)
{
let sec = 20;
let turn = this.turn
let turn = this.turn;
if (sec <= 0)
{
this.game.send(JSON.stringify({"timerIsDue" : this.sign}))
return;
}
if (this.turn)
{
this.context.beginPath();
@ -115,10 +122,10 @@ class TicTacToe
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)
if (sec <= 0 || turn != this.turn || this.game.finished)
{
clearInterval(id);
if (sec == 0 && !this.turn && this.game.finished == false)
if (sec <= 0 && this.game.finished == false)
this.game.send(JSON.stringify({"timerIsDue" : this.sign}))
return;
}
@ -175,7 +182,7 @@ class TicTacToe
{
morpion.setOutline(this.currentMorpion, true);
morpion.sendCase(targetMorpion, targetCase);
morpion.printTimer()
morpion.printTimer(20)
}
else
morpion.incorrectCase();
@ -221,7 +228,7 @@ class TicTacToe
this.context.strokeStyle = "red";
targetX += this.rectsize / 2;
targetY += this.rectsize / 2;
this.context.arc(targetX, targetY, 15, 0, 2 * Math.PI);
this.context.arc(targetX, targetY, this.rectsize / 2 - 7, 0, 2 * Math.PI);
this.context.stroke();
this.context.closePath();
}

View File

@ -86,8 +86,7 @@ export default class extends AbstractView {
games.forEach(game => {
if (game.finished === false)
return
if (this.profile.id === game.winner.id)
if (this.profile.id === game.winner?.id)
win++;
else
lose++;
@ -114,10 +113,16 @@ export default class extends AbstractView {
let game_item = document.createElement("div");
game_item.className = "game-item";
game_item.style.backgroundColor = "grey";
if (game.started)
game_item.style.backgroundColor = "yellow";
if (game.finished)
if (game.finished && game.winner == null)
game_item.style.backgroundColor = "red";
else if (game.finished)
game_item.style.backgroundColor = this.profile.id === game.winner.id ? "green" : "red";
else if (game.started)
game_item.style.backgroundColor = "yellow";
let gametype = document.createElement("b");
gametype.innerText = `${(game.game_type == "tictactoe") ? lang.get("ticTacToeTitle") : "Pong"}`;
game_item.appendChild(gametype);
game.players.forEach(player => {
let player_score = document.createElement("a");
@ -128,7 +133,6 @@ export default class extends AbstractView {
game_item.appendChild(player_score);
});
a.appendChild(game_item);
game_list.appendChild(a);
});

View File

@ -1,12 +1,12 @@
import AbstractView from "./abstracts/AbstractView.js";
import { lang } from "../index.js";
import { TicTacToe } from "../api/game/tictactoe/TicTacToeGame.js"
export class TicTacToeOnlineView extends AbstractView
import AbstractAuthenticatedView from "./abstracts/AbstractAuthenticatedView.js";
import { navigateTo } from "../index.js"
export class TicTacToeOnlineView extends AbstractAuthenticatedView
{
constructor(params, titleKey)
{
super(params, lang.get('ticTacToeTitle'));
super(params, 'ticTacToeTitle');
this.params = params;
this.titleKey = titleKey;
this.game_id = params.id;

View File

@ -5,7 +5,9 @@ from channels.generic.websocket import WebsocketConsumer
from django.contrib.auth.models import User
import json
import sys
from .objects.GameManager import GameManager
from .objects.tictactoe.TicTacToePlayer import TicTacToePlayer
@ -47,7 +49,7 @@ class TicTacToeWebSocket(WebsocketConsumer):
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 an user disconnected and joined back
self.member.send("catchup", {"morpion" : self.game._map, "turn" : self.game.turn, "currentMorpion": self.member.currentMorpion})
self.member.send("catchup", {"morpion" : self.game._map, "turn" : self.game.turn, "currentMorpion": self.member.currentMorpion, "timer" : 20 - (time.time() - self.game.time), "finished" : self.game.model.finished})
return
if (self.game._everbody_is_here() and self.game.model.started == False): # Launch the game if the two players are connected
@ -64,8 +66,10 @@ class TicTacToeWebSocket(WebsocketConsumer):
self.game.broadcast("game_move", data, [self.member])
if (data.get("timerIsDue") is not None and self.game.time + 20 < time.time()): # Frontend asking if the timer is due
self.winner = 'x' if self.game.turn == 'o' else 'o'
self.game.model.finish(self.user)
self.winner = "x" if self.game.turn == "o" else "o"
self.game.get_members()
self.game.model.finish(self.game.get_players_by_sign(self.winner).user)
self.game.broadcast("game_end", {"winning_sign": self.winner})
if (self.game.checkWin() != False): # Check if after a move, the game is finished
@ -77,6 +81,8 @@ class TicTacToeWebSocket(WebsocketConsumer):
def disconnect(self, event):
try:
self.member.socket = None
if (len(self.game.get_players_connected()) == 0):
self.game.model.finish(None)
except:
pass

View File

@ -8,13 +8,15 @@ from .TicTacToeSpectator import TicTacToeSpectator
import time
import sys
class TicTacToeGame(AGame):
def __init__(self, game_id: int, game_manager):
super().__init__("tictactoe", game_id, game_manager)
players: list[int] = self.model.get_players()
players = self.model.get_players()
self.players: list[TicTacToePlayer] = [TicTacToePlayer(player, None, self, ["x", "o"][i]) for i, player in enumerate(players)]
@ -29,6 +31,12 @@ class TicTacToeGame(AGame):
def _everbody_is_here(self):
return len(self.players) == len(self.get_players_connected())
def get_players_by_sign(self, sign):
for player in self.players:
if (player.sign == sign):
return player
return None
def _player_join(self, user_id: int, socket: WebsocketConsumer):
player = self.get_player_by_user_id(user_id)