Ejemplo n.º 1
0
def test_get_resp_moves():
    rival_move = [3, 3, 4, 4, 5, 5]
    cards = [5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 9, 20, 30]
    print("moves = %s" % get_resp_moves(cards, rival_move))

    rival_move = [5, 5, 5, 6, 6, 6, 7, 8]
    cards = [7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 11, 12, 20, 30]
    print("moves = %s" % get_resp_moves(cards, rival_move))
Ejemplo n.º 2
0
def minmax_search(result_dict, lorder_cards, farmer_cards, current_move,
                  next_player):
    global m_class
    global nodes_num

    def _get_best_move():
        best = False
        for _, item in result_dict.items():
            if item['score'] == MAX_SCORE:
                best = True
                break
        return best

    if next_player == 'farmer':
        if len(lorder_cards) == 0:
            # If any other process gets the best move, exit myself
            if nodes_num % 1e4 == 0 and _get_best_move():
                exit(0)
            nodes_num += 1
            return MAX_SCORE  # lorder win, return MAX_SCORE

    elif next_player == 'lorder':
        if len(farmer_cards) == 0:
            # If any other process gets the best move, exit myself
            if nodes_num % 1e4 == 0 and _get_best_move():
                exit(0)
            nodes_num += 1
            return MIN_SCORE  # farmer win, return MIN_SCORE

    if next_player == 'farmer':  # the parameter next_player is current player
        score = MAX_SCORE  # For farmer, the default score is MAX_SCORE
        all_moves = get_resp_moves(farmer_cards, current_move)
        # a kind of optimization
        all_moves = sorted(all_moves, key=lambda x: len(x), reverse=True)
        for farmer_move in all_moves:
            fc = get_rest_cards(farmer_cards, farmer_move)
            score = minmax_search(result_dict, lorder_cards, fc, farmer_move,
                                  'lorder')
            # Current player is farmer, so once finds MIN_SCORE, he must choose it.
            # Cut Branches! Ignore the rest farmer moves.
            if score == MIN_SCORE:
                break
        return score

    else:  # next_player is 'lorder', the parameter next_player is current player
        score = MIN_SCORE  # For 'lorder', the default value is MIN_SCORE
        all_moves = get_resp_moves(lorder_cards, current_move)
        # a kind of optimization
        all_moves = sorted(all_moves, key=lambda x: len(x), reverse=True)
        for lorder_move in all_moves:
            lc = get_rest_cards(lorder_cards, lorder_move)
            score = minmax_search(result_dict, lc, farmer_cards, lorder_move,
                                  'farmer')
            # Current player is lorder. So, once MAX_SCORE, choose it!
            # Cut Branches! Ignore the rest lorder moves.
            if score == MAX_SCORE:
                break
        return score
Ejemplo n.º 3
0
def start_engine(lorder_cards=list(), farmer_cards=list(), farmer_move=list()):
    """
    :return: the best move which can win, otherwise None
    """
    manager = multiprocessing.Manager()
    result_dict = manager.dict()

    process_pool = []
    lorder_cards = format_input_cards(lorder_cards)
    farmer_cards = format_input_cards(farmer_cards)
    farmer_move = format_input_cards(farmer_move)

    all_lorder_moves = get_resp_moves(format_input_cards(lorder_cards),
                                      farmer_move)
    # a kind of optimization
    all_lorder_moves = sorted(all_lorder_moves,
                              key=lambda x: len(x),
                              reverse=True)
    formatted_all_lorder_moves = [
        format_output_cards(move) for move in all_lorder_moves
    ]
    print("%d Moves totally: %s" %
          (len(formatted_all_lorder_moves), formatted_all_lorder_moves))

    if len(all_lorder_moves) == 1:  # Pass
        return all_lorder_moves[0]

    count = 0
    for move in all_lorder_moves:
        record = {'move': move, 'farmer_win': 0, 'lorder_win': 0}
        mc_records.append(record)

        lc = get_rest_cards(lorder_cards, move)
        p = multiprocessing.Process(target=process_search,
                                    args=(count, result_dict, lc, farmer_cards,
                                          move, 'farmer'))
        process_pool.append(p)
        count += 1

    for p in process_pool:
        p.start()
    for p in process_pool:
        p.join()

    for _, item in result_dict.items():
        if item['score'] == MAX_SCORE:
            return item['move']
Ejemplo n.º 4
0
    def run(lorder_cards=None, farmer_cards=None, farmer_move=None):
        if farmer_move is None:
            farmer_move = list()
        if farmer_cards is None:
            farmer_cards = list()
        if lorder_cards is None:
            lorder_cards = list()
        UIEngine.declare()

        if not lorder_cards and not farmer_cards:
            print("请输入对手的牌(以空格间隔): ")
            farmer_cards = input().split()
            while not validate_cards(farmer_cards):
                print("对手的牌输入错误,请重新输入: ")
                farmer_cards = input().split()

            print("请输入自己的牌(以空格间隔): ")
            lorder_cards = input().split()
            while not validate_cards(lorder_cards):
                print("自己的牌输入错误,请重新输入: ")
                lorder_cards = input().split()

        lorder_cards = format_input_cards(lorder_cards)
        farmer_cards = format_input_cards(farmer_cards)

        print("初始状态: ")
        print("自己家的牌: %s" % format_output_cards(lorder_cards))
        print("对手家的牌: %s" % format_output_cards(farmer_cards))
        print("当前出牌者: %s" % "自己")
        print("-" * 20)

        # LandLorder do the first move
        lorder_move = start_engine(lorder_cards=lorder_cards,
                                   farmer_cards=farmer_cards,
                                   farmer_move=farmer_move)

        if lorder_move is None:
            print("自己必败!")
            return

        lorder_cards = get_rest_cards(lorder_cards, lorder_move)
        if len(lorder_cards) == 0:
            print("自己出牌: %s" % format_output_cards(lorder_move))
            print("自己胜利!")
            return

        # Farmer and LandLorder play one by one
        while True:
            # Print the Situation after Lorder play a move
            str_lorder_move = format_output_cards(
                lorder_move) if lorder_move else 'Pass!'
            print("自己家的牌: %s" % format_output_cards(lorder_cards))
            print("对手家的牌: %s" % format_output_cards(farmer_cards))
            print("自己已出牌: %s" % str_lorder_move)
            print("-" * 20)

            # Farmer plays a move
            print("请帮对手出牌:")
            farmer_move = input("")
            if (farmer_move in ['pass', 'Pass', 'PASS', '不要']) or \
                    len(farmer_move.strip()) == 0:
                farmer_move = []
            elif farmer_move == 'quit':
                exit(0)
            else:
                farmer_move = format_input_cards(farmer_move.split())

            possible_moves = get_resp_moves(farmer_cards, lorder_move)
            # must sort, for 'not in' check.
            possible_moves = [sorted(move) for move in possible_moves]
            while farmer_move not in possible_moves:
                print("错误的出牌!请重新帮对手出牌: ")
                farmer_move = input("")
                if farmer_move in ['pass', 'Pass', 'PASS']:
                    farmer_move = []
                else:
                    farmer_move = format_input_cards(farmer_move.split())
                possible_moves = get_resp_moves(farmer_cards, lorder_move)
                # must sort, for 'not in' check.
                possible_moves = [sorted(move) for move in possible_moves]

            farmer_cards = get_rest_cards(farmer_cards, farmer_move)
            if len(farmer_cards) == 0:
                print("对手出牌: %s" % format_output_cards(farmer_move))
                print("对手胜利!")
                return

            str_farmer_move = format_output_cards(
                farmer_move) if farmer_move else 'Pass!'
            print("自己家的牌: %s" % format_output_cards(lorder_cards))
            print("对手家的牌: %s" % format_output_cards(farmer_cards))
            print("对手已出牌: %s" % str_farmer_move)
            print("-" * 20)

            # LandLorder plays a move
            lorder_move = start_engine(lorder_cards=lorder_cards,
                                       farmer_cards=farmer_cards,
                                       farmer_move=farmer_move)

            if lorder_move is None:
                print("自己必败!")
                return

            lorder_cards = get_rest_cards(lorder_cards, lorder_move)
            if len(lorder_cards) == 0:
                print("自己出牌: %s" % format_output_cards(lorder_move))
                print("自己胜利!")
                return