コード例 #1
0
ファイル: Program.cs プロジェクト: FireEmblem16/Mahjong
        /// <summary>
        /// Determines the next move for this AI to make.
        /// </summary>
        /// <param name="state">The state of the game. This will be cloned so that the AI does not affect the actual game state.</param>
        /// <returns>Returns the next move to make based on the current game state.</returns>
        public MahjongMove GetNextMove(GameState <MahjongMove> state)
        {
            MahjongGameState s  = state as MahjongGameState;
            MahjongAIPlayer  ai = state.GetPlayer(Player) as MahjongAIPlayer;
            MahjongPlayer    mp = ai as MahjongPlayer;

            // Pass if it's not this AI's turn
            if (s.ActivePlayer != Player)
            {
                return(new MahjongMove());
            }

            if (MahjongStaticFunctions.HasMahjong(ai.CardsInHand, mp.Melds))
            {
                return(new MahjongMove(true));
            }

            // Pick a random tile to discard
            int r = rand.Next(0, (int)ai.CardsInHand.CardsInHand);

            rc++;

            return(new MahjongMove(ai.CardsInHand.Cards[r]));
        }
コード例 #2
0
ファイル: Program.cs プロジェクト: FireEmblem16/Mahjong
        /// <summary>
        /// Determines the next move for this AI to make.
        /// </summary>
        /// <param name="state">The state of the game. This will be cloned so that the AI does not affect the actual game state.</param>
        /// <returns>Returns the next move to make based on the current game state.</returns>
        public MahjongMove GetNextMove(GameState <MahjongMove> state)
        {
            MahjongGameState s  = state as MahjongGameState;
            MahjongAIPlayer  ai = state.GetPlayer(Player) as MahjongAIPlayer;
            MahjongPlayer    mp = ai as MahjongPlayer;

            // Pass if it's not this AI's turn and it can't meld a pung or kong
            if (s.ActivePlayer != Player)
            {
                if (s.AvailableTile == null)
                {
                    return(new MahjongMove()); // The active player is going out, so there's nothing we can do
                }
                else
                {
                    switch (ai.CardsInHand.CountCard(s.AvailableTile))
                    {
                    case 1:
                        // If this is the last tile we needed to declare mahjong, go for it
                        if (ai.CardsInHand.CardsInHand == 1)
                        {
                            List <Card> eye = new List <Card>();
                            eye.Add(s.AvailableTile.Clone());
                            eye.Add(s.AvailableTile.Clone());

                            return(new MahjongMove(new MahjongMeld(eye, false), s.AvailableTile, true));
                        }

                        // Pass otherwise
                        return(new MahjongMove());

                    case 2:
                        List <Card> p2 = new List <Card>();
                        p2.Add(s.AvailableTile.Clone());
                        p2.Add(s.AvailableTile.Clone());
                        p2.Add(s.AvailableTile.Clone());

                        Hand htemp2 = new StandardHand(ai.CardsInHand.Cards);
                        htemp2.PlayCard(s.AvailableTile);
                        htemp2.PlayCard(s.AvailableTile);

                        MahjongMeld        m2     = new MahjongMeld(p2, false);
                        List <MahjongMeld> melds2 = new List <MahjongMeld>();

                        foreach (MahjongMeld m22 in mp.Melds)
                        {
                            melds2.Add(m22.Clone());
                        }

                        return(new MahjongMove(m2, s.AvailableTile, MahjongStaticFunctions.HasMahjong(htemp2, melds2)));

                    case 3:
                        List <Card> p3 = new List <Card>();
                        p3.Add(s.AvailableTile.Clone());
                        p3.Add(s.AvailableTile.Clone());
                        p3.Add(s.AvailableTile.Clone());
                        p3.Add(s.AvailableTile.Clone());

                        Hand htemp3 = new StandardHand(ai.CardsInHand.Cards);
                        htemp3.PlayCard(s.AvailableTile);
                        htemp3.PlayCard(s.AvailableTile);
                        htemp3.PlayCard(s.AvailableTile);

                        MahjongMeld        m3     = new MahjongMeld(p3, false);
                        List <MahjongMeld> melds3 = new List <MahjongMeld>();

                        foreach (MahjongMeld m33 in mp.Melds)
                        {
                            melds3.Add(m33.Clone());
                        }

                        return(new MahjongMove(m3, s.AvailableTile, MahjongStaticFunctions.HasMahjong(htemp3, melds3)));

                    default:
                        return(new MahjongMove());    // If we naturally drew a kong, it'll stick around until we're forced to discard one of the tiles or just lose
                    }
                }
            }

            // If it's our turn, check if we have mahjong
            if (MahjongStaticFunctions.HasMahjong(ai.CardsInHand, mp.Melds))
            {
                return(new MahjongMove(true));
            }

            // Find all the singletons
            List <int> singletons = new List <int>();

            for (int i = 0; i < ai.CardsInHand.CardsInHand; i++)
            {
                if (ai.CardsInHand.CountCard(ai.CardsInHand.Cards[i]) == 1)
                {
                    singletons.Add(i);
                }
            }

            // If we don't have a singleton tile, we'll have to part with another
            if (singletons.Count == 0)
            {
                singletons.Add(rand.Next(0, (int)ai.CardsInHand.CardsInHand));
                rc++;
            }

            // Pick a random singleton tile to discard
            int r = rand.Next(0, singletons.Count);

            rc++;

            return(new MahjongMove(ai.CardsInHand.Cards[r]));
        }