-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathset_track.py
201 lines (198 loc) · 6.86 KB
/
set_track.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
def set_track(d=2,_id=1,fields=None,stat=None):
'''
函数说明:更新圈地路径
传入参数:
d int 离开领地的距离
_id int 我方的编号
fields list[list[]] 二维数组,表示双方的领地
返回:
final list[list[]] 返回二维数组,值为字符’t‘的点为路径
Version:
1.0: date:2018/6/7 by st
'''
#预处理,保留了测试接口
if stat is not None:
fields,_id=stat['now']['fields'],stat['now']['me']['id']
col,row,corner_list=len(fields),len(fields[0]),[]
border = [[0 for y in range(row)] for x in range(col)] #边界数组,用于识别角
track = [[0 for y in range(row)] for x in range(col)] #路径数组
# 上下扫描和左右扫描,将每一边向外扩展d的距离
for x in range(col):
for y in range(row):
if fields[x][y] == _id:
count=0
if y>0 and fields[x][y - 1] != _id:
track[x][max(0,y-d)]+=1
count=1
if y<row-1 and fields[x][y + 1] != _id:
track[x][min(row-1,y+d)] += 1
count=1
border[x][y]+=count
for y in range(row):
for x in range(col):
if fields[x][y] == _id:
count=0
if x>0 and fields[max(0,x-1)][y] != _id:
track[x-d][y]+=1
count=1
if x<col-1 and fields[x+1][y] != _id:
track[min(col-1,x+d)][y] += 1
count=1
border[x][y]+=count
if border[x][y]==2:
corner_list.append((x,y))
#将track中的值复制到border中(border原来的值已经没有意义)
for x in range(col):
for y in range(row):
border[x][y]=track[x][y]
#处理角上的缺口
for i in corner_list:
x,y=i[0],i[1]
n=max(0,y-d) #m和n用于保证不出界
if border[x][n]!=0:
m=max(0,x-d)
if border[m][y]!=0:
for a in range(m,x):
track[a][n]+=1
for a in range(n, y):
track[m][a] += 1
m=min(col-1,x+d)
if border[m][y]!=0:
for a in range(x+1,m+1):
track[a][n]+=1
for a in range(n,y):
track[m][a]+=1
n=min(row-1,y+d)
if border[x][n]!=0:
m = max(0, x - d)
if border[m][y]!=0:
for a in range(m,x):
track[a][n]+=1
for a in range(y+1,n+1):
track[m][a]+=1
m = min(col - 1, x + d)
if border[m][y]!=0:
for a in range(x+1,m+1):
track[a][n]+=1
for a in range(y+1,n+1):
track[m][a]+=1
#去掉多余路径标记(通过模拟纸卷的行动)
x,y,stop,_min,min_x,min_y=0,0,False,float('inf'),0,0
while x<col: #初始定位
y=0
while y<row:
if track[x][y]==1:
min_x,min_y,stop=x,y,True
break
elif 1<track[x][y]<_min:
min_x,min_y=x,y
y+=1
if stop:
break
else:
x+=1
x,y=min_x,min_y
final=[[0 for b in range(row)] for a in range(col)] #最终返回值
#路径评估函数(内部使用)
def evaluate_dir(x, y, label=''):
'''
函数说明:以上方法可能生成一些岔路(尤其是领地有凹角、凹边、飞地甚至更糟的时候),本函数将评估出合适的路径
传入参数:
x,y int,int 待处理的位置坐标
label str 标记,即如何从上一个位置来到这里(向上、向下、向左、向右)
返回:
'left'or'right'or'up'or'down'or 'stop'
'''
if track[x][y] == 1:
if label == 'up':
return label if y > 0 and track[x][y - 1] > 0 else 'stop'
elif label == 'down':
return label if y < row - 1 and track[x][y + 1] > 0 else 'stop'
elif label == 'left':
return label if x > 0 and track[x - 1][y] > 0 else 'stop'
elif label == 'right':
return label if x < col - 1 and track[x + 1][y] > 0 else 'stop'
dis,_dir = 1,{'up': 0, 'down': 0, 'left': 0, 'right': 0}
while len(_dir) > 1:
if 'up' in _dir:
_dir['up'] = track[x][y - dis] if y > dis - 1 else -1
if 'down' in _dir:
_dir['down'] = track[x][y + dis] if y < row - dis else -1
if 'left' in _dir:
_dir['left'] = track[x - dis][y] if x > dis - 1 else -1
if 'right' in _dir:
_dir['right'] = track[x + dis][y] if x < col - dis else -1
m = max(_dir.values())
if m<0:
break
j = 0
while j < len(_dir):
k = list(_dir.keys())[j]
if _dir[k] < m:
_dir.pop(k)
else:
j += 1
dis += 1
if 'up' in _dir:
_dir['up'] = track[x][y - 1] if y > 0 else -1
if 'down' in _dir:
_dir['down'] = track[x][y + 1] if y < row - 1 else -1
if 'left' in _dir:
_dir['left'] = track[x - 1][y] if x > 0 else -1
if 'right' in _dir:
_dir['right'] = track[x + 1][y] if x < col - 1 else -1
j = 0
while j < len(_dir):
k = list(_dir.keys())[j]
if _dir[k] < 1:
_dir.pop(k)
else:
j += 1
if 'up' in _dir:
return 'up'
elif 'down' in _dir:
return 'down'
elif 'left' in _dir:
return 'left'
elif 'right' in _dir:
return 'right'
else:
return 'stop'
#开始模拟纸卷运动
prim_x,prim_y,prim_label=x,y,evaluate_dir(x,y)
label=prim_label
while True:
label = evaluate_dir(x, y, label)
final[x][y] ,track[x][y]= 1,-1
if label == 'up':
y-=1
elif label == 'down':
y+=1
elif label == 'left':
x-=1
elif label == 'right':
x+=1
else:
break
x,y=prim_x,prim_y
track[x][y]=1
dd=['up','left','down','right']
label=dd[(dd.index(prim_label)+2)%4]
while True:
label=evaluate_dir(x,y,label)
final[x][y] ,track[x][y]= 1,-1
if label == 'up':
y-=1
elif label == 'down':
y+=1
elif label == 'left':
x-=1
elif label == 'right':
x+=1
else:
break
for x in range(col):
for y in range(row):
if final[x][y]:
final[x][y]='t'
return final