Ejemplo n.º 1
0
 def __init__(self, paifu_path_list, n_max=100):
     self.paifu_path_list = paifu_path_list
     self.data_size = len(paifu_path_list) * n_max
     self.shanten_calculator = Shanten()
     self.n_max = n_max
     # self.device =  'cuda' if torch.cuda.is_available() else 'cpu'
     self.device = 'cpu'
Ejemplo n.º 2
0
def CountShanten(haishi):
    '''
    牌姿データからシャンテン数を数える
    '''

    man = ''
    pin = ''
    sou = ''
    honors = ''

    for x in haishi.split(','):
        if table.pai2[int(x)][1] == 'm':
            man += table.pai2[int(x)][0]
        if table.pai2[int(x)][1] == 'p':
            pin += table.pai2[int(x)][0]
        if table.pai2[int(x)][1] == 's':
            sou += table.pai2[int(x)][0]
        if table.pai2[int(x)][1] == 'z':
            honors += table.pai2[int(x)][0]

    shanten = Shanten()
    tiles = TilesConverter.string_to_34_array(
        man=man,
        pin=pin,
        sou=sou,
        honors=honors,
    )

    c = shanten.calculate_shanten(tiles)
    return (c if c > 0 else 0)
Ejemplo n.º 3
0
    def __init__(self):
        self.shanten = Shanten()
        self.agari = Agari()
        self.finished_hand = HandCalculator()

        self.data_to_save = []

        self.csv_exporter = CSVExporter()
Ejemplo n.º 4
0
 def __init__(self, player_seat, opponent):
     self.playereat = player_seat
     self.isOpponent = opponent
     self.hand = np.zeros(34, int)
     self.discarded = np.zeros(34, int)
     self.melds = np.zeros((34, 3), int)
     self.lastDraw = None
     self.riichi = False
     self.calshanten = Shanten()
Ejemplo n.º 5
0
 def __init__(self):
     """
     changed the input from filename to tiles_state_and_action data
     By Jun Lin
     """
     self.shanten_calculator = Shanten()
     self.hc = HandCalculator()
     self.sc = ScoresCalculator()
     self.hand_cache_shanten = {}
     self.hand_cache_points = {}
Ejemplo n.º 6
0
 def __init__(self, tiles, dora_indicators, revealed_tiles):
     self.tiles = tiles
     self.Shanten_calculater = Shanten()
     self.Hand_Calculator = HandCalculator()
     self.Tiles = TilesConverter()
     self.shanten = self.Shanten_calculater.calculate_shanten(
         self.Tiles.to_34_array(self.tiles))
     self.Hand_Config = HandConfig(is_riichi=True)
     self.dora_indicators = dora_indicators
     self.revealed_tiles = revealed_tiles
Ejemplo n.º 7
0
def getTile(s: str) -> dict:
    #translate s into supported format
    if len(s) == 0:
        return {}
    tiles = TilesConverter.one_line_string_to_136_array(s, True)
    test = {}
    # check tiles length
    added = []
    if len(tiles) % 3 == 0:
        #3n, add a random tile
        while True:
            tmp = randint(0, 135)
            if tmp not in tiles:
                tiles.append(tmp)
                added.append(tmp)
                break
    if len(tiles) % 3 == 1:
        #3n+1, add a random tile
        while True:
            tmp = randint(0, 135)
            if tmp not in tiles:
                tiles.append(tmp)
                added.append(tmp)
                break
    if len(added) > 0:
        test[-1] = added
    # now is a normal form
    tiles.sort()
    avaliable = []
    for i in range(0, 136):
        if i not in tiles:
            avaliable.append(i)
    calculator = Shanten()
    baseShanten = calculator.calculate_shanten(
        TilesConverter.to_34_array(tiles))
    if baseShanten == -1:
        return {-2: '已和牌'}
    #14*122 try

    tmp = copy.deepcopy(tiles)
    for t in tiles:
        tmp.remove(t)
        one_try = []
        for i in avaliable:
            tmp.append(i)
            res = calculator.calculate_shanten(
                TilesConverter.to_34_array(sorted(tmp)))
            if res < baseShanten:
                one_try.append(i)
            tmp.remove(i)
        t = 4 * (t // 4)
        if len(one_try) > 0 and t not in test.keys():
            test[t] = copy.deepcopy(one_try)
        tmp.append(t)
    return test
Ejemplo n.º 8
0
    def test_shanten_for_not_completed_hand(self):
        shanten = Shanten()

        tiles = self._string_to_34_array(sou="111345677", pin="1", man="567")
        self.assertEqual(shanten.calculate_shanten_for_regular_hand(tiles), 1)

        tiles = self._string_to_34_array(sou="111345677", man="567")
        self.assertEqual(shanten.calculate_shanten_for_regular_hand(tiles), 1)

        tiles = self._string_to_34_array(sou="111345677", man="56")
        self.assertEqual(shanten.calculate_shanten_for_regular_hand(tiles), 0)
Ejemplo n.º 9
0
    def __init__(self, player):
        super(ImplementationAI, self).__init__(player)

        self.agari = Agari()
        self.shanten = Shanten()
        self.defence = DefenceHandler(player)
        self.hand_divider = HandDivider()
        self.finished_hand = HandCalculator()
        self.previous_shanten = 7
        self.current_strategy = None
        self.waiting = []
        self.in_defence = False
        self.last_discard_option = None
Ejemplo n.º 10
0
    def test_shanten_number_and_chiitoitsu(self):
        shanten = Shanten()

        tiles = self._string_to_34_array(sou="114477", pin="114477", man="77")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         Shanten.AGARI_STATE)

        tiles = self._string_to_34_array(sou="114477", pin="114477", man="76")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         0)

        tiles = self._string_to_34_array(sou="114477", pin="114479", man="76")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         1)

        tiles = self._string_to_34_array(sou="114477",
                                         pin="14479",
                                         man="76",
                                         honors="1")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         2)

        tiles = self._string_to_34_array(sou="114477",
                                         pin="13479",
                                         man="76",
                                         honors="1")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         3)

        tiles = self._string_to_34_array(sou="114467",
                                         pin="13479",
                                         man="76",
                                         honors="1")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         4)

        tiles = self._string_to_34_array(sou="114367",
                                         pin="13479",
                                         man="76",
                                         honors="1")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         5)

        tiles = self._string_to_34_array(sou="124367",
                                         pin="13479",
                                         man="76",
                                         honors="1")
        self.assertEqual(shanten.calculate_shanten_for_chiitoitsu_hand(tiles),
                         6)
Ejemplo n.º 11
0
    def test_shanten_number_and_open_sets(self):
        shanten = Shanten()

        tiles = self._string_to_34_array(sou='44467778', pin='222567')
        self.assertEqual(shanten.calculate_shanten(tiles), Shanten.AGARI_STATE)

        melds = [self._string_to_open_34_set(sou='777')]
        self.assertEqual(shanten.calculate_shanten(tiles, melds), 0)

        tiles = self._string_to_34_array(sou='23455567', pin='222', man='345')
        melds = [
            self._string_to_open_34_set(man='345'),
            self._string_to_open_34_set(sou='555'),
        ]
        self.assertEqual(shanten.calculate_shanten(tiles, melds), 0)
Ejemplo n.º 12
0
def shanten():
    shanten = Shanten()
    req = flask.request.get_json()

    try:
        tiles = TilesConverter.one_line_string_to_34_array(req["hands"])
    except KeyError:
        return flask.jsonify({"error": "hands required"}), 400

    result = shanten.calculate_shanten(tiles)

    if result == -2:
        return flask.jsonify({"error": "hands over 14 tiles"}), 400

    return flask.jsonify({"shanten": result, "error": None})
Ejemplo n.º 13
0
 def draw_tile(self, tile):
     """
     :param tile: 136 tile format
     :return:
     """
     self.player.in_tempai = False
     self.shanten_calculator = Shanten()
     Tile = TilesConverter()
     current_shanten = self.shanten_calculator.calculate_shanten(
         Tile.to_34_array(self.player.tiles))
     logger.debug('Current_shanten:{}'.format(current_shanten))
     if current_shanten == 0:
         self.player.in_tempai = True
     logger.debug('whether_in_tempai:{}'.format(self.player.in_tempai))
     self.shanten_calculator = None
Ejemplo n.º 14
0
 def check_can_reach(self, player):
     if self.open_cnt[player] > 0:
         return 0
     now_reach = self.reach[player][0]
     for i in range(136):
         if now_reach[i][0]:
             return 0
     now_closehand = [
         i for i in range(136) if self.closehand[player][0][i][0] == 1
     ]
     #import mahjong
     shanten = Shanten()
     tiles = TilesConverter.to_34_array(now_closehand)
     result = shanten.calculate_shanten(tiles)
     return result <= 0
Ejemplo n.º 15
0
def tenpai(tiles, sute):
    shanten = Shanten()
    if len(tiles) == 34:
        # [3,1,1,...,3,0,...,0]
        tiles_34 = tiles
    else:
        # man='1112345678999', pin='', sou='', honors=''
        tiles_34 = TilesConverter.string_to_34_array(tiles)

    result = [0] * 34
    for i in range(34):
        if tiles_34[i] < 4 and not sute[i]:
            tiles_34[i] += 1
            if shanten.calculate_shanten(tiles_34) == -1:
                result[i] = 1
            tiles_34[i] -= 1
    return result
Ejemplo n.º 16
0
    def __init__(self, player):
        self.player = player
        self.table = player.table

        self.chi = Chi(player)
        self.pon = Pon(player)
        self.kan = Kan(player)
        self.riichi = Riichi(player)
        self.discard = Discard(player)
        self.grp = GlobalRewardPredictor()
        self.hand_builder = HandBuilder(player, self)
        self.shanten_calculator = Shanten()
        self.hand_cache_shanten = {}
        self.placement = player.config.PLACEMENT_HANDLER_CLASS(player)
        self.finished_hand = HandCalculator()
        self.hand_divider = HandDivider()

        self.erase_state()
Ejemplo n.º 17
0
    def __init__(self, player):
        self.player = player
        self.table = player.table

        self.kan = Kan(player)
        self.agari = Agari()
        self.shanten_calculator = Shanten()
        self.defence = TileDangerHandler(player)
        self.riichi = Riichi(player)
        self.hand_divider = HandDivider()
        self.finished_hand = HandCalculator()
        self.hand_builder = HandBuilder(player, self)
        self.placement = player.config.PLACEMENT_HANDLER_CLASS(player)

        self.suji = Suji(player)
        self.kabe = Kabe(player)

        self.erase_state()
Ejemplo n.º 18
0
    def __init__(self, player):
        super(ImplementationAI, self).__init__(player)

        self.agari = Agari()
        self.shanten_calculator = Shanten()
        self.defence = DefenceHandler(player)
        self.riichi = Riichi(player)
        self.hand_divider = HandDivider()
        self.finished_hand = HandCalculator()
        self.hand_builder = HandBuilder(player, self)

        self.erase_state()
Ejemplo n.º 19
0
def test_game(ai):
    pai = TEST_INIT_PAI.copy()
    random.shuffle(pai)

    calculator = HandCalculator()
    config = HandConfig(is_tsumo=True)
    config.yaku.yakuhai_place = config.yaku.east
    config.yaku.yakuhai_round = config.yaku.east

    # 1. 내 초기 패 13개 + 쯔모 1개
    hand = pai[:14].copy()
    tsumo = pai[13]
    # 2. tsumo 하자
    for x in range(1, TEST_STEP + 1):
        # DEBUG: 정상 작동하는지 중간 패 과정 출력
        logging.debug("%02d: %s", x, TilesConverter.to_one_line_string(hand))
        # 점수 확인
        result = calculator.estimate_hand_value(hand, tsumo)
        if not result.error:
            # 화료가 되었다는 뜻이다. 친의 쯔모인 3배 점수를 반환하자
            return result.cost['main'] * 3

        if x == TEST_STEP:
            break
        # 버린다
        discard = ai.next_move(hand, tsumo, TEST_STEP - x - 1)
        hand.remove(discard)
        # 쯔모한다
        tsumo = pai[14 + x]
        hand.append(tsumo)
    # 마지막으로 텐파이인지 확인한다
    # 샹텐수가 0이면 텐파이이다
    hand_34 = TilesConverter.to_34_array(hand)
    shanten = Shanten()
    result = shanten.calculate_shanten(hand_34)
    logging.debug('@: %d', result)
    if result == 0:
        return TEST_TEN_SCORE
    return TEST_NOTEN_SCORE
Ejemplo n.º 20
0
    def test_shanten_number_and_open_sets(self):
        shanten = Shanten()

        tiles = self._string_to_34_array(sou="44467778", pin="222567")
        self.assertEqual(shanten.calculate_shanten(tiles), Shanten.AGARI_STATE)

        tiles = self._string_to_34_array(sou="44468", pin="222567")
        self.assertEqual(shanten.calculate_shanten(tiles), 0)

        tiles = self._string_to_34_array(sou="68", pin="222567")
        self.assertEqual(shanten.calculate_shanten(tiles), 0)

        tiles = self._string_to_34_array(sou="68", pin="567")
        self.assertEqual(shanten.calculate_shanten(tiles), 0)

        tiles = self._string_to_34_array(sou="68")
        self.assertEqual(shanten.calculate_shanten(tiles), 0)

        tiles = self._string_to_34_array(sou="88")
        self.assertEqual(shanten.calculate_shanten(tiles), Shanten.AGARI_STATE)
Ejemplo n.º 21
0
class AI(defaultAI):
    def __init__(self):
        defaultAI.__init__(self)
        self.shanten = Shanten()
        self.log = logging.getLogger('ShantenAI')

    def next_move(self, hand, tsumo, remain_number):
        min_shanten = 8
        check = [False] * 34  # 핸드 중복 확인
        check_shanten = [8] * 14  # 손에 있는 14개 중에 어떤 것이 샹텐이 작은지 확인하는 배열

        hand_34 = TilesConverter.to_34_array(hand)

        for x in range(len(hand)):
            x4 = hand[x] // 4
            if check[x4]:  # 같은 타일이면 체크 안해도 됨
                continue
            check[x4] = True

            hand_34[x4] -= 1
            max_shanten = -2
            for y in range(34):
                if y == x4 or hand_34[y] == 4:
                    continue
                hand_34[y] += 1
                result = self.shanten.calculate_shanten(hand_34)
                if result > max_shanten:
                    max_shanten = result
                hand_34[y] -= 1
            hand_34[x4] += 1
            if min_shanten > max_shanten:
                min_shanten = max_shanten
            check_shanten[x] = max_shanten

        check_discard = []  #무엇을 버려야 할지 결정해주는 배열
        for x in range(14):
            if check_shanten[x] == min_shanten:  #최소 샨텐에 해당하는 번째의 패이면
                check_discard.append(x)

        self.log.debug("#: %d", min_shanten)
        return hand[random.choice(check_discard)]

    def get_name(self):
        return "shanten_min"
Ejemplo n.º 22
0
    def test_shanten_number_and_chitoitsu(self):
        shanten = Shanten()

        tiles = self._string_to_34_array(sou='114477', pin='114477', man='77')
        self.assertEqual(shanten.calculate_shanten(tiles), Shanten.AGARI_STATE)

        tiles = self._string_to_34_array(sou='114477', pin='114477', man='76')
        self.assertEqual(shanten.calculate_shanten(tiles), 0)

        tiles = self._string_to_34_array(sou='114477', pin='114479', man='76')
        self.assertEqual(shanten.calculate_shanten(tiles), 1)

        tiles = self._string_to_34_array(sou='114477', pin='14479', man='76', honors='1')
        self.assertEqual(shanten.calculate_shanten(tiles), 2)
Ejemplo n.º 23
0
    def test_shanten_number_and_kokushi_musou(self):
        shanten = Shanten()

        tiles = self._string_to_34_array(sou='19', pin='19', man='19', honors='12345677')
        self.assertEqual(shanten.calculate_shanten(tiles), Shanten.AGARI_STATE)

        tiles = self._string_to_34_array(sou='129', pin='19', man='19', honors='1234567')
        self.assertEqual(shanten.calculate_shanten(tiles), 0)

        tiles = self._string_to_34_array(sou='129', pin='129', man='19', honors='123456')
        self.assertEqual(shanten.calculate_shanten(tiles), 1)

        tiles = self._string_to_34_array(sou='129', pin='129', man='129', honors='12345')
        self.assertEqual(shanten.calculate_shanten(tiles), 2)
Ejemplo n.º 24
0
####################################################################

melds = [
    Meld(meld_type=Meld.PON,
         tiles=TilesConverter.string_to_136_array(man='444'))
]

result = calculator.estimate_hand_value(
    tiles, win_tile, melds=melds, config=HandConfig(has_open_tanyao=True))
print_hand_result(result)

####################################################################
# Shanten calculation                                              #
####################################################################

shanten = Shanten()
tiles = TilesConverter.string_to_34_array(man='13569', pin='123459', sou='443')
result = shanten.calculate_shanten(tiles)

print(result)

####################################################################
# Kazoe as a sanbaiman                                             #
####################################################################

tiles = TilesConverter.string_to_136_array(man='22244466677788')
win_tile = TilesConverter.string_to_136_array(man='7')[0]
melds = [Meld(Meld.KAN, TilesConverter.string_to_136_array(man='2222'), False)]

dora_indicators = [
    TilesConverter.string_to_136_array(man='1')[0],
Ejemplo n.º 25
0
class ImplementationAI(InterfaceAI):
    version = '0.0.1'

    agari = None
    shanten = None
    defence = None
    hand_divider = None
    finished_hand = None
    last_discard_option = None

    previous_shanten = 7
    in_defence = False
    waiting = None

    current_strategy = None

    def __init__(self, player):
        super(ImplementationAI, self).__init__(player)

        self.agari = Agari()
        self.shanten = Shanten()
        self.defence = DefenceHandler(player)
        self.hand_divider = HandDivider()
        self.finished_hand = HandCalculator()
        self.previous_shanten = 7
        self.current_strategy = None
        self.waiting = []
        self.in_defence = False
        self.last_discard_option = None

    def init_hand(self):
        """
        Let's decide what we will do with our hand (like open for tanyao and etc.)
        """
        self.determine_strategy()

    def erase_state(self):
        self.current_strategy = None
        self.in_defence = False
        self.last_discard_option = None

    def draw_tile(self, tile):
        """
        :param tile: 136 tile format
        :return:
        """
        self.determine_strategy()

    def discard_tile(self, discard_tile):
        # we called meld and we had discard tile that we wanted to discard
        if discard_tile is not None:
            if not self.last_discard_option:
                return discard_tile

            return self.process_discard_option(self.last_discard_option,
                                               self.player.closed_hand, True)

        results, shanten = self.calculate_outs(self.player.tiles,
                                               self.player.closed_hand,
                                               self.player.open_hand_34_tiles)

        selected_tile = self.process_discard_options_and_select_tile_to_discard(
            results, shanten)

        # bot think that there is a threat on the table
        # and better to fold
        # if we can't find safe tiles, let's continue to build our hand
        if self.defence.should_go_to_defence_mode(selected_tile):
            if not self.in_defence:
                logger.info('We decided to fold against other players')
                self.in_defence = True

            defence_tile = self.defence.try_to_find_safe_tile_to_discard(
                results)
            if defence_tile:
                return self.process_discard_option(defence_tile,
                                                   self.player.closed_hand)
        else:
            self.in_defence = False

        return self.process_discard_option(selected_tile,
                                           self.player.closed_hand)

    def process_discard_options_and_select_tile_to_discard(
            self, results, shanten, had_was_open=False):
        tiles_34 = TilesConverter.to_34_array(self.player.tiles)

        # we had to update tiles value there
        # because it is related with shanten number
        for result in results:
            result.tiles_count = self.count_tiles(result.waiting, tiles_34)
            result.calculate_value(shanten)

        # current strategy can affect on our discard options
        # so, don't use strategy specific choices for calling riichi
        if self.current_strategy:
            results = self.current_strategy.determine_what_to_discard(
                self.player.closed_hand, results, shanten, False, None,
                had_was_open)

        return self.chose_tile_to_discard(results)

    def calculate_outs(self, tiles, closed_hand, open_sets_34=None):
        """
        :param tiles: array of tiles in 136 format
        :param closed_hand: array of tiles in 136 format
        :param open_sets_34: array of array with tiles in 34 format
        :return:
        """
        tiles_34 = TilesConverter.to_34_array(tiles)
        closed_tiles_34 = TilesConverter.to_34_array(closed_hand)
        is_agari = self.agari.is_agari(tiles_34,
                                       self.player.open_hand_34_tiles)

        results = []
        for hand_tile in range(0, 34):
            if not closed_tiles_34[hand_tile]:
                continue

            tiles_34[hand_tile] -= 1

            shanten = self.shanten.calculate_shanten(tiles_34, open_sets_34)

            waiting = []
            for j in range(0, 34):
                if hand_tile == j or tiles_34[j] == 4:
                    continue

                tiles_34[j] += 1
                if self.shanten.calculate_shanten(tiles_34,
                                                  open_sets_34) == shanten - 1:
                    waiting.append(j)
                tiles_34[j] -= 1

            tiles_34[hand_tile] += 1

            if waiting:
                results.append(
                    DiscardOption(player=self.player,
                                  shanten=shanten,
                                  tile_to_discard=hand_tile,
                                  waiting=waiting,
                                  tiles_count=self.count_tiles(
                                      waiting, tiles_34)))

        if is_agari:
            shanten = Shanten.AGARI_STATE
        else:
            shanten = self.shanten.calculate_shanten(tiles_34, open_sets_34)

        return results, shanten

    def count_tiles(self, waiting, tiles_34):
        n = 0
        for item in waiting:
            n += 4 - self.player.total_tiles(item, tiles_34)
        return n

    def try_to_call_meld(self, tile, is_kamicha_discard):
        if not self.current_strategy:
            return None, None
        if len(self.player.discards) <= 5 and tile // 4 <= 27:
            return None, None
        meld, discard_option = self.current_strategy.try_to_call_meld(
            tile, is_kamicha_discard)
        tile_to_discard = None
        if discard_option:
            self.last_discard_option = discard_option
            tile_to_discard = discard_option.tile_to_discard

        return meld, tile_to_discard

    def determine_strategy(self):
        # for already opened hand we don't need to give up on selected strategy
        if self.player.is_open_hand and self.current_strategy:
            return False
        return False
        old_strategy = self.current_strategy
        self.current_strategy = None

        # order is important, the first appropriate strtegy will be used
        strategies = []

        if self.player.table.has_open_tanyao:
            strategies.append(TanyaoStrategy(BaseStrategy.TANYAO, self.player))

        strategies.append(YakuhaiStrategy(BaseStrategy.YAKUHAI, self.player))
        strategies.append(HonitsuStrategy(BaseStrategy.HONITSU, self.player))

        for strategy in strategies:
            if strategy.should_activate_strategy():
                self.current_strategy = strategy

        if self.current_strategy:
            if not old_strategy or self.current_strategy.type != old_strategy.type:
                message = '{} switched to {} strategy'.format(
                    self.player.name, self.current_strategy)
                if old_strategy:
                    message += ' from {}'.format(old_strategy)
                logger.debug(message)
                logger.debug('With hand: {}'.format(
                    TilesConverter.to_one_line_string(self.player.tiles)))

        if not self.current_strategy and old_strategy:
            logger.debug('{} gave up on {}'.format(self.player.name,
                                                   old_strategy))

        return self.current_strategy and True or False

    def chose_tile_to_discard(self, results: [DiscardOption]) -> DiscardOption:
        """
        Try to find best tile to discard, based on different valuations
        """
        def sorting(x):
            # - is important for x.tiles_count
            # in that case we will discard tile that will give for us more tiles
            # to complete a hand
            return x.shanten, -x.tiles_count, x.valuation

        had_to_be_discarded_tiles = [
            x for x in results if x.had_to_be_discarded
        ]
        if had_to_be_discarded_tiles:
            had_to_be_discarded_tiles = sorted(had_to_be_discarded_tiles,
                                               key=sorting)
            selected_tile = had_to_be_discarded_tiles[0]
        else:
            results = sorted(results, key=sorting)
            # remove needed tiles from discard options
            results = [x for x in results if not x.had_to_be_saved]

            # let's chose most valuable tile first
            temp_tile = results[0]
            # and let's find all tiles with same shanten
            results_with_same_shanten = [
                x for x in results if x.shanten == temp_tile.shanten
            ]
            possible_options = [temp_tile]
            for discard_option in results_with_same_shanten:
                # there is no sense to check already chosen tile
                if discard_option.tile_to_discard == temp_tile.tile_to_discard:
                    continue

                # we don't need to select tiles almost dead waits
                if discard_option.tiles_count <= 2:
                    continue

                # let's check all other tiles with same shanten
                # maybe we can find tiles that have almost same tiles count number
                if temp_tile.tiles_count - 2 < discard_option.tiles_count < temp_tile.tiles_count + 2:
                    possible_options.append(discard_option)

            # let's sort got tiles by value and let's chose less valuable tile to discard
            possible_options = sorted(possible_options,
                                      key=lambda x: x.valuation)
            selected_tile = possible_options[0]

        return selected_tile

    def process_discard_option(self,
                               discard_option,
                               closed_hand,
                               force_discard=False):
        self.waiting = discard_option.waiting
        self.player.ai.previous_shanten = discard_option.shanten
        self.player.in_tempai = self.player.ai.previous_shanten == 0

        # when we called meld we don't need "smart" discard
        if force_discard:
            return discard_option.find_tile_in_hand(closed_hand)

        last_draw_34 = self.player.last_draw and self.player.last_draw // 4 or None
        if self.player.last_draw not in AKA_DORA_LIST and last_draw_34 == discard_option.tile_to_discard:
            return self.player.last_draw
        else:
            return discard_option.find_tile_in_hand(closed_hand)

    def estimate_hand_value(self, win_tile, tiles=None, call_riichi=False):
        """
        :param win_tile: 34 tile format
        :param tiles:
        :param call_riichi:
        :return:
        """
        win_tile *= 4

        # we don't need to think, that our waiting is aka dora
        if win_tile in AKA_DORA_LIST:
            win_tile += 1

        if not tiles:
            tiles = self.player.tiles

        tiles += [win_tile]

        config = HandConfig(is_riichi=call_riichi,
                            player_wind=self.player.player_wind,
                            round_wind=self.player.table.round_wind,
                            has_aka_dora=self.player.table.has_aka_dora,
                            has_open_tanyao=self.player.table.has_open_tanyao)

        result = self.finished_hand.estimate_hand_value(
            tiles, win_tile, self.player.melds,
            self.player.table.dora_indicators, config)
        return result

    def should_call_riichi(self):
        print(self.player.discards)
        # empty waiting can be found in some cases
        if not self.waiting:
            return False

        if self.in_defence:
            return False

        #If we tenpai fast enough
        if len(self.player.discards) <= 8:
            return True
        if len(self.player.discards) >= 14:
            return False

        # we have a good wait, let's riichi
        if len(self.waiting) > 1:
            return True

        waiting = self.waiting[0]
        tiles = self.player.closed_hand + [waiting * 4]
        closed_melds = [x for x in self.player.melds if not x.opened]
        for meld in closed_melds:
            tiles.extend(meld.tiles[:3])

        tiles_34 = TilesConverter.to_34_array(tiles)

        results = self.hand_divider.divide_hand(tiles_34)
        result = results[0]

        count_of_pairs = len([x for x in result if is_pair(x)])
        # with chitoitsu we can call a riichi with pair wait
        if count_of_pairs == 7:
            return True

        for hand_set in result:
            # better to not call a riichi for a pair wait
            # it can be easily improved
            if is_pair(hand_set) and waiting in hand_set:
                return False

        return True

    def should_call_kan(self, tile, open_kan):
        """
        Method will decide should we call a kan,
        or upgrade pon to kan
        :param tile: 136 tile format
        :param open_kan: boolean
        :return: kan type
        """
        # we don't need to add dora for other players
        if self.player.ai.in_defence:
            return None

        if open_kan:
            # we don't want to start open our hand from called kan
            if not self.player.is_open_hand:
                return None

            # there is no sense to call open kan when we are not in tempai
            if not self.player.in_tempai:
                return None

            # we have a bad wait, rinshan chance is low
            if len(self.waiting) < 2:
                return None

        tile_34 = tile // 4
        tiles_34 = TilesConverter.to_34_array(self.player.tiles)
        closed_hand_34 = TilesConverter.to_34_array(self.player.closed_hand)
        pon_melds = [x for x in self.player.open_hand_34_tiles if is_pon(x)]

        # let's check can we upgrade opened pon to the kan
        if pon_melds:
            for meld in pon_melds:
                # tile is equal to our already opened pon,
                # so let's call chankan!
                if tile_34 in meld:
                    return Meld.CHANKAN

        count_of_needed_tiles = 4
        # for open kan 3 tiles is enough to call a kan
        if open_kan:
            count_of_needed_tiles = 3

        # we have 3 tiles in our hand,
        # so we can try to call closed meld
        if closed_hand_34[tile_34] == count_of_needed_tiles:
            if not open_kan:
                # to correctly count shanten in the hand
                # we had do subtract drown tile
                tiles_34[tile_34] -= 1

            melds = self.player.open_hand_34_tiles
            previous_shanten = self.shanten.calculate_shanten(tiles_34, melds)

            melds += [[tile_34, tile_34, tile_34]]
            new_shanten = self.shanten.calculate_shanten(tiles_34, melds)

            # called kan will not ruin our hand
            if new_shanten <= previous_shanten:
                return Meld.KAN

        return None

    def should_call_win(self, tile, enemy_seat):
        return True

    def enemy_called_riichi(self, enemy_seat):
        """
        After enemy riichi we had to check will we fold or not
        it is affect open hand decisions
        :return:
        """
        if self.defence.should_go_to_defence_mode():
            self.in_defence = True

    @property
    def enemy_players(self):
        """
        Return list of players except our bot
        """
        return self.player.table.players[1:]
Ejemplo n.º 26
0
import numpy as np
from mahjong.shanten import Shanten
from tqdm import tqdm
from itertools import product

from utils import *

np.random.seed(0)


def check_ryuiso(hand):
    return np.isin(hand, [19, 20, 21, 23, 25, 32]).all()


shanten = Shanten()

cases = []
for key in tqdm(product(range(5), repeat=9), total=5 ** 9):
    if sum(key) == 14:
        hand = [0] * 18 + list(key) + [0] * 7  # 索子14枚
    elif sum(key) == 12:
        hand = [0] * 18 + list(key) + [0, 0, 0, 0, 0, 2, 0]  # 索子12枚 + 發2枚
    elif sum(key) == 11:
        hand = [0] * 18 + list(key) + [0, 0, 0, 0, 0, 3, 0]  # 索子11枚 + 發3枚
    else:
        continue

    if shanten.calculate_shanten(hand) == -1:
        # 和了形の場合
        tiles = flatten_tile34(hand)
        win_tile = np.random.choice(tiles)
Ejemplo n.º 27
0
    def step(self, action):
        """
        Run one step of the environment. When current episode is ended
        (any player calls, the game ends with a winner or draw),then reset is called
        to reset the environment
        :param action: an action of the agent player
        :return: observation of the game state, reward of the action, whether the episode is ended, whether the move is validated
        as real players move
        """
        # Episode is finished
        if self.finish:
            return self.toReturn(self.state), 0., True, False
        # Action is not a possible move
        if action not in self.possibleActions(self.state):
            return self.toReturn(self.state), 0., False, False

        s = self.steps[self.current_step]
        # Step until player's discarding
        while s[0] > 0 or (s[0] == 0 and s[1] == 0):
            self.playermove()
            if self.current_step >= len(self.steps):
                return self.toReturn(self.state), 0., True, 0
            s = self.steps[self.current_step]
            # Episode is finished by opponents
            if self.finish:
                return self.toReturn(self.state), 0., True, 0
        # Draw and discard
        # s[0] = player_number
        # s[1] = move type 0 draw, 1 discard
        # s[2] = card number
        is_playermove = 0
        called = 0
        next_s = self.steps[self.current_step + 1]
        if s[0] == 0 and s[1] == 1:  # Player discarding, possible move
            if action == convert(
                    s[2]):  # Move validated as the same as real player, good
                self.playerdiscard(action)
                is_playermove = True
                shanten = Shanten().calculate_shanten(
                    self.state['Players'][0]
                    [0])  # Calculate the distance from winning
                shanten_prv = Shanten().calculate_shanten(
                    self.state['Previous'][0][0]
                    [0])  # Calculate previous distance
                if next_s[1] > 1 and next_s[0] == 0:  #Discarded get called, bad
                    called = 1
                return self.toReturn(self.state), self.cal_reward(
                    shanten, shanten_prv, is_playermove,
                    called), False, is_playermove
            else:  # unexpected move, finish
                self.playerdiscard(action)
                self.finish = True
                shanten = Shanten().calculate_shanten(
                    self.state['Players'][0]
                    [0])  # Calculate the distance from winning
                shanten_prv = Shanten().calculate_shanten(
                    self.state['Previous'][0][0]
                    [0])  # Calculate previous distance
                return self.toReturn(self.state), self.cal_reward(
                    shanten, shanten_prv, is_playermove,
                    called), True, is_playermove

        return self.toReturn(self.state), -10., True, 0
Ejemplo n.º 28
0
from keras.models import Sequential
from keras.layers import Dense
from keras.optimizers import Adam
from keras import backend as K
from keras.utils.training_utils import multi_gpu_model
from keras.utils import plot_model
from keras import losses
from collections import deque
import tensorflow as tf
from copy import deepcopy
from datetime import datetime
from time import time

Nmai_mahjong = 5

shanten = Shanten()
pailist = []
tehailist = []
senpai = []
result = 0
syanten = 0
paisID = np.zeros([136, 3])


class Mahjong():
    ripaitehai = []

    def pais(self):
        global paisID
        for num in range(0, 136):
            pailist.append(num)
Ejemplo n.º 29
0
class PaifuDataset(torch.utils.data.Dataset):
    pai_list = [
        "1m",
        "2m",
        "3m",
        "4m",
        "5m",
        "r5m",
        "6m",
        "7m",
        "8m",
        "9m",  #萬子
        "1p",
        "2p",
        "3p",
        "4p",
        "5p",
        "r5p",
        "6p",
        "7p",
        "8p",
        "9p",  #筒子
        "1s",
        "2s",
        "3s",
        "4s",
        "5s",
        "r5s",
        "6s",
        "7s",
        "8s",
        "9s",  #索子
        "東",
        "南",
        "西",
        "北",
        "白",
        "發",
        "中"
    ]

    def __init__(self, paifu_path_list, n_max=100):
        self.paifu_path_list = paifu_path_list
        self.data_size = len(paifu_path_list) * n_max
        self.shanten_calculator = Shanten()
        self.n_max = n_max
        # self.device =  'cuda' if torch.cuda.is_available() else 'cpu'
        self.device = 'cpu'

    def __len__(self):
        return self.data_size

    def __getitem__(self, idx):
        paifu = None

        file_idx = idx // self.n_max
        inner_idx = idx % self.n_max

        with open(self.paifu_path_list[file_idx], 'rb') as f:
            paifu = pickle.load(f)
        paifu = paifu[inner_idx]
        x, y = self.paifu_state_to_xy(paifu)
        # x = paifu['x'].to(self.device)
        # y = paifu['y'].to(self.device)
        return x, y
        # return paifu['x'], paifu['y']

    def paifu_state_to_xy(self, state):
        # device =  'cuda' if torch.cuda.is_available() else 'cpu'
        device = 'cpu'

        # action
        # Discard: 37, Reach:2 , Chow: 2, Pong: 2, Kong: 2
        x = {}

        positions = self.get_positions(state['action']['who'])

        # hand
        hand = state['hands'][state['action']['who']]
        hand = self.pais2ids(hand)
        x['hand'] = self.normalize_pai_list(hand, device)

        # discards : direction
        x['discards'] = self.normalize_discards(state['discards'], positions,
                                                device)

        # Shanten : direction
        x['shanten'], x['shanten_diff'] = self.calc_shantens(hand, device)

        # n_hands_list
        # x['n_hands_list'] = [len(h) for h in state['hands']]
        x['n_hands_list'] = [len(state['hands'][p]) for p in positions[1:]]

        # paifu id
        x['paifu_id'] = state['paifu_id']

        if state['action']['type'] == 'discard':
            y = state['hands'][state['action']['who']].index(
                state['action']['tile'])

            y = []
            n_players = 4
            for i in range(n_players - 1):
                enemy_hand = state['hands'][(state['action']['who'] + i + 1) %
                                            n_players]
                enemy_hand = self.pais2ids(enemy_hand)
                sep_token = 39
                y += enemy_hand
                y += [sep_token]
                # y += [i] * len(enemy_hand)
                # y += [4]

            # pad_token = 1
            pad_token = -100
            y += [pad_token] * ((13 + 1) * 3 + 1 - len(y))
            y = torch.tensor(y, dtype=torch.long, device=device)

        # melds : direction
        x['melds'] = [
            self.normalize_melds([m for m in state['melds'] if m['who'] == i],
                                 device) for i in positions
        ]

        # action_meld_tiles
        if state['action']['type'] in ['chow', 'pong', 'kong']:
            x['action_meld_tiles'] = self.normalize_action_meld_tiles(
                state['action']['meld_state']['meld_tiles'], device)
        else:
            x['action_meld_tiles'] = torch.zeros(4,
                                                 dtype=torch.long,
                                                 device=device)

        # menzen : direction
        x['menzen'] = torch.tensor([state['menzen'][i] for i in positions],
                                   dtype=torch.long,
                                   device=device)

        # reach_state : direction
        x['reach_state'] = torch.tensor(
            [state['reach_state'][i] for i in positions],
            dtype=torch.long,
            device=device)

        # n_reach
        x['n_reach'] = torch.tensor([min([state['n_reach'], 2])],
                                    dtype=torch.long,
                                    device=device)

        # reach_ippatsu : direction
        x['reach_ippatsu'] = torch.tensor(
            [state['reach_ippatsu'][i] for i in positions],
            dtype=torch.long,
            device=device)

        # doras
        x['doras'] = self.normalize_doras(state['doras'], device)

        # dans : direction
        x['dans'] = torch.tensor([state['dans'][i] for i in positions],
                                 dtype=torch.long,
                                 device=device)

        # rates : direction
        x['rates'] = self.normalize_rates(state['rates'],
                                          positions,
                                          device=device)

        # oya : direction
        x['oya'] = torch.tensor(
            [(state['oya'] - state['action']['who'] + 4) % 4],
            dtype=torch.long,
            device=device)

        # scores : direction
        x['scores'] = self.normalize_scores(state['scores'], positions, device)

        # n_honba
        x['n_honba'] = torch.tensor([min([state['n_honba'], 3])],
                                    dtype=torch.long,
                                    device=device)

        # n_round
        x['n_round'] = torch.tensor([state['n_round']],
                                    dtype=torch.long,
                                    device=device)

        # sanma_or_yonma
        x['sanma_or_yonma'] = torch.tensor([state['sanma_or_yonma']],
                                           dtype=torch.long,
                                           device=device)

        # han_or_ton
        x['han_or_ton'] = torch.tensor([state['han_or_ton']],
                                       dtype=torch.long,
                                       device=device)

        # aka_ari
        x['aka_ari'] = torch.tensor([state['aka_ari']],
                                    dtype=torch.long,
                                    device=device)

        # kui_ari
        x['kui_ari'] = torch.tensor([state['kui_ari']],
                                    dtype=torch.long,
                                    device=device)

        # who
        x['who'] = torch.tensor([state['action']['who']],
                                dtype=torch.long,
                                device=device)

        x['sum_discards'] = torch.tensor(
            [self.calc_sum_discards(state['discards'])],
            dtype=torch.long,
            device=device)

        return x, y

    def calc_sum_discards(self, discards):
        #  0から11 : 0
        # 12から23 : 1
        # 24から35 : 2
        # 36から47 : 3
        # 48から59 : 4
        # 60以上   : 5
        sum_discards = sum([len(d) for d in discards])

        if sum_discards >= 60:
            return 5

        return sum_discards // (4 * 3)

    def normalize_score(self, score):
        # 0 : 4000以下(満貫は2000-4000だから)
        # 1 : 4001から8000
        # …
        # 11 : 44000から48000
        # 12 : 48001以上

        score = (score - 1) // 4000

        if score < 0:
            return 0

        if score > 12:
            return 12

        return score

    def normalize_scores(self, scores, positions, device):
        return torch.tensor(
            [self.normalize_score(scores[i]) for i in positions],
            dtype=torch.long,
            device=device)

    def normalize_rate(self, rate):
        rate = int(rate) // 100 - 14

        if rate < 0:
            return 0

        if rate > 9:
            return 9

        return rate

    def normalize_rates(self, rates, positions, device):
        # id : rate range
        # 0 : 1499以下
        # 1 : 1500から1600
        # …
        # 9 : 2300以上

        return torch.tensor([self.normalize_rate(rates[i]) for i in positions],
                            dtype=torch.long,
                            device=device)

    def normalize_doras(self, doras, device, max_len=5):
        doras_tensor = torch.zeros(max_len, dtype=torch.long, device=device)
        l = len(doras)
        doras = self.pais2ids(doras)
        doras_tensor[:l] = torch.tensor(doras, dtype=torch.long, device=device)
        return doras_tensor

    def normalize_action_meld_tiles(self, tiles, device, max_len=4):
        tiles_tensor = torch.zeros(max_len, dtype=torch.long, device=device)
        l = len(tiles)
        tiles = self.pais2ids(tiles)
        tiles_tensor[:l] = torch.tensor(tiles, dtype=torch.long, device=device)

        return tiles_tensor

    def normalize_melds(self, melds, device, max_len=20):
        meld_tensor_list = [self.meld2tensor(meld, device) for meld in melds]
        meld_tensor = torch.zeros((2, max_len),
                                  dtype=torch.long,
                                  device=device)

        if len(meld_tensor_list) < 1:
            return meld_tensor

        meld_tensor_cat = torch.cat(meld_tensor_list, dim=1)
        l = meld_tensor_cat.size()[1]
        if l > max_len:
            print('Invalid meld data.')
            print(meld_tensor_cat)
        meld_tensor[:, :l] = meld_tensor_cat
        return meld_tensor

    def meld2tensor(self, meld, device):
        if meld['meld_type'] == 2:
            # Add Kan
            tiles = [self.pais2ids(meld['meld_tiles'])[0]]
        else:
            tiles = self.pais2ids(meld['meld_tiles'])

        l = len(tiles)
        tile_ids = torch.tensor(tiles, dtype=torch.long, device=device)
        token_type = torch.full((l, ),
                                fill_value=meld['meld_type'],
                                dtype=torch.long,
                                device=device)
        return torch.tensor([*tile_ids, *token_type]).reshape([2, -1])

    def normalize_discards(self, discards, positions, device):
        max_n_discards = 25
        l = len(discards)
        res = torch.zeros((4, max_n_discards), dtype=torch.long, device=device)

        for i, pos in enumerate(positions):
            res[i, :len(discards[pos])] = torch.tensor(self.pais2ids(
                discards[pos]),
                                                       dtype=torch.long,
                                                       device=device)
        return res

    def calc_shantens(self, hand, device):
        shantens = []
        hand_34_count = self.to_34_count(hand)
        hand_34 = self.to_34_array(hand)
        base_shanten, _ = self.calc_shanten(hand_34_count)

        # for tile in hand_34:
        #     hand_34_count[tile] -= 1
        #     shanten, _ = self.calc_shanten(hand_34_count)
        #     if shanten > base_shanten:
        #         shantens.append(1)
        #     else:
        #         shantens.append(0)
        #     hand_34_count[tile] += 1

        l = len(shantens)
        x = torch.full((14, ), fill_value=-1, dtype=torch.long, device=device)
        # x[:l] = torch.tensor(shantens, dtype=torch.long, device=device)

        base_shanten = min([base_shanten, 6]) + 1
        base_shanten = torch.tensor([base_shanten],
                                    dtype=torch.long,
                                    device=device)

        return base_shanten, x

    def to_34_array(self, hand):
        return [self.to_34(t) for t in hand]

    def to_34_count(self, hand):
        res = [0] * 34
        for tile in hand:
            res[self.to_34(tile)] += 1
        return res

    def to_34(self, tile):
        if tile <= 5:
            return tile - 1
        if tile <= 15:
            return tile - 2
        if tile <= 25:
            return tile - 3
        return tile - 4

    def calc_shanten(self, tiles_34, open_sets_34=None):
        shanten_with_chiitoitsu = self.shanten_calculator.calculate_shanten(
            tiles_34, open_sets_34, chiitoitsu=True)
        shanten_without_chiitoitsu = self.shanten_calculator.calculate_shanten(
            tiles_34, open_sets_34, chiitoitsu=False)

        return min([shanten_with_chiitoitsu, shanten_without_chiitoitsu
                    ]), shanten_with_chiitoitsu <= shanten_without_chiitoitsu

    def normalize_pai_list(self, pai_list, device, n=14):
        l = len(pai_list)
        x = torch.zeros(n, dtype=torch.long, device=device)
        x[:l] = torch.tensor(pai_list, dtype=torch.long, device=device)
        return x

    def pais2ids(self, pai_list):
        return [self.pai2id(pai, pai_list) for pai in pai_list]

    def pai2id(self, pai, pai_list=[]):
        assert (pai in pai_list)
        return self.pai_list.index(pai) + 1

    def get_positions(self, who, n_players=4):
        return [(i + who) % n_players for i in range(n_players)]
Ejemplo n.º 30
0
def index(request):
    # return HttpResponse("Hello, world. You're at the polls index.")

    if request.method == 'GET':
        return JsonResponse({})

    # JSON文字列
    datas = json.loads(request.body)

    #全37種
    syurui = {'1m':0,'2m':1,'3m':2,'4m':3,'5m':4,'6m':5,'7m':6,'8m':7,'9m':8,'1s':9,'2s':10,'3s':11,'4s':12,'5s':13,'6s':14,'7s':15,'8s':16,'9s':17,'1p':18,'2p':19,'3p':20,'4p':21,'5p':22,'6p':23,'7p':24,'8p':25,'9p':26,'a':27,'b':28,'c':29,'d':30,'e':31,'f':32,'g':33, 'a5m':34, 'a5s':35, 'a5p':36}
    #風4種
    field = {'a':0,'b':1,'c':2,'d':3}
    #萬子
    dic_man = {'1m':1, '2m':2, '3m':3, '4m':4, '5m':5, '6m':6, '7m':7, '8m':8, '9m':9, 'a5m':5}
    #索子
    dic_sou = {'1s':1, '2s':2, '3s':3, '4s':4, '5s':5, '6s':6, '7s':7, '8s':8, '9s':9, 'a5s':5}
    #筒子
    dic_pin = {'1p':1, '2p':2, '3p':3, '4p':4, '5p':5, '6p':6, '7p':7, '8p':8, '9p':9, 'a5p':5}
    #字牌
    dic_honors = {'a':1, 'b':2, 'c':3, 'd':4, 'e':5, 'f':6, 'g':7}

    dora = datas["dora"]["name"]
    ground = datas["ground"]["name"]
    own = datas["own"]["name"]

    #配牌リスト
    pai_list = [0 for i in range(37)]
    for i in datas["haipai"]:
        pai_list[syurui[i["hai"]]] += i["amount"]

    input_list = pai_list

    #シャンテン数
    man = ''
    sou = ''
    pin = ''
    honors = ''
    for i in datas["haipai"]:
        if 'm' in i["hai"]:
            for j in range(i["amount"]):
                man += str(dic_man[i["hai"]])
        elif 's' in i["hai"]:
            for j in range(i["amount"]):
                sou += str(dic_sou[i["hai"]])
        elif 'p' in i["hai"]:
            for j in range(i["amount"]):
                pin += str(dic_pin[i["hai"]])
        else:
            for j in range(i["amount"]):
                honors += str(dic_honors[i["hai"]])
    shanten = Shanten()
    tiles = TilesConverter.string_to_34_array(man=man, pin=pin, sou=sou, honors=honors)
    ss = shanten.calculate_shanten(tiles)

    ##萬子,索子,筒子,字牌,中張牌,么九牌,ドラのカウント
    dd = 0
    m = 0
    s = 0
    p = 0
    h = 0
    tyu = 0
    yao = 0
    for i in datas["haipai"]:
        #ドラ枚数
        if i["hai"] == dora or i["hai"] == 'a5m' or i["hai"] == 'a5s' or i["hai"] == 'a5p':
            dd += i["amount"]
        #萬子枚数
        if 'm' in i["hai"]:
            m += i["amount"]
        #索子枚数
        elif 's' in i["hai"]:
            s += i["amount"]
        #筒子枚数
        elif 'p' in i["hai"]:
            p += i["amount"]
        #字牌枚数
        else:
            h += i["amount"]
        #么九牌
        if '1' in i["hai"] or '9' in i["hai"] or 'a' in i["hai"] or 'b' in i["hai"] or 'c' in i["hai"] or 'd' in i["hai"] or 'e' in i["hai"] or 'f' in i["hai"] or 'g' in i["hai"]:
            yao += i["amount"]
        else:
            tyu += i["amount"]

    input_list.append(dd)
    input_list.append(ss)
    input_list.append(m)
    input_list.append(s)
    input_list.append(p)
    input_list.append(h)
    input_list.append(tyu)
    input_list.append(yao)

    #ドラリスト化
    dora_list = [0 for i in range(34)]
    dora_list[syurui[dora]] += 1

    input_list[len(input_list):len(input_list)] = dora_list

    #場風リスト化
    field1_list = [0 for i in range(4)]
    field1_list[field[ground]] += 1

    input_list[len(input_list):len(input_list)] = field1_list

    #自風リスト化
    field2_list = [0 for i in range(4)]
    field2_list[field[own]] += 1

    input_list[len(input_list):len(input_list)] = field2_list

    input_data = []
    input_data.append(input_list)
    input_data = np.array(input_data)
    input_data = input_data.astype('float32')

    ##訓練済みネットワークを用いた推論
    #保存したネットワークの読み込み
    #訓練済みのネットワークと同様のクラスのインスタンス生成
    loaded_net = Net(n_hidden=200)

    #訓練済みネットワークのパラメータを読み込ませる
    chainer.serializers.load_npz('./genapp/ml_models/m_data.net', loaded_net)

    # テストデータで予測値を計算
    with chainer.using_config('train', False), chainer.using_config('enable_backprop', False):
        y = loaded_net(input_data)

    resignation = np.argmax(y[0,:].array)

    point = random.randint(1,5)

    result = {
        'res':str(resignation),
        'point':str(point)
    }

    response = JsonResponse(
        result
    )
    return response