-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
146 lines (124 loc) · 5.17 KB
/
utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from douzero.env.move_generator_new import MovesGener
from douzero.env.move_detector import get_move_type
from douzero.env import move_selector_new
from constants import EnvCard2RealCard
def action_to_str(action):
if len(action) == 0:
return "Pass"
else:
return "".join([EnvCard2RealCard[card] for card in action])
def type_exist(mlist, type):
if not isinstance(mlist, list):
return False
for item in mlist:
if not isinstance(item, type):
return False
return True
def action_in_tree(path_list, action):
for ac in path_list:
ac[0].sort()
if action == ac[0]:
return ac
return None
def search_actions(my_cards, other_cards, path_list, rival_move=None, prev_moves=None):
if len(path_list) > 100:
return None
if prev_moves is None:
my_cards.sort()
other_cards.sort()
other_gener = MovesGener(other_cards)
other_bombs = other_gener.gen_type_4_bomb()
other_bombs.extend(other_gener.gen_type_5_king_bomb())
my_gener = MovesGener(my_cards)
my_bombs = my_gener.gen_type_4_bomb()
my_bombs.extend(my_gener.gen_type_5_king_bomb())
legal_move_tree = []
rival_move_info = {}
type_range = [4, 5, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
if rival_move is not None:
if len(rival_move) > 0:
rival_move_info = get_move_type(rival_move)
type_range = [4, 5, rival_move_info["type"]]
else:
rival_move = None
for mtype in type_range:
my_moves = my_gener.gen_moves_by_type(mtype)
if len(my_moves) == 0:
continue
if mtype == 4:
other_moves = other_bombs
else:
other_moves = other_gener.gen_moves_by_type(mtype)
for move in my_moves:
if len(move) != len(my_cards):
if mtype != 4 and mtype != 5 and len(other_bombs) > 0:
break
if len(move_selector_new.filter_type_n(mtype, other_moves, move)) == 0:
if rival_move is not None:
move_info = get_move_type(move)
if mtype != 5:
if "rank" in move_info and "rank" in rival_move_info and move_info["rank"] <= \
rival_move_info["rank"]:
continue
if "len" in move_info and move_info["len"] != rival_move_info["len"]:
continue
if rival_move_info["type"] == 5:
continue
new_cards = my_cards.copy()
for card in move:
new_cards.remove(card)
if prev_moves is not None:
new_prev = prev_moves.copy()
new_prev.append(move)
else:
new_prev = [move]
actions = search_actions(new_cards, other_cards, path_list, prev_moves=new_prev)
del new_prev
del new_cards
if actions is not None and len(actions) > 0:
legal_move_tree.append([move, actions])
else:
if rival_move is not None:
move_info = get_move_type(move)
if "rank" in move_info and "rank" in rival_move_info and move_info["rank"] <= rival_move_info["rank"]:
continue
if "len" in move_info and move_info["len"] != rival_move_info["len"]:
continue
if rival_move_info["type"] == 5:
continue
legal_move_tree.append(move)
if prev_moves is not None:
new_path = prev_moves.copy()
new_path.append(move)
path_list.append(new_path)
else:
path_list.append([move])
legal_moves_count = len(legal_move_tree)
del my_gener, other_gener, my_bombs, other_bombs, my_cards, other_cards, legal_move_tree
return None
def eval_path(path):
bomb = 0
for action in path:
if 30 in action and 20 in action or len(action) == 4 and len(set(action)) == 1:
bomb += 1
return 1 + bomb - len(path) * 0.05
def select_optimal_path(path_list):
if len(path_list) != 0:
max_path = max(path_list, key=lambda x: eval_path(x))
for action in max_path:
action.sort()
return max_path
else:
return None
def check_42(path):
for action in path:
move_type = get_move_type(action)
if move_type["type"] == 13 or move_type["type"] == 14:
return True
return False
def remove_chars_from_string(source_str, chars_to_remove):
for char in chars_to_remove:
# 如果字符在源字符串中出现,则从源字符串中删除该字符
if char in source_str:
source_str = source_str.replace(char, '', 1)
return source_str