diff --git a/pong/game/game.py b/pong/game/game.py index 48d3d8b..b5f86fc 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -9,8 +9,6 @@ from asgiref.sync import sync_to_async from .models import Tournoi from concurrent.futures import ThreadPoolExecutor -executor = ThreadPoolExecutor(max_workers=5) -lock = asyncio.Lock() class Game: # Global variable to handle the using of the database USING_DB = False @@ -59,14 +57,18 @@ class Game: async def start_game(self): print(f"- Game #{self.game_id} STARTED ({self.game_state['player1_name']} vs {self.game_state['player2_name']}) --- ({self})") + + await sync_to_async(create_player)(self.game_state['player1_name'], self.game_state['player2_name']) + self.game_loop_task = asyncio.create_task(self.game_loop()) print(f" Begin MATCH at: {self.start_time}") - await sync_to_async(create_player)(self.game_state['player1_name'], self.game_state['player2_name']) + async def game_loop(self): print(" In the game loop..") x = 59 while not self.ended: + print(f" ended : {self.ended}") if self.botgame: x += 1 if x == 60: @@ -80,6 +82,33 @@ class Game: await self.update_game_state() await self.send_game_state() await asyncio.sleep(1/60) # Around 60 FPS + if self.ended: + print(f" IN WHILE EXIT ???????? ended : {self.ended}") + print("IN WHILE here !!!!!") + try: + await self.save_match() + print("IN WHILE end here !!!!") + except Exception as e: + print(f"Erreur lors de l'appel de save_match: {e}") + print(f" OUT WHILE EXIT ???????? ended : {self.ended}") + if self.ended : + print(" OUT WHILE here !!!!!") + try: + #await self.save_match() + print("OUT WHILE end here !!!!") + except Exception as e: + print(f"Erreur lors de l'appel de save_match: {e}") + + async def save_match(self) : + avd, d = (True, self.tournament.tournoi_reg) if hasattr(self, 'tournament') else (False, None) + end_time = datetime.now() + duration = (end_time - self.start_time).total_seconds() / 60 + print("CALL IN SYNC") + await sync_to_async(create_match, thread_sensitive=True)(self.game_state['player1_name'], self.game_state['player2_name'], + self.game_state['player1_score'], self.game_state['player2_score'], + self.bt1, self.bt2, duration, avd, d + ) + async def update_bot_position(self): #future_ball_position = self.predict_ball_trajectory() @@ -143,7 +172,7 @@ class Game: if self.game_state['player2_score'] > 2: self.game_state['game_text'] = f"{self.game_state['player2_name']} WINS!" await self.send_game_state() - await self.end_game() + await self.end_game(self) #printf("player2 wins") self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: @@ -151,7 +180,7 @@ class Game: if self.game_state['player1_score'] > 2: self.game_state['game_text'] = f"{self.game_state['player1_name']} WINS!" await self.send_game_state() - await self.end_game() + await self.end_game(self) #printf("player1 wins") self.reset_ball() @@ -222,18 +251,16 @@ class Game: elif self.p2_mov == 1: self.game_state['player2_position'] = min(self.game_state['player2_position'] + (5 * self.speed), 300) + async def end_game(self, disconnected_player=None): if not self.ended: - self.ended = True - if self.game_loop_task: - self.game_loop_task.cancel() + self.ended = True print(f"- Game #{self.game_id} ENDED --- ({self})") - end_time = datetime.now() - duration = (end_time - self.start_time).total_seconds() / 60 + #await sync_to_async(save_match)() # Notify that one player left the game - if disconnected_player: + """ if disconnected_player: printf("Disconnected player") remaining_player = self.player2 if disconnected_player == self.player1 else self.player1 disconnected_name = disconnected_player.user.username @@ -249,27 +276,30 @@ class Game: 'type': 'game_ended', 'game_id': self.game_id }) + await self.player1.send(end_message) if not self.botgame: if not self.localgame: - await self.player2.send(end_message) + await self.player2.send(end_message) """ print(f"Try to save game #{self.game_id} ({self})") - avd, d = (True, self.tournament.tournoi_reg) if hasattr(self, 'tournament') else (False, None) + #avd, d = (True, self.tournament.tournoi_reg) if hasattr(self, 'tournament') else (False, None) # Essaye d'appeler handle_game_data print("TRY CREATE MATCH") - - await sync_to_async(create_match)( - self.game_state['player1_name'], self.game_state['player2_name'], - self.game_state['player1_score'], self.game_state['player2_score'], - self.bt1, self.bt2, duration, avd, d - ) + #await sync_to_async(create_match)( + # self.game_state['player1_name'], self.game_state['player2_name'], + # self.game_state['player1_score'], self.game_state['player2_score'], + # self.bt1, self.bt2, duration, avd, d + #) print("MATCH OK") + #if self.game_loop_task: + # self.game_loop_task.cancel() + \ No newline at end of file diff --git a/pong/game/migrations/0003_alter_tournoi_winner.py b/pong/game/migrations/0003_alter_tournoi_winner.py new file mode 100644 index 0000000..c3879b0 --- /dev/null +++ b/pong/game/migrations/0003_alter_tournoi_winner.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.1 on 2024-09-14 11:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('game', '0002_alter_match_player1_alter_match_player2_and_more'), + ] + + operations = [ + migrations.AlterField( + model_name='tournoi', + name='winner', + field=models.CharField(max_length=200), + ), + ] diff --git a/pong/game/migrations/0004_alter_tournoi_winner.py b/pong/game/migrations/0004_alter_tournoi_winner.py new file mode 100644 index 0000000..f8caa6a --- /dev/null +++ b/pong/game/migrations/0004_alter_tournoi_winner.py @@ -0,0 +1,18 @@ +# Generated by Django 5.1.1 on 2024-09-14 12:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('game', '0003_alter_tournoi_winner'), + ] + + operations = [ + migrations.AlterField( + model_name='tournoi', + name='winner', + field=models.CharField(blank=True, max_length=200, null=True), + ), + ] diff --git a/pong/game/migrations/0005_remove_player_num_won_tournaments.py b/pong/game/migrations/0005_remove_player_num_won_tournaments.py new file mode 100644 index 0000000..de94bab --- /dev/null +++ b/pong/game/migrations/0005_remove_player_num_won_tournaments.py @@ -0,0 +1,17 @@ +# Generated by Django 5.1.1 on 2024-09-14 12:41 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('game', '0004_alter_tournoi_winner'), + ] + + operations = [ + migrations.RemoveField( + model_name='player', + name='num_won_tournaments', + ), + ] diff --git a/pong/game/models.py b/pong/game/models.py index b24134f..8125baa 100644 --- a/pong/game/models.py +++ b/pong/game/models.py @@ -11,7 +11,6 @@ class Player(models.Model): total_win = models.PositiveSmallIntegerField(default=0) p_win = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True) num_participated_tournaments = models.PositiveSmallIntegerField(default=0) - num_won_tournaments = models.PositiveSmallIntegerField(default=0) def __str__(self): return self.name @@ -20,7 +19,7 @@ class Tournoi(models.Model): name = models.CharField(max_length=200) nbr_player = models.PositiveSmallIntegerField() date = models.DateField(auto_now_add=True) - winner = models.ForeignKey('Player', on_delete=models.SET_NULL, null=True) + winner = models.CharField(max_length=200, null=True, blank=True) def __str__(self): return self.name @@ -38,18 +37,5 @@ class Match(models.Model): is_tournoi = models.BooleanField() tournoi = models.ForeignKey('Tournoi', related_name='matches', on_delete=models.SET_NULL, null=True) - def clean(self): - if self.score_player1 < 0 or self.score_player2 < 0: - raise ValidationError('Les scores doivent être positifs.') - if self.score_player1 > self.score_player2 and self.winner != self.player1: - raise ValidationError('Le gagnant ne correspond pas aux scores.') - if self.score_player2 > self.score_player1 and self.winner != self.player2: - raise ValidationError('Le gagnant ne correspond pas aux scores.') - super().clean() - - def save(self, *args, **kwargs): - self.clean() - super().save(*args, **kwargs) - def __str__(self): - return f"{self.player1.name} vs {self.player2.name}" \ No newline at end of file + return f"{self.player1} vs {self.player2}" \ No newline at end of file diff --git a/pong/game/utils.py b/pong/game/utils.py index 7cb85c3..e07a20f 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -8,6 +8,7 @@ from django.db.models import Q import asyncio players_name_list = [] +tournament_participations = {} def handle_game_data(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament): try: @@ -45,8 +46,7 @@ def create_player(name_p1, name_p2): total_match = 0, total_win = 0, p_win = 0, - num_participated_tournaments = 0, - num_won_tournaments = 0) + num_participated_tournaments = 0) player1.save() players_name_list.append(name_p1) print(f"Player {name_p1} creation done") @@ -60,8 +60,7 @@ def create_player(name_p1, name_p2): total_match = 0, total_win = 0, p_win = 0, - num_participated_tournaments = 0, - num_won_tournaments = 0) + num_participated_tournaments = 0) player2.save() players_name_list.append(name_p2) print(f"Player {name_p2} creation done") @@ -69,12 +68,6 @@ def create_player(name_p1, name_p2): #return player - -def create_tournoi(name, nbr_player, date, winner): - tournoi = Tournoi(name=name, nbr_player=nbr_player, date=date, winner=winner) - tournoi.save() - return tournoi - def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration, is_tournoi, tournoi): print("MATCH BEING REGISTERD") match = Match( @@ -100,57 +93,35 @@ def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_ print("MATCH SAVE IN DB") match.save() print("MATCH DONE") - #update_player_statistics(player1) - #update_player_statistics(player2) - #print("STAT DONE") + update_player_statistics(player1, match.winner, is_tournoi, tournoi) + print("STAT P1 DONE") + update_player_statistics(player2, match.winner, is_tournoi, tournoi) + print("STAT P2 DONE") + +def update_player_statistics(player_name, winner, is_tournoi, tournoi): -def update_player_statistics(player_name): print("UPDATED DATA") + global tournament_participations + print("GET PLAYER") player = get_object_or_404(Player, name=player_name) - - - matches = Match.objects.filter(Q(player1=player) | Q(player2=player)) - - total_match = matches.count() - - - # avoid dividing by 0 - if total_match == 0: - player.total_match = total_match - player.total_win = 0 - player.p_win = 0 - player.num_participated_tournaments = 0 - player.num_won_tournaments = 0 - player.save() - return - - nb_win =0 - - for match in matches : - if match.winner == player: - nb_win = nb_win + 1 - - - #won_matches = Match.objects.filter(winner=player) - #part_tourn_as_p1 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player1=player) - #part_tourn_as_p2 = Tournoi.objects.filter(matches__is_tournoi=True, matches__matches_as_player2=player) - #won_tourn = Tournoi.objects.filter(winner=player) - - - #total_win = won_matches.count() - - - p_win = (nb_win/ total_match) * 100 - - #total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() - #total_win_tourn = won_tourn.count() - #p_win_tourn = (total_win_tourn / total_tourn_p) * 100 if total_tourn_p else 0 + print("PLAYER FIND") - player.total_match = total_match - player.total_win = total_win - player.p_win = p_win - # player.num_participated_tournaments = total_tourn_p - #player.num_won_tournaments = total_win_tourn + player.total_match += 1 + if winner == player.name : + player.total_win += 1 + + if player.total_match > 0: + player.p_win = player.total_win / player.total_match + + if is_tournoi: + if tournoi.name not in tournament_participations: + tournament_participations[tournoi] = [] + + if player_name not in tournament_participations[tournoi]: + tournament_participations[tournoi].append(player.name) + player.num_participated_tournaments += 1 + + player.save() @@ -160,19 +131,19 @@ def get_player_p_win(player_name): def create_tournament(name, nbr_player): print("tournoi created!!!") - tournoi=Tournoi(name=name, nbr_player=nbr_player, winner=None) + tournoi=Tournoi(name=name, nbr_player=nbr_player, winner="No one yet ...") tournoi.save() print(f"tournoi name : {tournoi.name} *******!*!*!*!**!*!**!*!*!*!*!*!*!*!*!*") return tournoi def update_tournament(name_tournoi, winner_name): tournoi = get_object_or_404(Tournoi, name=name_tournoi) - winner_p = get_object_or_404(Player, name=winner_name) + print(f"in update tourna - tournoi name : {tournoi.name} *******!*!*!*!**!*!**!*!*!*!*!*!*!*!*!*") - print(f"in update tourna - winner is : {winner_p.name} *******!*!*!*!**!*!**!*!*!*!*!*!*!*!*!*") + - tournoi.winner = winner_p - print(f"in update tourna - TOURNOI winner is : {tournoi.winner.name} *******!*!*!*!**!*!**!*!*!*!*!*!*!*!*!*") + tournoi.winner = winner_name + print(f"in update tourna - TOURNOI winner is : {tournoi.winner} *******!*!*!*!**!*!**!*!*!*!*!*!*!*!*!*") tournoi.save() diff --git a/pong/game/views.py b/pong/game/views.py index b76deb1..cee736d 100644 --- a/pong/game/views.py +++ b/pong/game/views.py @@ -3,7 +3,6 @@ from django.shortcuts import render from django.core.exceptions import ObjectDoesNotExist from .models import Player, Tournoi, Match -from .utils import create_tournoi, create_match from django.http import JsonResponse from django.contrib.auth.models import User from django.contrib.auth import authenticate @@ -84,7 +83,7 @@ def player_list_json(request): data = { 'players': list(players.values( 'id', 'name', 'total_match', 'total_win', 'p_win', - 'num_participated_tournaments', 'num_won_tournaments' + 'num_participated_tournaments' )) } return JsonResponse(data) @@ -95,14 +94,11 @@ def get_tournoi_data(tournoi): "name": tournoi.name, "nbr_player": tournoi.nbr_player, "date": tournoi.date, - "winner": { - "id": tournoi.winner.id, - "name": tournoi.winner.name - } if tournoi.winner else None + "winner": tournoi.winner } def tournoi_list_json(request): - tournois = Tournoi.objects.select_related('winner').all() # Charge les données du gagnant + tournois = Tournoi.objects.all() # Charge les données du gagnant tournois_data = [get_tournoi_data(tournoi) for tournoi in tournois] return JsonResponse({"tournois": tournois_data}) diff --git a/pong/static/burger.js b/pong/static/burger.js index 44b9099..1b61877 100644 --- a/pong/static/burger.js +++ b/pong/static/burger.js @@ -147,7 +147,6 @@ document.addEventListener('DOMContentLoaded', () => { ${player.total_win} ${player.p_win} ${player.num_participated_tournaments} - ${player.num_won_tournaments} `; playersListBody.appendChild(row); }); @@ -173,7 +172,7 @@ document.addEventListener('DOMContentLoaded', () => { ${tournoi.name} ${tournoi.nbr_player} ${tournoi.date} - ${tournoi.winner ? tournoi.winner.name : 'No one yet ...'} + ${tournoi.winner} `; tournoisListBody.appendChild(row); });