From 697d8b5d0f14793936867911842cb7ad28630941 Mon Sep 17 00:00:00 2001 From: CHIBOUB Chakib Date: Tue, 27 Aug 2024 18:46:56 +0200 Subject: [PATCH] starting the tournament code --- pong/game/consumers.py | 18 +++++++ pong/game/game.py | 25 ++++++---- pong/game/matchmaking.py | 3 -- .../pong/tournament_waiting_room.html | 10 ++++ pong/game/tournament.py | 36 +++++++++++++ pong/static/game.js | 50 +++++++++---------- pong/static/index.html | 4 +- pong/static/styles.css | 19 +++---- requirements.txt | 4 +- 9 files changed, 116 insertions(+), 53 deletions(-) create mode 100644 pong/game/templates/pong/tournament_waiting_room.html create mode 100644 pong/game/tournament.py diff --git a/pong/game/consumers.py b/pong/game/consumers.py index e3d68a1..a5e3853 100644 --- a/pong/game/consumers.py +++ b/pong/game/consumers.py @@ -5,6 +5,7 @@ from channels.generic.websocket import AsyncWebsocketConsumer from django.contrib.auth.models import User from channels.db import database_sync_to_async from .matchmaking import match_maker +from .tournament import tournament_match_maker class GameConsumer(AsyncWebsocketConsumer): async def connect(self): @@ -18,6 +19,8 @@ class GameConsumer(AsyncWebsocketConsumer): await self.authenticate(data['token']) elif data['type'] == 'authenticate2': await self.authenticate2(data['token_1'], data['token_2']) + elif data['type'] == 'authenticate3': + await self.authenticate3(data['token']) elif data['type'] == 'key_press': if self.game: await self.game.handle_key_press(self, data['key']) @@ -74,10 +77,25 @@ class GameConsumer(AsyncWebsocketConsumer): except User.DoesNotExist: return None + async def authenticate3(self, token): + user = await self.get_user_from_token(token) + if user: + self.user = user + await self.send(text_data=json.dumps({'type': 'authenticated'})) + print(f"User {self.user} authenticated") + await self.join_tournament_waiting_room() + else: + await self.send(text_data=json.dumps({'type': 'error', 'message': 'Authentication failed'})) + print("Authentication failed") + + async def join_tournament_waiting_room(self): + await tournament_match_maker.add_player(self) + async def disconnect(self, close_code): if self.game: await self.game.end_game(disconnected_player=self) await match_maker.remove_player(self) + await tournament_match_maker.remove_player(self) print(f"User {self.user.username if hasattr(self, 'user') else 'Unknown'} disconnected") async def set_game(self, game): diff --git a/pong/game/game.py b/pong/game/game.py index 2baeae2..4708878 100644 --- a/pong/game/game.py +++ b/pong/game/game.py @@ -22,7 +22,8 @@ class Game: 'ball_position': {'x': 390, 'y': 190}, 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, 'player1_score': 0, - 'player2_score': 0 + 'player2_score': 0, + 'game_text': '' } else: self.botgame = player2 is None @@ -34,7 +35,8 @@ class Game: 'ball_position': {'x': 390, 'y': 190}, 'ball_velocity': {'x': random.choice([-5, 5]), 'y': random.choice([-5, 5])}, 'player1_score': 0, - 'player2_score': 0 + 'player2_score': 0, + 'game-text': '' } self.speed = 1 self.game_loop_task = None @@ -53,9 +55,13 @@ class Game: async def game_loop(self): print(" In the game loop..") + x = 0 while not self.ended: if self.botgame: - await self.update_bot_position() + x += 1 + if x == 60: + await self.update_bot_position() + x = 0 await self.handle_pad_movement() await self.update_game_state() await self.send_game_state() @@ -66,9 +72,9 @@ class Game: if self.game_state['player2_position'] < target_y < self.game_state['player2_position'] + 80: pass elif self.game_state['player2_position'] < target_y: - self.game_state['player2_position'] = min(self.game_state['player2_position'] + (5 * self.speed), 300) + self.game_state['player2_position'] = min(self.game_state['player2_position'] + (50 * self.speed), 300) elif self.game_state['player2_position'] + 80 > target_y: - self.game_state['player2_position'] = max(self.game_state['player2_position'] - (5 * self.speed), 0) + self.game_state['player2_position'] = max(self.game_state['player2_position'] - (50 * self.speed), 0) async def update_game_state(self): if self.ended: @@ -92,21 +98,18 @@ class Game: self.game_state['ball_velocity']['x'] *= -1 self.bt2 += 1 self.update_ball_velocity() - # Check for scoring - #print(f"########### score user 1 {self.game_state['player1_score']} ###########") - #print(f"§§§§§§§§§§§ score user 2 {self.game_state['player2_score']} §§§§§§§§§§§") - + # Check if some player won the game if self.game_state['ball_position']['x'] <= 10: self.game_state['player2_score'] += 1 if self.game_state['player2_score'] > 2: - print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + self.game_state['game_text'] = f"{self.game_state['player2_name']} WINS!" await self.send_game_state() await self.end_game() self.reset_ball() elif self.game_state['ball_position']['x'] >= 790: self.game_state['player1_score'] += 1 if self.game_state['player1_score'] > 2: - print("Here !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") + self.game_state['game_text'] = f"{self.game_state['player1_name']} WINS!" await self.send_game_state() await self.end_game() self.reset_ball() diff --git a/pong/game/matchmaking.py b/pong/game/matchmaking.py index 9d20580..5ca454c 100644 --- a/pong/game/matchmaking.py +++ b/pong/game/matchmaking.py @@ -110,6 +110,3 @@ 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/templates/pong/tournament_waiting_room.html b/pong/game/templates/pong/tournament_waiting_room.html new file mode 100644 index 0000000..dc09859 --- /dev/null +++ b/pong/game/templates/pong/tournament_waiting_room.html @@ -0,0 +1,10 @@ + +
+

Tournament Waiting Room

+

Players currently waiting: {{ players|length }}

+ +
\ No newline at end of file diff --git a/pong/game/tournament.py b/pong/game/tournament.py new file mode 100644 index 0000000..60dd111 --- /dev/null +++ b/pong/game/tournament.py @@ -0,0 +1,36 @@ +# /pong/game/tournament.py + +import json +from django.template.loader import render_to_string + +class TournamentMatchMaker: + def __init__(self): + self.waiting_players = [] + + async def add_player(self, player): + if player not in self.waiting_players: + self.waiting_players.append(player) + print(f"User {player.user.username} joins the TOURNAMENT WAITING ROOM") + await self.update_waiting_room() + + async def remove_player(self, player): + if player in self.waiting_players: + self.waiting_players.remove(player) + await self.update_waiting_room() + + async def update_waiting_room(self): + html = self.generate_waiting_room_html() + for player in self.waiting_players: + await player.send(json.dumps({ + 'type': 'update_waiting_room', + 'html': html + })) + + def generate_waiting_room_html(self): + context = { + 'players': [player.user.username for player in self.waiting_players] + } + return render_to_string('pong/tournament_waiting_room.html', context) + +# Instance of the class +tournament_match_maker = TournamentMatchMaker() \ No newline at end of file diff --git a/pong/static/game.js b/pong/static/game.js index 1a65cdf..6eb7096 100644 --- a/pong/static/game.js +++ b/pong/static/game.js @@ -28,6 +28,7 @@ document.addEventListener('DOMContentLoaded', () => { const loginButton2 = document.getElementById('login2'); const gameContainer = document.getElementById('game1'); + const tournamentContainer = document.getElementById('tournament-bracket'); const menuButton = document.querySelector('.burger-menu'); const dropdownMenu = document.getElementById('dropdown-menu'); @@ -351,7 +352,12 @@ document.addEventListener('DOMContentLoaded', () => { } function startTournament() { - console.log("For now, do nothing, hurry up and work Senor chaku !!!!") + tournamentContainer.style.display = 'flex'; + logo.style.display = 'none'; + pongElements.style.display = 'none'; + //menuButton.style.display = 'none'; + formBlock.style.display = 'none'; + startWebSocketConnection(token, 42); } function startWebSocketConnection(token, players) { @@ -360,11 +366,14 @@ document.addEventListener('DOMContentLoaded', () => { socket.onopen = function (event) { console.log('WebSocket connection established'); if (players === 1) { - console.log("Sending token for 1 player game"); + console.log("Sending token for a quick match game"); socket.send(JSON.stringify({ type: 'authenticate', token: token })); - } else { - console.log("Sending tokens for 2 player game"); + } else if (players === 2) { + console.log("Sending tokens for a local game"); socket.send(JSON.stringify({ type: 'authenticate2', token_1: token, token_2: token2 })); + } else { + console.log("Sending token for a tournament game") + socket.send(JSON.stringify({ type: 'authenticate3', token: token })); } }; @@ -376,7 +385,7 @@ document.addEventListener('DOMContentLoaded', () => { console.log('Entered the WAITING ROOM'); } else if (data.type === 'game_start') { console.log('Game started:', data.game_id, '(', data.player1, 'vs', data.player2, ')'); - startGame(data.game_id, data.player1, data.player2); + document.addEventListener('keydown', handleKeyDown); } else if (data.type === 'game_state_update') { updateGameState(data.game_state); } else if (data.type === 'player_disconnected') { @@ -385,6 +394,8 @@ document.addEventListener('DOMContentLoaded', () => { console.log("Game ended:", data.game_id); } else if (data.type === 'error') { console.error(data.message); + } else if (data.type === 'update_waiting_room') { + document.getElementById('tournament-bracket').innerHTML = data.html; } else { console.log('Message from server:', data.type, data.message); } @@ -399,14 +410,6 @@ document.addEventListener('DOMContentLoaded', () => { }; } - function startGame(gameCode, player1_name, player2_name) { - document.getElementById('gameCode').textContent = `Game Code: ${gameCode}`; - document.getElementById('player1-name').textContent = `${player1_name}`; - document.getElementById('player2-name').textContent = `${player2_name}`; - document.addEventListener('keydown', handleKeyDown); - - } - function handleKeyDown(event) { if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'w' || event.key === 's') { //console.log('Key press: ', event.key); @@ -427,24 +430,21 @@ document.addEventListener('DOMContentLoaded', () => { } function renderGame() { - const player1Pad = document.getElementById('player1-pad'); - player1Pad.style.top = `${gameState.player1_position}px`; + document.getElementById('player1-name').textContent = `${gameState.player1_name}`; + document.getElementById('player2-name').textContent = `${gameState.player2_name}`; - const player2Pad = document.getElementById('player2-pad'); - player2Pad.style.top = `${gameState.player2_position}px`; + document.getElementById('player1-pad').style.top = `${gameState.player1_position}px`; + document.getElementById('player2-pad').style.top = `${gameState.player2_position}px`; - const ball = document.getElementById('ball'); - ball.style.left = `${gameState.ball_position.x}px`; - ball.style.top = `${gameState.ball_position.y}px`; + document.getElementById('ball').style.left = `${gameState.ball_position.x}px`; + document.getElementById('ball').style.top = `${gameState.ball_position.y}px`; - const player1Score = document.getElementById('player1-score'); - player1Score.textContent = gameState.player1_score; + document.getElementById('player1-score').textContent = gameState.player1_score; + document.getElementById('player2-score').textContent = gameState.player2_score; - const player2Score = document.getElementById('player2-score'); - player2Score.textContent = gameState.player2_score; + document.getElementById('game-text').textContent = gameState.game_text; } - ////////////////////////////// BEG BURGER BUTTON //////////////////////////////// menuButton.addEventListener('click', toggleMenu); diff --git a/pong/static/index.html b/pong/static/index.html index 63f1278..7731712 100644 --- a/pong/static/index.html +++ b/pong/static/index.html @@ -111,8 +111,9 @@ + + diff --git a/pong/static/styles.css b/pong/static/styles.css index 450ac4e..4103df0 100644 --- a/pong/static/styles.css +++ b/pong/static/styles.css @@ -59,20 +59,10 @@ button:hover { align-items: center; } -.game-code { - font-size: 24px; - position: absolute; - top: 10px; -} - -#gameCode { - left: 10px; -} - .name { font-size: 24px; position: absolute; - top: 30px; + top: 20px; } #player1-name { @@ -144,6 +134,13 @@ button:hover { position: absolute; } +#game-text { + font-size: 64px; + color: #00ffff; + position: absolute; + top: 150px; +} + .logo { position: absolute; top: 20px; diff --git a/requirements.txt b/requirements.txt index 3c91bd0..54b2e96 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,8 @@ -Django +django psycopg2 python-dotenv channels daphne djangorestframework web3 -asyncpg +asyncpg \ No newline at end of file