add basic optimization code to editor.py

This commit is contained in:
Pavel 2021-10-16 12:03:48 +02:00
parent 0ddcd149f6
commit 6ba7093885
1 changed files with 76 additions and 33 deletions

View File

@ -34,8 +34,8 @@ def load():
buffer = f.read()
except IOError:
return
text.delete('1.0', 'end')
text.insert('end', buffer)
text.edit_separator()
text.replace('1.0', 'end', buffer)
redraw()
def save():
@ -48,8 +48,55 @@ def save():
except IOError:
return
def read_steps(buffer):
steps = []
for element in buffer.split():
try:
steps.append(float(element))
except:
pass
return steps
def write_steps(steps):
size = len(steps)
buffer = '\n'
buffer += 'start (x y angle boat):\n'
buffer += '%7.3f %6.3f %g %d\n' % (steps[0], steps[1], steps[2], steps[3])
buffer += '\n'
buffer += 'steps (x a y b):\n'
for k in range(1, size // 4):
x2, a, y2, b = steps[k * 4:(k + 1) * 4]
buffer += '%7.3f %2d %6.3f %2d\n' % (x2, a, y2, b)
return buffer
def optimize():
return
global text, state
buffer = text.get('1.0', 'end - 1c')
steps = read_steps(buffer)
draw_path(steps, False)
smax = state[3] + 1000 * (len(state[7]) >= 10)
size = len(steps)
kmax = -1
cmax = -1
for k in range(4, size, 2):
backup = steps[k]
for v in [-0.03, -0.02, -0.01, 0.01, 0.02, 0.03]:
steps[k] = backup + v
buffer = write_steps(steps)
steps = read_steps(buffer)
draw_path(steps, False)
s = state[3] + 1000 * (len(state[7]) >= 10)
if smax < s:
smax = s
kmax = k
cmax = backup + v
steps[k] = backup
if kmax >= 0:
steps[kmax] = cmax
buffer = write_steps(steps)
text.edit_separator()
text.replace('1.0', 'end', buffer)
redraw()
button = Button(frame2, text = 'load', command = load)
button.pack(side = 'left')
@ -73,7 +120,7 @@ def draw_coordinates():
def draw_state():
global canvas, map_h, state
score = state[3] + 1000 * (len(state[7]) >= 10)
t = 'score: %9.4f, life: %5.1f' % (score, state[4])
t = 'score: %20.15f, life: %5.1f' % (score, state[4])
canvas.create_text(4, map_h + 20, anchor = 'nw', text = t, fill = 'black', font = 'TkFixedFont')
def draw_help():
@ -81,39 +128,35 @@ def draw_help():
t = 'append step: left click, insert step: right click, undo: ctrl+z, select all: ctrl+a, reverse selection: ctrl+r'
canvas.create_text(4, map_h + 36, anchor = 'nw', text = t, fill = 'black', font = 'TkFixedFont')
def draw_path():
global text, state
buffer = text.get('1.0', 'end - 1c')
steps = []
for element in buffer.split():
try:
steps.append(float(element))
except:
pass
def draw_path(steps, draw = True):
global state
state = [0, 0, 0, 0, 250, 1, 0, [], 0]
if len(steps) >= 4:
x1, y1, a1 = steps[0:3]
state[0:3] = x1, y1, a1
state[6] = steps[3]
for i in range(2, len(steps) // 2):
x2, y2 = steps[i * 2:(i + 1) * 2]
for k in range(1, len(steps) // 4):
x2, a, y2, b = steps[k * 4:(k + 1) * 4]
x2 += a * 1e-14
y2 += b * 1e-14
da = atan2(y2 - y1, x2 - x1) * 180.0 / pi - a1
dr = hypot(x2 - x1, y2 - y1)
a_droite(da)
en_avant(dr)
if abs(x2 - state[0]) < 1e-9 and abs(y2 - state[1]) < 1e-9:
draw_line(x1, y1, x2, y2, 'black')
else:
draw_line(x1, y1, x2, y2, 'red')
if draw:
if abs(x2 - state[0]) < 1e-9 and abs(y2 - state[1]) < 1e-9:
draw_line(x1, y1, x2, y2, 'black')
else:
draw_line(x1, y1, x2, y2, 'red')
a1 += da
x1 += dr * cos(a1 * pi / 180.0)
y1 += dr * sin(a1 * pi / 180.0)
def redraw():
global canvas, image, map_w, map_h
global canvas, image, text, map_w, map_h
canvas.delete('all')
canvas.create_image(1, 1, image = image, anchor = 'nw')
draw_path()
draw_path(read_steps(text.get('1.0', 'end - 1c')))
draw_state()
draw_help()
draw_coordinates()
@ -143,7 +186,7 @@ def append_step(event):
x = convert_coordinate(x)
y = convert_coordinate(y)
text.edit_separator()
text.insert('end', '%5.1f %4.1f\n' % (x, y))
text.insert('end', '%7.3f 0 %6.3f 0\n' % (x, y))
def insert_step(event):
global text, cell_w, cell_h
@ -152,7 +195,7 @@ def insert_step(event):
x = convert_coordinate(x)
y = convert_coordinate(y)
text.edit_separator()
text.insert('insert linestart', '%5.1f %4.1f\n' % (x, y))
text.insert('insert linestart', '%7.3f 0 %6.3f 0\n' % (x, y))
def select_all(event):
global text
@ -223,9 +266,9 @@ def en_avant(l):
desty = state[1] + l * sin(a)
l = segments(state[0], state[1], destx, desty)
for k in range(1, len(l)):
xr = min(state[0], l[k][0])
yr = min(state[1], l[k][1])
c = map[int(xr) + int(yr) * 146]
xr = int(min(state[0], l[k][0]))
yr = int(min(state[1], l[k][1]))
c = map[xr + yr * 146]
id = map[int(l[k][0]) + int(l[k][1]) * 146]
if c == 1 or id == 1 or ((c == 3 or id == 3) and not state[6]): break
d = hypot(l[k][0]- state[0], l[k][1] - state[1]) * (.2 + ((c == 5) and .1 or (c == 4) and .2 or (c == 2) and .3))
@ -252,14 +295,14 @@ coordinates = [0, 0, None]
buffer = '''
start (x y angle boat):
47.5 43.5 0 0
47.500 43.500 0 0
steps (x y):
49.5 43.5
34.5 34.5
28.5 34.5
25.5 40.5
17.5 38.5
steps (x a y b):
49.500 0 43.500 0
34.500 0 34.500 0
28.500 0 34.500 0
25.500 0 40.500 0
17.500 0 38.500 0
'''
text.insert('end', buffer)