Exemplo n.º 1
0
        bool CheckGameEndDelete(string channel)
        {
            UnoChannel uno = GetUnoChannel(channel);

            if (uno == null)
            {
                return(true);
            }

            if (uno.players.Count > 1)
            {
                return(false);
            }

            if (uno.is_active)
            {
                E.Say(channel, "[UNO] Game ended");
            }

            m_settings.SyncFileContents();             // Save player data

            m_channels.Remove(channel);
            uno = null;             // So that GC works
            GC.Collect();
            return(true);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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));
        }
Exemplo n.º 4
0
        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);
        }
Exemplo n.º 5
0
        void Cmd_Leave(string nick, string message)
        {
            Channel    channel = p_manager.GetChannel();
            UnoChannel uno     = GetUnoChannel(channel.GetName());

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

            OnUserLeave(nick);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        public override void OnUserLeave(string nick)
        {
            Channel    channel    = p_manager.GetChannel();
            UnoChannel uno        = GetUnoChannel(channel.GetName());
            string     old_player = uno == null ? null : uno.current_player;

            if (uno == null || !uno.RemovePlayer(channel, nick))
            {
                return;
            }

            // Either close the game or echo the status
            if (!CheckGameEndDelete(channel.GetName()))
            {
                if (nick == old_player)
                {
                    TellGameStatus(channel);
                }
            }
        }
Exemplo n.º 8
0
        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 = 0x03;
                try {
                    modes = Convert.ToByte(modes_s, 16);
                } catch { }
                uno = new UnoChannel(modes);
                m_channels[channel.GetName()] = uno;
            }

            UserData user = channel.GetUserData(nick);

            user.cmd_scope = m_subcommand;
            uno.players.Add(new UnoPlayer(nick, user));
            uno.current_player = nick;

            channel.Say("[UNO] " + uno.players.Count +
                        " player(s) are waiting for a new UNO game. " +
                        string.Format("Modes: 0x{0:X2}", uno.modes));
        }
Exemplo n.º 9
0
        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);
            }
        }
Exemplo n.º 10
0
        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));
        }