[Python] Raycasting periodically crashes HP Prime calculator

Discussão em 'Python' iniciado por Stack, Junho 1, 2025.

  1. Stack

    Stack Membro Participativo

    I have recently been trying to write a more basic, Wolfstein style version of Doom for the HP Prime graphing calculator. I've been using Python for this and successfully got simple 3d working using raycasting. However, the graphing calculator quickly crashes a few seconds after the program is launched. After doing some troubleshooting, it seems like the calculator's RAM is being entirely exhausted. I have tried tinkering with the garbage collection, but when the threshold is adjusted, it often triggers errors seemingly by deleting actual objects used in the code, such as functions.

    My calculator is hardware revision D. It is running the most recent firmware version as of writing this question, which was released February of 2025.

    Adding wait statements in between the stepping of rays seems to have helped a little, but it is not a good solution due to the heavy amount of time casting large amounts of rays will take.

    My code is as follows. I am terribly sorry for it being so messy - it was written on the actual calculator, so writing comments proves to be very difficult.

    #PYTHON Doom

    import math
    import hpprime
    import gc
    import micropython
    micropython.opt_level(3)
    gc.enable()
    #gc.threshold(1000000)

    from builtins import *

    """
    grid = [
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
    ]
    """
    grid = [
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    [0,0,0,0,0,0,0,0,0],
    ]
    class Enemy:
    pass

    class Player:
    def __init__(self,hp,x,y,r,fov=(60),density=10):
    self.hp = hp
    self.x = x
    self.y = y
    self.r = r
    self.density = density
    self.fov = fov * math.pi/180
    self.fov2 = self.fov/2
    self.fov3 = (self.fov/self.density)


    def cast(self):
    res = []
    for i in range(self.density):
    tmp = Ray(self.x,self.y,(self.r-self.fov2)+(self.fov3*i),0.2)
    tmp.seek()
    res.append(math.sqrt(((tmp.x-self.x)**2)+( (tmp.y-self.y)**2))*math.cos(tmp.r-self.r))
    return res

    class Ray:
    def __init__(self,x,y,r,i):
    self.x = x
    self.y = y
    self.r = r
    self.i = i
    self.sr = math.sin(self.r) * self.i
    self.cr = math.cos(self.r) * self.i


    def step(self):
    self.x -= self.sr
    self.y -= self.cr
    if (self.x > len(grid[0])-1) or (self.y > len(grid)-1) or (self.x < 0) or (self.y < 0):
    return True #ray is out of bounds
    if grid[int(self.y)][int(self.x)] == 1:
    return True
    return False

    def seek(self):
    tmp = self.step()
    while not tmp:
    tmp = self.step()
    hpprime.eval("WAIT(0.0003);")
    return tmp
    hpprime.dimgrob(1,320,240,0)
    e = Player(100,3,3,0)
    e320 = 320/e.density
    while True:
    #micropython.mem_info()
    hpprime.eval("WAIT(0.015);")
    hits = e.cast()
    c = 0
    hpprime.fillrect(1,0,0,320,240,0,0)
    #hpprime.fillrect(1,0,120,320,240,0,0)
    p = []
    p2 = []
    for t in hits:
    c+=1

    p.append((8-(t))*12)
    b = (t*30)*(t/10)
    if b > 255:
    b = 255
    if b < 0:
    b = 0
    p2.append(b)

    for i in range(e.density-1):
    x0= (e320)*(i+0.5)
    y0= 120+p
    x1= (e320)*(i+1.5)
    y1= 120+p[i+1]
    x2= (e320)*(i+1.5)
    y2= 120-p[i+1]
    x3= (e320)*(i+0.5)
    y3= 120-p
    co1=[x0,y0,x1,y1,x2,y2,x3]
    co2=""

    for v in co1:
    co2+=str(v)
    co2+=","

    co2+=str(y3)
    del co1
    #hpprime.line(1,(320/e.density)*i,120+p[i-1],(320/e.density)*(i+1),120+p,255)
    #hpprime.line(1,(320/e.density)*i,120-p[i-1],(320/e.density)*(i+1),120-p,255)
    #hpprime.line(1,(320/e.density)*i,120+p[i-1],(320/e.density)*(i+1),120-p,255)
    hpprime.eval("FILLPOLY_P(G1,{"+co2+"},RGB("+str(int(255-p2))+","+str(int(255-p2))+","+str(int(255-p2))+"));")
    #print(gc.mem_free())
    del p
    del p2
    if hpprime.keyboard() == 2**7:
    e.r -= 0.05
    if hpprime.keyboard() == 2**8:
    e.r += 0.05
    if hpprime.keyboard() == 2**2:
    e.x -= math.sin(e.r) * 0.05
    e.y -= math.cos(e.r) * 0.05
    if grid[int(e.y)][int(e.x)] == 1:
    e.x += math.sin(e.r) * 0.06
    e.y += math.cos(e.r) * 0.06
    if e.x < 0: e.x = 0
    if e.y < 0: e.y = 0
    if hpprime.keyboard() == 2**12:
    e.x += math.sin(e.r) * 0.05
    e.y += math.cos(e.r) * 0.05
    if grid[int(e.y)][int(e.x)] == 1:
    e.x -= math.sin(e.r) * 0.06
    e.y -= math.cos(e.r) * 0.06
    if e.x < 0: e.x = 0
    if e.y < 0: e.y = 0
    #hpprime.line(1,160,120,160-10*math.sin(e.r*(math.pi/math.pi)),120-10*math.cos(e.r*(math.pi/math.pi)),255255)
    hpprime.blit(0,0,0,1)
    #end

    EXPORT DOOM()
    BEGIN
    PYTHON(Doom);
    END;

    Continue reading...

Compartilhe esta Página