Example #1
0
def add_bet(state, total):
    # amount: 本局需要下的总注
    amount = total - state.player[state.currpos].totalbet
    assert (amount > state.player[state.currpos].bet)
    # Obey the rule of last_raised
    minamount = state.last_raised + state.minbet
    real_amount = max(amount, minamount)
    # money_needed = real_amount - state.player[state.currpos].bet
    decision = Decision()
    decision.raisebet = 1
    decision.amount = real_amount
    return decision
Example #2
0
    def make_decision(self, state):

        # record run time for making one decision
        if self.record_time:
            start_time = time.time()

        shared_cards = state.sharedcards.copy()
        my_id = state.currpos

        # see which round we are at, based on length of shared cards
        if len(shared_cards) == 0:
            round = 0
        elif len(shared_cards) == 3:
            round = 1
        elif len(shared_cards) == 4:
            round = 2
        else:
            round = 3

        my_cards = state.player[my_id].cards
        remain_card = list(range(0, 52))
        for x in shared_cards:
            remain_card.pop(remain_card.index(x))
        for x in my_cards:
            remain_card.pop(remain_card.index(x))

        # check how many players are still alive
        # check how many players are making bold bet (larger than big blind)
        alive_players_num = 0
        bold_better_list = []
        for player_id in range(len(state.player)):
            if state.player[player_id].active & (player_id != my_id):
                player = state.player[player_id]
                alive_players_num += 1

                total_bet = player.totalbet + player.bet
                if total_bet > 40:
                    wealth = player.money + total_bet
                    bold_better_list.append(
                        bold_better(player=player,
                                    total_bet=total_bet,
                                    wealth=wealth))

        def simulate_win_rate(in_hand_cards,
                              bold_better_list=[],
                              iterate=self.win_rate_sim_iterate):
            win_count = 0
            _remain_card = list(range(0, 52))
            for x in shared_cards:
                _remain_card.pop(_remain_card.index(x))
            for x in in_hand_cards:
                _remain_card.pop(_remain_card.index(x))

            # iterate, simulate unguessed players' cards, shared cards
            for i in range(iterate):
                _remain_card_sim = _remain_card.copy()
                other_players_cards_sim = []

                random.shuffle(_remain_card_sim)
                for _bold_better in bold_better_list:
                    player_cards = random.choice(_bold_better.card_guess)
                    other_players_cards_sim.append(player_cards)
                    for x in player_cards:
                        if x in _remain_card_sim:
                            _remain_card_sim.pop(_remain_card_sim.index(x))

                for player in range(alive_players_num - len(bold_better_list)):
                    player_cards = []
                    player_cards.append(_remain_card_sim.pop())
                    player_cards.append(_remain_card_sim.pop())
                    # player_hand = Hand(player_cards)
                    other_players_cards_sim.append(player_cards)

                shared_cards_sim = shared_cards.copy()
                my_cards_sim = in_hand_cards.copy()
                random.shuffle(_remain_card_sim)
                while len(shared_cards_sim) < 5:
                    shared_cards_sim.append(_remain_card_sim.pop())
                my_cards_shared_cards_sim = my_cards_sim + shared_cards_sim
                # my_hand = Hand(my_cards_sim)

                win = 0
                even = 0
                assert (alive_players_num == len(other_players_cards_sim))
                survive = True
                for other_player_cards_sim in other_players_cards_sim:
                    compare = judge_two(
                        other_player_cards_sim + shared_cards_sim,
                        my_cards_shared_cards_sim)
                    if compare == 0:
                        even += 1
                    if compare == -1:
                        survive = False
                    if compare == 1:
                        win += 1
                if win == alive_players_num:
                    win_count += 1
                # if even, counted as
                elif survive == True:
                    win_count += 1 / (even + 1)

            win_rate = win_count / iterate
            return win_rate

        # simulate possible in-hand cards set for bold better, calculate win rate
        def remove_known_card(card, card_set):
            card_set_ = [x for x in card_set if card not in x.cards]
            return card_set_

        _shared_cards = shared_cards.copy()

        def rank_with_shared_card(hand_cards1, hand_cards2):

            result = judge_two(
                list(hand_cards1) + _shared_cards,
                list(hand_cards2) + _shared_cards)
            return result

        if len(bold_better_list) != 0:
            if round == 0:
                guess_card_list_full = pickle.load(
                    open(
                        '/Users/Simon-CWG/Documents/quantresearch/Texaspoker/modules/texaspoker/AI/research/pair_score_sorted',
                        'rb'))
                for x in shared_cards:
                    guess_card_list_full = remove_known_card(
                        x, guess_card_list_full)
                for x in my_cards:
                    guess_card_list_full = remove_known_card(
                        x, guess_card_list_full)

            else:
                guess_card_list_full = []
                remain_card_comb = list(combinations(remain_card, 2))
                remain_card_comb = sorted(
                    remain_card_comb,
                    key=functools.cmp_to_key(rank_with_shared_card))
                hand_level = 10
                pair = remain_card_comb[0]
                hand = Hand(list(pair) + shared_cards)
                hand_level = hand.level
                while hand_level >= 3:
                    guess_card_list_full.append(
                        guess_cards(cards=list(remain_card_comb.pop(0))))
                    if len(remain_card_comb) == 0:
                        break
                    pair = remain_card_comb[0]
                    hand = Hand(list(pair) + shared_cards)
                    hand_level = hand.level

                guess_card_list_full = list(reversed(guess_card_list_full))
                if len(remain_card_comb) > 0:
                    print('number of simulations: ', len(remain_card_comb))
                    remain_card_comb = map((lambda x: guess_cards(
                        cards=list(x), shared_cards=shared_cards)),
                                           remain_card_comb)
                    pool = multiprocessing.Pool()
                    # guess_card_list_full = pool.map(lambda x: pickable_simulate_win_rate(x, shared_cards=shared_cards), card_only)
                    guess_card_list_rest = pool.map(pickable_simulate_win_rate,
                                                    remain_card_comb)
                    pool.close()
                    guess_card_list_rest = sorted(guess_card_list_rest,
                                                  key=(lambda x: x.win_rate))
                    guess_card_list_full = guess_card_list_rest + guess_card_list_full

        # assess bold better's confidence based on their betting, bayesian style
        for _bold_better in bold_better_list:
            _invest_base = min(_bold_better.wealth,
                               self.bold_better_invest_base_upper)
            _invest_base = max(_invest_base,
                               self.bold_better_invest_base_lower)
            confidence = (_bold_better.total_bet /
                          _invest_base)**(1 / self.bold_better_risk_averse)
            # set confidence upper bound for different round
            confidence = min(confidence, self.confidence_upper_bound[round])
            # take upper subset of guess cards based on confidence
            guess_card_list_part = guess_card_list_full[
                int(confidence * len(guess_card_list_full)):]
            guess_card_list = [i.cards for i in guess_card_list_part]
            _bold_better.card_guess = guess_card_list

        # finally, simulate my win rate given bold betters' cards guessed
        my_win_rate = simulate_win_rate(in_hand_cards=my_cards,
                                        bold_better_list=bold_better_list)

        if self.record_time:
            print("simulate guess book finish --- %s seconds ---" %
                  (time.time() - start_time))
        # print('estimated win rate: ', my_win_rate)

        # make decision
        decision = Decision()

        delta = state.minbet - state.player[state.currpos].bet
        me = state.player[my_id]
        wealth = me.money + me.totalbet + me.bet

        def add_bet(state, total):
            # amount: 本局需要下的总注
            amount = total - state.player[state.currpos].totalbet
            assert (amount > state.player[state.currpos].bet)
            if amount > me.money:
                decision.allin = 1
                return decision
            # Obey the rule of last_raised
            min_amount = state.last_raised + state.minbet
            real_amount = max(amount, min_amount)
            # money_needed = real_amount - state.player[state.currpos].bet
            decision.raisebet = 1
            decision.amount = int(real_amount)
            return decision

        # set target total bet
        # if win rate smaller than average win rate ( 1 / number of players), fold
        if my_win_rate < 1 / (alive_players_num + 1):
            target = 0
        # if high win rate, bet based on current wealth
        elif my_win_rate > 0.75:
            base = max(state.player[state.currpos].money,
                       self.invest_base_lower)
            base = min(base, self.invest_base_upper)
            target = my_win_rate**self.risk_averse * base + 15
        # if modest win rate, bet based on $2000
        else:
            base = 2000
            target = my_win_rate**self.risk_averse * base + 15
            target = min(target, wealth * 0.6)

        # if nearly broke and good win rate, all in
        if (wealth <= 300) & (my_win_rate > 0.6):
            decision.allin = 1
            return decision

        at_stake = me.totalbet + me.bet

        # make action based on target
        # if target less than minimum bet
        if (state.minbet + state.player[state.currpos].totalbet) >= target:
            # call if free to
            if delta == 0:
                decision.callbet = 1
            # compare expected loss of fold and expected loss of call, choose smaller loss
            else:
                er_giveup = -at_stake
                er_call = -(1 - my_win_rate) * (
                    at_stake + delta) + my_win_rate * (state.moneypot)
                if er_giveup >= er_call:
                    decision.giveup = 1
                else:
                    decision.callbet = 1

        # if target grater than minimum bet, raise bet
        else:
            decision = add_bet(state, target)
        if self.log:
            log_text = 'estimated win rate, ' + str(
                my_win_rate) + ', ' + 'target, ' + str(target)
            print(log_text)
            state.logger.info(log_text)
        if self.record_time:
            print("FINISH--- %s seconds ---" % (time.time() - start_time))

        return decision
Example #3
0
def ai(id, state):
	shared_cards = state.sharedcards.copy()
	my_cards = state.player[id].cards
	remain_card = list(range(0, 52))
	for x in shared_cards:
		remain_card.pop(remain_card.index(x))
	for x in my_cards:
		remain_card.pop(remain_card.index(x))
	# guess other player's card strength based on their betting
	alive_players = []
	for player_id in range(len(state.player)):
		if state.player[id].active & player_id != id:
			alive_players.append(state.player[id])

	for player in alive_players:
		guess_card_list = []
		for i in range(1000):
			guess_card = []
			heap = remain_card[:]
			random.shuffle(heap)
			guess_card.append(heap.pop())
			guess_card.append(heap.pop())
			for i in range(100):
				pass

	# 模拟发牌1000次
	def simulate_win_rate(inhand_cards, other_player_cards = []):
		win_count = 0
		_remain_card = list(range(0, 52))
		for x in shared_cards:
			_remain_card.pop(remain_card.index(x))
		for x in inhand_cards:
			_remain_card.pop(remain_card.index(x))

		for i in range(1000):
			score = 0
			for player in range(len(alive_players)):
				player_cards = []
				if len(other_player_cards) == 0:
					player_cards.append(heap.pop())
					player_cards.append(heap.pop())
					player_cards = player_cards
					# player_hand = Hand(player_cards)
					other_player_cards.append(player_cards)

				else:
					pass
					# player_hand = other_player_cards[player].

			shared_cards_sim = shared_cards
			my_cards_sim = inhand_cards
			heap = remain_card[:]
			random.shuffle(heap)
			while len(shared_cards_sim) < 5:
				shared_cards_sim.append(heap.pop())
			my_cards_sim = my_cards_sim + shared_cards
			# my_hand = Hand(my_cards_sim)
			# other_player = []


			score += judge_two(my_cards_sim, player_cards)
			if score == -len(alive_players):
				win_count += 1

		win_rate = win_count / 1000

		return win_rate
	my_win_rate = simulate_win_rate(inhand_cards = my_cards)
	decision = Decision()

	def add_bet(state, total):
		# amount: 本局需要下的总注
		amount = total - state.player[state.currpos].totalbet
		assert (amount > state.player[state.currpos].bet)
		# Obey the rule of last_raised
		minamount = state.last_raised + state.minbet
		real_amount = max(amount, minamount)
		# money_needed = real_amount - state.player[state.currpos].bet
		decision.raisebet = 1
		decision.amount = int(real_amount)
		return decision

	delta = state.minbet - state.player[state.currpos].bet

	target = my_win_rate**5 * state.player[state.currpos].money
	if (state.player[state.currpos].bet + state.player[state.currpos].totalbet) >= target:
		if delta == 0:
			decision.callbet = 1
		else:
			decision.giveup = 1
	else:
		decision = add_bet(state, target)
	return decision
def ai(id, state, risk_averse=2, log=True):
    start_time = time.time()
    shared_cards = state.sharedcards.copy()
    if len(shared_cards) == 0:
        round = 0
    elif len(shared_cards) == 3:
        round = 1
    elif len(shared_cards) == 4:
        round = 2
    else:
        round = 3
    my_cards = state.player[id].cards
    remain_card = list(range(0, 52))
    for x in shared_cards:
        remain_card.pop(remain_card.index(x))
    for x in my_cards:
        remain_card.pop(remain_card.index(x))
    # guess other player's card strength based on their betting
    alive_players = []
    for player_id in range(len(state.player)):
        if state.player[player_id].active & (player_id != id):
            alive_players.append(state.player[player_id])
    bold_better = []
    for alive_player in alive_players:
        total = alive_player.totalbet + alive_player.bet
        if total > 40:
            bold_better.append(alive_player)

    def simulate_win_rate(inhand_cards, other_player_cards=[], iterate=1000):
        win_count = 0
        _remain_card = list(range(0, 52))
        for x in shared_cards:
            _remain_card.pop(_remain_card.index(x))
        for x in inhand_cards:
            _remain_card.pop(_remain_card.index(x))

        for i in range(iterate):
            heap = _remain_card.copy()
            other_player_cards_sim = []

            random.shuffle(heap)
            for player in range(len(other_player_cards)):
                player_cards = random.choice(other_player_cards[player])
                other_player_cards_sim.append(player_cards)
                for x in player_cards:
                    if x in heap:
                        heap.pop(heap.index(x))

            for player in range(len(alive_players) - len(other_player_cards)):
                player_cards = []
                player_cards.append(heap.pop())
                player_cards.append(heap.pop())
                # player_hand = Hand(player_cards)
                other_player_cards_sim.append(player_cards)

            shared_cards_sim = shared_cards.copy()
            my_cards_sim = inhand_cards.copy()
            random.shuffle(heap)
            while len(shared_cards_sim) < 5:
                shared_cards_sim.append(heap.pop())
            my_cards_sim = my_cards_sim + shared_cards_sim
            # my_hand = Hand(my_cards_sim)
            # other_player = []

            score = 0
            even = 0
            assert (len(alive_players) == len(other_player_cards_sim))
            for player in range(len(alive_players)):
                compare = judge_two(
                    my_cards_sim,
                    other_player_cards_sim[player] + shared_cards_sim)
                if compare == 0:
                    even += 1
                score += compare
            if score == -len(alive_players):
                win_count += 1
            if even == alive_players:
                win_count += 0.5

        win_rate = win_count / iterate
        return win_rate

    guess_book = []

    guess_card_list_full = []
    if len(bold_better) != 0:
        for i in range(100):
            guess_card = []
            heap = remain_card[:]
            random.shuffle(heap)
            guess_card.append(heap.pop())
            guess_card.append(heap.pop())
            guess_card_win_rate = simulate_win_rate(inhand_cards=guess_card,
                                                    iterate=50)
            guess_card_list_full.append([guess_card, guess_card_win_rate])
        guess_card_list_full = sorted(guess_card_list_full, key=lambda x: x[1])

    print("--- %s seconds ---" % (time.time() - start_time))

    for player_id in range(len(bold_better)):
        cache_wealth = alive_players[player_id].money + alive_players[
            player_id].bet + alive_players[player_id].totalbet
        cache_invest_base = min(cache_wealth, 4000)
        cache_invest_base = max(cache_invest_base, 1000)
        confidence = (alive_players[player_id].bet / cache_invest_base)**(1 /
                                                                          2)
        if round == 0:
            confidence = min(confidence, 0.8)
        elif round == 1:
            confidence = min(confidence, 0.9)
        elif round == 2:
            confidence = min(confidence, 0.95)
        elif round == 3:
            confidence = min(confidence, 0.98)
        guess_card_list_part = guess_card_list_full[
            int(confidence * len(guess_card_list_full)):]
        guess_card_list = [i[0] for i in guess_card_list_part]
        guess_book.append(guess_card_list)

    my_win_rate = simulate_win_rate(inhand_cards=my_cards,
                                    other_player_cards=guess_book)
    print("--- %s seconds ---" % (time.time() - start_time))
    # print('estimated win rate: ', my_win_rate)
    decision = Decision()

    delta = state.minbet - state.player[state.currpos].bet
    me = state.player[id]
    wealth = me.money + me.totalbet + me.bet

    def add_bet(state, total):
        # amount: 本局需要下的总注
        amount = total - state.player[state.currpos].totalbet
        assert (amount > state.player[state.currpos].bet)
        if amount > me.money:
            decision.allin = 1
            return decision
        # Obey the rule of last_raised
        minamount = state.last_raised + state.minbet
        real_amount = max(amount, minamount)
        # money_needed = real_amount - state.player[state.currpos].bet
        decision.raisebet = 1
        decision.amount = int(real_amount)
        return decision

    if my_win_rate < 1 / (len(alive_players) + 1):
        target = 0
    elif my_win_rate > 0.75:
        base = max(state.player[state.currpos].money, 2000)
        base = min(base, 4000)
        target = my_win_rate**risk_averse * base + 15
    else:
        base = 2000
        target = my_win_rate**risk_averse * base + 15
        target = 0.6 * min(target, wealth * 0.6)

    if (wealth <= 300) & (my_win_rate > 0.6):
        decision.allin = 1
        return decision

    at_stake = state.player[id].totalbet + state.player[id].bet

    if (state.minbet + state.player[state.currpos].totalbet) >= target:
        if delta == 0:
            decision.callbet = 1
        else:
            er_giveup = -at_stake
            er_call = -(1 - my_win_rate) * (at_stake + delta) + my_win_rate * (
                state.moneypot)
            if er_giveup >= er_call:
                decision.giveup = 1
            else:
                decision.callbet = 1
    else:
        decision = add_bet(state, target)
    if log:
        log_text = 'estimated win rate, ' + str(
            my_win_rate) + ', ' + 'target, ' + str(target)
        print(log_text)
        state.logger.info(log_text)
    print("FINISH--- %s seconds ---" % (time.time() - start_time))
    return decision
Example #5
0
def ai(id, state):
    weight = [0, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
    remain_card = list(range(0, 52))
    cards = state.sharedcards + state.player[id].cards
    num = len(cards)
    for x in cards:
        remain_card.pop(remain_card.index(x))
    cnt = [0 for col in range(11)]
    # 模拟发牌1000次
    for i in range(1000):
        heap = remain_card[:]
        mycards = cards[:]
        random.shuffle(heap)
        while len(mycards) != 7:
            mycards.append(heap.pop())
        hand = Hand(mycards)
        level = hand.level
        cnt[level] += weight[level]

    # sum为评估值
    sum = 0
    for x in cnt:
        sum += x / 1000

    decision = Decision()
    totalbet = 0
    delta = state.minbet - state.player[state.currpos].bet
    if delta >= state.player[state.currpos].money:
        totalbet = 1000
    else:
        totalbet = state.player[state.currpos].totalbet + state.minbet

    if num == 2:
        # 两张牌
        if cards[0] != cards[1]:
            # 非对子
            if max(cards) <= 8 and 0 not in cards:
                # 最大不超过9:若跟注后超过100,放弃。否则跟注
                if totalbet <= 100:
                    decision.callbet = 1
                else:
                    decision.giveup = 1
            if max(cards) <= 11 and 0 not in cards:
                # 最大为10-Q:若跟注后超过150,放弃。否则跟注
                if totalbet <= 150:
                    decision.callbet = 1
                else:
                    decision.giveup = 1
            else:
                # 最大为K-A: 若跟注后超过200,放弃。否则跟注
                if totalbet <= 200:
                    decision.callbet = 1
                else:
                    decision.giveup = 1
        else:
            # 对子
            if max(cards) <= 11 and 0 not in cards:
                # 对子,不超过Q:跟注。若跟注后低于200,加注到200以上
                if totalbet < 200:
                    decision = add_bet(state, 200)
                else:
                    decision.callbet = 1
            else:
                # 双A、双K:跟注。若跟注后低于300,加注到300
                if totalbet < 300:
                    decision = add_bet(state, 300)
                else:
                    decision.callbet = 1

    elif num == 5:
        # 五张牌
        if sum < 4:
            # 直接放弃
            decision.giveup = 1
        elif sum >= 4 and sum < 10:
            # 若跟注后超过150,放弃。否则跟注
            # 若已下的注额大于200, 且本次需跟注额不大于50, 则跟注
            if totalbet < 150:
                decision.callbet = 1
            elif state.player[state.currpos].totalbet + state.player[
                    state.currpos].bet > 200 and delta < 50:
                decision.callbet = 1
            else:
                decision.giveup = 1
        elif sum >= 10 and sum < 20:
            # 跟注。若跟注后低于300,加注到300
            if totalbet < 300:
                decision = add_bet(state, 300)
            else:
                decision.callbet = 1
        elif sum >= 20 and sum < 50:
            # 跟注。若跟注后低于600,加注到600
            if totalbet < 600:
                decision = add_bet(state, 600)
            else:
                decision.callbet = 1
        else:
            # allin
            decision.allin = 1

    elif num == 6:
        # 六张牌
        if sum < 2:
            # 直接放弃
            decision.giveup = 1
        elif sum >= 2 and sum < 8:
            # 若跟注后超过300,放弃。否则跟注
            # 若已下的注额大于200, 且本次需跟注额不大于50, 则跟注
            if totalbet < 300:
                decision.callbet = 1
            elif state.player[state.currpos].totalbet + state.player[
                    state.currpos].bet > 200 and delta < 50:
                decision.callbet = 1
            else:
                decision.giveup = 1
        elif sum >= 8 and sum < 20:
            # 跟注。若跟注后低于300,加注到300
            if totalbet < 300:
                decision = add_bet(state, 300)
            else:
                decision.callbet = 1
        elif sum >= 20 and sum < 40:
            # 跟注。若跟注后低于600,加注到600
            if totalbet < 600:
                decision = add_bet(state, 600)
            else:
                decision.callbet = 1
        else:
            # allin
            decision.allin = 1

    elif num == 7:
        # 七张牌
        if level == 7:
            # allin
            decision.allin = 1
        elif level == 6:
            # 跟注,若跟注后低于600,加注到600
            if totalbet < 600:
                decision = add_bet(state, 600)
            else:
                decision.callbet = 1
        elif level == 5:
            # 跟注,若跟注后低于500,加注到500
            if totalbet < 500:
                decision = add_bet(state, 500)
            else:
                decision.callbet = 1
        elif level == 4:
            # 跟注,若跟注后低于400,加注到400
            if totalbet < 400:
                decision = add_bet(state, 400)
            else:
                decision.callbet = 1

        elif level == 3:
            # 若跟注后超过500,放弃。否则跟注。若跟注后低于300,加注到300
            # 若已下的注额大于200, 且本次需跟注额不大于50, 则跟注
            if totalbet < 300:
                decision = add_bet(state, 300)
            elif totalbet < 500:
                decision.callbet = 1
            elif state.player[state.currpos].totalbet + state.player[
                    state.currpos].bet > 200 and delta < 50:
                decision.callbet = 1
            else:
                decision.giveup = 1
        elif level == 2:
            if cards.count(0) == 2 or cards.count(12) == 2:
                # 双A双K 若跟注后超过200,放弃。否则跟注
                # 若已下的注额大于200, 且本次需跟注额不大于50, 则跟注
                if totalbet < 200:
                    decision.callbet = 1
                elif state.player[state.currpos].totalbet + state.player[
                        state.currpos].bet > 200 and delta < 50:
                    decision.callbet = 1
                else:
                    decision.giveup = 1
            else:
                # 不超过双Q 若跟注后超过200,放弃。否则跟注
                if totalbet > 200:
                    decision.giveup = 1
                else:
                    decision.callbet = 1
        elif level == 1:
            decision.giveup = 1
        else:
            print('the num of cards is {}'.format(num))
            assert (0)
    if decision.callbet == 1 and delta == state.player[state.currpos].money:
        decision.callbet = 0
        decision.allin = 1
    if decision.callbet == 1 and state.minbet == 0:
        t = random.randint(0, 2)
        if t == 0:
            decision.callbet = 0
            decision.raisebet = 1
            decision.amount = state.bigBlind
    return decision