Exemple #1
0
def score_honor_tiles(fixed_hand, grouped_hand, game=None, **kwargs):
    matched_count = 0
    pair_involved = False

    for meld_type, _, tiles in fixed_hand:
        is_matched = tiles[0] == Tile.tile_map["honor"]["red"]
        is_matched = is_matched or tiles[0] == Tile.tile_map["honor"]["green"]
        is_matched = is_matched or tiles[0] == Tile.tile_map["honor"]["white"]
        matched_count += is_matched

    for meld_type, tiles in grouped_hand:
        is_matched = tiles[0] == Tile.tile_map["honor"]["red"]
        is_matched = is_matched or tiles[0] == Tile.tile_map["honor"]["green"]
        is_matched = is_matched or tiles[0] == Tile.tile_map["honor"]["white"]
        matched_count += is_matched

        if is_matched and meld_type == "pair":
            pair_involved = True

    if matched_count == 3:
        if not pair_involved:
            return __score_upper_limit, None if game is None else get_text(
                game.lang_code, "HKRULE_RGW_LARGE")

        return 5, None if game is None else get_text(game.lang_code,
                                                     "HKRULE_RGW_SMALL")

    return matched_count - pair_involved, None if game is None else get_text(
        game.lang_code,
        "HKRULE_RGW_NORMAL") if matched_count - pair_involved > 0 else None
Exemple #2
0
def score_one_suit(fixed_hand, grouped_hand, game=None, **kwargs):
    non_honor_suit = None
    honor_involved = False

    for _, _, tiles in fixed_hand:
        if tiles[0].suit == "honor":
            honor_involved = True
            continue

        if non_honor_suit is None:
            non_honor_suit = tiles[0].suit

        if tiles[0].suit != non_honor_suit:
            return 0, None

    for _, tiles in grouped_hand:
        if tiles[0].suit == "honor":
            honor_involved = True
            continue

        if non_honor_suit is None:
            non_honor_suit = tiles[0].suit

        if tiles[0].suit != non_honor_suit:
            return 0, None

    if honor_involved:
        return 3, None if game is None else get_text(
            game.lang_code, "HKRULE_ONE_SUIT_WITH_HONOR")

    return 7, None if game is None else get_text(game.lang_code,
                                                 "HKRULE_ONE_SUIT")
Exemple #3
0
def inline_language(userid, username, callback_data, bot, update):
    path = "settings/lang"

    if len(callback_data) == 0:
        lang_opts = []
        for lang_code in get_lang_codes():
            lang_opts.append((get_text(lang_code, "LANG_NAME"), lang_code))
        keyboard = get_tg_inline_keyboard(path, lang_opts)
        update.callback_query.edit_message_reply_markup(
            reply_markup=keyboard, timeout=get_tgmsg_timeout())

    else:
        tg_user = TGUser.load(userid)
        tg_user.change_lang(callback_data)
        tg_user.save()
        bot.send_message(tg_user.tg_userid,
                         "Updated language settings: " +
                         get_text(callback_data, "LANG_NAME"),
                         timeout=get_tgmsg_timeout())
        update.callback_query.edit_message_reply_markup(
            timeout=get_tgmsg_timeout())
        bot.send_message(tg_user.tg_userid,
                         get_text(tg_user.lang, "MSG_GREET") %
                         tg_user.username,
                         timeout=get_tgmsg_timeout())
Exemple #4
0
def score_ones_nines(fixed_hand, grouped_hand, game=None, **kwargs):
    honor_involved = False

    for meld_type, _, tiles in fixed_hand:
        if meld_type == "chow":
            return 0, None

        if tiles[0].value != 1 and tiles[0].value != 9:
            if tiles[0].suit != "honor":
                return 0, None
            honor_involved = True

    for meld_type, tiles in grouped_hand:
        if meld_type == "chow":
            return 0, None

        if tiles[0].value != 1 and tiles[0].value != 9:
            if tiles[0].suit != "honor":
                return 0, None
            honor_involved = True

    if honor_involved:
        return 1, None if game is None else get_text(game.lang_code,
                                                     "HKRULE_ONE_NINE_SMALL")

    return __score_upper_limit, None if game is None else get_text(
        game.lang_code, "HKRULE_ONE_NINE_LARGE")
Exemple #5
0
def generate_TG_board(lang_code, player_name, fixed_hand, hand, neighbors, game, new_tile = None, print_stolen_tiles = False):
	global PIL_IMPORTED
	if not PIL_IMPORTED:
		raise Exception("failed to import PIL")
	board = TGBoard()
	board.add_aligned_line(get_text(lang_code, "TITLE_GAME")%(get_tile_name(lang_code, "honor", game.game_wind), game.deck_size))
	
	for i in range(len(neighbors)):
		neighbor = neighbors[i]
		identifier = "%s"%neighbor.name
		if i == 0:
			identifier += " (%s)"%get_text(lang_code, "PLAYER_NEXT")
		elif i == 2:
			identifier += " (%s)"%get_text(lang_code, "PLAYER_PREV")

		fixed_hand_list = []
		for meld_type, is_secret, tiles in neighbor.fixed_hand:
			meld_list = []
			if is_secret:
				meld_list += [("back", 1), tiles[0], tiles[0], ("back", 1)]
			else:
				meld_list = tiles

			fixed_hand_list.extend(meld_list)

		board.add_aligned_line(identifier)
		if len(fixed_hand_list) > 0:
			board.add_aligned_line(*fixed_hand_list)
		board.add_aligned_line(("back", neighbor.hand_size), alignment = "right")
		board.add_aligned_line()

	board.add_aligned_line(get_text(lang_code, "TITLE_TILE_DISPOSED"))
	
	disposed_tiles = game.disposed_tiles
	while len(disposed_tiles) > 0:
		board.add_aligned_line(*disposed_tiles[0:15])
		disposed_tiles = disposed_tiles[15:]
	board.add_aligned_line()

	fixed_hand_list, hand_list = [], list(hand)
	for meld_type, is_secret, tiles in fixed_hand:
		meld_list = []
		if is_secret:
			meld_list = [("back", 1), tiles[0], tiles[0], ("back", 1)]
		else:
			meld_list = tiles
		fixed_hand_list.extend(meld_list)

	if new_tile is not None:
		hand_list.extend([("space", 1), new_tile])

	board.add_aligned_line(get_text(lang_code, "TITLE_YOUR_TILES"))
	if len(fixed_hand_list) > 0:
		board.add_aligned_line(*fixed_hand_list)
		board.add_aligned_line()
	board.add_aligned_line(*hand_list, alignment = "right")

	return board
Exemple #6
0
def score_game_wind(fixed_hand, grouped_hand, game=None, **kwargs):
    if game is not None:
        game_wind_tile = Tile.Tile("honor", game.game_wind)
        for _, _, tiles in fixed_hand:
            if tiles[0] == game_wind_tile:
                return 1, None if game is None else get_text(
                    game.lang_code, "HKRULE_GAME_WIND"
                ) % game_wind_tile.get_display_name(game.lang_code)

        for _, tiles in grouped_hand:
            if tiles[0] == game_wind_tile:
                return 1, None if game is None else get_text(
                    game.lang_code, "HKRULE_GAME_WIND"
                ) % game_wind_tile.get_display_name(game.lang_code)

    return 0, None
Exemple #7
0
    def decide_win(self, player, grouped_hand, new_tile, src, score, neighbors,
                   game):
        self.begin_decision()
        if not self.skip_history and self.history_waiting:
            self.update_transition("terminal", REWARD_VICTORY)

        fixed_hand, hand = player.fixed_hand, player.hand
        if self.display_step:
            if src == "steal":
                self.print_game_board(fixed_hand, hand, neighbors, game)
                self.print_msg("Someone just discarded a %s." %
                               new_tile.symbol)
            else:
                self.print_game_board(fixed_hand,
                                      hand,
                                      neighbors,
                                      game,
                                      new_tile=new_tile)

            self.print_msg("%s [%s] chooses to declare victory." %
                           (self.player_name, display_name))
            if game.lang_code is not None:
                game.add_notification(
                    get_text(game.lang_code, "NOTI_CHOOSE_VICT") %
                    (self.player_name))

            self.print_msg("You can form a victory hand of: ")
            utils.print_hand(fixed_hand, end=" ")
            utils.print_hand(grouped_hand, end=" ")
            self.print_msg("[%d]" % score)

        self.end_decision()

        return True
    def decide_pong(self, player, new_tile, neighbors, game):
        self.begin_decision()

        fixed_hand, hand = player.fixed_hand, player.hand

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        self.print_msg("Someone just discarded a %s." % new_tile.symbol)

        criteria = self.majority_suit == "mixed" or new_tile.suit in [
            self.majority_suit, "honor"
        ]

        self.end_decision()
        if criteria:
            self.print_msg("%s [%s] chooses to form a Pong %s%s%s." %
                           (self.player_name, display_name, new_tile.symbol,
                            new_tile.symbol, new_tile.symbol))
            if game.lang_code is not None:
                game.add_notification(
                    get_text(game.lang_code, "NOTI_CHOOSE_PONG") %
                    (self.player_name,
                     new_tile.get_display_name(game.lang_code,
                                               is_short=False)))
            return True
        else:
            self.print_msg("%s [%s] chooses not to form a Pong %s%s%s." %
                           (self.player_name, display_name, new_tile.symbol,
                            new_tile.symbol, new_tile.symbol))
            return False
Exemple #9
0
def score_pure_one_to_nine(fixed_hand, grouped_hand, game=None, **kwargs):
    suit = None
    record = [-1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    for _, is_secret, tiles in fixed_hand:
        return 0, None

    for meld_type, tiles in grouped_hand:
        if tiles[0].suit == "honor":
            return 0, None

        if suit is None:
            suit = tiles[0].suit

        for tile in tiles:
            if tile.suit != suit:
                return 0, None

            record[tile.value] += 1

    for i in range(1, len(record)):
        if record[i] == 0:
            return 0, None

    return __score_upper_limit, None if game is None else get_text(
        game.lang_code, "HKRULE_PURE_ONE_TO_NINE")
	def decide_chow(self, player, new_tile, choices, neighbors, game):
		self.begin_decision()

		fixed_hand, hand = player.fixed_hand, player.hand

		if self.display_step:
			self.print_game_board(fixed_hand, hand, neighbors, game)
		
		self.print_msg("Someone just discarded a %s."%new_tile.symbol)

		action = random.choice(choices)
		self.end_decision()
		
		if action == -1:
			self.print_msg("%s chooses not to Chow %s."%(self.player_name, new_tile.symbol))
			return False, None
		else:
			chow_tiles_tgstrs = []
			chow_tiles_str = ""
			for i in range(action - 1, action + 2):
				neighbor_tile = new_tile.generate_neighbor_tile(i)
				chow_tiles_str += neighbor_tile.symbol
				chow_tiles_tgstrs.append(neighbor_tile.get_display_name(game.lang_code, is_short = False))

			self.print_msg("%s chooses to Chow %s."%(self.player_name, chow_tiles_str))

			if game.lang_code is not None:
				game.add_notification(get_text(game.lang_code, "NOTI_CHOOSE_CHOW")%(self.player_name, ",".join(chow_tiles_tgstrs)))
			
			return True, action
	def decide_kong(self, player, new_tile, kong_tile, location, src, neighbors, game):
		self.begin_decision()
		fixed_hand, hand = player.fixed_hand, player.hand

		if self.display_step:
			self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)
			
		if src == "steal":
			self.print_msg("Someone just discarded a %s."%kong_tile.symbol)
		elif src == "draw":
			self.print_msg("You just drew a %s"%kong_tile.symbol)
		elif src == "existing":
			self.print_msg("You have 4 %s in hand"%kong_tile.symbol)

		if location == "fixed_hand":
			location = "fixed hand"
		else:
			location = "hand"

		action = random.choice([0, 1])

		self.end_decision()

		if action == 0:
			self.print_msg("%s [%s] chooses to form a Kong %s%s%s%s."%(self.player_name, display_name, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol))
			if game.lang_code is not None:
				game.add_notification(get_text(game.lang_code, "NOTI_CHOOSE_KONG")%(self.player_name, kong_tile.get_display_name(game.lang_code, is_short = False)))

			return True
		else:
			self.print_msg("%s [%s] chooses not to form a Kong %s%s%s%s."%(self.player_name, display_name, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol))
			return False
Exemple #12
0
	def decide_chow(self, player, new_tile, choices, neighbors, game):
		self.begin_decision()

		fixed_hand, hand = player.fixed_hand, player.hand

		if self.display_step:
			self.print_game_board(fixed_hand, hand, neighbors, game)
		
		self.print_msg("Someone just discarded a %s."%new_tile.symbol)

		pg_model = get_MJPGFitted(self.pg_model_path)
		state = utils.extended_dnn_encode_state(player, neighbors, cpk_tile = new_tile)

		valid_actions = [34 + decisions_.index("no_action")]
		for choice in choices:
			valid_actions.append(34 + decisions_.index("chow_%d"%(choice)))
		action_filter = np.zeros(n_decisions)
		action_filter[valid_actions] = 1
		action = None

		if not self.skip_history and self.history_waiting:
			self.update_transition(state, REWARD_NON_TERMINAL, action_filter)
		
		while True:
			if action is not None and not self.skip_history:
				self.update_history(state, action, action_filter)
				self.update_transition(state, REWARD_INVALID_DECISION, action_filter)
			
			action, value = pg_model.choose_action(state, action_filter = action_filter, return_value = True, strict_filter = True)
			
			if action in valid_actions:
				break
			elif not self.is_train:
				action = random.choice(valid_actions)
				break

		if not self.skip_history:
			self.update_history(state, action, action_filter)

		self.end_decision()
		
		if action == 34 + decisions_.index("no_action"):
			self.print_msg("%s chooses not to Chow %s [%.2f]."%(self.player_name, new_tile.symbol, value))
			return False, None
		else:
			chow_tiles_tgstrs = []
			chow_tiles_str = ""
			choice = int(decisions_[action - 34].split("_")[1])
			for i in range(choice - 1, choice + 2):
				neighbor_tile = new_tile.generate_neighbor_tile(i)
				chow_tiles_str += neighbor_tile.symbol
				chow_tiles_tgstrs.append(neighbor_tile.get_display_name(game.lang_code, is_short = False))

			self.print_msg("%s chooses to Chow %s [%.2f]."%(self.player_name, chow_tiles_str, value))

			if game.lang_code is not None:
				game.add_notification(get_text(game.lang_code, "NOTI_CHOOSE_CHOW")%(self.player_name, ",".join(chow_tiles_tgstrs)))
			
			return True, choice
Exemple #13
0
    def decide_drop_tile(self, player, new_tile, neighbors, game):
        self.begin_decision()

        fixed_hand, hand = player.fixed_hand, player.hand
        state = utils.extended_dnn_encode_state(player,
                                                neighbors,
                                                new_tile=new_tile)

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        q_network = get_network[self.network_type](self.q_network_path)

        valid_actions = []
        tiles = player.hand if new_tile is None else player.hand + [new_tile]
        for tile in tiles:
            valid_actions.append(Tile.convert_tile_index(tile))

        action_filter = np.zeros(n_decisions)
        action_filter[valid_actions] = 1
        action = None

        if not self.skip_history and self.history_waiting:
            self.update_transition(state, REWARD_NON_TERMINAL, action_filter)

        while True:
            if action is not None and not self.skip_history:
                self.update_history(state, action, action_filter)
                self.update_transition(state, REWARD_INVALID_DECISION,
                                       action_filter)

            action, value = q_network.choose_action(
                state,
                action_filter=action_filter,
                eps_greedy=self.is_train,
                return_value=True,
                strict_filter=not self.is_train)

            if action in valid_actions:
                break
            elif not self.is_train:
                action = random.choice(valid_actions)
                break

        if not self.skip_history:
            self.update_history(state, action, action_filter)
        drop_tile = Tile.convert_tile_index(action)
        self.print_msg(
            "%s [%s] chooses to drop %s. [%.2f]" %
            (self.player_name, display_name, drop_tile.symbol, value))
        self.end_decision(True)

        if game.lang_code is not None:
            game.add_notification(
                get_text(game.lang_code, "NOTI_CHOOSE_DISCARD") %
                (self.player_name,
                 drop_tile.get_display_name(game.lang_code, is_short=False)))

        return drop_tile
Exemple #14
0
    def decide_drop_tile(self, player, new_tile, neighbors, game):
        self.begin_decision()

        #print("drop")

        fixed_hand, hand = player.fixed_hand, player.hand
        state = utils.dnn_encode_state(player, neighbors)

        if not self.skip_history and self.history_waiting:
            self.update_transition(state, REWARD_NON_TERMINAL)

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        #model here
        #pg_model = get_MJPolicyGradient(self.pg_model_path)

        valid_actions = []
        tiles = player.hand if new_tile is None else player.hand + [new_tile]
        for tile in tiles:
            valid_actions.append(Tile.convert_tile_index(tile))

        action_filter = np.zeros(n_decisions)
        action_filter[valid_actions] = 1

        action, value = self.actor.choose_action(
            state,
            action_filter=action_filter,
            return_value=True,
            strict_filter=not self.is_train)

        if action not in valid_actions:
            #print("invalid")
            if self.is_train:
                action = random.choice(valid_actions)
                if not self.skip_history:
                    self.update_history(state, action, action_filter)
                    self.update_transition(state, REWARD_INVALID_DECISION)
            else:
                raise Exception("Invalid action when not training")

        if not self.skip_history:
            self.update_history(state, action, action_filter)
        drop_tile = Tile.convert_tile_index(action)
        self.print_msg(
            "%s [%s] chooses to drop %s. [%.2f]" %
            (self.player_name, display_name, drop_tile.symbol, value))

        self.end_decision(True)

        if game.lang_code is not None:
            game.add_notification(
                get_text(game.lang_code, "NOTI_CHOOSE_DISCARD") %
                (self.player_name,
                 drop_tile.get_display_name(game.lang_code, is_short=False)))

        return drop_tile
Exemple #15
0
    def decide_pong(self, player, new_tile, neighbors, game):
        self.begin_decision()

        fixed_hand, hand = player.fixed_hand, player.hand

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        self.print_msg("Someone just discarded a %s." % new_tile.symbol)

        pg_model = get_MJPolicyGradient(self.pg_model_path)
        state = utils.dnn_encode_state(player, neighbors)

        if not self.skip_history and self.history_waiting:
            self.update_transition(None, REWARD_NON_TERMINAL)

        valid_actions = [
            34 + decisions_.index("%s_pong" % new_tile.suit),
            34 + decisions_.index("no_action")
        ]
        action_filter = np.zeros(n_decisions)
        action_filter[valid_actions] = 1
        action, value = pg_model.choose_action(state,
                                               action_filter=action_filter,
                                               return_value=True,
                                               strict_filter=not self.is_train)

        if action not in valid_actions:
            if self.is_train:
                action = random.choice(valid_actions)
                if not self.skip_history:
                    self.update_history(state, action, action_filter)
                    self.update_transition(None, REWARD_INVALID_DECISION)
            else:
                raise Exception("Invalid action when not training")

        if not self.skip_history:
            self.update_history(state, action, action_filter)

        self.end_decision()
        if action == 34 + decisions_.index("no_action"):
            self.print_msg("%s [%s] chooses to form a Pong %s%s%s. [%.2f]" %
                           (self.player_name, display_name, new_tile.symbol,
                            new_tile.symbol, new_tile.symbol, value))
            if game.lang_code is not None:
                game.add_notification(
                    get_text(game.lang_code, "NOTI_CHOOSE_PONG") %
                    (self.player_name,
                     new_tile.get_display_name(game.lang_code,
                                               is_short=False)))
            return True
        else:
            self.print_msg(
                "%s [%s] chooses not to form a Pong %s%s%s. [%.2f]" %
                (self.player_name, display_name, new_tile.symbol,
                 new_tile.symbol, new_tile.symbol, value))
            return False
Exemple #16
0
    def decide_kong(self, player, new_tile, kong_tile, location, src,
                    neighbors, game):
        self.begin_decision()
        fixed_hand, hand = player.fixed_hand, player.hand

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        if src == "steal":
            self.print_msg("Someone just discarded a %s." % kong_tile.symbol)
        elif src == "draw":
            self.print_msg("You just drew a %s" % kong_tile.symbol)
        elif src == "existing":
            self.print_msg("You have 4 %s in hand" % kong_tile.symbol)

        if location == "fixed_hand":
            location = "fixed hand"
        else:
            location = "hand"

        q_network = get_DeepQNetwork(self.q_network_path)
        state = qnetwork_encode_state(fixed_hand, hand)
        if self.q_network_waiting:
            self.update_transition(0, state)

        valid_actions = [
            q_decisions.index(new_tile.suit + "_pong"),
            q_decisions.index("no_action")
        ]
        action_filter = np.full(len(q_decisions), float("-inf"))
        action_filter[valid_actions] = 0
        action = q_network.choose_action(state,
                                         action_filter=action_filter,
                                         eps_greedy=self.q_network_is_train)
        self.__update_history(state, action, action_filter)

        self.end_decision()

        if action == q_decisions.index("no_action"):
            self.print_msg(
                "%s [%s] chooses to form a Kong %s%s%s%s." %
                (self.player_name, display_name, kong_tile.symbol,
                 kong_tile.symbol, kong_tile.symbol, kong_tile.symbol))
            if game.lang_code is not None:
                game.add_notification(
                    get_text(game.lang_code, "NOTI_CHOOSE_KONG") %
                    (self.player_name,
                     kong_tile.get_display_name(game.lang_code,
                                                is_short=False)))

            return True
        else:
            self.print_msg(
                "%s [%s] chooses not to form a Kong %s%s%s%s." %
                (self.player_name, display_name, kong_tile.symbol,
                 kong_tile.symbol, kong_tile.symbol, kong_tile.symbol))
            return False
Exemple #17
0
	def decide_kong(self, player, new_tile, kong_tile, location, src, neighbors, game):
		self.begin_decision()
		fixed_hand, hand = player.fixed_hand, player.hand

		if self.display_step:
			self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)
			
		if src == "steal":
			self.print_msg("Someone just discarded a %s."%kong_tile.symbol)
		elif src == "draw":
			self.print_msg("You just drew a %s"%kong_tile.symbol)
		elif src == "existing":
			self.print_msg("You have 4 %s in hand"%kong_tile.symbol)

		if location == "fixed_hand":
			location = "fixed hand"
		else:
			location = "hand"

		pg_model = get_MJPGFitted(self.pg_model_path)
		state = utils.extended_dnn_encode_state(player, neighbors, cpk_tile = kong_tile)

		valid_actions = [34 + decisions_.index("pong"), 34 + decisions_.index("no_action")]
		action_filter = np.zeros(n_decisions)
		action_filter[valid_actions] = 1
		action = None

		if not self.skip_history and self.history_waiting:
			self.update_transition(state, REWARD_NON_TERMINAL, action_filter)
		
		while True:
			if action is not None and not self.skip_history:
				self.update_history(state, action, action_filter)
				self.update_transition(state, REWARD_INVALID_DECISION, action_filter)
			
			action, value = pg_model.choose_action(state, action_filter = action_filter, return_value = True, strict_filter = True)
			
			if action in valid_actions:
				break
			elif not self.is_train:
				action = random.choice(valid_actions)
				break

		if not self.skip_history:
			self.update_history(state, action, action_filter)

		self.end_decision()

		if action == 34 + decisions_.index("no_action"):
			self.print_msg("%s [%s] chooses to form a Kong %s%s%s%s [%.2f]."%(self.player_name, display_name, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol, value))
			if game.lang_code is not None:
				game.add_notification(get_text(game.lang_code, "NOTI_CHOOSE_KONG")%(self.player_name, kong_tile.get_display_name(game.lang_code, is_short = False)))

			return True
		else:
			self.print_msg("%s [%s] chooses not to form a Kong %s%s%s%s [%.2f]."%(self.player_name, display_name, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol, kong_tile.symbol, value))
			return False
Exemple #18
0
def score_all_pongs(fixed_hand, grouped_hand, game=None, **kwargs):
    for meld_type, _, _ in fixed_hand:
        if meld_type == "chow":
            return 0, None

    for meld_type, _ in grouped_hand:
        if meld_type == "chow":
            return 0, None

    return 3, None if game is None else get_text(game.lang_code,
                                                 "HKRULE_ALL_PONGS")
Exemple #19
0
def score_four_kongs(fixed_hand, game=None, **kwargs):
    count = 0
    for meld_type, _, _ in fixed_hand:
        if meld_type == "kong":
            count += 1

    if count >= 4:
        return __score_upper_limit, None if game is None else get_text(
            game.lang_code, "HKRULE_FOUR_KONGS")

    return 0, None
Exemple #20
0
def score_pure_honor_suit(fixed_hand, grouped_hand, game=None, **kwargs):
    for _, _, tiles in fixed_hand:
        if tiles[0].suit != "honor":
            return 0, None

    for _, tiles in grouped_hand:
        if tiles[0].suit != "honor":
            return 0, None

    return __score_upper_limit, None if game is None else get_text(
        game.lang_code, "HKRULE_PURE_HONOR_SUIT")
Exemple #21
0
def score_all_chows(fixed_hand, grouped_hand, game=None, **kwargs):
    for meld_type, _, _ in fixed_hand:
        if meld_type != "chow":
            return 0, None

    for meld_type, _ in grouped_hand:
        if meld_type != "chow" and meld_type != "pair":
            return 0, None

    return 1, None if game is None else get_text(game.lang_code,
                                                 "HKRULE_ALL_CHOWS")
Exemple #22
0
    def decide_chow(self, player, new_tile, choices, neighbors, game):
        self.begin_decision()

        fixed_hand, hand = player.fixed_hand, player.hand

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game)

        self.print_msg("Someone just discarded a %s." % new_tile.symbol)

        q_network = get_DeepQNetwork(self.q_network_path)
        state = qnetwork_encode_state(fixed_hand, hand)
        if self.q_network_waiting:
            self.update_transition(0, state)

        valid_actions = [
            q_decisions.index(new_tile.suit + "_chow"),
            q_decisions.index("no_action")
        ]
        action_filter = np.full(len(q_decisions), float("-inf"))
        action_filter[valid_actions] = 0
        action = q_network.choose_action(state,
                                         action_filter=action_filter,
                                         eps_greedy=self.q_network_is_train)
        self.__update_history(state, action, action_filter)

        self.end_decision()

        if action == q_decisions.index("no_action"):
            self.print_msg("%s chooses not to Chow %s." %
                           (self.player_name, new_tile.symbol))
            return False, None
        else:
            chow_tiles_tgstrs = []
            chow_tiles_str = ""
            choice = random.choice(choices)
            for i in range(choice - 1, choice + 2):
                neighbor_tile = new_tile.generate_neighbor_tile(i)
                chow_tiles_str += neighbor_tile.symbol
                chow_tiles_tgstrs.append(
                    neighbor_tile.get_display_name(game.lang_code,
                                                   is_short=False))

            self.print_msg("%s chooses to Chow %s." %
                           (self.player_name, chow_tiles_str))

            if game.lang_code is not None:
                game.add_notification(
                    get_text(game.lang_code, "NOTI_CHOOSE_CHOW") %
                    (self.player_name, ",".join(chow_tiles_tgstrs)))

            return True, choice
Exemple #23
0
def generate_TG_end_board(lang_code, players, game, center_player, extra_tile = None):
	global PIL_IMPORTED
	if not PIL_IMPORTED:
		raise Exception("failed to import PIL")
	board = TGBoard()
	board.add_aligned_line(get_text(lang_code, "TITLE_GAME")%(get_tile_name(lang_code, "honor", game.game_wind), game.deck_size))
	center_player_index = players.index(center_player)
	for i in range(4):
		player_index = (center_player_index + i + 1) % 4
		player = players[player_index]
		identifier = "%s"%player.name
		if i == 0:
			identifier += " (%s)"%get_text(lang_code, "PLAYER_NEXT")
		elif i == 2:
			identifier += " (%s)"%get_text(lang_code, "PLAYER_PREV")


		fixed_hand_list, hand_list = [], list(player.hand)
		for meld_type, is_secret, tiles in player.fixed_hand:
			meld_list = []
			if is_secret:
				meld_list = [("back", 1), tiles[0], tiles[0], ("back", 1)]
			else:
				meld_list = tiles
			fixed_hand_list.extend(meld_list)

		if extra_tile is not None and extra_tile[0] == player:
			hand_list.extend([("space", 1), extra_tile[1]])			

		board.add_aligned_line(identifier)
		if len(fixed_hand_list) > 0:
			board.add_aligned_line(*fixed_hand_list)
			board.add_aligned_line()

		board.add_aligned_line(*hand_list, alignment = "right")
		board.add_aligned_line()

	return board
	def decide_drop_tile(self, player, new_tile, neighbors, game):
		self.begin_decision()

		tiles = player.hand
		if new_tile is not None:
			tiles += [new_tile]
		drop_tile = random.choice(tiles)
		self.print_msg("%s [%s] chooses to drop %s."%(self.player_name, display_name, drop_tile.symbol))
		self.end_decision(True)

		if game.lang_code is not None:
			game.add_notification(get_text(game.lang_code, "NOTI_CHOOSE_DISCARD")%(self.player_name, drop_tile.get_display_name(game.lang_code, is_short = False)))

		return drop_tile
Exemple #25
0
def score_secret_all_pongs_with_draw(fixed_hand,
                                     grouped_hand,
                                     additional_tile_src,
                                     game=None,
                                     **kwargs):
    if additional_tile_src != "draw":
        return 0, None

    for meld_type, is_secret, _ in fixed_hand:
        return 0, None

    for meld_type, _ in grouped_hand:
        if meld_type == "chow":
            return 0, None

    return __score_upper_limit, None if game is None else get_text(
        game.lang_code, "HKRULE_ALL_PONGS_WITH_DRAW")
    def decide_drop_tile(self, player, new_tile, neighbors, game):
        self.begin_decision()

        fixed_hand, hand = player.fixed_hand, player.hand

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        drop_tile_score, drop_tile = None, None
        hand = list(hand)
        if new_tile is not None:
            hand.append(new_tile)

        used_tiles_map, hand_tiles_map, neighbor_suit_prob = self.preprocess_info(
            hand, player, neighbors)

        if (136 -
                13 * 4) * (1 - self.s_explore
                           ) >= game.deck_size and self.majority_suit is None:
            self.majority_suit = self.decide_strategy(hand, used_tiles_map,
                                                      neighbor_suit_prob)

        melds_distribution = self.scoring_distribution_melds(
            hand, used_tiles_map, hand_tiles_map)

        score_tile_rank = []

        for i in range(len(melds_distribution)):
            score_tile_rank.append((melds_distribution[i], hand[i]))

        score_tile_rank = sorted(score_tile_rank, key=lambda x: x[0])

        drop_tile_score, drop_tile = score_tile_rank[0]
        self.print_msg("%s [%s] chooses to drop %s (%.2f) [majority = %s]." %
                       (self.player_name, display_name, drop_tile.symbol,
                        drop_tile_score, self.majority_suit))
        self.end_decision(True)
        if game.lang_code is not None:
            game.add_notification(
                get_text(game.lang_code, "NOTI_CHOOSE_DISCARD") %
                (self.player_name,
                 drop_tile.get_display_name(game.lang_code, is_short=False)))
        return drop_tile
	def decide_pong(self, player, new_tile, neighbors, game):
		self.begin_decision()

		fixed_hand, hand = player.fixed_hand, player.hand

		if self.display_step:
			self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

		self.print_msg("Someone just discarded a %s."%new_tile.symbol)

		action = random.choice([0, 1])

		self.end_decision()
		if action == 0:
			self.print_msg("%s [%s] chooses to form a Pong %s%s%s."%(self.player_name, display_name, new_tile.symbol, new_tile.symbol, new_tile.symbol))
			if game.lang_code is not None:
				game.add_notification(get_text(game.lang_code, "NOTI_CHOOSE_PONG")%(self.player_name, new_tile.get_display_name(game.lang_code, is_short = False)))
			return True
		else:
			self.print_msg("%s [%s] chooses not to form a Pong %s%s%s."%(self.player_name, display_name, new_tile.symbol, new_tile.symbol, new_tile.symbol))
			return False
Exemple #28
0
def score_four_winds(fixed_hand, grouped_hand, game=None, **kwargs):
    match_count = 0
    for _, _, tiles in fixed_hand:
        if tiles[0].suit == "honor":
            match_count += tiles[0] == Tile.tile_map["honor"]["east"]
            match_count += tiles[0] == Tile.tile_map["honor"]["south"]
            match_count += tiles[0] == Tile.tile_map["honor"]["west"]
            match_count += tiles[0] == Tile.tile_map["honor"]["north"]

    for _, tiles in grouped_hand:
        if tiles[0].suit == "honor":
            match_count += tiles[0] == Tile.tile_map["honor"]["east"]
            match_count += tiles[0] == Tile.tile_map["honor"]["south"]
            match_count += tiles[0] == Tile.tile_map["honor"]["west"]
            match_count += tiles[0] == Tile.tile_map["honor"]["north"]

    if match_count == 4:
        return __score_upper_limit, None if game is None else get_text(
            game.lang_code, "HKRULE_FOUR_WINDS")

    return 0, None
Exemple #29
0
def validate_thirteen_yiu(fixed_hand, hand, additional_tile, game, **kwargs):
    if len(fixed_hand) > 0:
        return 0, None

    required_tiles_map = {tile: 0 for tile in THIRTEEN_YIU_TILES}
    tiles = hand + [additional_tile] if additional_tile is not None else hand
    for tile in tiles:
        if tile not in required_tiles_map:
            return 0, None
        else:
            required_tiles_map[tile] += 1

    n_total = 0
    for tile, count in required_tiles_map.items():
        n_total += count
        if count == 0:
            return 0, None

    if n_total != 14:
        return 0, None

    return __score_upper_limit, None if game is None else get_text(
        game.lang_code, "HKRULE_THIRTEEN_TERMINAL_TILES")
Exemple #30
0
    def decide_pong(self, player, new_tile, neighbors, game):
        self.begin_decision()

        fixed_hand, hand = player.fixed_hand, player.hand

        if self.display_step:
            self.print_game_board(fixed_hand, hand, neighbors, game, new_tile)

        self.print_msg("Someone just discarded a %s." % new_tile.symbol)

        q_network = get_network[self.network_type](self.q_network_path)
        state = utils.extended_dnn_encode_state(player,
                                                neighbors,
                                                cpk_tile=new_tile)

        valid_actions = [
            34 + decisions_.index("%s_pong" % new_tile.suit),
            34 + decisions_.index("no_action")
        ]
        action_filter = np.zeros(n_decisions)
        action_filter[valid_actions] = 1
        action = None

        if not self.skip_history and self.history_waiting:
            self.update_transition(state, REWARD_NON_TERMINAL, action_filter)

        while True:
            if action is not None and not self.skip_history:
                self.update_history(state, action, action_filter)
                self.update_transition(state, REWARD_INVALID_DECISION,
                                       action_filter)

            action, value = q_network.choose_action(
                state,
                action_filter=action_filter,
                eps_greedy=self.is_train,
                return_value=True,
                strict_filter=not self.is_train)

            if action in valid_actions:
                break
            elif not self.is_train:
                action = random.choice(valid_actions)
                break

        if not self.skip_history:
            self.update_history(state, action, action_filter)

        self.end_decision()
        if action == 34 + decisions_.index("no_action"):
            self.print_msg("%s [%s] chooses to form a Pong %s%s%s. [%.2f]" %
                           (self.player_name, display_name, new_tile.symbol,
                            new_tile.symbol, new_tile.symbol, value))
            if game.lang_code is not None:
                game.add_notification(
                    get_text(game.lang_code, "NOTI_CHOOSE_PONG") %
                    (self.player_name,
                     new_tile.get_display_name(game.lang_code,
                                               is_short=False)))
            return True
        else:
            self.print_msg(
                "%s [%s] chooses not to form a Pong %s%s%s. [%.2f]" %
                (self.player_name, display_name, new_tile.symbol,
                 new_tile.symbol, new_tile.symbol, value))
            return False