Пример #1
0
 public void CreateMeld(Meld meld)
 {
     Melds.Add(meld);
     foreach (var tile in meld.Tiles)
     {
         var found = TilesLeft.FirstOrDefault(q => q.Rank == tile.Rank && q.Suit == tile.Suit);
         if (found != null)
         {
             TilesLeft.Remove(found);
         }
         else
         {
             throw new Exception("Could not create meld");
         }
     }
 }
Пример #2
0
        readonly bool N暗刻(int n)
        {
            var setCount = Sets.Count(_ => _.刻子) + Melds.Count(_ => _.暗槓);

            if (自摸)
            {
                return(setCount == n);
            }

            if (Pairs.Contains(newTileInHand))
            {
                // 単騎待ち
                return(setCount == n);
            }
            else
            {
                // シャボ
                return(setCount == n + 1);
            }
        }
Пример #3
0
        /// <summary>
        /// Copies the data in the given player into this one.
        /// </summary>
        /// <param name="mp">The player data to copy.</param>
        public void CopyData(MahjongPlayer mp)
        {
            Score          = mp.Score;
            SeatWind       = mp.SeatWind;
            PrevailingWind = mp.PrevailingWind;

            while (BonusTiles.CardsInHand > 0)
            {
                BonusTiles.PlayCard(0);
            }

            Melds.Clear();

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

            BonusTiles.DrawCards(mp.BonusTiles.Cards);
            return;
        }
Пример #4
0
        /// <summary>
        /// Given a move encoded in m, will perform all the necessary work to make the player reflect the move occuring.
        /// </summary>
        /// <param name="m">The move to make. It is assumed that the move is valid (and not null).</param>
        /// <returns>Returns true if the move is valid and false otherwise.</returns>
        public override bool MakePlay(MahjongMove m)
        {
            // We assume that the move we're given is valid, so let's jump right in
            if (m.Pass)
            {
                return(true);
            }

            // Discarding is simple to deal with
            if (m.Discard)
            {
                CardsInHand.PlayCard(m.DiscardedTile);
                return(true);
            }

            // Melding takes a bit of work
            // Note that if we're melding to declare mahjong, the meld is fixed and must happen, so we do it here always
            if (m.Meld)
            {
                // First decide if we're upgrading a pung
                bool upgrade = false;

                if (m.MeldTiles.Kong)
                {
                    foreach (MahjongMeld meld in Melds)
                    {
                        if (meld.Pung && meld.Cards.Contains(m.DiscardedTile))
                        {
                            upgrade = true;
                            break;
                        }
                    }
                }

                if (upgrade)
                {
                    // If we're adding to a pung to make a kong, we only need to play the tile we drew (and we HAVE to have drawn the tile from the wall)
                    CardsInHand.PlayCard(m.DiscardedTile);

                    // We do also have to update the meld we already have
                    foreach (MahjongMeld meld in Melds)
                    {
                        if (meld.ConvertToKong(m.DiscardedTile))                        // This will eventually work and fail all other times
                        {
                            break;
                        }
                    }
                }
                else
                {
                    // Add the meld
                    Melds.Add(m.MeldTiles.Clone());

                    // We're not expanding a pung, so we don't have to worry about that case now
                    List <Card> meld = new List <Card>(m.MeldTiles.Cards);

                    if (!m.ConcealedMeld)                    // If this is a concealed meld, then we drew the tile we're currently melding
                    {
                        meld.Remove(m.DiscardedTile);        // We don't need to play the tile we don't technically have yet
                    }
                    foreach (Card c in meld)
                    {
                        CardsInHand.PlayCard(c);
                    }
                }
            }

            // If we have Mahjong, we need to put whatever is left of the player's hand into melds
            // This can occur as a meld is declared, so we don't return early before to catch that case here
            if (m.Mahjong)
            {
                List <MahjongMeld> mm = MahjongStaticFunctions.BestMahjong(CardsInHand, Melds, SeatWind, PrevailingWind, m.SelfPick);

                if (mm != null)                // This should always be the case, but let's be careful
                {
                    Melds = mm;
                }
            }

            return(true);
        }