Xuanwu path finder

Oct 20th, 2020
1,095
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. from laby import *
2. from math import atan2, sqrt, pi
3. import numpy as np
4.
6.   state = list(pos)
7.   dx, dy = cos(state[2]), sin(state[2])
8.   while(dist > 0):
9.     x, y = state[0] + dx/4, state[1] + dy/4
10.     ix, iy = int(x) - (x < 0), int(y) - (y < 0)
11.     drx, dry = ix - int(state[0]), iy - int(state[1])
12.     vw = lambda y, x: wl[y] & 2**x
13.     hw = lambda y, x: wl[y + laby_h] & 2**x
14.     wx = laby_w - 2 - min(ix, ix - drx)
15.     tx = drx and (ix < 0 or ix >= laby_w or vw(iy - dry, laby_w - 2 - min(ix, ix - drx)))
16.     ty = dry and (iy < 0 or iy >= laby_h or hw(min(iy, iy - dry), laby_w - 1 - (ix - drx)))
17.     t = dx <= 0 or int(x) < laby_w - 1 or int(y) < laby_h - 1
18.     if t and tx or ty or (drx and dry and (t and tx or ty)) or (drx and dry and (t and vw(iy, laby_w - 2 - min(ix, ix - drx)) or hw(min(iy, iy - dry), laby_w - 1 - ix))):
19.       return False
20.     dist -= .25
21.     state[0:1] = (x, y)
22.   return True
23.
24. def get_positions(pos_list, target_pos):
25.     result = []
26.     count = 0
27.     for pos in pos_list:
28.         count += 1
29.         if count % 1000 == 0: print(count)
30.         for da10 in range(-99, 100):
31.             da = da10 / 10.
32.             new_angle = pos[2] + da
33.             rot_pos = (pos[0], pos[1], new_angle)
34.             for dist10 in range(-3, 3):
35.                 dx = target_pos[0] - pos[0]
36.                 dy = target_pos[1] - pos[1]
37.                 dist = sqrt(dx**2 + dy**2)
38.                 dist += dist10 / 2.
39.                 dist = round(dist * 2) / 2
40.                 new_pos = (pos[0] + dist * cos(new_angle), pos[1] + dist * sin(new_angle), new_angle, da, dist, pos[5] + [pos[0:5]])
41.                 if abs(new_pos[0] - target_pos[0]) < .75 and abs(new_pos[1] - target_pos[1]) < .75:
43.                         result.append(new_pos)
44.                     else:
45.                         break
46.     return result
47.
48. manual_positions = [
49.     (2.5, 1.5),
50.     (4, 7.5),
51.     (8.75, 8.75),
52.     (9.5, 5),
53.     (14.75, 3.6),
54.     (16.2, 8.5),
55.     (17.2, 9),
56.     (16, 10.9),
57.     (40, 11.9)
58. ]
59.
60. colors = [
61.     (0, 0x64, 0),
62.     (0xbc, 0x8f, 0x8f),
63.     (0xff, 0, 0),
64.     (0xff, 0xd7, 0),
65.     (0, 0xff, 0),
66.     (0, 0xff, 0xff),
67.     (0xa0, 0x20, 0xf0),
68.     (0x1e, 0x90, 0xff),
69.     (0xff, 0x14, 0x93)
70. ]
71.
72. def pos_list(pos):
73.     return pos[5][1:] + [pos[0:5]]
74.
75. import cv2, numpy as np
76. screen_w, screen_h = 640, 480
77. w_scale, h_scale = 640 / 20, 480 / 12
78. img = np.full((screen_h, screen_w, 3), 255, np.uint8)
79.
80. positions = [(0., 0.5, 0., 0., 0., [])]
81. for index, new_pos in enumerate(manual_positions):
82.     print(index, ':', len(positions))
83.     positions = get_positions(positions, new_pos)
84.     for pos in positions:
85.         for p in pos_list(pos):
86.             try:
87.                 img[int(p[1] * h_scale)][int(p[0] * w_scale)] = colors[index]
88.             except: pass
89.
90. print(len(manual_positions), ':', len(positions))
91.
92. def sign_score(pos, signs):
93.     total = 0
94.     for i, x in enumerate(pos_list(pos)):
95.         total += x[4]
96.         total += x[3] * signs[i]
97.     return 72 + sin(total), total
98.
99. def score(pos):
100.     min_score = 73
101.     for i in np.ndindex((2, 2, 2, 2, 2, 2, 2, 2, 2)):
102.         signs = np.subtract(np.multiply(i, 2.0), 1.0)
103.         s, total = sign_score(pos, signs)
104.         if s < min_score:
105.             min_score = s
106.             min_signs = signs
107.             min_total = total
108.     return min_score, min_signs, min_total % (pi*2) - 3*pi/2
109.
110. def get_orders(pos, s):
111.     score, signs, total = s
112.     return ([(x[3], x[4], sign) for x, sign in zip(pos_list(pos), signs)], score, total)
113.
114. with open('out.txt', 'w') as f:
115.     orders = []
116.     for i, pos in enumerate(positions):
117.         if i % 1000 == 0: print(i)
118.         orders.append(get_orders(pos, score(pos)))
119.     print('sorting...')
120.     orders.sort(key= lambda x: x[1])
121.     f.write(str(orders))
122.
123. cv2.imshow('Xuanwu', img)
124. cv2.waitKey(0)
RAW Paste Data