/
ledart
/
RRP_LedNik
Обзор
Документация
Войти
/
ledart
/
RRP_LedNik
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
server/GameSession.java
268 строк
9 KB
Darya
обновлены комментарии
18 дек 2025, 14:46
18 дек 2025, 14:46
95c0a7f
Код
Авторство
О чём код?
package server; import java.util.*; import java.util.concurrent.ConcurrentHashMap; public class GameSession extends Thread { private final Room room; private static final int WIDTH = 20; private static final int HEIGHT = 20; private static final int TICK_MS = 300; private final Map<String, LinkedList<int[]>> snakes = new ConcurrentHashMap<>(); private final Map<String, int[]> directions = new ConcurrentHashMap<>(); private final Map<String, Integer> scores = new ConcurrentHashMap<>(); public volatile boolean running = true; public GameSession(Room room) { this.room = room; initSnakes(); sendGameState(); System.out.println("[GameSession] Created for room: " + room.getName()); } private void initSnakes() { Random rnd = new Random(); for (ClientHandler player : room.getPlayers()) { String username = player.getUsername(); LinkedList<int[]> snake = new LinkedList<>(); int x = 5 + rnd.nextInt(WIDTH - 10); int y = 5 + rnd.nextInt(HEIGHT - 10); snake.add(new int[]{x, y}); snake.add(new int[]{x, y + 1}); snake.add(new int[]{x, y + 2}); snakes.put(username, snake); directions.put(username, new int[]{0, -1}); scores.put(username, 0); System.out.println("[GameSession] Created snake for: " + username + " at " + x + "," + y); } if (room.hasBot()) { Bot bot = room.getBot(); LinkedList<int[]> botSnake = new LinkedList<>(); int x = 5 + rnd.nextInt(WIDTH - 10); int y = 5 + rnd.nextInt(HEIGHT - 10); botSnake.add(new int[]{x, y}); botSnake.add(new int[]{x, y + 1}); botSnake.add(new int[]{x, y + 2}); snakes.put(bot.getName(), botSnake); directions.put(bot.getName(), new int[]{0, -1}); scores.put(bot.getName(), 0); System.out.println("[GameSession] Created snake for bot: " + bot.getName()); } } @Override public void run() { System.out.println("[GameSession] Game loop started for room: " + room.getName()); while (running && snakes.size() > 1) { try { Thread.sleep(TICK_MS); // Тик игры moveSnakes(); // Движение checkCollisions(); // Коллизии sendGameState(); // Синхронизация sendScores(); // Очки if (snakes.size() == 1) { String winner = snakes.keySet().iterator().next(); scores.put(winner, scores.getOrDefault(winner, 0) + 1); System.out.println("[GameSession] Winner: " + winner + ", score: " + scores.get(winner)); sendScores(); Thread.sleep(1000); break; } } catch (InterruptedException e) { System.out.println("[GameSession] Interrupted: " + e.getMessage()); break; } } running = false; sendScores(); // ОБНОВЛЯЕМ СЕССИОННЫЕ ОЧКИ В КОМНАТЕ saveGameResults(); room.broadcast("GAME_OVER"); System.out.println("[GameSession] Game loop ended for room: " + room.getName()); } private void saveGameResults() { if (room == null) { System.out.println("[GameSession] Cannot save results: room is null"); return; } // ИЩЕМ ПОБЕДИТЕЛЯ (последнего выжившего, не бота) String winner = null; if (snakes.size() == 1) { winner = snakes.keySet().iterator().next(); } // ПРОПУСКАЕМ БОТОВ if (winner == null || winner.startsWith("Bot")) { System.out.println("[GameSession] No human winner, skipping session score update"); return; } // +1 ОЧКО В СЕССИЮ ДЛЯ ПОБЕДИТЕЛЯ room.updateSessionScore(winner, 1); System.out.println("[GameSession] Session score +1 for " + winner); } public void handleMove(String username, String dir) { int[] currentDir = directions.get(username); if (currentDir == null) return; int[] newDir; switch (dir.toUpperCase()) { case "UP" -> newDir = new int[]{0, -1}; case "DOWN" -> newDir = new int[]{0, 1}; case "LEFT" -> newDir = new int[]{-1, 0}; case "RIGHT" -> newDir = new int[]{1, 0}; default -> { return; } } if (newDir[0] == -currentDir[0] && newDir[1] == -currentDir[1]) { System.out.println("[GameSession] " + username + " tried to reverse direction, ignoring"); return; } directions.put(username, newDir); System.out.println("[GameSession] " + username + " moved: " + dir); } private void moveSnakes() { for (String name : new ArrayList<>(snakes.keySet())) { LinkedList<int[]> snake = snakes.get(name); int[] dir = directions.get(name); if (snake == null || dir == null) continue; int[] head = snake.getFirst(); int nx = head[0] + dir[0]; int ny = head[1] + dir[1]; if (nx < 0 || ny < 0 || nx >= WIDTH || ny >= HEIGHT) { kill(name); System.out.println("[GameSession] " + name + " hit wall at (" + nx + "," + ny + ")"); continue; } snake.addFirst(new int[]{nx, ny}); snake.removeLast(); } } private void checkCollisions() { Set<String> dead = new HashSet<>(); for (String a : snakes.keySet()) { LinkedList<int[]> snakeA = snakes.get(a); if (snakeA.isEmpty()) continue; int[] headA = snakeA.getFirst(); for (int i = 1; i < snakeA.size(); i++) { int[] segment = snakeA.get(i); if (headA[0] == segment[0] && headA[1] == segment[1]) { dead.add(a); System.out.println("[GameSession] " + a + " collided with itself"); break; } } for (String b : snakes.keySet()) { if (a.equals(b)) continue; LinkedList<int[]> snakeB = snakes.get(b); if (snakeB.isEmpty()) continue; int[] headB = snakeB.getFirst(); if (headA[0] == headB[0] && headA[1] == headB[1]) { dead.add(a); dead.add(b); System.out.println("[GameSession] Head collision between " + a + " and " + b); continue; } for (int i = 1; i < snakeB.size(); i++) { int[] segment = snakeB.get(i); if (headA[0] == segment[0] && headA[1] == segment[1]) { dead.add(a); scores.put(b, scores.getOrDefault(b, 0) + 1); System.out.println("[GameSession] " + a + " hit " + b + "'s body. " + b + " gets a point!"); break; } } } } for (String name : dead) { kill(name); } } private void kill(String name) { snakes.remove(name); directions.remove(name); room.broadcast("PLAYER_DEAD:" + name); System.out.println("[GameSession] Player killed: " + name); } private void sendScores() { if (scores.isEmpty()) return; StringBuilder sb = new StringBuilder("SCORES:"); for (Map.Entry<String, Integer> entry : scores.entrySet()) { sb.append(entry.getKey()).append(":").append(entry.getValue()).append(";"); } if (sb.charAt(sb.length() - 1) == ';') { sb.deleteCharAt(sb.length() - 1); } room.broadcast(sb.toString()); System.out.println("[GameSession] Sent scores: " + sb); } private void sendGameState() { if (snakes.isEmpty()) return; StringBuilder sb = new StringBuilder("GAME_STATE:"); for (String name : snakes.keySet()) { sb.append(name).append(":"); LinkedList<int[]> snake = snakes.get(name); for (int i = 0; i < snake.size(); i++) { int[] pos = snake.get(i); sb.append(pos[0]).append(",").append(pos[1]); if (i < snake.size() - 1) { sb.append("|"); } } sb.append(";"); } if (sb.charAt(sb.length() - 1) == ';') { sb.deleteCharAt(sb.length() - 1); } room.broadcast(sb.toString()); } public boolean isGameOver() { return !running; } public Map<String, Integer> getScores() { return new HashMap<>(scores); } }