diff --git a/.env b/.env index 41d604b..4ecdb09 100644 --- a/.env +++ b/.env @@ -11,5 +11,5 @@ POSTGRES_PASSWORD=qwerty DB_HOST=db DB_PORT=5432 -PROJECT_PATH=/home/mchiboub/42cursus/transcendence/pong -POSTGRES_DATA_PATH=/home/mchiboub/42cursus/transcendence/data/db \ No newline at end of file +PROJECT_PATH=${PWD}/pong +POSTGRES_DATA_PATH=${PWD}/data/db \ No newline at end of file diff --git a/makefile b/makefile index f84c03f..b662bde 100644 --- a/makefile +++ b/makefile @@ -28,6 +28,8 @@ destroy: logs: $(COMPOSE) logs -f $(CONTAINER) +re: destroy up + ps: $(COMPOSE) ps diff --git a/pong/game/game.py b/pong/game/game.py index b1308ad..ea2a5a6 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -5,6 +5,51 @@ import asyncio import random from .utils import endfortheouche +class BotPlayer: + def __init__(self, game_state, speed): + self.game_state = game_state + self.speed = speed + + async def update_bot_position(self): + print("Update bot position started") + try: + target_y = self.predict_ball_position() + #print(f"Target Y: {target_y}") + player2_position = self.game_state['player2_position'] + #print(f"Player2 Position: {player2_position}") + + if player2_position < target_y < player2_position + 80: + print("Bot is already aligned with the ball, no move needed.") + elif player2_position < target_y: + new_position = min(player2_position + (5 * self.speed), 300) + print(f"Moving bot down to {new_position}") + self.game_state['player2_position'] = new_position + elif player2_position + 80 > target_y: + new_position = max(player2_position - (5 * self.speed), 0) + print(f"Moving bot up to {new_position}") + self.game_state['player2_position'] = new_position + + #await asyncio.sleep(1) # Rafraîchir toutes les secondes + except Exception as e: + print(f"Error in BotPlayer.update_bot_position: {e}") + + + def predict_ball_position(self): + # Prédire la future position de la balle en tenant compte de sa vitesse + ball_y = self.game_state['ball_position']['y'] + ball_speed_y = self.game_state['ball_velocity']['y'] + # Prédiction simple, peut être améliorée pour plus de précision + future_ball_y = ball_y + ball_speed_y * 1 # prédire pour la prochaine seconde + + # Gérer les rebonds sur les limites + if future_ball_y < 0: + future_ball_y = -future_ball_y + elif future_ball_y > 300: + future_ball_y = 600 - future_ball_y + + return future_ball_y + + class Game: def __init__(self, game_id, player1, player2): self.game_id = game_id @@ -29,14 +74,21 @@ class Game: self.bt1 = 0 self.bt2 = 0 + if self.botgame: + self.bot_player = BotPlayer(self.game_state, self.speed) + async def start_game(self): print(f"- Game #{self.game_id} STARTED") self.game_loop_task = asyncio.create_task(self.game_loop()) async def game_loop(self): + #print("Here, ok") while True: if self.botgame: + #print('still ok') + #await self.bot_player.update_bot_position() await self.update_bot_position() + #print('is it ok ?? ') await self.handle_pad_movement() self.update_game_state() await self.send_game_state() @@ -114,6 +166,7 @@ class Game: if self.ended: return if player == self.player1: + print(f"Key press: {key}") if key == 'arrowup': self.p1_mov = -1 #self.game_state['player1_position'] = max(self.game_state['player1_position'] - 25, 0) @@ -164,9 +217,9 @@ class Game: await self.player1.send(end_message) if not self.botgame: await self.player2.send(end_message) - #await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], - # self.game_state['player1_score'], self.game_state['player2_score'], - # self.bt1, self.bt2, 42, False, None) + await endfortheouche(self.game_state['player1_name'], self.game_state['player2_name'], + self.game_state['player1_score'], self.game_state['player2_score'], + self.bt1, self.bt2, 42, False, None) ### pour Theo ### # nickname player1 diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index ab6b21e..fe6504c 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -40,7 +40,7 @@ class MatchMaker: await asyncio.sleep(1) self.timer += 1 # Waiting for more than 30s -> BOT game - if self.timer >= 30 and self.waiting_players: + if self.timer >= 3 and self.waiting_players: player1 = self.waiting_players.pop(0) print(f"*** MATCH FOUND: {player1.user.username} vs BOT") self.botgame = True @@ -98,3 +98,6 @@ class MatchMaker: # Instance of the class match_maker = MatchMaker() + +# to get what you want use get_player_p_win(player_name) !! (voir utils.py) +# \ No newline at end of file diff --git a/pong/game/migrations/0001_initial.py b/pong/game/migrations/0001_initial.py index ceac39a..3e3a389 100644 --- a/pong/game/migrations/0001_initial.py +++ b/pong/game/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.0.7 on 2024-07-31 13:42 +# Generated by Django 5.0.7 on 2024-07-31 15:16 import django.db.models.deletion from django.db import migrations, models @@ -24,7 +24,7 @@ class Migration(migrations.Migration): ('m_score_adv_match', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True)), ('best_score', models.PositiveSmallIntegerField(default=0)), ('m_nbr_ball_touch', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True)), - ('total_duration', models.DurationField(blank=True, null=True)), + ('total_duration', models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)), ('m_duration', models.DecimalField(blank=True, decimal_places=2, max_digits=5, null=True)), ('num_participated_tournaments', models.PositiveSmallIntegerField(default=0)), ('num_won_tournaments', models.PositiveSmallIntegerField(default=0)), diff --git a/pong/game/models.py b/pong/game/models.py index a7b3993..a4525b6 100644 --- a/pong/game/models.py +++ b/pong/game/models.py @@ -15,7 +15,7 @@ class Player(models.Model): m_score_adv_match = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True) best_score = models.PositiveSmallIntegerField(default=0) m_nbr_ball_touch = models.DecimalField(max_digits=5, decimal_places=2, null=True, blank=True) - total_duration = models.DurationField(null=True, blank=True) + total_duration = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True) m_duration = 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) diff --git a/pong/game/utils.py b/pong/game/utils.py index 07dc265..e260e81 100644 --- a/pong/game/utils.py +++ b/pong/game/utils.py @@ -9,20 +9,26 @@ async def endfortheouche(p1, p2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_ # Check if player p1 exists, if not create if not await database_sync_to_async(Player.objects.filter(name=p1).exists)(): player_1 = await create_player(p1) + print("############# PLAYER DONE") else: player_1 = await database_sync_to_async(Player.objects.get)(name=p1) # Check if player p2 exists, if not create if not await database_sync_to_async(Player.objects.filter(name=p2).exists)(): player_2 = await create_player(p2) + print("############# PLAYER DONE") else: player_2 = await database_sync_to_async(Player.objects.get)(name=p2) # create Match + print("############# BEFORE MATCH") await create_match(player_1, player_2, s_p1, s_p2, bt_p1, bt_2, dur, is_tournoi, name_tournament) + print("############# AFTER DONE") # Update data p1 et p2 + await uptdate_player_statistics(p1) + print("############# END STAT P1") await uptdate_player_statistics(p2) @database_sync_to_async @@ -92,11 +98,14 @@ def create_match(player1, player2, score_player1, score_player2, nbr_ball_touch_ @database_sync_to_async def uptdate_player_statistics(player_name): + print("############# BEG STAT P") player = get_object_or_404(Player, name=player_name) # Filtrer les matchs où le joueur est joueur 1 ou joueur 2 + print("############# HERE") matches_as_player1 = Match.objects.filter(player1=player) matches_as_player2 = Match.objects.filter(player2=player) + print("############# ACTUALLY, IT'S GOOD") # Calculer les statistiques total_match = matches_as_player1.count() + matches_as_player2.count() @@ -118,9 +127,9 @@ def uptdate_player_statistics(player_name): return 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_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) + won_tourn = Tournoi.objects.filter(winner=player) """ total_score = matches_as_player1.aggregate(Sum('score_player1'))['score_player1__sum'] or 0 total_score += matches_as_player2.aggregate(Sum('score_player2'))['score_player2__sum'] or 0 @@ -138,8 +147,8 @@ def uptdate_player_statistics(player_name): nbr_ball_touch += matches_as_player2.aggregate(Sum('nbr_ball_touch_p2'))['nbr_ball_touch_p2__sum'] or 0 m_nbr_ball_touch = nbr_ball_touch / total_match - total_duration = matches_as_player1.aggregate(Sum('duration'))['duration__sum'] - total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] + total_duration = matches_as_player1.aggregate(Sum('duration'))['duration__sum'] or 0 + total_duration += matches_as_player2.aggregate(Sum('duration'))['duration__sum'] or 0 m_duration = total_duration / total_match """ total_tourn_p = part_tourn_as_p1.count() + part_tourn_as_p2.count() @@ -164,6 +173,13 @@ def uptdate_player_statistics(player_name): player.num_won_tournaments = total_win_tourn """ player.save() + print("CHAKU IS THE BEST") + +def get_player_p_win(player_name): + # Rechercher le joueur par son nom + player = get_object_or_404(Player, name=player_name) + # Retourner la valeur de p_win + return player.p_win """ def complete_match(match_id, score_player1, score_player2, nbr_ball_touch_p1, nbr_ball_touch_p2, duration): diff --git a/pong/static/game.js b/pong/static/game.js index eacd1db..f5b430d 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -204,12 +204,14 @@ document.addEventListener('DOMContentLoaded', () => { function handleKeyDown(event) { if (event.key === 'ArrowUp' || event.key === 'ArrowDown') { + console.log('Key press: ', event.key); sendKeyPress(event.key.toLowerCase()); } } function sendKeyPress(key) { if (socket.readyState === WebSocket.OPEN) { + console.log('Key sent: ', key); socket.send(JSON.stringify({ type: 'key_press', key })); } }