void TellGameStatus(Channel channel, UnoPlayer player = null) { UnoChannel uno = GetUnoChannel(channel.GetName()); if (uno == null) { return; } // No specific player. Take current one var current = uno.GetPlayer(); if (player == null) { player = current; } var sb = new System.Text.StringBuilder(); sb.Append("[UNO] " + uno.current_player); sb.Append(" (" + current.cards.Count + " cards) - "); sb.Append("Top card: " + FormatCards(new List <Card> { uno.top_card })); if (uno.draw_count > 0) { sb.Append("- draw count: " + uno.draw_count); } channel.Say(sb.ToString()); E.Notice(player.name, "Your cards: " + FormatCards(player.cards)); }
void Cmd_Deal(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); UnoPlayer nplayer = uno != null?uno.GetPlayer(nick) : null; if (nplayer == null || uno.is_active) { E.Notice(nick, "You are either not part of the game or " + " another is already ongoing."); return; } if (uno.players.Count < 2) { channel.Say("At least two player are required to start the game."); return; } foreach (UnoPlayer player in uno.players) { player.DrawCards(11, 2); } uno.top_card = nplayer.cards[0]; uno.is_active = true; TellGameStatus(channel); }
void Cmd_Draw(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); UnoPlayer player = uno != null?uno.GetPlayer(nick) : null; if (player == null || !uno.is_active) { E.Notice(nick, "You are not part of an UNO game."); return; } if (uno.current_player != nick && !uno.CheckMode(UnoMode.LIGRETTO)) { E.Notice(nick, "It is not your turn (current: " + uno.current_player + ")."); return; } var drawn = player.DrawCards(Math.Max(1, uno.draw_count)); uno.draw_count = 0; E.Notice(nick, "You drew following cards: " + FormatCards(drawn)); uno.TurnNext(); TellGameStatus(channel); }
void Cmd_EloTop(string nick, string message) { Channel channel = p_manager.GetChannel(); var leaderboard = new Dictionary <string, int>(); var dummy = new UnoPlayer(null, null); foreach (string key in m_settings.IterateKeys()) { if (!m_settings.Get(key, ref dummy)) { continue; } leaderboard.Add(key, dummy.GetElo()); } int n = 0; string val = ""; foreach (var record in leaderboard.OrderByDescending(i => i.Value)) { if (n > 0) { val += ", "; } val += record.Key + " (" + record.Value + ")"; if (++n == 5) { break; } } channel.Say("[UNO] Top 5 leaderboard: " + val); }
public bool RemovePlayer(Channel channel, string nick) { UnoPlayer player = GetPlayer(nick); if (player == null) { return(false); } if (current_player == player.name) { TurnNext(); } if (is_active && player.cards.Count == 0) { int score = 0; foreach (UnoPlayer up in players) { if (up != player) { score += up.GetCardsValue(); } } string log = player.name + " finishes the game and gains " + score + " points"; if (CheckMode(UnoMode.RANKED)) { player.Win(players, initial_player_count); foreach (UnoPlayer up in players) { m_settings.Set(up.name, up); } log += ". Elo: " + player.ShowElo(false); } channel.Say(log); } else { channel.Say(player.name + " left this UNO game."); } players.Remove(player); if (!is_active) { initial_player_count = players.Count; } return(true); }
void Cmd_Top(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); UnoPlayer player = uno != null?uno.GetPlayer(nick) : null; if (player == null || !uno.is_active) { E.Notice(nick, "You are not part of an UNO game."); return; } TellGameStatus(channel, player); }
public override void OnUserRename(string nick, string old_nick) { foreach (KeyValuePair <string, UnoChannel> chan in m_channels) { UnoPlayer player = chan.Value.players.Find(item => item.name == old_nick); if (player != null) { player.name = nick; } if (chan.Value.current_player == old_nick) { chan.Value.current_player = nick; } } }
void Cmd_Elo(string nick, string message) { Channel channel = p_manager.GetChannel(); string who = Chatcommand.GetNext(ref message); if (who.Length == 0) { who = nick; } var player = new UnoPlayer(who, null); if (!m_settings.Get(who, ref player)) { channel.Say("[UNO] " + who + ": No information available"); } else { channel.Say("[UNO] " + who + ": " + player.ShowElo(true)); } }
public bool RemovePlayer(Channel channel, string nick) { UnoPlayer player = GetPlayer(nick); if (player == null) { return(false); } if (current_player == player.name) { TurnNext(); } if (is_active && player.cards.Count == 0) { int score = 0; foreach (UnoPlayer up in players) { if (up != player) { score += up.GetCardsValue(); } } channel.Say(player.name + " finishes the game and gains " + score + " points"); } else { channel.Say(player.name + " left this UNO game."); } players.Remove(player); player = null; // So that GC works GC.Collect(); return(true); }
void Cmd_Put(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); UnoPlayer player = uno != null?uno.GetPlayer(nick) : null; if (player == null || !uno.is_active) { E.Notice(nick, "huh?? You don't have any cards."); return; } if (uno.current_player != nick && !uno.CheckMode(UnoMode.LIGRETTO)) { E.Notice(nick, "It is not your turn (current: " + uno.current_player + ")."); return; } uno.current_player = nick; // UnoMode.LIGRETTO string put_color_s = Chatcommand.GetNext(ref message).ToUpper(); CardColor put_color = CardColor.NONE; string put_face = Chatcommand.GetNext(ref message).ToUpper(); if (put_color_s.Length >= 2) { // The following format: "gwd4", "g4" put_face = put_color_s.Substring(1); put_color_s = put_color_s.Remove(1); } // Convert user input to internal format switch (put_color_s) { case "B": put_color = CardColor.BLUE; break; case "R": put_color = CardColor.RED; break; case "G": put_color = CardColor.GREEN; break; case "Y": put_color = CardColor.YELLOW; break; } bool change_face = false; if (put_face.Contains("W")) { // Convert/validate W and WD4 change_face = true; } if (put_color == CardColor.NONE || !card_faces.Contains(put_face)) { E.Notice(nick, "Invalid input. Syntax: $uno p <color> <face>, $p <color><face>."); return; } // Check whether color of face matches if (put_color != uno.top_card.Key && put_face != uno.top_card.Value && !change_face) { E.Notice(nick, "This card cannot be played. Please check color and face."); return; } int card_index = -1; if (change_face) { card_index = player.cards.FindIndex(item => item.Value == put_face); } else { card_index = player.cards.FindIndex( item => item.Key == put_color && item.Value == put_face); } if (card_index < 0) { E.Notice(nick, "You don't have this card."); return; } if (uno.draw_count > 0) { bool ok = false; if (put_face == "D2" && put_face == uno.top_card.Value && // No downgrade uno.CheckMode(UnoMode.STACK_D2)) { ok = true; } else if (put_face == "WD4" && put_face == uno.top_card.Value && uno.CheckMode(UnoMode.STACK_WD4)) { ok = true; } else if (put_face == "WD4" && uno.top_card.Value == "D2" && uno.CheckMode(UnoMode.UPGRADE)) { ok = true; } if (!ok) { E.Notice(nick, "You cannot play this card due to the top card."); return; } } // All OK. Put the card on top uno.top_card = new Card(put_color, put_face); player.cards.RemoveAt(card_index); bool pending_autodraw = false; switch (put_face) { case "D2": uno.draw_count += 2; pending_autodraw = !uno.CheckMode(UnoMode.STACK_D2); break; case "WD4": uno.draw_count += 4; pending_autodraw = !uno.CheckMode(UnoMode.STACK_WD4); break; case "R": if (uno.players.Count > 2) { uno.players.Reverse(); } else { uno.TurnNext(); // Acts as Skip for 2 players } break; case "S": uno.TurnNext(); break; } uno.TurnNext(); // Player won, except when it's again their turn (last card = skip) if (player.cards.Count == 0 && uno.current_player != player.name) { uno.RemovePlayer(channel, player.name); } if (CheckGameEndDelete(channel.GetName())) { return; // Game ended } if (pending_autodraw) { Cmd_Draw(uno.current_player, ""); } else { TellGameStatus(channel); } }
void Cmd_Join(string nick, string message) { Channel channel = p_manager.GetChannel(); UnoChannel uno = GetUnoChannel(channel.GetName()); if (uno != null && uno.is_active) { channel.Say(nick + ": Please wait for " + uno.current_player + " to finish their game."); return; } if (uno != null && uno.GetPlayer(nick) != null) { E.Notice(nick, "You already joined the game."); return; } // Create a new UnoChannel if (uno == null) { string modes_s = Chatcommand.GetNext(ref message); byte modes = 0x87; try { modes = Convert.ToByte(modes_s, 16); } catch { } uno = new UnoChannel(modes, m_settings); } if (uno.CheckMode(UnoMode.RANKED) && p_manager.GetUserStatus(nick) != 3) { E.Notice(nick, "You must be logged in to play ranked UNO."); return; } m_channels[channel.GetName()] = uno; // For new channels UserData user = channel.GetUserData(nick); user.cmd_scope = m_subcommand; var player = new UnoPlayer(nick, user); m_settings.Get(nick, ref player); uno.AddPlayer(player); // Human readable modes var modes_list = new List <string>(); for (int i = 1; i < byte.MaxValue; i <<= 1) { if ((uno.modes & i) > 0) { modes_list.Add(FormatMode((UnoMode)(uno.modes & i))); } } channel.Say("[UNO] " + uno.players.Count + " player(s) are waiting for a new UNO game. " + string.Format("Modes: [0x{0:X2}] ", uno.modes) + string.Join(", ", modes_list)); }
public void AddPlayer(UnoPlayer player) { players.Add(player); current_player = player.name; initial_player_count = players.Count; }