单身贵族跳棋

单身贵族跳棋_第1张图片
image.png

单身贵族跳棋_第2张图片
image.png
import numpy as np
import math
import copy
row_array_data = [np.arange(start=1, stop=6), np.arange(start=6, stop=12), np.arange(start=12, stop=19), np.arange(start=19, stop=25), np.arange(start=25, stop=30)]
print('row_array_data:', row_array_data)
node_flag_arr = []  # 第0个不用
row_mapping = {
    0: (None, [5, 6]),
    1: ([6, 5], [6, 7]),
    2: ([7, 6], [6, 7]),
    3: ([7, 6], [5, 6]),
    4: ([6, 5], None),
}


same_line_arr = [
    [1, 6, 12],
    [2, 7, 13],
    [7, 13, 19],
    [3, 8, 14],
    [8, 14, 20],
    [14, 20, 25],
    [4, 9, 15],
    [9, 15, 21],
    [15, 21, 26],
    [5, 10, 16],
    [10, 16, 22],
    [16, 22, 27],
    [11, 17, 23],
    [17, 23, 28],
    [18, 24, 29],
    [12, 19, 25],
    [6, 13, 20],
    [13, 20, 26],
    [1, 7, 14], [7, 14, 21], [14, 21, 27],
    [2, 8, 15], [8, 15, 22], [15, 22, 28],
    [3, 9, 16], [9, 16, 23], [16, 23, 29],
    [4, 10, 17], [10, 17, 24],
    [5, 11, 18],
]

# row_array_data = [np.arange(start=1, stop=3), np.arange(start=3, stop=6), np.arange(start=6, stop=10), np.arange(start=10, stop=13), np.arange(start=13, stop=15)]
# print('row_array_data:', row_array_data)
# node_flag_arr = []  # 第0个不用
# row_mapping = {
#     0: (None, [2, 3]),
#     1: ([2, 3], [4, 3]),
#     2: ([3, 4], [3, 4]),
#     3: ([3, 4], [3, 2]),
#     4: ([3, 2], None),
# }

# same_line_arr = [
#     [1, 3, 6],
#     [1, 4, 8],
#     [2, 4, 7],
#     [2, 5, 9],
#     [3, 7, 11],
#     [4, 7, 10],
#     [4, 8, 12],
#     [5, 8, 11],
#     [6, 10, 13],
#     [7, 11, 14],
#     [8, 11, 13],
#     [9, 12, 14],
# ]

class Node(object):
    def __init__(self, _num, _row_index, _sibling):
        self.num = _num
        self.row_index = _row_index
        self.sibling = _sibling

    def __str__(self):
        return 'num:%d  row_index:%d sibling: %s' % (self.num, self.row_index, self.sibling)


def get_empty_flag_idx(_node_flag_arr):
    result_index = []
    for idx, node_flag in enumerate(_node_flag_arr):
        if idx == 0:
            continue
        if node_flag == 0:
            result_index.append(idx)
    return result_index


def is_same_order(_empty_node_idx, _sibling_num, _sibling_num2):
    return _empty_node_idx > _sibling_num > _sibling_num2 or _empty_node_idx < _sibling_num < _sibling_num2


def is_candidate_elm(existed_arr):
    if existed_arr[0] == existed_arr[1] or existed_arr[0] == existed_arr[2]:
        return False
    for arr in same_line_arr:
        if existed_arr[0] in arr and existed_arr[1] in arr and existed_arr[2] in arr:
            return True
    return False


def process_empty_node(node_idx, operation_list):
    _node = node_dict[node_idx]
    # print('_node:', _node)
    useful_sibling_num_arr = []
    for sibling_num in _node.sibling:
        if node_flag_arr[sibling_num] != 0:
            useful_sibling_num_arr.append(sibling_num)

    for sibling_num in useful_sibling_num_arr:
        # print('###node_idx:', node_idx, ' sibling_num:', sibling_num)
        delta = abs(node_idx - sibling_num)
        next_delta_arr = []
        if delta == 1:
            next_delta_arr = [1]
        sibling_node = node_dict[sibling_num]
        for sibling_num2 in sibling_node.sibling:
            delta2 = abs(sibling_num2 - sibling_num)
            cond1 = delta2 in next_delta_arr and node_flag_arr[sibling_num2] != 0 and is_same_order(node_idx, sibling_num, sibling_num2)
            if cond1 or (node_flag_arr[sibling_num2] != 0 and is_candidate_elm([node_idx, sibling_num2, sibling_num])):
                operation = str(sibling_num2) + '->' + str(node_idx) + ' x' + str(sibling_num)

                # if operation in operation_list:
                #     # print('operation重复,暂时不做', operation)
                #     continue

                # print('operation:', operation)
                operation_list.append(operation)
                # print('operation_list:', operation_list)
                backup_operation_list = copy.deepcopy(operation_list)

                node_flag_arr[sibling_num2] = node_flag_arr[sibling_num] = 0
                node_flag_arr[node_idx] = 1

                process_all_empty_nodes(operation_list)
                print('00operation_list:', operation_list)
                operation_list = backup_operation_list
                # node_flag_arr[sibling_num2] = node_flag_arr[sibling_num] = 1
                # node_flag_arr[node_idx] = 0


def process_all_empty_nodes(operation_list):
    useful_node_count = 0
    for idx, node_flag in enumerate(node_flag_arr):
        if node_flag == 1:
            useful_node_count += 1
    # if useful_node_count <= 1 or len(operation_list) >= 300:
    if (useful_node_count == 1) or len(operation_list) >= 10000: # and node_flag_arr[15] == 1 FIXME # or len(operation_list) >= 10000:
        print('###operation_list:', operation_list)
        return

    empty_node_idx_arr = get_empty_flag_idx(node_flag_arr)
    for empty_node_idx in empty_node_idx_arr:
        # print('empty_node_idx:', empty_node_idx)
        process_empty_node(empty_node_idx, operation_list)


if __name__ == '__main__':
    node_dict = {}
    row_index = 0
    for row_data in row_array_data:
        # print(row_index, ':', row_data)
        prev_row_data = row_array_data[row_index - 1] if row_index >= 1 else []
        next_row_data = row_array_data[row_index + 1] if row_index < len(row_array_data) - 1 else []
        col_index = 0
        for elm in row_data:
            # print('elm:', elm)
            sibling = []
            if col_index > 0:
                sibling.append(row_data[col_index - 1])
            if col_index < len(row_data) - 1:
                sibling.append(row_data[col_index + 1])

            row_mapping_data = row_mapping[row_index]
            upstream_data, downstream_data = row_mapping_data
            if upstream_data is not None:
                for u_length in upstream_data:
                    u_num = elm - u_length
                    if u_num in prev_row_data:
                        sibling.append(u_num)
            if downstream_data is not None:
                for d_length in downstream_data:
                    d_num = elm + d_length
                    if d_num in next_row_data:
                        sibling.append(d_num)

            sibling.sort()
            node = Node(elm, row_index, sibling)
            node_dict[elm] = node
            col_index += 1
        row_index += 1


    for i in range(0, 30):
        node_flag_arr.append(1)
    node_flag_arr[15] = 0

    # for i in range(0, 15):
    #     node_flag_arr.append(1)
    # node_flag_arr[8] = 0

    # 处理
    operation_list0 = []
    process_all_empty_nodes(operation_list0)
    print('operation_list0:', operation_list0)
    print('node_flag_arr:', node_flag_arr)

2->15表示2到15,经过8,x8表示去掉8

['2->15 x8'
 '4->2 x3'
 '1->3 x2'
 '12->1 x6'
 '13->2 x7'
 '2->4 x3'
 '5->3 x4'
 '15->4 x9'
 '4->2 x3'
 '1->3 x2'
 '17->4 x10'
 '4->2 x3'
 '18->5 x11'
 '21->7 x14'
 '23->9 x16'
 '25->12 x19'
 '2->13 x7'
 '20->6 x13'
 '12->1 x6'
 '28->15 x22'
 '15->4 x9'
 '5->3 x4'
 '29->18 x24'
 '27->25 x26']
单身贵族跳棋_第3张图片
image.png

你可能感兴趣的:(单身贵族跳棋)