from polycal5 import * SCREEN_WIDTH, SCREEN_HEIGHT, FONT_WIDTH, FONT_HEIGHT, HAS_COLOR, fill_rect, draw_string, show_screen, sleep, wait_key, wait_release, esc_key, HAS_KEYS, ignore_events = get_infos(("w","h","fw","fh","hc","fr","ds","sh","s","wk","wr","ek","hk","ie"), 160, 120, 2) get_infos = None from math import pi, cos, sin, tan, sqrt, ceil, atan2, floor from tools import * from myrandom import * from interval import * try: # load compressed bytearray data + uncompress + pack bytearray() from pyka3dmc import * if HAS_COLOR: from pyka3dtc import * else: from pyka3dsc import * except: # bytearray() missing on Casio/NumWorks - directly load final bytearray data from pyka3dmr import * if HAS_COLOR: from pyka3dtr import * else: from pyka3dsr import * # ACTIONS def cango(player, x, y): z_player = player[P_Z] z_bottom, z_top = getBlockAltitudes(x, y) return z_player >= z_top - player_climbing_step(player) and not player[P_VZ] or z_player >= z_top or z_player + player_height(player) <= z_bottom def get_avance_position(player, l, angle): l = bound_min_max(l, -1, 1) * player_step(player) x, y = player[:P_Z] dx, dy = cos_sin(angle) nx = x + l*dx ny = y + l*dy if (nx != x or ny != y) and cango(player, nx, ny): pr = player_radius(player) if cango(player, nx + pr*sign(dx), y): x = nx if cango(player, x, ny + pr*sign(dy)): y = ny return x, y, dx, dy def randomanip(v): while uniform(0, v) < .5 * v: pass def action_forward(player, params): param = bound_min_max(params, -1, 1) randomanip(abs(param) % 1) x0, y0 = player[:P_Z] x, y, dx, dy = get_avance_position(player, param, player[P_ANGLE]) if player == main_player: player[P_SCORE_IA] -= .01*abs(param) + .001 if x != x0 or y != y0: player[:P_Z]=(x, y) z_player = player[P_Z] z_top = getBlockTop(x, y) if z_player < z_top and z_player >= z_top - player_climbing_step(player): player[P_Z] = z_top return params - param def action_backward(player, l): random() return -action_forward(player, -l) def action_turn_right(player, param): for k in range(2): random() if player == main_player: player[P_SCORE_IA] -= .0001 randomanip((dprinc(abs(param)) + pi) / 2 / pi) player[P_ANGLE] = dprinc(player[P_ANGLE] + param) return 0 def action_turn_left(player, param): random() return action_turn_right(player, -param) def action_strife_left(player, params): random() action_turn_left(player, pi / 2) param = action_forward(player, params) action_turn_right(player, pi / 2) if player == main_player: player[P_SCORE_IA] += .0002 random() return param def action_strife_right(player, params): for k in range(2): random() action_turn_right(player, pi / 2) param = action_forward(player, params) action_turn_left(player, pi / 2) if player == main_player: player[P_SCORE_IA] += .0002 return param def action_jump(player, params): for k in range(6): random() params = abs(params) param = bound_min_max(params, 0, 1) if player == main_player: player[P_SCORE_IA] -= .0001 + param randomanip(param) if not player[P_VZ]: x, y, z_player = player[:P_ANGLE] z_top = getBlockTop(x, y) if z_player == z_top or not z_player: player[P_VZ] = player_jump(player)*param return params - param def action_pause(player, params): for k in range(7): random() if player == main_player: player[P_SCORE_IA] -= .0001 return max(0, abs(params) - 1) action_keys = (KEY_UP, KEY_6, KEY_DOWN, KEY_4, KEY_5, KEY_LEFT, KEY_RIGHT, KEY_ENTER, KEY_ESC) action_names = ("Pas Avant", "Pas Droite", "Pas Arriere", "Pas Gauche", "Attend ", "Tourne Gauche", "Tourne Droite", "Saute ", "Quitte") action_fcts = (action_forward, action_strife_right, action_backward, action_strife_left, action_pause, action_turn_left, action_turn_right, action_jump) id_action = 0 def is_visible(a, b): return a <= SCREEN_HEIGHT - 1 and b >= 0 def remove_hidden_by_screen(a, b): return [bound_min_max(v, 0, SCREEN_HEIGHT) for v in min_max(a, b)] # 3D ENGINE ( EXTENDED RAYCASTING ) T_TOP, T_BOTTOM, T_COLOR_TEXTURE, T_COEFF = range(4) TT_HEIGHT, TT_DATA, TT_PALETTE, TT_TRANS, TT_REPEAT, TT_BLOCK_HEIGHT, TT_BITS = range(7) def ctransform(col, coeff): return tuple([bound_min_max(ambiant_color[i] + round((col[i] - ambiant_color[i])*coeff), 0, 255) for i in range(len(col))]) def next(v, d): if v % 1: if d > 0: v = ceil(v) else: v = floor(v) else: v += sign(d) return v def nextxy(x, y, x0, y0, dx, dy, r): lx, ly = x, y d2min = 0 if dx: x = next(x, dx) yt = ly + (x - lx)*dy/dx dist2_yt = dist2(x0, y0, x, yt) d2min = dist2_yt if dy: y = next(y, dy) xt = lx + (y - ly)*dx/dy dist2_xt = dist2(x0, y0, xt, y) d2min = not d2min and dist2_xt or min(dist2_xt, dist2_yt) if not dy: y = yt elif not dx: x = xt elif dist2_xt < dist2_yt: x=xt else: y=yt return x, y, sqrt(d2min)*cos(r-main_player[P_ANGLE]) def inject_players_tiles(bt, tt, players_ids, last_block_infos, x0, y0, r, d, last_d): if bt or tt: global cast_ray_list, cast_ray_shown_players_ids for player_id in players_ids: if not player_id in cast_ray_shown_players_ids: player = players[player_id] if player[P_Z] >= last_block_infos[B_TOP] and tt or player[P_Z] < last_block_infos[B_BOTTOM] and bt: r0 = atan2(player[P_Y]-y0, player[P_X]-x0) if abs(((r0-r)+pi)%(2*pi)-pi) < pi/2: dp=sqrt(dist2(x0, y0, player[P_X], player[P_Y])) dw = dp * tan(r - r0) pr = player_radius(player) if abs(dw) <= pr and (dp/cos(r - r0) >= last_d or dp/cos(r - r0) <= d): sprite = textures[-1] i = floor(sprite[S_WIDTH]*(dw + pr)/(2*pr)) if i < sprite[S_WIDTH]: ph = player_height(player) pt=SCREEN_HEIGHT/2-(player[P_Z]+ph-player_eye_altitude(main_player))*SCREEN_HEIGHT/dp/Z_XY_RATIO pb=SCREEN_HEIGHT/2+(player_eye_altitude(main_player)-player[P_Z])*SCREEN_HEIGHT/dp/Z_XY_RATIO y1, y2 = min_max(pt, pb) if is_visible(y1, y2): color = (sprite[S_HEIGHT],sprite[S_DATA][i],player[P_LEVEL] <= main_player[P_LEVEL] and sprite[S_PALETTE] or HAS_COLOR and (MAGENTA,BLACK,(255,20,20),(253,52,52),(200,5,5) ,(163,28,28) ,(255,189,0),(255,239,255)) or (MAGENTA,WHITE,BLACK),sprite[S_TRANSP],0,ph/Z_XY_RATIO, sprite[S_BITS]) if not inclus_inter(cast_ray_inter, y1, y2): cast_ray_list.extend((floor(y1), ceil(y2), color, 1/(1+d))) cast_ray_shown_players_ids.append(player_id) def cast_ray(x0, y0, r): global cast_ray_inter, cast_ray_list, cast_ray_shown_players_ids ok = 1 dx, dy = cos_sin(r) cast_ray_list = [] cast_ray_inter = [] cast_ray_shown_players_ids = [] last_block_infos = getBlockInfos(x0, y0) last_texture = textures[last_block_infos[B_TEXTURE]] lb = player_eye_altitude(main_player)last_block_infos[B_TOP] and SCREEN_HEIGHT or -1 for k in range(2): x, y, d = nextxy(x0, y0, x0, y0, -dx, -dy, r+pi) while ok and (not dx or dx>0 and x<=MAP_WIDTH or dx<0 and x>=-1) and (not dy or dy>0 and y<=MAP_HEIGHT or dy<0 and y>=-1): last_d = d # neighbour players players_ids = [] for player_id in range(1, len(players)): player = players[player_id] x_player, y_player = player[:P_Z] pr = ceil(player_radius(player)) if abs(x - x_player) <= pr and abs(y - y_player) <= pr: players_ids.append(player_id) players_ids.sort(key=d2mainplayer) lx, ly = x, y x, y, d = nextxy(lx, ly, x0, y0, dx, dy, r) #0=North 1=South 2=East 3=West wall_direction = not (x%1) and 2+(dx<0) or (dy<0) block_infos = getBlockInfos(x-(not (x%1) and dx<0),y-(not(y%1) and dy<0)) texture = textures[block_infos[B_TEXTURE]] if d > 0: inject_players_tiles(player_eye_altitude(main_player) <= last_block_infos[B_BOTTOM], player_eye_altitude(main_player) >= last_block_infos[B_TOP], players_ids, last_block_infos, x0, y0, r, d, last_d) # last block bottom (ceiling) + top (floor) for b in player_eye_altitude(main_player)>last_block_infos[B_TOP] and (B_TOP, B_BOTTOM) or (B_BOTTOM, B_TOP): if last_block_infos[b] and (b == B_BOTTOM and player_eye_altitude(main_player)<=last_block_infos[B_BOTTOM] or b == B_TOP and player_eye_altitude(main_player)>=last_block_infos[B_TOP] or last_texture[S_TRANSP]>=0): lv = lb if b == B_TOP: lv = lt y1, y2 = min_max(min(max(SCREEN_HEIGHT/2+(player_eye_altitude(main_player)-last_block_infos[b])*SCREEN_HEIGHT/d/Z_XY_RATIO,-1),SCREEN_HEIGHT), lv) if is_visible(y1, y2): y1, y2 = remove_hidden_by_screen(y1, y2) if not inclus_inter(cast_ray_inter, y1, y2): y1, y2 = remove_hidden_by_inter(floor(y1), ceil(y2), cast_ray_inter) cast_ray_list.extend((y1, y2, last_block_infos[B_COLOR], ambiant_shading[b == B_BOTTOM and 5 or 4]/(not HAS_COLOR or 1+last_d))) cast_ray_inter = reunion_inter(cast_ray_inter, y1, y2) # last + current block wall for b in last_texture[S_TRANSP]>=0 and (last_block_infos, block_infos) or (block_infos,): if b[B_HEIGHT] and (b == block_infos or block_infos[B_BOTTOM] > last_block_infos[B_BOTTOM] or block_infos[B_TOP] < last_block_infos[B_TOP]): if b == block_infos: lt, lb = [SCREEN_HEIGHT/2+(player_eye_altitude(main_player)-b[v])*SCREEN_HEIGHT/d/Z_XY_RATIO for v in (B_TOP, B_BOTTOM)] transparent = 0 if is_visible(lt, lb): if b[B_TEXTURE]: texture = textures[b[B_TEXTURE]] if wall_direction >= 2 : i = y else: i = x color = (texture[S_HEIGHT],texture[S_DATA][floor((i%1)*(len(texture[S_DATA])))],texture[S_PALETTE],texture[S_TRANSP],texture[S_REPEAT],b[B_HEIGHT]/Z_XY_RATIO,texture[S_BITS]) transparent = texture[S_TRANSP] >= 0 else: lt, lb = remove_hidden_by_screen(lt, lb) lt, lb = remove_hidden_by_inter(lt, lb, cast_ray_inter) color = b[B_COLOR] if not inclus_inter(cast_ray_inter, lt, lb): cast_ray_list.extend((floor(lt), ceil(lb), color, ambiant_shading[wall_direction]/(not HAS_COLOR or 1+d))) if not transparent: cast_ray_inter=reunion_inter(cast_ray_inter,lt,lb) inject_players_tiles(player_eye_altitude(main_player) > last_block_infos[B_BOTTOM], player_eye_altitude(main_player) < last_block_infos[B_TOP], players_ids, last_block_infos, x0, y0, r, d, last_d) ok=not inclus_inter(cast_ray_inter, max(SCREEN_HEIGHT/2 - (max(255,player_eye_altitude(main_player)) - player_eye_altitude(main_player))*SCREEN_HEIGHT/d/Z_XY_RATIO, 0), min(SCREEN_HEIGHT/2 + player_eye_altitude(main_player)*SCREEN_HEIGHT/d/Z_XY_RATIO, SCREEN_HEIGHT-1)) last_block_infos = block_infos last_texture = texture def draw_texture_tile(rle, nbits, x, y, width, disph, palette, itransp, coeff, zoom): x, y = round(x), round(y) maskval, maskcnt = (1 << nbits) - 1, (255 >> nbits >> 1) << nbits i = 0 while y < SCREEN_HEIGHT and disph > 0: v = rle[i] mv = v & maskval c = (v & maskcnt) >> nbits if v & 128: i += 1 c |= rle[i] << (7 - nbits) if c: h = c * zoom if mv != itransp and y + h >= 0 and y < SCREEN_HEIGHT: yf = max(0, y) fill_rect(x, floor(yf), width, ceil(min(disph, min(h - yf + y, SCREEN_HEIGHT - yf))), ctransform(palette[mv], coeff)) y += h disph -= h i = (i + 1) % len(rle) # PLAYERS ACCESSORS P_X, P_Y, P_Z, P_ANGLE, P_VZ, P_LEVEL, P_SCORE_IA = range(7) DEFAULT_PLAYER_HEIGHT = 2 DEFAULT_PLAYER_RADIUS = .15 DEFAULT_PLAYER_FACTOR = 1 / 3 def player_height(player): return DEFAULT_PLAYER_HEIGHT + (player[P_LEVEL] - 1)//2*DEFAULT_PLAYER_HEIGHT*DEFAULT_PLAYER_FACTOR def player_radius(player): return DEFAULT_PLAYER_RADIUS + (player[P_LEVEL] - 2)//2*DEFAULT_PLAYER_RADIUS*DEFAULT_PLAYER_FACTOR def player_climbing_step(player): return player_height(player) * 3 / 7 def player_eye_height(player): return player_height(player) * 5 / 7 def player_eye_altitude(player): return player[P_Z] + player_eye_height(player) def player_jump(player): return 3 * (player_radius(player) + player_height(player)/14) def player_step(player): return sqrt(dist2(player_radius(player) / 2, player_eye_height(player) / Z_XY_RATIO / 2)) def player_attract_sensor(player): return max(player_step(player), sqrt(dist2(player_radius(player), player_eye_height(player) / Z_XY_RATIO))) def player_repulse_sensor(player): return max(player_attract_sensor(player), dist2(1 + player_radius(player)*2, 1 + player_height(player)/Z_XY_RATIO) - 1) def d2mainplayer(player_id): player = players[player_id] return dist2(player[P_X], player[P_Y], main_player[P_X], main_player[P_Y]) def levelup(player): block_altitude_bottom, block_altitude_top = getBlockAltitudes(player[P_X], player[P_Y]) player[P_LEVEL] += 1 if player[P_Z] < block_altitude_top and player[P_Z] + player_height(player) > block_altitude_top: player[P_LEVEL] -= 1 # MAP ACCESSORS B_BOTTOM, B_HEIGHT, B_TOP, B_TEXTURE, B_COLOR = range(5) def getBlockTop(x, y): return getBlockBottom(x, y) + getBlockHeight(x, y) def getBlockAltitudes(x, y): return getBlockBottom(x, y), getBlockTop(x, y) def getBlockInfos(x, y): a, h, it = getBlockBottom(x, y), getBlockHeight(x, y), getBlockTextureIndex(x, y) return a, h, a + h, it, (floor(x), floor(y)) in map_cp and colors_palette[2%len(colors_palette)] or map_colors_palette[textures[it][S_COLOR]] # 3D ENGINE SETUP RAY_WIDTH, VIEW_ANGLE, Z_XY_RATIO = 1, atan2(SCREEN_WIDTH, SCREEN_HEIGHT)*1.13, 10 # INITIALIZATION & GLOBALS BLACK = (0,0,0) WHITE = (255,255,255) MAGENTA = (255,0,255) ambiant_shading = HAS_COLOR and (.8, .8, .9, .9, 1, .7) or (0, 0, 1, 1, 1, 1) # from North South West East Top Bottom colors_palette = HAS_COLOR and ((64,64,0),(64,0,0),(255,0,0),None,MAGENTA,WHITE) or (BLACK,WHITE) def jouer_selon(l, display): global liste_actions_clavier, ambiant_color, map_cp, players, main_player, id_action, map_color seed(20100) # Hello Vincent map_cp = [(2, 2), (2, 26), (26, 2), (26, 26), (14, 14)] ambiant_color = BLACK liste_actions_clavier = [] nplayers = 100 main_player = [39.35, 30.3, 47, -3*pi/4, 0, 1, 1000] for k in range(2): levelup(main_player) players = [main_player] for k in range(nplayers - 1): # populates 3 zones : Tri-Maze (1/2) + Pikastle (1/3) + Heroes Arena x, y = k <= nplayers / 2 and (uniform(42, MAP_WIDTH - 3), uniform(5, MAP_HEIGHT - 4)) or k < 5 * nplayers / 6 and (uniform(2, 27), uniform(2, MAP_HEIGHT - 2)) or (uniform(28, 41), uniform(4, MAP_HEIGHT - 4)) block_altitude_bottom, block_altitude_top = getBlockAltitudes(x, y) player = [x, y, block_altitude_bottom >= DEFAULT_PLAYER_HEIGHT and random() < 2/3 and uniform(0, block_altitude_bottom - DEFAULT_PLAYER_HEIGHT) or uniform(block_altitude_top, 255), uniform(0, 2*pi), 0, 1, 0] for k in range(int(uniform(0, 4))): levelup(player) players.append(player) ok = 1 n = len(l) px_old = 0 while ok and (not esc_key() or len(l)): try: if esc_key(): l = [] wait_release() t = len(l) # 3d display if not t or display: j = main_player[P_ANGLE]-VIEW_ANGLE/2 s = VIEW_ANGLE*RAY_WIDTH/SCREEN_WIDTH; z0 = round(SCREEN_HEIGHT/2+main_player[P_Z]/Z_XY_RATIO) if not HAS_COLOR: fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE) fill_rect(0, z0, SCREEN_WIDTH, 1, BLACK) else: fill_rect(0, 0, SCREEN_WIDTH, z0, ctransform((128,192,255),1/9)) ymax = ceil(SCREEN_HEIGHT/2) for y in range(ymax): fill_rect(0, z0+y, SCREEN_WIDTH, 1, ctransform((255,153,0),DEFAULT_PLAYER_HEIGHT/player_eye_altitude(main_player)*(y+1)/SCREEN_HEIGHT)) for c in range(0, SCREEN_WIDTH, RAY_WIDTH): # 3D rendering engine x0, y0 = main_player[P_X],main_player[P_Y] for c in range(0, SCREEN_WIDTH, RAY_WIDTH): ignore_events() cast_ray(main_player[P_X],main_player[P_Y],j) j += s for i in range(len(cast_ray_list)-4,-1,-4): if len(cast_ray_list[i+T_COLOR_TEXTURE])==3: fill_rect(c, round(cast_ray_list[i+T_TOP]), RAY_WIDTH, max(1, round(cast_ray_list[i+T_BOTTOM]-cast_ray_list[i+T_TOP]+1)), ctransform(cast_ray_list[i+T_COLOR_TEXTURE],cast_ray_list[i+T_COEFF])) if not HAS_COLOR and cast_ray_list[i+T_COLOR_TEXTURE] == WHITE: fill_rect(c, round(cast_ray_list[i+T_TOP]), RAY_WIDTH, 1, BLACK) fill_rect(c, round(cast_ray_list[i+T_BOTTOM]), RAY_WIDTH, 1, BLACK) else: draw_texture_tile(cast_ray_list[i+T_COLOR_TEXTURE][TT_DATA],cast_ray_list[i+T_COLOR_TEXTURE][TT_BITS],c,round(cast_ray_list[i+T_TOP]), RAY_WIDTH, round(cast_ray_list[i+T_BOTTOM]-cast_ray_list[i+T_TOP]), cast_ray_list[i+T_COLOR_TEXTURE][TT_PALETTE], cast_ray_list[i+T_COLOR_TEXTURE][TT_TRANS], not HAS_COLOR and 1 or cast_ray_list[i+T_COEFF], round(cast_ray_list[i+T_BOTTOM]-cast_ray_list[i+T_TOP]) / cast_ray_list[i+T_COLOR_TEXTURE][TT_HEIGHT] / (not cast_ray_list[i+T_COLOR_TEXTURE][TT_REPEAT] and 1 or cast_ray_list[i+T_COLOR_TEXTURE][TT_BLOCK_HEIGHT])) # infos display back_text = HAS_COLOR and not display and t and BLACK or colors_palette[HAS_COLOR and 3 or 1] draw_string(str(round(main_player[P_SCORE_IA],1)) + " ", 0, 0, colors_palette[HAS_COLOR and 2 or 0], back_text) if not display and n and t==n and HAS_COLOR: fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, BLACK) elif not display and n and t==n: fill_rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, WHITE) if display or t == n or not t: texture = textures[-1] z = FONT_HEIGHT/texture[S_HEIGHT] w = round(texture[S_WIDTH]*z) for k in range(w): draw_texture_tile(texture[S_DATA][round(k/z)], texture[S_BITS], k, SCREEN_HEIGHT-1-FONT_HEIGHT, 1, FONT_HEIGHT, texture[S_PALETTE], texture[S_TRANSP], 1, z) draw_string("x" + str(len(players)-1) + " ", w, SCREEN_HEIGHT-1-FONT_HEIGHT, colors_palette[HAS_COLOR and 2 or 0], back_text) if t and not display: p = 1 - (t - 1)/n px = round(SCREEN_WIDTH * p) fill_rect(px_old, FONT_HEIGHT + 1, px - px_old, 1, colors_palette[HAS_COLOR and 4 or 0]) draw_string(str(round(100 * p, 1)) + "% ", 0, FONT_HEIGHT + 3,colors_palette[HAS_COLOR and 4 or 0], HAS_COLOR and BLACK or WHITE) px_old = px show_screen() # next action fid, params = t and l[0] or not t and None, t and l[1] ambiant_color = tuple([v // 2 for v in ambiant_color]) for player in players: main = player == main_player # get nearest player p2near, d2near = None, dist2(MAP_WIDTH, MAP_HEIGHT) for p2id in range(len(players)): p2 = players[p2id] if p2 != player: td2=dist2(p2[P_X], p2[P_Y], player[P_X], player[P_Y]) if td2 < d2near: d2near = td2 p2near = p2 p2nearid = p2id # handle gravity x, y, z = player[:P_ANGLE] block_altitude_bottom, block_altitude_top = getBlockAltitudes(x, y) minz = z >= block_altitude_top and block_altitude_top ph = player_height(player) if player[P_VZ]: maxz = z + ph >= block_altitude_top and 255 or max(0, block_altitude_bottom - ph) z = bound_min_max(z + player[P_VZ], minz, maxz) player[P_Z] = z if z == minz or z == maxz: player[P_VZ] = 0 if z != minz: player[P_VZ] -= 1 if p2near: # handle interactions with nearest player if d2near <= player_radius(player)**2 and player[P_Z] <= p2near[P_Z] + player_height(p2near) and player[P_Z] + ph >= p2near[P_Z]: if player[P_LEVEL] >= p2near[P_LEVEL] and p2near != main_player: # fusion players.remove(p2near) if main: player[P_SCORE_IA] += 100/(1 + main_player[P_LEVEL] - p2near[P_LEVEL]) levelup(player) if HAS_COLOR and ambiant_color != colors_palette[5]: ambiant_color = colors_palette[not main] elif player[P_LEVEL] > p2near[P_LEVEL] and p2near == main_player: # attack p2near[P_SCORE_IA] -= player[P_LEVEL] - p2near[P_LEVEL] player[P_SCORE_IA] = 0 if HAS_COLOR: ambiant_color = colors_palette[5] # handle interactions with special blocks if main and not player[P_VZ] and z == block_altitude_top: #evolution-stone x, y = floor(x), floor(y) try: i = map_cp.index((x, y)) for player in players[1:]: levelup(player) map_cp.pop(i) if HAS_COLOR and ambiant_color != colors_palette[5]: ambiant_color = colors_palette[1] except: pass if main: # main player actions clavier = fid is None if clavier: if HAS_KEYS: k = 0 while not k in action_keys: k = wait_key() else: nb_actions = len(action_names) id_action -= 1 try: while(1): id_action_copy = (id_action + 1) % nb_actions id_action = id_action_copy draw_string(" " + action_names[id_action], SCREEN_WIDTH // 2, SCREEN_HEIGHT-FONT_HEIGHT, colors_palette[4%len(colors_palette)], colors_palette[5%len(colors_palette)]) show_screen() sleep(.5) except KeyboardInterrupt: try: id_action except: id_action = id_action_copy k = action_keys[id_action] fid, params = action_keys.index(k), k in (KEY_LEFT, KEY_RIGHT) and pi/8 or 1 else: # random + reactive ia actions mode = player[P_SCORE_IA] player[P_SCORE_IA] = (p2near[P_Z] >= player[P_Z] and p2near[P_Z] <= player[P_Z] + player_height(player) or player[P_Z] >= p2near[P_Z] and player[P_Z] <= p2near[P_Z] + player_height(p2near)) and (d2near <= player_repulse_sensor(player)**2 and (player[P_LEVEL] < p2near[P_LEVEL] or p2near == main_player and player[P_LEVEL] == p2near[P_LEVEL]) and -1 or d2near <= player_attract_sensor(player)**2 and (player[P_LEVEL] > p2near[P_LEVEL] or p2near != main_player and player[P_LEVEL] == p2near[P_LEVEL])) s = not mode or d2near >= player_step(player)**2 and 1 or d2near / player_step(player)**2 nxs = [] nys = [] nds = [] i = 0 for k in range( mode and 4 or 1): nx, ny, dx, dy = get_avance_position(player, s, player[P_ANGLE] + k*pi/2) nds.append(dist2(p2near[P_X], p2near[P_Y], nx, ny)) nxs.append(nx) nys.append(ny) if mode: i_max, i_min = 0, 0 nd_max, nd_min = nds[0], nds[0] for k in range(1, len(nds)): v = nds[k] if v < nd_min: i_min = k nd_min = v elif v > nd_max: i_max = k nd_max = v i = i_min if mode < 0: i = i_max if nxs[i] >= 0 and nxs[i] < MAP_WIDTH and nys[i] >= 0 and nys[i] < MAP_HEIGHT and ((mode > 0 and nds[i] < d2near or mode < 0 and nds[i] > d2near) and abs(dprinc(player[P_ANGLE], p2near[P_ANGLE], pi/2)) < pi/8 or not mode and random()<.9): action_fcts[i](player, s) elif mode and player[P_ANGLE] != p2near[P_ANGLE] or random()<.5: action_turn_left(player, mode and p2near[P_ANGLE] - player[P_ANGLE] or uniform(0, 2*pi)) else: action_jump(player, 1) ok = fid < len(action_fcts) param = 0 if ok: param = action_fcts[fid](main_player, params) if clavier: if fid in (0, 1, 2, 5, 6, 7) and len(liste_actions_clavier) and liste_actions_clavier[-2] == fid and sign(liste_actions_clavier[-1]) == sign(params) and not fpart(liste_actions_clavier[-1]): liste_actions_clavier[-1] += params else: liste_actions_clavier.extend((fid, params)) if t: ignore_events() if param: l[1] = param else: l.pop(1) l.pop(0) if not len(l): print(main_player[P_SCORE_IA]) except KeyboardInterrupt: l = [] return main_player[P_SCORE_IA], liste_actions_clavier