Beispiel #1
0
        public override void OnUserLeave(string nick)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || !game.RemovePlayer(nick))
            {
                return;                 // Player was not part of the round
            }
            if (game.players.Count < 3 && game.is_active)
            {
                lchans.Remove(game);
                game = null;
                GC.Collect();
                channel.Say("Game ended.");
                return;
            }
            if (game.is_active)
            {
                channel.Say(nick + " left the game. Next player: " + game.GetPlayer().nick);
                return;
            }
            channel.Say(nick + " left the game.");

            if (game.players.Count == 0)
            {
                lchans.Remove(game);
                game = null;
                GC.Collect();                 // Force calling LGPlayer::~LGPlayer
            }
        }
Beispiel #2
0
        void Cmd_start(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || game.GetPlayer(nick) == null)
            {
                E.Notice(nick, "You are not part of the game.");
                return;
            }

            if (game.is_active)
            {
                E.Notice(nick, "The game is already running.");
                return;
            }

            int total_players = game.players.Count;

            if (total_players < 3)
            {
                channel.Say(nick + ": At least 3 players are required to start the game.");
                return;
            }

            var cards = new List <string>();

            foreach (string card in CARD_TYPES)
            {
                int amount = (card == "Q") ? 3 : 4;
                while (amount > 0)
                {
                    cards.Add(card);
                    amount--;
                }
            }
            Utils.Shuffle(ref cards);

            foreach (string card in cards)
            {
                game.NextPlayer().cards.Add(card);
            }

            game.is_active = true;

            foreach (LGPlayer n in game.players)
            {
                E.Notice(n.nick, "Your cards: " + FormatCards(n.cards, true));
                Thread.Sleep(300);
            }
            game.CleanStack();

            channel.Say("Game started! Player " + game.GetPlayer().nick +
                        " can play the first card using \"$add <'main card'> <card nr.> [<card nr.> [<card nr.>]]\"" +
                        " (Card nr. from your hand)");

            CheckCards();
        }
Beispiel #3
0
        void Cmd_leave(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || game.GetPlayer(nick) == null)
            {
                E.Notice(nick, "You are not part of a liar game.");
                return;
            }

            OnUserLeave(nick);
        }
Beispiel #4
0
        void Cmd_join(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game != null && game.is_active)
            {
                channel.Say(nick + ": Please wait for " + game.GetPlayer() +
                            " to finish their game.");
                return;
            }

            if (game != null && game.GetPlayer(nick) != null)
            {
                E.Notice(nick, "You already joined the game.");
                return;
            }

            if (game == null)
            {
                game = new LGameChannel(channel.GetName());
                lchans.Add(game);
            }

            UserData user = channel.GetUserData(nick);

            user.cmd_scope = m_subcommand;
            game.players.Add(new LGPlayer(nick, user));

            int    count = game.players.Count;
            string text  = "Player " + nick + " joined the game. Total " + count + " players ready.";

            if (count > 2)
            {
                text += " If you want to start the game, use \"$start\"";
            }
            else if (count == 1)
            {
                text += " At least 3 players are required to start the game.";
            }
            channel.Say(text);
        }
Beispiel #5
0
        void Cmd_cards(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            if (game == null || !game.is_active)
            {
                E.Notice(nick, "There's no game or it did not start yet.");
                return;
            }

            LGPlayer player = game.GetPlayer(nick);

            if (player == null)
            {
                E.Notice(nick, "You are not part of the game.");
                return;
            }

            Utils.Shuffle(ref player.cards);
            E.Notice(nick, FormatCards(player.cards, true));
        }
Beispiel #6
0
        void CheckCards(string nick = null)
        {
            Channel      chan = p_manager.GetChannel();
            LGameChannel game = GetLChannel(chan.GetName());

            if (game == null || !game.is_active)
            {
                return;
            }

            List <string> player_remove = new List <string>();

            foreach (LGPlayer player in game.players)
            {
                int amount = player.cards.Count;

                if (amount >= 4)
                {
                    // Count cards
                    var cards = new Dictionary <string, int>();
                    foreach (string card in player.cards)
                    {
                        if (cards.ContainsKey(card))
                        {
                            cards[card]++;
                        }
                        else
                        {
                            cards.Add(card, 1);
                        }
                    }

                    // Discard pairs
                    var discarded = new List <string>();
                    foreach (KeyValuePair <string, int> card in cards)
                    {
                        if (card.Value >= 4)
                        {
                            player.cards.RemoveAll(item => item == card.Key);
                            discarded.Add(card.Key);
                        }
                    }
                    if (discarded.Count > 0)
                    {
                        chan.Say(player.nick + " can discard four " + FormatCards(discarded) +
                                 " cards. Left cards: " + player.cards.Count);
                        Thread.Sleep(300);
                    }
                }

                if (amount == 0)
                {
                    if (nick == null || (nick != null && nick != player.nick))
                    {
                        chan.Say(player.nick + " has no cards left. Congratulations, you're a winner!");
                        player_remove.Add(player.nick);
                    }
                    else
                    {
                        chan.Say(player.nick + " played " + Utils.Colorize("their last card", IRC_Color.ORANGE) + "!");
                    }
                }
                else if (amount <= 3)
                {
                    if (nick != null && nick == player.nick)
                    {
                        chan.Say(player.nick + " has " +
                                 Utils.Colorize("only " + amount + " cards", IRC_Color.ORANGE) + " left!");
                    }
                }
            }

            foreach (string player in player_remove)
            {
                OnUserLeave(player);
            }
        }
Beispiel #7
0
        void Cmd_check(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());

            #region Sanity check
            if (game == null || !game.is_active)
            {
                E.Notice(nick, "There's no game or it did not start yet.");
                return;
            }

            LGPlayer player = game.GetPlayer(nick);
            if (player == null)
            {
                E.Notice(nick, "You are not part of the game.");
                return;
            }
            if (player != game.GetPlayer())
            {
                E.Notice(nick, "It's not your turn yet. Please wait for " +
                         game.GetPlayer().nick);
                return;
            }
            if (game.main_card == "")
            {
                E.Notice(nick, "You cannot check an empty stack.");
                return;
            }
            #endregion

            player = null;
            string main_card        = game.main_card;
            bool   contains_invalid = game.stack_top.FindIndex(item => item != main_card) >= 0;

            string card_msg = "";
            if (contains_invalid)
            {
                card_msg = "One or more top cards were not a [" + main_card + "]. ";
            }
            else
            {
                card_msg = "The top cards were correct! ";

                game.NextPlayer();
            }

            card_msg += "(" + FormatCards(game.stack_top) + ") ";

            // Add cards to previous player
            game.GetPlayer(-1).cards.AddRange(game.stack_all);
            game.CleanStack();
            CheckCards();

            // "channel" reference is not updated after deleting the channel!
            if (GetLChannel(channel.GetName()) == null)
            {
                channel.Say(card_msg);
                return;
            }

            var prev_player = game.GetPlayer(-1);
            var curr_player = game.GetPlayer(0);

            card_msg += "Complete stack goes to " + prev_player.nick + ". " +
                        curr_player.nick + " can start with an empty stack.";

            channel.Say(card_msg);
            E.Notice(prev_player.nick, FormatCards(prev_player.cards, true));
            E.Notice(curr_player.nick, FormatCards(curr_player.cards, true));
        }
Beispiel #8
0
        void Cmd_add(string nick, string message)
        {
            Channel      channel = p_manager.GetChannel();
            LGameChannel game    = GetLChannel(channel.GetName());
            LGPlayer     player  = game != null?game.GetPlayer(nick) : null;

            #region Sanity check
            if (player == null || !game.is_active)
            {
                E.Notice(nick, "There's no game ongoing yet. Join & start to begin.");
                return;
            }

            if (player != game.GetPlayer())
            {
                E.Notice(nick, "It's not your turn yet. Please wait for " +
                         game.GetPlayer().nick);
                return;
            }
            #endregion

            string card       = Chatcommand.GetNext(ref message);
            string card_upper = card.ToUpper();
            string main_card  = game.main_card;

            // Check for valid card, correct name
            bool   valid_main_card = false;
            string cards           = "";
            for (int i = 0; i < CARD_TYPES.Length; i++)
            {
                string l_card = CARD_TYPES[i].ToUpper();
                if (l_card == card_upper)
                {
                    valid_main_card = true;
                    // Correct spelling
                    card = CARD_TYPES[i];
                    break;
                }
                if (l_card != "Q")
                {
                    cards += CARD_TYPES[i] + " ";
                }
            }

            // $lg <fake> <c1> <c2>
            if (main_card != "" && main_card != card)
            {
                channel.Say(nick + ": Wrong card type! Please pretend to place a card of type [" + main_card + "]!");
                return;
            }

            if (card_upper == "Q")
            {
                channel.Say(nick + ": The Queen is the bad card and can not be used as the main card of a stack.");
                return;
            }

            if (!valid_main_card)
            {
                channel.Say(nick + ": There is no such card type. Valid types: " + cards);
                return;
            }

            if (main_card == "")
            {
                main_card = card;
            }

            string[] card_mirror = player.cards.ToArray();

            var card_add = new List <int>();
            for (int n = 0; true; n++)
            {
                string index_s = Chatcommand.GetNext(ref message);
                if (index_s == "" && n == 0)
                {
                    channel.Say(nick + ": Expected arguments <'main card'> <index> [<index> ..]" +
                                "(Blue number: card value, Black number: index)");
                    return;
                }
                if (index_s == "")
                {
                    break;
                }

                int index_i = Utils.toInt(index_s) - 1;
                if (index_i < 0 || index_i >= card_mirror.Length)
                {
                    E.Notice(nick, "Invalid card index \"" + index_s + "\". Play one between 1 and " +
                             card_mirror.Length + " from your hand.");
                    return;
                }

                if (!card_add.Contains(index_i))
                {
                    card_add.Add(index_i);
                }
            }

            game.stack_top.Clear();
            foreach (int card_i in card_add)
            {
                string l_card = card_mirror[card_i];

                game.stack_all.Add(l_card);
                game.stack_top.Add(l_card);
                bool success = player.cards.Remove(l_card);
                if (!success)
                {
                    L.Log("m_lGame::$ladd, failed to remove cards", true);
                }
            }

            game.main_card = main_card;
            player         = game.NextPlayer();

            channel.Say("[LGame] Main card: [" + main_card + "]" +
                        ", Stack height: " + game.stack_all.Count +
                        ", Next player: " + player.nick);
            Thread.Sleep(300);
            E.Notice(player.nick, FormatCards(player.cards, true));

            CheckCards(nick);
        }