/// <summary> /// Start meld round. /// </summary> /// <param name="trump"> Trump suit </param> /// <returns> List of messages to be sent </returns> private MessagePackets StartMeld(string trump) { MessagePackets messages = new MessagePackets(); foreach (Player p in GetPlayersMutable()) { MeldCounter counter = new MeldCounter(p.Cards, trump, Suits.Count, Ranks.Count); p.MeldScore = counter.TotalMeld(); MeldMessage message = new MeldMessage(p.Name, trump, p.MeldScore) { AcesAround = counter.AcesAround(), KingsAround = counter.KingsAround(), QueensAround = counter.QueensAround(), JacksAround = counter.JacksAround(), TrumpNine = counter.Nines(), Run = counter.Runs(), ClubsMarriage = counter.ClubsMarriage(), DiamondsMarriage = counter.DiamondsMarriage(), SpadesMarriage = counter.SpadesMarriage(), HeartsMarriage = counter.HeartsMarriage(), Pinochle = counter.Pinochle() }; messages.Add(message, p.Uid); } return(messages); }
/// <summary> /// Start passing round. /// </summary> /// <returns> List of messages to be sent </returns> private MessagePackets StartPass() { MessagePackets messages = new MessagePackets(); List <Player> players = GetPlayersMutable(); for (int i = 0; i < players.Count; i++) { // Get player to pass to int idx = (i + PASS_DIRS[CurPass]) % players.Count; if (idx < 0) { idx = players.Count() + idx; } string passingTo = players[idx].Name; // Update and send pass message PassMessage passMessage = new PassMessage(players[i].Name, NUM_TO_PASS, passingTo); PassMessages.Add(passMessage); messages.Add(passMessage, players[i].Uid); } // Update pass direction CurPass = (CurPass + 1) % PASS_DIRS.Length; return(messages); }
public void TestHandleGameTypes(string chosenGame, params Type[] messageTypes) { // TODO: check values in messages // TODO: check game state afterwards (need to expose static game state info) string uid = "uid"; GameTypeMessage gt = new GameTypeMessage() { ChosenGame = chosenGame }; if (messageTypes.Length > 0) { MessagePackets messages = GamesManager.Get().HandleGameTypes(uid, gt); Assert.IsTrue(Utils.VerifyMessagePackets(messages, messageTypes)); foreach (MessagePacket m in messages.Messages) { Assert.AreEqual(m.SendTo.Count(), 1); Assert.AreEqual(m.SendTo.Single(), uid); } } else { Assert.ThrowsException <Exception>(() => GamesManager.Get().HandleGameTypes(uid, gt)); } }
public void Send(MessagePackets messages) { foreach (MessagePacket m in messages.Messages) { LogSent(m.Message); if (m.SendTo == null) { SocketServer.WebSocketServices["/"].Sessions.Broadcast(JsonConvert.SerializeObject(m.Message)); } else { foreach (string uid in m.SendTo) { if (SocketServer.WebSocketServices["/"].Sessions.ActiveIDs.Any(s => s == uid)) { SocketServer.WebSocketServices["/"].Sessions.SendTo(JsonConvert.SerializeObject(m.Message), uid); } else { Console.WriteLine("Unable to send to " + uid); } } } } }
public void TestHandleRestartSameGame() { string uid = "uid"; string userName = "******"; CreateExistingGame(); JoinGame(uid, userName, ExistingGameName); JoinGame("uid2", "2", ExistingGameName); JoinGame("uid3", "3", ExistingGameName); MessagePackets messages = gm.HandleRestart(new RestartMessage(userName, true)); CollectionAssert.DoesNotContain(gm.GetPlayers().Select(p => p.Uid).ToList(), uid); Assert.IsFalse(gm.HasEnded()); Assert.IsTrue(gm.HasStarted()); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(RestartMessage), typeof(DisconnectMessage))); RestartMessage rm = (RestartMessage)messages.Messages[0].Message; Assert.AreEqual(messages.Messages[0].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[0].SendTo.Single(), uid); Assert.AreEqual(rm.PlayerName, userName); Assert.IsTrue(rm.NewGame); DisconnectMessage d = (DisconnectMessage)messages.Messages[1].Message; Assert.AreEqual(messages.Messages[1].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[1].SendTo.Single(), ExistingUid); Assert.AreEqual(d.PlayerName, userName); Assert.IsFalse(d.ShouldDisableGame); }
public void TestHandleJoin() { string uid = "uid"; string userName = "******"; string gameName = "game"; MessagePackets messages = JoinGame(uid, userName, gameName); List <Player> players = gm.GetPlayers(); Assert.AreEqual(players.Count, 1); Assert.AreEqual(players.Last().Name, userName); Assert.AreEqual(players.Last().Uid, uid); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(JoinResponse), typeof(JoinMessage))); JoinResponse jr = (JoinResponse)messages.Messages[0].Message; Assert.AreEqual(messages.Messages[0].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[0].SendTo.Single(), uid); Assert.AreEqual(jr.UserName, userName); Assert.AreEqual(jr.ErrorMessage, null); Assert.IsTrue(jr.Success); JoinMessage jm = (JoinMessage)messages.Messages[1].Message; Assert.AreEqual(messages.Messages[1].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[1].SendTo.Single(), uid); Assert.AreEqual(jm.UserName, userName); Assert.AreEqual(jm.GameName, gameName); Assert.AreEqual(jm.Order, 0); }
public void HandleDisconnectStarted() { string uid = "uid"; string userName = "******"; string gameName = "fullGame"; JoinGame(uid, userName, gameName); JoinGame("uid2", "2", gameName); JoinGame("uid3", "3", gameName); JoinGame("uid4", "4", gameName); MessagePackets messages = gm.HandleDisconnect(uid); Assert.AreEqual(gm.GetPlayers().Count, 3); Assert.IsTrue(gm.HasEnded()); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(DisconnectMessage))); DisconnectMessage d = (DisconnectMessage)messages.Messages[0].Message; Assert.AreEqual(messages.Messages[0].SendTo.Count(), 3); CollectionAssert.AreEqual(messages.Messages[0].SendTo.ToList(), new List <string>() { "uid2", "uid3", "uid4" }); Assert.AreEqual(d.PlayerName, userName); Assert.IsTrue(d.ShouldDisableGame); }
public void TestHandleDisconnectGameOver() { string uid = "uid"; string userName = "******"; CreateExistingGame(); JoinGame("tmp", "tmp", ExistingGameName); JoinGame("tmp2", "tmp2", ExistingGameName); JoinGame(uid, userName, ExistingGameName); gm.HandleDisconnect("tmp"); MessagePackets messages = gm.HandleDisconnect(uid); Assert.AreEqual(gm.GetPlayers().Count, 2); Assert.IsTrue(gm.HasEnded()); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(DisconnectMessage))); DisconnectMessage d = (DisconnectMessage)messages.Messages[0].Message; Assert.AreEqual(messages.Messages[0].SendTo.Count(), 2); CollectionAssert.AreEqual(messages.Messages[0].SendTo.ToList(), new List <string>() { ExistingUid, "tmp2" }); Assert.AreEqual(d.PlayerName, userName); Assert.IsFalse(d.ShouldDisableGame); }
/// <summary> /// Get messages to send in response to a JoinMessage /// </summary> /// <param name="uid"> The uid of the player </param> /// <param name="joinMessage"></param> /// <returns> List of messages to be sent </returns> public MessagePackets HandleJoin(string uid, JoinMessage joinMessage) { lock (this) { if (PlayerGameTypeMap.ContainsKey(uid)) { PlayerGameNameMap.Add(uid, joinMessage.GameName); string gameType = PlayerGameTypeMap[uid]; if (GameNameMap[gameType].ContainsKey(joinMessage.GameName)) { // The game exists, so join it return(GameNameMap[gameType][joinMessage.GameName].HandleJoin(uid, joinMessage)); } else { MessagePackets messages = new MessagePackets(); // The game doesn't exist, so make a new one and join it GameManager gm = (GameManager)Activator.CreateInstance(GameManagerMap[gameType]); GameNameMap[gameType].Add(joinMessage.GameName, gm); messages.Add(gm.HandleJoin(uid, joinMessage)); // Push available games update messages.Add(GetAvailableGamesMessage(gameType)); return(messages); } } else { throw new Exception("Game type not known for player " + uid); } } }
/// <summary> /// Start a round by starting passing. /// </summary> /// <returns> List of messages to be sent </returns> protected override MessagePackets DoStartRound() { MessagePackets messages = new MessagePackets(); messages.Add(GetStartMessages()); messages.Add(StartPass()); return(messages); }
/// <summary> /// By default, when the round is started just start the first trick with the current player. /// Called when enough players have joined the game, or when the game is restarted. /// Subclasses should override to enable different behaviors. /// </summary> /// <returns> List of messages to be sent </returns> protected virtual MessagePackets DoStartRound() { MessagePackets messages = new MessagePackets(); messages.Add(GetStartMessages()); messages.Add(StartTrick(CurPlayer, true)); return(messages); }
/// <summary> /// Starts a round by starting the bid and sending out meld points /// </summary> /// <returns> List of messages to be sent </returns> protected override MessagePackets DoStartRound() { MessagePackets messages = new MessagePackets(); messages.Add(GetStartMessages()); messages.Add(StartBid(GetCurrentPlayer(), GetDealerIndex())); messages.Add(GetMeldPointsMessages()); return(messages); }
/// <summary> /// Start the round with dealing first 5 cards and deciding trump /// </summary> /// <returns> List of messages to be sent </returns> protected override MessagePackets DoStartRound() { MessagePackets messages = new MessagePackets(); Player p = GetPlayer(GetDealerIndex()); messages.Add(new StartMessage(p.Cards.Take(5).ToArray()), p.Uid); messages.Add(GetBroadcastMessage(new TrumpMessage(p.Name, unavailableOptions: p.TrumpUsed.ToArray(), extraOptions: ExtraTrumpOptions))); return(messages); }
/// <summary> /// Update all player scores and broadcast them to all players /// </summary> /// <returns> List of messages to be sent </returns> private MessagePackets GetScoreMessages() { MessagePackets messages = new MessagePackets(); foreach (Player p in Players) { messages.Add(GetBroadcastMessage(new ScoreMessage(p.Name, p.Score, p.Score - p.OldScore, p.MissedBidBy))); } return(messages); }
protected MessagePackets GetStartMessages() { MessagePackets messages = new MessagePackets(); foreach (Player p in Players) { messages.Add(new StartMessage(p.Cards.ToArray()), p.Uid); } return(messages); }
/// <summary> /// Get messages to send in response to a player disconnecting /// </summary> /// <param name="playerId"> The uid of the player </param> /// <returns> List of messages to be sent </returns> public MessagePackets HandlePlayerDisconnect(string playerId) { lock (this) { MessagePackets messages = new MessagePackets(); GameManager gm = GetGameManager(playerId); messages.Add(Do(gm, () => gm.HandleDisconnect(playerId))); messages.Add(RemovePlayer(playerId)); return(messages); } }
public static bool VerifyMessagePackets(MessagePackets messages, params Type[] messageTypes) { if (messages.Messages.Count != messageTypes.Length) { return(false); } for (int i = 0; i < messages.Messages.Count; i++) { if (messages.Messages[i].Message.GetType() != messageTypes[i]) { return(false); } } return(true); }
/// <summary> /// Handle a TrumpMessage. /// </summary> /// <param name="trumpMessage"></param> /// <returns> List of messages to be sent </returns> public override MessagePackets HandleTrump(TrumpMessage trumpMessage) { MessagePackets messages = new MessagePackets(); // Broadcast to all players messages.Add(GetBroadcastMessage(trumpMessage)); // Set trump suit ((PinochleTrickDecider)GetDecider()).Trump = trumpMessage.TrumpSuit; // Initiate meld round messages.Add(StartMeld(trumpMessage.TrumpSuit)); return(messages); }
public void TestHandleNewConnection() { string uid = "uid"; MessagePackets messages = GamesManager.Get().HandleNewConnection(uid); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(GameTypeMessage))); Assert.AreEqual(messages.Messages[0].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[0].SendTo.Single(), uid); GameTypeMessage gt = (GameTypeMessage)messages.Messages[0].Message; CollectionAssert.AreEqual(gt.GameTypes, new string[3] { "Hearts", "Mizerka", "Pinochle" }); Assert.AreEqual(gt.ChosenGame, null); }
/// <summary> /// Handle a MeldMessage /// </summary> /// <param name="meldMessage"></param> /// <returns> List of messages to be sent </returns> public override MessagePackets HandleMeld(MeldMessage meldMessage) { MessagePackets messages = new MessagePackets(); // Broadcast to all players messages.Add(GetBroadcastMessage(meldMessage)); // Start first trick if all meld is in NumMeld++; if (NumMeld == GetNumPlayers()) { NumMeld = 0; messages.Add(StartTrick(LastBidder)); } return(messages); }
/// <summary> /// Handle a DisconnectMessage. /// </summary> /// <param name="playerId"> The uid of the disconnected player </param> /// <returns> List of messages to be sent </returns> public MessagePackets HandleDisconnect(string playerId) { MessagePackets messages = new MessagePackets(); Player player = Players.Where(p => p.Uid == playerId).SingleOrDefault(); if (player != null) { messages.Add(DisconnectPlayer(player)); } else { throw new Exception("Player " + playerId + " does not exist"); } return(messages); }
/// <summary> /// Get messages to send in response to a RestartMessage /// </summary> /// <param name="playerId"> The uid of the player </param> /// <param name="restartMessage"></param> /// <returns> List of messages to be sent </returns> public MessagePackets HandleRestart(string playerId, RestartMessage restartMessage) { lock (this) { MessagePackets messages = new MessagePackets(); GameManager gm = GetGameManager(playerId); messages.Add(Do(gm, () => gm.HandleRestart(restartMessage))); if (restartMessage.NewGame) { RemovePlayer(playerId); } return(messages); } }
public void TestHandleJoinExistingGame() { string uid = "uid"; string userName = "******"; CreateExistingGame(); MessagePackets messages = JoinGame(uid, userName, ExistingGameName); List <Player> players = gm.GetPlayers(); Assert.AreEqual(players.Count, 2); Assert.AreEqual(players.Last().Name, userName); Assert.AreEqual(players.Last().Uid, uid); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(JoinResponse), typeof(JoinMessage), typeof(JoinMessage))); JoinResponse jr = (JoinResponse)messages.Messages[0].Message; Assert.AreEqual(messages.Messages[0].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[0].SendTo.Single(), uid); Assert.AreEqual(jr.UserName, userName); Assert.AreEqual(jr.ErrorMessage, null); Assert.IsTrue(jr.Success); JoinMessage jm1 = (JoinMessage)messages.Messages[1].Message; Assert.AreEqual(messages.Messages[1].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[1].SendTo.Single(), uid); Assert.AreEqual(jm1.UserName, ExistingUserName); Assert.AreEqual(jm1.GameName, ExistingGameName); Assert.AreEqual(jm1.Order, 0); JoinMessage jm2 = (JoinMessage)messages.Messages[2].Message; Assert.AreEqual(messages.Messages[2].SendTo.Count(), 2); CollectionAssert.AreEqual(messages.Messages[2].SendTo.ToList(), new List <string>() { ExistingUid, uid }); Assert.AreEqual(jm2.UserName, userName); Assert.AreEqual(jm2.GameName, ExistingGameName); Assert.AreEqual(jm2.Order, 1); }
/// <summary> /// Handle a TrumpMessage. /// </summary> /// <param name="trumpMessage"></param> /// <returns> List of messages to be sent </returns> public override MessagePackets HandleTrump(TrumpMessage trumpMessage) { MessagePackets messages = new MessagePackets(); // Broadcast to all players messages.Add(GetBroadcastMessage(trumpMessage)); // Save trump and update player model ((TrumpDecider)GetDecider()).Trump = trumpMessage.TrumpSuit; Player choosingPlayer = GetPlayersMutable().Where(p => p.Name == trumpMessage.ChoosingPlayer).Single(); choosingPlayer.TrumpUsed.Add(trumpMessage.TrumpSuit); // Send out cards and start first trick messages.Add(GetStartMessages()); messages.Add(GetTrickInfoMessage()); messages.Add(StartTrick(GetDealerIndex())); return(messages); }
/// <summary> /// Handle a BidMessage. /// </summary> /// <param name="bidMessage"></param> /// <returns> List of messages to be sent </returns> public override MessagePackets HandleBid(BidMessage bidMessage) { MessagePackets messages = new MessagePackets(); // Broadcast bid to all players messages.Add(GetBroadcastMessage(bidMessage)); // Parse bid CurBid = bidMessage.Bid; if (bidMessage.Bid != 0) { LastBidder = GetCurrentPlayerIndex(); } else { CurBid = bidMessage.CurBid; PassedPlayers.Add(GetCurrentPlayerIndex()); } // Get next non-passed player NextPlayer(); while (PassedPlayers.Contains(GetCurrentPlayerIndex()) && GetCurrentPlayerIndex() != LastBidder) { NextPlayer(); } // Handle last bid if (GetCurrentPlayerIndex() == LastBidder) { messages.Add(GetBroadcastMessage(new BidMessage(GetCurrentPlayer().Name, CurBid, CurBid))); PassedPlayers = new List <int>(); messages.Add(StartKitty(GetCurrentPlayerIndex())); } // Initiate next bid else { Player player = GetCurrentPlayer(); messages.Add(GetBroadcastMessage(new BidMessage(player.Name, CurBid))); } return(messages); }
public void TestHandleJoinDuplicateUserName() { string uid = "uid"; CreateExistingGame(); Assert.AreEqual(gm.GetPlayers().Count, 1); MessagePackets messages = JoinGame(uid, ExistingUserName, ExistingGameName); Assert.AreEqual(gm.GetPlayers().Count, 1); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(JoinResponse))); JoinResponse jr = (JoinResponse)messages.Messages[0].Message; Assert.AreEqual(messages.Messages[0].SendTo.Count(), 1); Assert.AreEqual(messages.Messages[0].SendTo.Single(), uid); Assert.AreEqual(jr.UserName, null); Assert.AreNotEqual(jr.ErrorMessage, null); Assert.IsFalse(jr.Success); }
/// <summary> /// Handle a JoinMessage. /// </summary> /// <param name="message"> The received join message </param> /// <param name="playerId"> The uid of the player joining </param> /// <returns> List of messages to be sent </returns> public MessagePackets HandleJoin(string playerId, JoinMessage message) { // Verify game state VerifyNotOver(); VerifyNotStarted(); MessagePackets messages = new MessagePackets(); if (Players.Any(p => p.Name == message.UserName)) { // Handle user name already exists in game messages.Add(new JoinResponse(false, errorMessage: string.Format("The name '{0}' already exists in the game '{1}'", message.UserName, message.GameName)), playerId); } else { // Send success response messages.Add(new JoinResponse(true, message.UserName), playerId); // Inform new player of all existing players foreach (Player p in Players) { messages.Add(new JoinMessage(p.Name, message.GameName, p.Order), playerId); } // Create new player model Player player = new Player(message.UserName, playerId, Players.Count); Players.Add(player); // Broadcast new player to all players with correct order message.Order = player.Order; messages.Add(GetBroadcastMessage(message)); // There are enough players, so start the game if (Players.Count == DoGetMinPlayers()) { messages.Add(StartRound()); } } return(messages); }
public void TestHandleJoinGameStart() { string uid = "uid"; string gameName = "fullGame"; List <string> uids = new List <string>(); MessagePackets messages = new MessagePackets(); for (int i = 0; i < 4; i++) { string num = i.ToString(); uids.Add(uid + num); messages = JoinGame(uid + num, num, gameName); } Assert.IsTrue(gm.HasStarted()); Assert.AreEqual(gm.GetCurrentPlayerIndex(), 1); Assert.AreEqual(gm.GetDealerIndex(), 0); Assert.IsTrue(Utils.VerifyMessagePackets(messages, typeof(JoinResponse), typeof(JoinMessage), typeof(JoinMessage), typeof(JoinMessage), typeof(JoinMessage), typeof(StartMessage), typeof(StartMessage), typeof(StartMessage), typeof(StartMessage), typeof(TurnMessage))); List <Player> players = gm.GetPlayers(); for (int i = 5; i < 9; i++) { Assert.AreEqual(messages.Messages[i].SendTo.Single(), uid + (i - 5).ToString()); StartMessage sm = (StartMessage)messages.Messages[i].Message; Assert.AreEqual(sm.Cards.Length, 13); CollectionAssert.AreEqual(sm.Cards, players[i - 5].Cards); } CollectionAssert.AreEqual(messages.Messages[9].SendTo.ToList(), uids); TurnMessage tm = (TurnMessage)messages.Messages[9].Message; Assert.AreEqual(tm.PlayerName, "1"); CollectionAssert.AreEqual(tm.ValidCards, ((StartMessage)messages.Messages[6].Message).Cards); Assert.IsTrue(tm.IsFirstCard); }
/// <summary> /// Handle a RestartMessage. /// </summary> /// <param name="restartMessage"></param> /// <returns> List of messages to be sent </returns> public MessagePackets HandleRestart(RestartMessage restartMessage) { if (!restartMessage.NewGame) { // Restart the same game VerifyStarted(); Reset(); return(StartRound()); } else { MessagePackets messages = new MessagePackets(); // Confirm restart request Player player = Players.Where(p => p.Name == restartMessage.PlayerName).Single(); messages.Add(restartMessage, player.Uid); // Inform other players the player left the old game messages.Add(DisconnectPlayer(player)); return(messages); } }
/// <summary> /// Handle a PassMessage. /// </summary> /// <param name="passMessage"></param> /// <returns> List of messages to be sent </returns> public override MessagePackets HandlePass(PassMessage passMessage) { MessagePackets messages = new MessagePackets(); // Add pass message PassMessages.Where(pm => pm.PassingPlayer == passMessage.PassingPlayer).Single().PassedCards = passMessage.PassedCards; // Continue once all passes have been completed if (PassMessages.Where(pm => pm.PassedCards != null).Count() == GetNumPlayers()) { foreach (PassMessage pm in PassMessages) { if (pm.PassingPlayer != pm.PassingTo) { // Update players' cards Player passingToPlayer = GetPlayersMutable().Where(p => p.Name == pm.PassingTo).Single(); Player passingPlayer = GetPlayersMutable().Where(p => p.Name == pm.PassingPlayer).Single(); passingToPlayer.Cards.AddRange(pm.PassedCards); passingPlayer.Cards.RemoveAll(c => pm.PassedCards.Any(h => h.Equals(c))); // Send new cards to player messages.Add(pm, passingToPlayer.Uid); } } // Initiate first trick List <Player> players = GetPlayersMutable(); int startingPlayer = players.IndexOf(players.Where(p => p.Cards.Any(c => c.Suit == "C" && c.Rank == "2")).Single()); messages.Add(StartTrick(startingPlayer, true)); // Reset pass messages PassMessages = new List <PassMessage>(); } return(messages); }