/// <summary> /// Comprueba si los jugadores están conectados y si no es así los elimina de la sala. /// Si la sala está vacia, la cierra y elimina. /// </summary> /// <param name="room">Sala a comprobar.</param> /// <param name="rooms">Coleccion de salas</param> public static void refreshGameConectedPeople(Room room, Dictionary <int, Room> rooms) { while (!room.GameFinished) { lock (room) { int initialClients = room.Clients.Count; foreach (var client in room.Clients.ToList()) { if (!client.Value.isConected()) { room.deletePlayer(client.Key); client.Value.disconnect(); } } if (initialClients != room.Clients.Count) { sendData(room); if (room.Clients.Count <= 1) { room.GameFinished = true; finishPlayer(room, true); WaitingRoom.closeRoom(room, rooms); } } } Thread.Sleep(100); } }
/// <summary> /// Crea una sala, añade al host y lanza un hilo para la sala de espera. /// Una vez creada, aumenta el número de la sala disponible. /// </summary> /// <param name="client">Creador de la sala.</param> /// <param name="rooms">Coleccion de salas.</param> /// <param name="roomsCount">Número de la nueva sala.</param> /// <returns></returns> public static bool createRoom(Client client, Dictionary <int, Room> rooms, ref int roomsCount) { string name = client.getData(); if (name.Trim().Length >= 3) { //Creo la nueva sala lock (rooms) { Room room = new Room(roomsCount, name, client); client.sendData(roomsCount.ToString()); //Aumento el identificador para evitar repetir salas roomsCount++; //Añado la sala a la colección rooms.Add(room.IdRoom, room); Thread hiloSala = new Thread(() => WaitingRoom.waitingRoom(room, rooms)); hiloSala.Start(); Console.WriteLine($"El usuario {name} ha creado la sala {roomsCount-1}"); } return(true); } return(false); }
/// <summary> /// Función principal que gestiona el juego. Se encarga de generar una baraja base aleatoria y /// repartir a cada jugador la suya. /// Mientras haya al menos 2 jugadores, la partida continúa existiendo. En cada turno, el servidor /// espera respuesta unicamente del jugador cuyo nombre coincida con el turno. En función de su acción, añade /// o elimina cartas a la baraja del jugador. /// Si el jugador se queda sin cartas, gana la partida, por lo que se le borra de la sala. /// En todo momento se comprueba la conexion del jugador del turno mediante el hilo lanzado. /// Si acaba la partida, cierra la sala. /// </summary> /// <param name="room">Sala actual.</param> /// <param name="rooms">Coleccion de salas.</param> public static void partida(Room room, Dictionary <int, Room> rooms) { room.Match = new Match(); Thread refreshClientsThread = new Thread(() => refreshGameConectedPeople(room, rooms)); refreshClientsThread.Start(); int playersInGame = room.Clients.Count; int maxCards = 8; foreach (var cl in room.Clients) { List <Card> deck = new List <Card>(); for (int i = 0; i < maxCards; i++) { deck.Add(randomCard()); } room.Match.PlayersDeck.Add(cl.Key, deck); } room.Match.Turn = room.PlayersNames[0]; do { sendData(room); Card cardPlayed = null; if (room.PlayersNames.Count < 2) { room.GameFinished = true; } else { try { switch (room.Clients[room.Match.Turn].getData()) { case "jugar": cardPlayed = room.Clients[room.Match.Turn].getCard(); //Borro de su baraja la carta jugada room.Match.PlayersDeck[room.Match.Turn].Remove(searchCard(cardPlayed, room.Match.PlayersDeck[room.Match.Turn])); //La carta realiza su función en mesa switch (cardPlayed.Type) { case Card.eType.Number: int dif = 0; bool overLimit = false; //En función del sentido de la mesa, sumamos o restamos su valor if (room.Match.TableWay) { dif = room.Match.TableValue + cardPlayed.Value; if (dif >= room.Match.Limit) { overLimit = true; dif -= room.Match.Limit; } } else { dif = room.Match.TableValue - cardPlayed.Value; if (dif <= -room.Match.Limit) { overLimit = true; dif += room.Match.Limit; } } Console.WriteLine("Table limit: " + room.Match.Limit); Console.WriteLine($"Operation in this last turn: {room.Match.TableValue}+{cardPlayed.Value}={cardPlayed.Value + room.Match.TableValue}"); room.Match.TableValue = dif; //Si el jugador sobrepasa el límite, se reinicia el valor de mesa y se //añaden 3 cartas a su baraja. if (overLimit) { for (int i = 0; i < 3; i++) { room.Match.PlayersDeck[room.Match.Turn].Add(randomCard()); } } break; case Card.eType.Way: //Se cambia la operación de la mesa room.Match.TableWay = cardPlayed.Way; break; case Card.eType.Effect: //Cada jugador recibe 2 cartas a excepción del que ha jugado último foreach (var cl in room.Match.PlayersDeck) { if (cl.Key != room.Match.Turn) { for (int i = 0; i < 2; i++) { cl.Value.Add(randomCard()); } } } break; } break; case "pasar": room.Match.PlayersDeck[room.Match.Turn].Add(randomCard()); break; default: room.Clients[room.Match.Turn].sendData("You must play or pass"); continue; } if (room.Match.PlayersDeck[room.Match.Turn].Count <= 0) { finishPlayer(room, false); } else { room.nextTurn(); } } catch (IOException) { if (!room.GameFinished) { deleteDisconnectedPlayer(room.Match.Turn, room); } } } } while (!room.GameFinished); if (room.PlayersNames.Count > 0) { finishPlayer(room, true); WaitingRoom.closeRoom(room, rooms); } }