Пример #1
0
    def _check_dfs(self, node):
        action_dim, hole_dim = 0, 1
        if node.node_type == NodeTypes.TERMINAL_CALL or node.node_type == NodeTypes.TERMINAL_FOLD:
            return

        assert node.strategy is not None

        action_count = len(node.children)
        strategy_ = node.strategy

        board_mask = Mask.get_board_mask(board=node.board)

        if node.current_player == Players.CHANCE:
            check_sum = strategy_.sum(axis=action_dim)
            assert not (strategy_ <= 0).any()
            assert not (check_sum > 1.001).any()
            assert not (check_sum < 0.999).any()

        assert (node.ranges_absolute[node.ranges_absolute < 0]).sum() == 0
        assert (node.ranges_absolute[node.ranges_absolute > 1]).sum() == 0

        # check if range consist only of cards that don't overlap with the board
        board_mask_inverse = Mask.get_board_mask_inverse(
            board=node.board).reshape((1, Argument.hole_count))
        impossible_range_sum = node.ranges_absolute * board_mask_inverse.repeat(
            repeats=2, axis=0).astype(dtype=float)
        assert impossible_range_sum.sum() == 0

        for child_node in node.children:
            self._check_dfs(child_node)

        return
Пример #2
0
 def compute_mask(self, board):
     """compute hole mask and it's inverse, should be called before _set_xxx_matirx()
     :param board: a list of board cards
     :return: None
     """
     self.hole_mask = Mask.get_hole_mask()
     self.inverse_hole_mask = 1 - self.hole_mask
Пример #3
0
	def compute_fold_matrix(self, board):
		fold_matrix = np.ones(shape=(self.hc, self.hc), dtype=float)
		fold_matrix = self.hole_mask.copy()  # make sure player hole don't conflict with opponent hole
		board_mask = Mask.get_board_mask(board)  # make sure hole don't conflict with board
		fold_matrix[board_mask == False, :] = 0
		fold_matrix[:, board_mask == False] = 0

		return fold_matrix
Пример #4
0
	def __init__(self):
		self.hc, self.cc = Argument.hole_count, Argument.card_count
		self.hole_mask = Mask.get_hole_mask()
		self.board_mask = None
		self.call_matrix = None
		self.fold_matrix = None
		self.call_matrix_tensor = None
		self.fold_matrix_tensor = None
Пример #5
0
 def get_uniform_range(cls, board):
     """construct a range vector where all possible hands have same probability
     all impossible hands have zero probability
     :return: a uniform range which doesn't conflict with board
     """
     out = Argument.Tensor(Argument.hole_count).zero_()
     mask = Mask.get_board_mask(board)
     out[mask] = 1
     out.div_(out.sum())
     assert out.sum() == 1
     return out
def test_terminal_equity_numpy():
	dll = cdll.LoadLibrary("../so/hand_eval.dll") if platform.system() == "Windows" \
		else cdll.LoadLibrary("../so/hand_eval.so")
	deck = list(range(52))
	te = TerminalEquity()
	hole_mask = Mask.get_hole_mask()

	for t in range(10):
		shuffle(deck)
		board = deck[0:5]
		te.set_board(board=board)
		call_matrix = te.get_call_matrix()
		fold_matrix = te.get_fold_matrix()

		# eval using dll
		_strength = (c_int * 1326)()  # param 1
		_board = (c_int * 5)(*board)  # param3
		dll.eval5Board(_board, 5, _strength)
		strenght_list = np.array(_strength, dtype=int)

		for i in range(1325):
			for j in range(i + 1, 1326):
				assert call_matrix[i, j] == -call_matrix[j, i]

		# test call matrix
		for i in range(1325):
			for j in range(i + 1, 1326):
				if strenght_list[i] == -1 or strenght_list[j] == -1:
					# call_matrix[i, j] should be 0, because is conflict with board
					assert call_matrix[i, j] == 0
				elif not hole_mask[i][j]:
					assert call_matrix[i, j] == 0
				elif strenght_list[i] > strenght_list[j]:
					try:
						assert call_matrix[i, j] == -1
					except AssertionError:
						print(call_matrix[i, j], strenght_list[i], strenght_list[j])
						raise Exception
				elif strenght_list[i] == strenght_list[j]:
					assert call_matrix[i, j] == 0
				else:
					assert call_matrix[i, j] == 1

		# test fold matrix
		for i in range(51):
			for j in range(i + 1, 52):
				index1 = j * (j - 1) // 2 + i
				for m in range(51):
					for n in range(m + 1, 52):
						index2 = n * (n - 1) // 2 + m
					if i == m or i == n or j == m or j == n or i in board or j in board or m in board or n in board:
						assert fold_matrix[index1, index2] == fold_matrix[index2, index1] == 0
					else:
						assert fold_matrix[index1, index2] == fold_matrix[index2, index1] == 1
Пример #7
0
def test_terminal_equity():
    dll = cdll.LoadLibrary("../so/hand_eval.dll") if platform.system() == "Windows" \
        else cdll.LoadLibrary("../so/hand_eval.so")
    deck = list(range(52))
    te = TerminalEquity()
    hole_mask = Mask.get_hole_mask()
    inv_mask = 1 - hole_mask

    for t in range(10):
        shuffle(deck)
        board = deck[0:5]
        te.set_board(board=board)
        call_matrix = te.call_matrix
        fold_matrix = te.fold_matrix

        _strength = (c_int * 1326)()
        dll.eval5Board((c_int * 5)(*board), 5, _strength)
        strength = torch.FloatTensor(_strength)

        assert call_matrix[inv_mask].sum() == 0
        assert (call_matrix == -call_matrix.t()).all()

        # test call matrix
        for i in range(51):
            for j in range(i + 1, 52):
                for m in range(51):
                    for n in range(m + 1, 52):
                        idx1 = (j * (j - 1)) // 2 + i
                        idx2 = (n * (n - 1)) // 2 + m
                        if m in (i, j) or n in (i, j) or i in board or j in board or m in board or n in board:
                            assert call_matrix[idx1, idx2] == 0
                        else:
                            if strength[idx1] > strength[idx2]:
                                assert call_matrix[idx1, idx2] == -1
                            elif strength[idx1] < strength[idx2]:
                                assert call_matrix[idx1, idx2] == 1
                            elif strength[idx1] == strength[idx2]:
                                assert call_matrix[idx1, idx2] == 0

        # test fold matrix
        for i in range(51):
            for j in range(i + 1, 52):
                index1 = j * (j - 1) // 2 + i
                for m in range(51):
                    for n in range(m + 1, 52):
                        index2 = n * (n - 1) // 2 + m
                    if i == m or i == n or j == m or j == n or i in board or j in board or m in board or n in board:
                        assert fold_matrix[index1, index2] == fold_matrix[index2, index1] == 0
                    else:
                        assert fold_matrix[index1, index2] == fold_matrix[index2, index1] == 1
Пример #8
0
    def _set_fold_matrix(self, board):
        """compute fold_matrix according to hole_mask
        :param board: a list of board cards
        :return: None
        """
        self.fold_matrix = Argument.Tensor(Argument.hole_count,
                                           Argument.hole_count)

        board_mask = Mask.get_board_mask(board)
        inverse_board_mask = 1 - board_mask
        inverse_board_mask_view1 = inverse_board_mask.view(1, -1).expand_as(
            self.fold_matrix)
        inverse_board_mask_view2 = inverse_board_mask.view(-1, 1).expand_as(
            self.fold_matrix)
        self.fold_matrix.copy_(self.hole_mask.float())
        self.fold_matrix[inverse_board_mask_view1] = 0
        self.fold_matrix[inverse_board_mask_view2] = 0
Пример #9
0
    def compute_buckets(self, board):
        """compute buckets using expected hand strength
        :parameter board: a list of board card
        :return a buckets FloatTensor (bucket_count, )
        """
        board_count = len(board)
        rd = [0, None, None, 1, 2, 3][board_count]
        assert board_count in (0, 3, 4, 5)

        ehs_tensor = self.ehs.get_hand_ehs(board)
        board_mask = Mask.get_board_mask(board)
        # use fixed interval bucketing, convert ehs to [0,1,2...499]
        buckets = ehs_tensor.clone()
        buckets[board_mask] *= (self.bucket_count - 1)
        buckets.floor_()

        return buckets
Пример #10
0
    def generate_data(self, data_count):
        self.batch_count = data_count // self.batch_size

        # initialize inputs, targets, masks' place holder
        if self.inputs_ph is None:
            self.inputs_ph = Arguments.Tensor(self.batch_size, 2 * 1326 + 1)
            self.targets_ph = Arguments.Tensor(self.batch_size, 2 * 1326)
            self.mask_ph = Arguments.Tensor(self.batch_size, 1326)

        for i in range(self.batch_count):
            # [1.0] generate random poker situations
            # board list, ranges FloatTensor, pots FloatTensor
            board, ranges, pots = self.generate_random_poker_situation()
            # ranges_tensor = Arguments.Tensor(ranges).view(Arguments.hole_count)
            # pots_tensor = Arguments.Tensor(pots).div_(Arguments.stack)
            mask = Mask.get_board_mask(board).float()  # convert ByteTensor to FloatTensor
            # mask
            self.mask_ph.copy_(mask.view(1, -1).expand_as(self.mask_ph))
            # pots of inputs
            pots.mul_(1 / Arguments.stack)
            self.inputs_ph[:, -1:].copy_(pots.view(self.batch_size, 1))
            # [2.0] solve random poker situations
            for j in range(self.batch_size):
                bet = int(pots[j])
                bets = [bet, bet]
                root = self.tree_builder.build_tree(street=self.round, initial_bets=bets,
                                                    current_player=Players.P0, board=board)
                start_range = ranges[:, j, :]  # (2, hole_count)
                self.solver.run_cfr(root, start_range=start_range)
                cf_values = root.cf_values
                # inputs
                self.inputs_ph[j, :Arguments.hole_count].copy_(ranges[0, j, :])
                self.inputs_ph[j, Arguments.hole_count:-1].copy_(ranges[1, j, :])

                # targets
                self.targets_ph[j, :Arguments.hole_count].copy_(cf_values[0])
                self.targets_ph[j, Arguments.hole_count:].copy_(cf_values[1])
                # mask already handled before loop
            # end for
            # save a batch of data
            self.save_batch_data()
Пример #11
0
# -*- coding: utf-8 -*-

from Equity.mask import Mask

hole_mask = Mask.get_hole_mask()
row_sum = hole_mask.float().sum(1)
col_sum = hole_mask.float().sum(0)
assert (row_sum == 1225).all()
assert (col_sum == 1225).all()
for i in range(51):
    for j in range(i + 1, 52):
        index1 = j * (j - 1) // 2 + i
        for m in range(51):
            for n in range(m + 1, 52):
                index2 = n * (n - 1) // 2 + m
                if i == m or i == n or j == m or j == n:
                    assert hole_mask[index1,
                                     index2] == hole_mask[index2,
                                                          index1] == False
                else:
                    assert hole_mask[index1,
                                     index2] == hole_mask[index2,
                                                          index1] == True

board = [0, 1, 2]
board_mask = Mask.get_board_mask(board=board)
assert len(board_mask.float()) == 1326
assert sum(board_mask.float()) == 1176
for i in range(51):
    for j in range(i + 1, 52):
        index = j * (j - 1) // 2 + i