Exemple #1
0
    def drop(self):
        """ try to discard every card to find the best """
        #print "drop_list: {0}".format(" ".join(self.gb.drop_list))
        result = []
        all_cards = [
            self.wang_list, self.tube_list, self.bamb_list, self.word_list,
            self.wind_list
        ]
        previous = ""
        for cards in all_cards:
            for i in range(len(cards)):
                """ avoid running same card """
                if (cards[i] == previous): continue
                c = cards.pop(i)
                previous = c
                mini, useful_amount, score = self.count_steps()
                cards.insert(i, c)
                result.append([mini, useful_amount, score, c])
                #print "min: {0}, useful_amount: {1}, score: {2}, dcard: {3}".format(mini, useful_amount, score, c)

        dcard = self.sorting_by_criteria(result)
        #print "\tGeniusAgent drop: {0}".format(dcard)
        ctype = GameBoard.CardType(dcard)
        all_cards[ctype - 1].remove(dcard)
        self.card_count -= 1
        return dcard
Exemple #2
0
 def _feedCard(self, card):
     ctype = GameBoard.CardType(card)
     if ctype == 1:
         self.wang_list.append(card)
         self.wang_list.sort()
         self.card_count += 1
         return True
     elif ctype == 2:
         self.tube_list.append(card)
         self.tube_list.sort()
         self.card_count += 1
         return True
     elif ctype == 3:
         self.bamb_list.append(card)
         self.bamb_list.sort()
         self.card_count += 1
         return True
     elif ctype == 4:
         self.word_list.append(card)
         self.word_list.sort()
         self.card_count += 1
         return True
     elif ctype == 5:
         self.wind_list.append(card)
         self.wind_list.sort()
         self.card_count += 1
         return True
     else:
         self.flow_list.append(card)
         self.flow_list.sort()
Exemple #3
0
    def draw(self, keep=False):
        card = self.gb.drawCard()
        #print "\tGeniusAgent draw: {0}".format(card)
        prewin_tiles = GameBoard.PreWinTiles(self)
        if card in prewin_tiles:
            self.gb.win_agent = self
            self.win_card = card
            self.win_by_draw += 1
            #print("\t[Test] Agent({0}) 自摸 {1}!".format(self.name, card))
            return

        #print("\t[Test] {0} draw {1}...".format(self.name, card))
        ctype = GameBoard.CardType(card)
        if ctype == 1:
            if self.wang_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.wang_list.append(card)
            self.wang_list.sort()
            self.card_count += 1
        elif ctype == 2:
            if self.tube_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.tube_list.append(card)
            self.tube_list.sort()
            self.card_count += 1
        elif ctype == 3:
            if self.bamb_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.bamb_list.append(card)
            self.bamb_list.sort()
            self.card_count += 1
        elif ctype == 4:
            if self.word_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.word_list.append(card)
            self.word_list.sort()
            self.card_count += 1
        elif ctype == 5:
            if self.wind_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.wind_list.append(card)
            self.wind_list.sort()
            self.card_count += 1
        else:
            self.flow_list.append(card)
            self.flow_list.sort()
            return self.draw()

        dcard = self.drop()
        return dcard
Exemple #4
0
    def sorting_by_criteria(self, result):
        """ sort by steps to prewin (small -> big) """
        result = sorted(result, key=lambda r: r[0])
        flag = False
        m = result[0][0]
        for i in range(len(result)):
            if (result[i][0] == m): continue
            flag = True
            break
        if not flag: i += 1
        result = result[:i]
        """ in prewin status, compare useful_amount only """
        if (result[0][0] == 0):
            result = sorted(result, key=lambda r: r[1], reverse=True)
            test = ""
            for r in result:
                test += "[{0}, {1}, {2}, {3}], ".format(r[0], r[1], r[2], r[3])
#			print "prewin status: {0}".format(test)
            self.current_best_state = [
                result[0][0], result[0][1], result[0][2]
            ]
            return result[0][3]
        """ sort by score (big -> small) """
        result = sorted(result, key=lambda r: r[2], reverse=True)
        flag = False
        m = result[0][2]
        for i in range(len(result)):
            if (result[i][2] == m): continue
            flag = True
            break
        if not flag: i += 1
        result = result[:i]
        """ sort by useful card amount (big -> small) """
        result = sorted(result, key=lambda r: r[1], reverse=True)
        """ choose one to discard """
        dcard = result[0][3]
        m = result[0][1]
        best = result[0]
        for r in result:
            if (r[1] != m): break
            ctype = GameBoard.CardType(r[3])
            if (ctype == 4) and (self.word_list.count(r[3]) == 1):
                dcard = r[3]
                best = r
            if (ctype == 5) and (self.wind_list.count(r[3]) == 1):
                dcard = r[3]
                best = r
        self.current_best_state = [r[0], r[1], r[2]]
        return dcard
Exemple #5
0
    def draw(self, keep=False):
        """ Draw card. (Required API by Agent)
        Gameboard will call this API to informat agent to draw card. Here should be responsible for:
        1. Call API:drawCard() from GameBoard object to draw card.
        2. Add drawn card into hand.
        3. Return card as dropped card. (In general, you will call API:drop() for dropped card)
        * Return:
          Dropped card."""
        card = self.gb.drawCard()
        if GameBoard.GoalState(self, card):  # Check goal state
            self.gb.win_agent = self
            self.win_card = card
            self.win_by_draw += 1
            print("\t[Test] Agent({0}) 自摸 {1}!".format(self.name, card))
            return
        #print("\t[Test] {0} draw {1}...".format(self.name, card))
        ctype = GameBoard.CardType(card)
        if ctype == 1:
            self.wang_list.append(card)
            self.wang_list.sort()
            self.card_count += 1
        elif ctype == 2:
            self.tube_list.append(card)
            self.tube_list.sort()
            self.card_count += 1
        elif ctype == 3:
            self.bamb_list.append(card)
            self.bamb_list.sort()
            self.card_count += 1
        elif ctype == 4:
            self.word_list.append(card)
            self.word_list.sort()
            self.card_count += 1
        elif ctype == 5:
            self.wind_list.append(card)
            self.wind_list.sort()
            self.card_count += 1
        else:
            self.flow_list.append(card)
            self.flow_list.sort()
            return self.draw()

        dcard = None
        if not keep:
            dcard = self.drop()
            #print("\t[Test] {0} drop {1}...".format(self.name, dcard))
            #self.gb.disCard(self, dcard)
        return dcard
Exemple #6
0
 def _isPrewin(self):
     prewin_tiles = GameBoard.PreWinTiles(self)
     if len(prewin_tiles) > 0:
         for tile in prewin_tiles:
             ctype = GameBoard.CardType(tile)
             if ctype == 1:
                 if tile in self.gb.wang_list:
                     return True
             elif ctype == 2:
                 if tile in self.gb.tube_list:
                     return True
             elif ctype == 3:
                 if tile in self.gb.bamb_list:
                     return True
             elif ctype == 4:
                 if tile in self.gb.word_list:
                     return True
             elif ctype == 5:
                 if tile in self.gb.wind_list:
                     return True
Exemple #7
0
 def _isPrewin(self):
     """ Check if entering pre-win(ready hand) status."""
     prewin_tiles = GameBoard.PreWinTiles(self)
     if len(prewin_tiles) > 0:
         for tile in prewin_tiles:
             ctype = GameBoard.CardType(tile)
             if ctype == 1:
                 if tile in self.gb.wang_list:
                     return True
             elif ctype == 2:
                 if tile in self.gb.tube_list:
                     return True
             elif ctype == 3:
                 if tile in self.gb.bamb_list:
                     return True
             elif ctype == 4:
                 if tile in self.gb.word_list:
                     return True
             elif ctype == 5:
                 if tile in self.gb.wind_list:
                     return True
Exemple #8
0
    def draw(self, keep=False):
        """ Draw card. (Required API by Agent)
        Gameboard will call this API to informat agent to draw card. Here should be responsible for:
        1. Call API:drawCard() from GameBoard object to draw card.
        2. Add drawn card into hand.
        3. Return card as dropped card. (In general, you will call API:drop() for dropped card)

        Different from the extended class, SmartAgent has its' own algorithm in drawing card:
        1. 使用 self.gb.drawCard() 從牌桌抽一張牌.
        2. 檢查是否滿足 Goal State (自摸).
           2.1 如果已經聽牌, 則打出抽到的牌.
        3. 檢查是否可以槓
           3.1 如果槓, 可以再抽一張.
        4. 選擇要放棄的牌.
        * Return:
          Dropped card."""
        card = self.gb.drawCard()
        prewin_tiles = GameBoard.PreWinTiles(self)
        if card in prewin_tiles:
            #if GameBoard.GoalState(self, card): # Check goal state
            self.gb.win_agent = self
            self.win_card = card
            self.win_by_draw += 1
            self.dprint("\t[Test] Agent({0}) 自摸 {1}!".format(self.name, card))
            return
        elif len(prewin_tiles) > 0:
            self.pwin_flag = True
            for tile in prewin_tiles:
                ctype = GameBoard.CardType(tile)
                if ctype == 1:
                    if tile in self.gb.wang_list:
                        return card
                elif ctype == 2:
                    if tile in self.gb.tube_list:
                        return card
                elif ctype == 3:
                    if tile in self.gb.bamb_list:
                        return card
                elif ctype == 4:
                    if tile in self.gb.word_list:
                        return card
                elif ctype == 5:
                    if tile in self.gb.wind_list:
                        return card

        self.dprint("\t[Test] {0} draw {1}...".format(self.name, card))
        ctype = GameBoard.CardType(card)
        if ctype == 1:
            if self.wang_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.wang_list.append(card)
            self.wang_list.sort()
            self.card_count += 1
        elif ctype == 2:
            if self.tube_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.tube_list.append(card)
            self.tube_list.sort()
            self.card_count += 1
        elif ctype == 3:
            if self.bamb_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.bamb_list.append(card)
            self.bamb_list.sort()
            self.card_count += 1
        elif ctype == 4:
            if self.word_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.word_list.append(card)
            self.word_list.sort()
            self.card_count += 1
        elif ctype == 5:
            if self.wind_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.wind_list.append(card)
            self.wind_list.sort()
            self.card_count += 1
        else:
            self.flow_list.append(card)
            self.flow_list.sort()
            return self.draw()

        dcard = None
        if not keep:
            dcard = self.drop()
            self.dprint("\t[Test] {0} drop {1}...".format(self.name, dcard))
            #self.gb.disCard(self, dcard)
        if (len(self.word_list) % 3 + len(self.wind_list) % 3 +
                len(self.tube_list) % 3 + len(self.wang_list) % 3 +
                len(self.bamb_list) % 3) == 0:
            self.wrong = True
        return dcard
Exemple #9
0
    def drop(self):
        """ Drop card from hand. (Required API by Agent)
        This API will implement the algorithm to deside the dropped card. It will be called during game when necessary.
        Agent is responsible for removing dropped card from hand when make decision.
        The implemented dropping card algorithm as below:
        1. 只有獨張的風牌或中發白
        2. 沒有機會形成 Triplet 或 Sequence 的萬/筒/條 (只有單張)
        3. 頭尾的先丟. (Ex. 1萬/9萬/1筒/9筒/1條/9條)
        4. 下家有丟過的先丟.
        5. 最後都沒有滿足, 任意丟一張 萬/筒/條.
        * Return
          Dropped card which being removed from hand.
        """
        card = ''
        # 1. 只有獨張的風牌或中發白就丟.
        if (not card) and len(self.word_list) == 1:
            card = self.word_list.pop()
            self.card_count -= 1
            return card
        else:
            for c in set(self.word_list):
                if self.word_list.count(c) == 1:
                    self.word_list.remove(c)
                    self.card_count -= 1
                    return c

        if (not card) and len(self.wind_list) == 1:
            card = self.wind_list.pop()
            self.card_count -= 1
            return card
        else:
            for c in set(self.wind_list):
                if self.wind_list.count(c) == 1:
                    self.wind_list.remove(c)
                    self.card_count -= 1
                    return c
        # 2. 沒有機會形成 Triplet 或 Sequence 的萬/筒/條 (只有單張)
        # 3. 頭尾的先丟. (Ex. 1萬/9萬/1筒/9筒/1條/9條)
        if (not card) and len(self.tube_list) > 0:
            for c in set(self.tube_list):
                #number = int(card[:1])
                if self.tube_list.count(c) > 1:
                    continue
                elif GameBoard.PrevCard(
                        c) in self.tube_list or GameBoard.NextCard(
                            c) in self.tube_list:
                    continue
                else:
                    self.tube_list.remove(c)
                    self.card_count -= 1
                    return c
            if (not card) and '1筒' in self.tube_list:
                card = '1筒'
                self.tube_list.remove(card)
                self.card_count -= 1
                return card
            elif (not card) and '9筒' in self.tube_list:
                card = '9筒'
                self.tube_list.remove(card)
                self.card_count -= 1
                return card

        if (not card) and len(self.wang_list) > 0:
            for c in set(self.wang_list):
                if self.wang_list.count(c) > 1:
                    continue
                elif GameBoard.PrevCard(
                        c) in self.wang_list or GameBoard.NextCard(
                            c) in self.wang_list:
                    continue
                else:
                    self.wang_list.remove(c)
                    self.card_count -= 1
                    return c
            if (not card) and '1萬' in self.wang_list:
                card = '1萬'
                self.wang_list.remove(card)
                self.card_count -= 1
                return card
            elif (not card) and '9萬' in self.wang_list:
                card = '9萬'
                self.wang_list.remove(card)
                self.card_count -= 1
                return card

        if (not card) and len(self.bamb_list) > 0:
            for c in set(self.bamb_list):
                if self.bamb_list.count(c) > 1:
                    continue
                elif GameBoard.PrevCard(
                        c) in self.bamb_list or GameBoard.NextCard(
                            c) in self.bamb_list:
                    continue
                else:
                    self.bamb_list.remove(c)
                    self.card_count -= 1
                    return c
            if (not card) and '1條' in self.bamb_list:
                card = '1條'
                self.bamb_list.remove(card)
                self.card_count -= 1
                return card
            elif (not card) and '9條' in self.bamb_list:
                card = '9條'
                self.bamb_list.remove(card)
                self.card_count -= 1
                return card

        # 4. 下家有丟過的先丟
        rightAgt = self.gb.rightOpponent(self)
        if rightAgt.name in self.gb.drop_record and len(
                self.gb.drop_record[rightAgt.name]) > 0:
            dc = self.gb.drop_record[rightAgt.name][-1]
            ct = GameBoard.CardType(dc)
            if ct == 1 and dc in self.wang_list:
                self.wang_list.remove(dc)
                self.card_count -= 1
                return dc
            elif ct == 2 and dc in self.tube_list:
                self.tube_list.remove(dc)
                self.card_count -= 1
                return dc
            elif ct == 3 and dc in self.bamb_list:
                self.bamb_list.remove(dc)
                self.card_count -= 1
                return dc
            elif ct == 4 and dc in self.word_list:
                self.word_list.remove(dc)
                self.card_count -= 1
                return dc
            elif ct == 5 and dc in self.wind_list:
                self.wind_list.remove(dc)
                self.card_count -= 1
                return dc

        # 5. 任意丟一張 萬/筒/條
        if (not card) and len(self.tube_list) > 0:
            card = self.tube_list.pop()
            self.card_count -= 1
            return card
        if (not card) and len(self.wang_list) > 0:
            card = self.wang_list.pop()
            self.card_count -= 1
            return card
        if (not card) and len(self.bamb_list) > 0:
            card = self.bamb_list.pop()
            self.card_count -= 1
            return card
Exemple #10
0
    def way_to_prewin(self, one):
        """
		kind = [triple, pair, neighbor, single]
		useful: how many cards can we get one more triple
		score: a metric to evaluate how good
			triple = 3, pair/consecutive neighbor = 2, non-consecutive = 1, single = 0
		"""
        kind = [0, 0, 0, 0]
        useful = []
        score = 0
        for part in one.split("\t"):
            #print "part: {0}".format(part)
            tmp = part.split()
            length = len(tmp)
            if (length == 3):  # triple
                kind[0] += 1
                score += 3
            elif (length == 1):  # single
                kind[3] += 1
            elif (tmp[0] == tmp[1]):  # pair
                kind[1] += 1
                useful.append("{0}".format(tmp[0]))
                score += 2
            else:
                kind[2] += 1
                n = GameBoard.NextCard(tmp[0])
                p = GameBoard.PrevCard(tmp[0])
                nn = GameBoard.NextCard(tmp[1])
                if (n == tmp[1]):  # consecutive neighbor
                    score += 2
                    if (p != None): useful.append(p)
                    if (nn != None): useful.append(nn)
                else:
                    useful.append(n)
                    score += 1

        #print "kind: {0}".format(kind)
        """ how many cards can we probably get """
        useful_amount = 0
        for card in set(useful):
            ctype = GameBoard.CardType(card)
            if (ctype == 1): a = self.wang_list.count(card)
            elif (ctype == 2): a = self.tube_list.count(card)
            elif (ctype == 3): a = self.bamb_list.count(card)
            elif (ctype == 4): a = self.word_list.count(card)
            else: a = self.wind_list.count(card)
            b = self.gb.drop_list.count(card)
            useful_amount += (4 - a - b)
        """
		1. enumerate, because goal state not too much
		2. counting pong_list so that we can focus on 16 cards
		3. check prewin first	
		"""
        goals = [[4, 1, 1, 0], [5, 0, 0, 1], [4, 2, 0, 0]]
        gpattern = [["***", "***", "***", "***", "##", "$$"],
                    ["***", "***", "***", "***", "***", "/"],
                    ["***", "***", "***", "***", "##", "##"]]
        result = [0, 0, 0]
        size = len(self.pong_list) / 3
        if ((size + kind[0]) > 4): return [0, useful_amount, score]
        for i in range(size):
            gpattern[0].remove("***")
            gpattern[1].remove("***")
            gpattern[2].remove("***")
        for number in range(3):
            k0 = kind[0]
            k1 = kind[1]
            k2 = kind[2]
            k3 = kind[3]
            p1 = gpattern[number]
            for i in range(k0):
                p1.remove("***")
            for i in range(min(k1, goals[number][1])):
                k1 -= 1
                p1.remove("##")
            for i in range(min(k2, goals[number][2])):
                k2 -= 1
                p1.remove("$$")
            #print "p1: {0}, size: {1}".format(p1, (k1+k2)*2+k3)
            step = 0
            two = k1 + k2
            for i in range(len(p1)):
                length = len(p1[i])
                if (length == 3):
                    if two:
                        two -= 1
                        step += 1
                    else:
                        step += 2
                elif (length == 2):
                    step += 1
            result[number] = step
        #print "steps to goal: {0}, useful: {1}".format(result, len(useful))

        return [min(result), useful_amount, score]
Exemple #11
0
    def find_all_combination(self, ctype, cards, comb_str, combination):
        if len(cards) == 0:
            combination.append(comb_str)
            return combination
        card = cards[0]
        ctype = GameBoard.CardType(card)
        if (ctype == 1) or (ctype == 2) or (ctype == 3):
            count = cards.count(card)
            if count == 3:
                copy = list(cards)
                copy.remove(card)
                copy.remove(card)
                copy.remove(card)
                new = "{0} {0} {0}\t".format(card)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            if count == 2:
                copy = list(cards)
                copy.remove(card)
                copy.remove(card)
                new = "{0} {0}\t".format(card)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            n = GameBoard.NextCard(card)
            if n != None: nn = GameBoard.NextCard(n)
            else: nn = ""
            if (n in cards) and (nn in cards):
                copy = list(cards)
                copy.remove(card)
                copy.remove(n)
                copy.remove(nn)
                new = "{0} {1} {2}\t".format(card, n, nn)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            if n in cards:
                copy = list(cards)
                copy.remove(card)
                copy.remove(n)
                new = "{0} {1}\t".format(card, n)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            if nn in cards:
                copy = list(cards)
                copy.remove(card)
                copy.remove(nn)
                new = "{0} {1}\t".format(card, nn)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            cards.remove(card)
            new = "{0}\t".format(card)
            self.find_all_combination(ctype, cards, comb_str + new,
                                      combination)

        if (ctype == 4) or (ctype == 5):
            count = cards.count(card)
            if count == 3:
                copy = list(cards)
                copy.remove(card)
                copy.remove(card)
                copy.remove(card)
                new = "{0} {0} {0}\t".format(card)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            if count == 2:
                copy = list(cards)
                copy.remove(card)
                copy.remove(card)
                new = "{0} {0}\t".format(card)
                self.find_all_combination(ctype, copy, comb_str + new,
                                          combination)
            cards.remove(card)
            new = "{0}\t".format(card)
            self.find_all_combination(ctype, cards, comb_str + new,
                                      combination)

        return combination
Exemple #12
0
    def draw(self, keep=False):
        card = self.gb.drawCard()
        if GameBoard.GoalState(self, card):  # Check goal state
            self.gb.win_agent = self
            self.win_card = card
            self.win_by_draw += 1
            print("\t[Test] Agent({0}) 自摸 {1}!".format(self.name, card))
            return

        print("\t[Test] {0} draw {1}...".format(self.name, card))
        ctype = GameBoard.CardType(card)
        if ctype == 1:
            if self.wang_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.wang_list.append(card)
            self.wang_list.sort()
            self.card_count += 1
        elif ctype == 2:
            if self.tube_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.tube_list.append(card)
            self.tube_list.sort()
            self.card_count += 1
        elif ctype == 3:
            if self.bamb_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.bamb_list.append(card)
            self.bamb_list.sort()
            self.card_count += 1
        elif ctype == 4:
            if self.word_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.word_list.append(card)
            self.word_list.sort()
            self.card_count += 1
        elif ctype == 5:
            if self.wind_list.count(card) == 3:  # 確認槓牌
                self._kong(ctype, card)
                return self.draw()
            self.wind_list.append(card)
            self.wind_list.sort()
            self.card_count += 1
        else:
            self.flow_list.append(card)
            self.flow_list.sort()
            return self.draw()

        dcard = None
        if not keep:
            dcard = self.drop()
            print("\t[Test] {0} drop {1}...".format(self.name, dcard))
            #self.gb.disCard(self, dcard)
        if len(self.word_list) % 3 + len(self.wind_list) % 3 + len(
                self.tube_list) % 3 + len(self.wang_list) % 3 + len(
                    self.bamb_list) % 3 != 2:
            self.wrong = True
        return dcard
Exemple #13
0
    def idraw(self):
        card = self.gb.drawCard()
        dctype = GameBoard.CardType(card)
        if GameBoard.GoalState(self, card):  # Check goal state
            self.gb.win_agent = self
            self.win_card = card
            self.win_by_draw += 1
            print("\t[Test] Agent({0}) 自摸 {1}!".format(self.name, card))
            return

        if dctype > 5:
            self.flow_list.append(card)
            self.flow_list.sort()
            return self.idraw()
        print("\t[Info] {0}: You draw {1}...".format(self, card))

        # 確認槓牌
        if dctype == 1:
            if self.wang_list.count(card) == 3:  # 確認槓牌
                kong_opt = input('\t[Info] Kong {0} (y/n): '.format(card))
                if len(kong_opt) > 0 and (kong_opt == 'y' or kong_opt == 'Y'):
                    self._kong(dctype, card)
                    return self.idraw()
        elif dctype == 2:
            if self.tube_list.count(card) == 3:  # 確認槓牌
                kong_opt = input('\t[Info] Kong {0} (y/n): '.format(card))
                if len(kong_opt) > 0 and (kong_opt == 'y' or kong_opt == 'Y'):
                    self._kong(dctype, card)
                    return self.idraw()
        elif dctype == 3:
            if self.bamb_list.count(card) == 3:  # 確認槓牌
                kong_opt = input('\t[Info] Kong {0} (y/n): '.format(card))
                if len(kong_opt) > 0 and (kong_opt == 'y' or kong_opt == 'Y'):
                    self._kong(dctype, card)
                    return self.idraw()
        elif dctype == 4:
            if self.word_list.count(card) == 3:  # 確認槓牌
                kong_opt = input('\t[Info] Kong {0} (y/n): '.format(card))
                if len(kong_opt) > 0 and (kong_opt == 'y' or kong_opt == 'Y'):
                    self._kong(dctype, card)
                    return self.idraw()
        elif dctype == 5:
            if self.wind_list.count(card) == 3:  # 確認槓牌
                kong_opt = input('\t[Info] Kong {0} (y/n): '.format(card))
                if len(kong_opt) > 0 and (kong_opt == 'y' or kong_opt == 'Y'):
                    self._kong(dctype, card)
                    return self.idraw()

        # choose drop card
        dcard = self._chooseDropCard()

        if dcard:
            if dctype == 1:
                self.wang_list.append(card)
                self.wang_list.sort()
                self.card_count += 1
            elif dctype == 2:
                self.tube_list.append(card)
                self.tube_list.sort()
                self.card_count += 1
            elif dctype == 3:
                self.bamb_list.append(card)
                self.bamb_list.sort()
                self.card_count += 1
            elif dctype == 4:
                self.word_list.append(card)
                self.word_list.sort()
                self.card_count += 1
            elif dctype == 5:
                self.wind_list.append(card)
                self.wind_list.sort()
                self.card_count += 1
            print("\t[Test] {0} drop card={1}...".format(self.name, dcard))
            #self.gb.disCard(self, dcard)
            return dcard
        else:
            print("\t[Test] {0} drop draw card={1}...".format(self.name, card))
            #self.gb.disCard(self, card)
            return card