public Meld(List <Tile> tiles, MeldType type, Tile lastDraw = null, bool isExposed = false) { Tiles = tiles; Type = type; LastDraw = lastDraw; IsExposed = isExposed; }
private Meld(IEnumerable <Tile> tiles, Tile?called, Tile?added, MeldType meldType) { Tiles = tiles.OrderBy(t => t.TileId).ToList(); CalledTile = called; AddedTile = added; MeldType = meldType; IsKan = meldType == MeldType.CalledKan || meldType == MeldType.ClosedKan || meldType == MeldType.AddedKan; }
//Constructor public OpenMeld(MeldType type, List <Tile> tiles, int playerNumber) { Type = type; _tiles = new SortedTileCollection(tiles); PlayerNumber = playerNumber; for (int i = 0; i < Tiles.Count; i++) { Tiles[i].InOpenMeld = true; } }
public static Meld MakeMeld(MeldType meldType, string man = "", string pin = "", string sou = "", string honors = "", bool isOpen = true) { var tiles = TileIds.Parse(man: man, pin: pin, sou: sou, honors: honors); return(new Meld(meldType, tiles, isOpen, tiles[0], who: 0)); }
public Card GetCardByMeldType(MeldType meldType) //Get the first card found of the meld type { foreach (Card card in mCards) { if (card.MeldType == meldType) { return(card); } } Debug.Log("Card not found, error"); return(null); }
public Meld(MeldType meldType = MeldType.None, TileIds tiles = null, bool opened = true, TileId calledTile = null, int?who = null, int?fromWho = null) { Type = meldType; Tiles = tiles; Opened = opened; CalledTile = calledTile; Who = who; FromWho = fromWho; }
public virtual int NumOfCardsOfType(MeldType cardType) //get the number of cards that belong to a meld type { int count = 0; if (mCards.Count != 0) { foreach (Card card in mCards) { if (card.MeldType == cardType) { count++; } } } return(count); }
public double simulate() //It simulates all the way to the end of the game, from currentNode { //Based on the result of the simulation(Win/lose), it return different sim value, used to judge whether its a good node or not MCTSState simState = new MCTSState(state.currentTurn, state.drawDeck, state.discardDeck, state.humanCards, state.AICards, state.hasDrawn, state.lastDiscard, state.lastDrawDeck); simState.stateResult = state.stateResult; int simValue = int.MinValue; while (simState.stateResult == MCTSState.Result.None && simState.drawDeck.Count > 0) { if (!simState.hasDrawn)//In Draw phase { simState.hasDrawn = true; if (simState.currentTurn == Main.Turn.AI) //AI's turn { if (simState.discardDeck.Count > 0) { if (simState.AICards.NumOfCardsOfType(simState.discardDeck.GetTop().MeldType) == 2) //if drawing from discard deck can form a meld { simState.AICards.Add(simState.discardDeck.Pop()); //Draw from discard deck } else { simState.AICards.Add(simState.drawDeck.Pop()); //Other wise just take from draw deck } } else //If no card in discard deck, draw from draw deck { simState.AICards.Add(simState.drawDeck.Pop()); } if (simState.drawDeck.Count <= 0) //After draw finish, if the draw deck is empty, mark the game result as draw { simState.stateResult = MCTSState.Result.Draw; break; } if (CardsInHand.CheckVictory(simState.AICards)) //If victory goal met, mark the game result as AIWIN { simState.stateResult = MCTSState.Result.AIWin; break; } } else if (simState.currentTurn == Main.Turn.Human) //Human's turn,everything same as above, basically duplicated code { if (simState.discardDeck.Count > 0) { if (simState.humanCards.NumOfCardsOfType(simState.discardDeck.GetTop().MeldType) == 2) //if drawing from discard deck can form a meld { simState.humanCards.Add(simState.discardDeck.Pop()); } else { simState.humanCards.Add(simState.drawDeck.Pop()); } } else { simState.humanCards.Add(simState.drawDeck.Pop()); } if (simState.drawDeck.Count <= 0) { simState.stateResult = MCTSState.Result.Draw; break; } if (CardsInHand.CheckVictory(simState.humanCards)) { simState.stateResult = MCTSState.Result.HumanWin; break; } } } else if (simState.hasDrawn)//In discard phase { simState.hasDrawn = false; if (simState.currentTurn == Main.Turn.AI) //AI's turn { MeldType typeToDiscard = MostUselessType(simState.AICards); //Get the least valuable meld type among the cards in hand Card cardToDiscard = simState.AICards.GetCardByMeldType(typeToDiscard); //get a card of that meld type, then discard it simState.AICards.Remove(cardToDiscard); simState.AICards.LeftShiftElement(); simState.discardDeck.Add(cardToDiscard); simState.discardDeck.LeftShiftElement(); simState.currentTurn = Main.Turn.Human; } else //duplicated code { MeldType typeToDiscard = MostUselessType(simState.humanCards); Card cardToDiscard = simState.humanCards.GetCardByMeldType(typeToDiscard); simState.humanCards.Remove(cardToDiscard); simState.humanCards.LeftShiftElement(); simState.discardDeck.Add(cardToDiscard); simState.discardDeck.LeftShiftElement(); simState.currentTurn = Main.Turn.AI; } } } switch (simState.stateResult) { case MCTSState.Result.Draw: { // Debug.Log("Draw result simed"); simValue = 0; break; } case MCTSState.Result.HumanWin: { // Debug.Log("HumanWin result simed"); simValue = -1; //1 means victory, -1 means defeat break; } case MCTSState.Result.AIWin: { //Debug.Log("AIWin result simed"); simValue = 1; break; } default: { // Debug.LogError("illegal simStateResult value"); break; } } return(simValue); }
public Meld(bool revealed, params Tile[] tiles) { Revealed = revealed; Tiles = new Tile[tiles.Length]; Array.Copy(tiles, Tiles, tiles.Length); Array.Sort(Tiles); IsKong = false; switch (Tiles.Length) { case 1: Type = MeldType.Single; break; case 2: if (!Tiles[0].EqualsIgnoreColor(Tiles[1])) { throw new ArgumentException("Invalid meld composition"); } Type = MeldType.Pair; break; case 3: Type = Tiles[0].EqualsIgnoreColor(Tiles[2]) ? MeldType.Triplet : MeldType.Sequence; if (Type == MeldType.Triplet) { if (!Tiles[0].EqualsIgnoreColor(Tiles[1])) { throw new ArgumentException("Invalid meld composition"); } } else if (Type == MeldType.Sequence) { if (Tiles[0].Suit == Suit.Z) { throw new ArgumentException("Suit of Z cannot form sequences"); } if (Tiles[0].Suit != Tiles[1].Suit || Tiles[0].Suit != Tiles[2].Suit) { throw new ArgumentException("Invalid meld composition"); } if (Tiles[1].Rank != Tiles[0].Rank + 1 || Tiles[2].Rank != Tiles[0].Rank + 2) { throw new ArgumentException("Invalid meld composition"); } } else { throw new ArgumentException("Will not happen"); } break; case 4: for (int i = 1; i < 4; i++) { if (!Tiles[i].EqualsIgnoreColor(Tiles[i - 1])) { throw new ArgumentException("Invalid meld composition"); } } Type = MeldType.Triplet; IsKong = true; break; default: throw new ArgumentException("Invalid tile count"); } }
public bool IdenticalTo(MeldType type, Tile first) { return(Type == type && First.EqualsIgnoreColor(first)); }
MeldType meldType; //Regardless of its suit, as long as the cards can form a meld, they belong to the same meld type public Card(Suit mSuit, int mValue, MeldType mMeldType) //sets value for variables { this.value = mValue; this.suit = mSuit; this.meldType = mMeldType; }