0% encontró este documento útil (0 votos)
20 vistas6 páginas

Examen Mayo 25

El documento describe la estructura de un programa de emparejamiento de jugadores en un juego, que incluye clases como Player, GameRoom y MatchmakingServer, junto con sus propiedades y métodos. Se implementa la gestión de hilos para simular conexiones simultáneas y se asegura la exclusión mutua para evitar condiciones de carrera al acceder a las salas de juego. Además, se detalla un mecanismo de cancelación por espera excesiva para los jugadores que intentan unirse a una sala.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
20 vistas6 páginas

Examen Mayo 25

El documento describe la estructura de un programa de emparejamiento de jugadores en un juego, que incluye clases como Player, GameRoom y MatchmakingServer, junto con sus propiedades y métodos. Se implementa la gestión de hilos para simular conexiones simultáneas y se asegura la exclusión mutua para evitar condiciones de carrera al acceder a las salas de juego. Además, se detalla un mecanismo de cancelación por espera excesiva para los jugadores que intentan unirse a una sala.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

PARTE 1: Estructura General del Programa

Clases necesarias:
1. Player
o Propiedades: Id, Level, Thread, IsConnected
o Métodos: JoinMatchmaking()
2. GameRoom
o Propiedades: List<Player> Players, MinLevel, MaxLevel
o Métodos: CanJoin(Player p), AddPlayer(Player p)
3. MatchmakingServer
o Propiedades: List<GameRoom> Rooms
o Métodos: TryJoin(Player p), CreateRoom(Player p)
o Gestión de sincronización y concurrencia
4. Level (enum)
o Valores: Beginner = 0, Intermediate = 1, Advanced = 2, Expert = 3

Hilos:
• Cada jugador será ejecutado en un hilo independiente (simula conexión simultánea).
• Un hilo principal para iniciar múltiples jugadores concurrentemente.

Exclusión mutua:
• Acceso a la lista de salas (Rooms) debe estar protegido con lock para evitar condiciones de carrera.
• Al agregar jugadores a una sala, también se debe usar exclusión mutua.

Sincronización condicional:
• Si no hay sala compatible, el jugador espera durante cierto tiempo (simulación con [Link] o [Link]) antes de decidir crear nueva
sala.
• En la parte 3 se usará [Link]() para forzar la salida.
using System;
using [Link];
using [Link];
using [Link];

// Niveles posibles de los jugadores


public enum Level { BEGINNER = 0, INTERMEDIATE = 1, ADVANCED = 2, EXPERT = 3 }

// Clase que representa un jugador


public class Player
{
public int Id { get; }
public Level Level { get; }
private MatchmakingServer server;

public Player(int id, Level level, MatchmakingServer server)


{
Id = id;
Level = level;
[Link] = server;
}

// Método que simula el intento de emparejamiento


public void JoinMatchmaking()
{
try
{
[Link](2000); // Simula una espera de emparejamiento que puede ser interrumpida

[Link]($"Jugador {Id} (Nivel: {Level}) intentando unirse a una sala...");

// Intenta unirse a una sala existente


if (![Link](this))
{
// Si no encuentra sala compatible, crea una nueva
[Link]($"Jugador {Id} no encontró sala válida, creando nueva sala.");
[Link](this);
}
}
catch (ThreadInterruptedException)
{
// El hilo fue interrumpido por haber esperado demasiado
[Link]($"Jugador {Id} desconectado por espera excesiva.");
}
}
}

// Clase que representa una sala de juego


public class GameRoom
{
private List<Player> players = new();
private object lockObj = new(); // Protección contra concurrencia

public bool CanJoin(Player p) // Verifica si un jugador puede unirse a la sala actual


{
lock (lockObj)
{
if ([Link] >= 4) return false; // Límite de 4 jugadores

if ([Link] == 0) return true; // Sala vacía, se puede unir

int min = [Link](pl => (int)[Link]);


int max = [Link](pl => (int)[Link]);
int level = (int)[Link];

// Requiere que la diferencia con todos los niveles actuales sea ≤ 1


return [Link](level - min) <= 1 && [Link](level - max) <= 1;
}
}

// Agrega un jugador a la sala


public void AddPlayer(Player p)
{
lock (lockObj)
{
[Link](p);
[Link]($" Jugador {[Link]} añadido a sala con niveles [{[Link](pl => [Link])} -
{[Link](pl => [Link])}]");
}
}
public int Count => [Link]; // Devuelve el número de jugadores en la sala
}
// Clase que representa el SERVIDOR de emparejamiento
public class MatchmakingServer
{
private List<GameRoom> rooms = new(); // Lista de salas
private object lockObj = new(); // Protección contra condiciones de carrera

// Intenta unir un jugador a una sala existente


public bool TryJoin(Player p)
{
lock (lockObj)
{
// Busca la sala compatible más llena
GameRoom? target = rooms
.Where(r => [Link](p))
.OrderByDescending(r => [Link])
.FirstOrDefault();

if (target != null)
{
[Link](p);
return true;
}

return false;
}
}

// Crea una sala nueva para el jugador


public void CreateRoom(Player p)
{
lock (lockObj)
{
GameRoom room = new();
[Link](p);
[Link](room);
[Link]($"Nueva sala creada por Jugador {[Link]}");
}
}
}

class Program
{
static void Main()
{
MatchmakingServer server = new(); // Instancia del servidor
Random rand = new(); // Para asignar niveles aleatorios
List<Thread> threads = new(); // Lista de hilos de jugadores

// Simula 15 jugadores conectándose al servidor


for (int i = 1; i <= 15; i++)
{
int id = i;
Level level = (Level)[Link](0, 4); // Nivel aleatorio (0 a 3)
Player player = new(id, level, server);

// Cada jugador será ejecutado en un hilo


Thread thread = new(() =>
{
[Link](); // Intenta unirse a una sala
});

[Link]();
[Link](thread);

[Link](200); // Simula llegadas escalonadas


}

// Espera hasta 3 segundos por cada jugador antes de interrumpir


foreach (Thread thread in threads)
{
if (![Link](3000)) // Espera 3 segundos como máximo
{
[Link](); // Interrumpe si sigue esperando
}
}
}
}
PARTE 3: Cancelación por espera excesiva

// Cambios en el MAIN

Thread thread = new(() =>


{
try
{
[Link]();
}
catch (ThreadInterruptedException)
{
[Link]($"Jugador {id} cancelado por espera.");
}
});

[Link]();
[Link](3000); // Tiempo máximo de espera
if ([Link])
{
[Link](); // Fuerza la desconexión si sigue esperando
}

También podría gustarte