commit e8ab128231b333edcfa58e8395e836bfd8ff610c Author: Pavel Date: Fri Oct 9 16:15:23 2020 +0200 initial commit diff --git a/README b/README new file mode 100644 index 0000000..3c748d3 --- /dev/null +++ b/README @@ -0,0 +1,12 @@ +This is a modified version of the Python script for the TI-Planet and +Planete Casio back to school 2020 contest. + +This modified version works with Python 3 under GNU Linux and MS Windows. + +The original code can be found at: + +https://tiplanet.org/forum/viewtopic.php?f=49&t=24309 + +This script can be executed with the following command: + + python3 cavegui.py diff --git a/cavegui.png b/cavegui.png new file mode 100644 index 0000000..40c0e1f Binary files /dev/null and b/cavegui.png differ diff --git a/cavegui.py b/cavegui.py new file mode 100644 index 0000000..a8eb092 --- /dev/null +++ b/cavegui.py @@ -0,0 +1,237 @@ +from math import pi, sin, cos, sqrt, asin +from tkinter import * + +cave_w, cave_h = 128, 64 +zx, zy = 8, 8 +screen_w, screen_h = (cave_w - 1) * zx + 1, (cave_h - 1) * zy + 1 + +fl = [43, 40, 34, 28, 26, 26, 27, 26, 23, 20, 19, 20, 20, 20, 21, 24, 27, 28, 24, 19, 15, 15, 17, 18, 17, 15, 15, 16, 18, 19, 21, 25, 30, 34, 35, 31, 27, 26, 27, 30, 30, 27, 24, 23, 22, 22, 21, 21, 23, 26, 27, 24, 19, 16, 16, 19, 22, 22, 20, 19, 18, 19, 18, 17, 17, 19, 21, 20, 15, 10, 8, 10, 14, 17, 18, 17, 17, 18, 19, 18, 17, 17, 18, 18, 15, 8, 3, 2, 5, 9, 11, 11, 11, 13, 15, 17, 18, 19, 22, 24, 24, 21, 16, 13, 14, 17, 20, 21, 19, 18, 19, 19, 19, 19, 19, 20, 21, 20, 15, 10, 7, 9, 12, 13, 11, 8, 6, 5] + +cv = [38, 37, 35, 33, 33, 35, 36, 35, 32, 28, 26, 25, 26, 26, 27, 29, 30, 29, 26, 22, 19, 19, 20, 20, 17, 13, 9, 8, 9, 10, 11, 14, 17, 19, 20, 19, 18, 19, 22, 26, 28, 28, 26, 25, 26, 28, 29, 30, 32, 33, 33, 30, 27, 24, 24, 27, 29, 28, 26, 23, 22, 22, 23, 23, 23, 23, 22, 20, 16, 11, 9, 10, 13, 15, 14, 13, 12, 14, 16, 19, 20, 22, 23, 23, 20, 16, 12, 12, 13, 15, 16, 14, 12, 11, 12, 14, 16, 17, 19, 20, 19, 17, 14, 12, 13, 16, 19, 19, 17, 15, 15, 16, 18, 19, 20, 21, 22, 20, 18, 15, 15, 17, 21, 22, 20, 17, 14, 13] + +master = Tk() +master.resizable(0, 0) + +index = 0 +plan = [(0.0, 0.0, 1)] + +def escape(event): + global master + master.quit() + +def add(event): + global plan, index + if len(plan) < 20: + index += 1 + plan.append((0.0, 0.0, 1)) + voler_selon(plan) + +def remove(event): + global plan, index + if len(plan) > 1: + plan = plan[:-1] + if index > len(plan) - 1: + index = len(plan) - 1 + voler_selon(plan) + +def next(event): + global plan, index + if index < len(plan) - 1: + index += 1 + voler_selon(plan) + +def previous(event): + global plan, index + if index > 0: + index -= 1 + voler_selon(plan) + +def left(event, step): + global plan, index + plan[index] = (round(plan[index][0] + step, 3), plan[index][1], plan[index][2]) + voler_selon(plan) + +def right(event, step): + global plan, index + plan[index] = (round(plan[index][0] - step, 3), plan[index][1], plan[index][2]) + voler_selon(plan) + +def up(event): + global plan, index + plan[index] = (plan[index][0], plan[index][1], round(plan[index][2] + 1, 1)) + voler_selon(plan) + +def down(event): + global plan, index + if plan[index][2] > 0: + plan[index] = (plan[index][0], plan[index][1], round(plan[index][2] - 1, 1)) + voler_selon(plan) + +def plus(event): + global plan, index + plan[index] = (plan[index][0], round(plan[index][1] + 0.1, 1), plan[index][2]) + voler_selon(plan) + +def minus(event): + global plan, index + plan[index] = (plan[index][0], round(plan[index][1] - 0.1, 1), plan[index][2]) + voler_selon(plan) + +def print_code(event): + global plan + print('') + print('def plan():') + print(' for e in %s:' % plan) + print(' modifier_vol(e[0], e[1], e[2])') + print('') + +master.bind('', escape) +master.bind('', add) +master.bind('', remove) +master.bind('', previous) +master.bind('', next) +master.bind('', lambda e: left(e, 0.1)) +master.bind('', lambda e: right(e, 0.1)) +master.bind('', lambda e: left(e, 0.01)) +master.bind('', lambda e: right(e, 0.01)) +master.bind('', plus) +master.bind('', minus) +master.bind('', up) +master.bind('', down) +master.bind('p', print_code) +master.bind('P', print_code) + +canvas = Canvas(master, width = screen_w, height = screen_h + 68, bg = 'white') +canvas.pack() + +def clean_screen(): + global canvas + canvas.delete('all') + +def draw_oval(x, y, rx, ry, color): + global canvas + canvas.create_oval(x - rx, y - ry, x + rx * 2, y + ry * 2, fill = color, outline = '') + +def draw_rect(x, y, w, h, color): + global canvas + canvas.create_rectangle(x, y, x + w, y + h, fill = color, outline = '') + +def draw_line(x1, y1, x2, y2, color): + global canvas + canvas.create_line(x1, y1, x2, y2, fill = color) + +def draw_plan(): + global canvas, plan + for i in range(len(plan)): + if i == index: + color = 'blue' + else: + color = 'black' + color = 'black' + if i < 10: + y = 0 + else: + y = 16 + canvas.create_text(4 + (i % 10) * 100, screen_h + 4 + y, anchor = NW, text = '(%5.2f, %4.1f, %2.0f)' % plan[i], fill = color) + +def draw_help(): + global canvas + help = 'ay: [Shift+]Left/Right, da: Ctrl+Up/Down, dt: Up/Down, add/remove element: Enter/BackSpace, previous/next element: Ctrl+Left/Right, print code: P, exit: Esc' + canvas.create_text(4, screen_h + 36, anchor = NW, text = help, fill = 'black') + +def draw_score(state): + global canvas + canvas.create_text(4, screen_h + 52, anchor = NW, text = 'score: %7.1f (state[0]: %3.1f, state[1]: %3.1f, state[2]: %3.1f, collisions: %2.0f)' % (state[4], state[0], state[1], state[2], state[5]), fill = 'black') + +def fix_angle(a): + return a * 2 * asin(1) / pi + +def interpol1(yi, yf, dx): + return yi + dx*(yf - yi) + +def interpol_list(lst, i): + i0 = int(i) + v = lst[i0] + if i > i0 and i < len(lst) - 1: + v = interpol1(v, lst[i0 + 1], i - i0) + return v + +def test_collision(x, y): + f = cave_h - interpol_list(fl, x) + return y >= f or y <= f-interpol_list(cv, x) + +def test_collision_rect(x, y, dx, dy): + x1, x2, y1, y2 = max(0, x - dx), min(cave_w - 1, x + dx), y - dy, y + dy + return test_collision(x1, y1) + test_collision(x2, y1) + test_collision(x1, y2) + test_collision(x2, y2) + +def test_balloon(x, y, rx, ry, d_vert): + rmax, r2, k, collisions = [rx, ry][d_vert], [ry, rx][d_vert], -1, 0 + while k < rmax: + k = min(k + 1, rmax) + k2 = sqrt(max(0, r2*r2*(1 - k*k/rmax/rmax))) + collisions += test_collision_rect(x, y, [k, k2][d_vert], [k2, k][d_vert]) + return collisions + +def rxy(a): + if a%2 == 1: + rx, ry = 0, 1-2*(a%4 == 3) + else: + a = fix_angle(a * pi/2) + rx, ry = abs(cos(a)), abs(sin(a)) + return 1 + abs(rx), 1 + abs(ry) + +def modifier_vol(ay, da, dt, current): + global state + if ay or da: + state[4] += 10 + x, y, a = state[0:3] + while state[0] < cave_w - 1 and dt: + state[0] += 1 + state[2] = max(0, min(1, a + da)) + state[3] -= ay + state[1] = max(0, min(cave_h - 1, state[1] + state[3])) + dt = max(0, dt - 1) + da, dapi, dx = abs(state[2] - a), abs(state[2] - .5), 1 + state[4] += 3*(da > 0)*(1 + da) + 2*(dapi > 0)*(1 + dapi) + xc, yc, dx = x, y, 1 + rx, ry = rxy(state[2]) + if state[1] != y: + dx = min(1 / abs(state[1] - y), 1) + collisions = test_balloon(state[0], state[1], rx, ry, 0) + test_balloon(state[0], state[1], rx, ry, 1) + if collisions: + state[4] += 7 * (1 + collisions) + state[5] += collisions + while xc < state[0]: + xc += dx/zx + yc = interpol1(y, state[1], xc - x) + rx, ry = rxy(interpol1(a, state[2], state[2] - a)) + if collisions > 0: + draw_oval(xc * zx, yc * zy, rx * zx, ry * zy, 'red') + elif current: + draw_oval(xc * zx, yc * zy, rx * zx, ry * zy, 'blue') + else: + draw_oval(xc * zx, yc * zy, rx * zx, ry * zy, 'black') + x, y, a = state[0], state[1], state[2] + +def voler_selon(plan): + global state, fl, cv + state = [0, 12, .5, 0, 0, 0] + clean_screen() + draw_rect(0, 0, screen_w, screen_h, 'grey') + for x in range(cave_w): + f1, dx = cave_h - fl[x], 0 + c1 = f1 - cv[x] + while dx < zx: + f2 = cave_h - interpol_list(fl, x + dx/zx) + c2 = f2 - interpol_list(cv, x + dx/zx) + draw_line(x*zx + dx, c2 * zy, x*zx + dx, f2 * zy, 'white') + dx += 1 + for i in range(len(plan)): + modifier_vol(*plan[i], i == index) + draw_plan() + draw_help() + draw_score(state) + +voler_selon(plan) + +master.mainloop()