-- Shootout bot: P1 skater (obj0) from saved state. Skate up, optional lateral deke, shoot at y>=SY. local sp=manager.machine.devices[":maincpu"].spaces["program"] local ports=manager.machine.ioport.ports local function F(b) return ports[":ctrl1:mdpad:PAD"].fields["P1 "..b] end local K={U=F("Up"),D=F("Down"),L=F("Left"),R=F("Right"),C=F("C")} local function w(a) local v=sp:read_u16(a); if v>=0x8000 then v=v-0x10000 end return v end local lf=io.open(os.getenv("EVOUT") or "sb.txt","w") local S1=tonumber(os.getenv("S1") or "1"); local S2=tonumber(os.getenv("S2") or "9") local trials={} for s=S1,S2 do for _,sy in ipairs({100,125,170,205,230}) do for _,lat in ipairs({"","L","R"}) do for _,aim in ipairs({"L","","R"}) do for _,ch in ipairs({3,25}) do trials[#trials+1]={s=s,sy=sy,lat=lat,aim=aim,ch=ch} end end end end end local function clr() for _,k in pairs(K) do k:clear_value() end end local function sc() local s={} for a=0xffc470,0xffc4a0 do s[#s+1]=sp:read_u8(a) end return table.concat(s,",") end local i=0; local t=-1; local fr=0; local cur; local ph; local base; local shotf; local sx,sy0; local lt local G=0 emu.register_frame_done(function() fr=fr+1 if t<0 then if fr>20 then i=i+1; if i>#trials then lf:write("SUMMARY n="..#trials.." goal="..G.."\n"); lf:close(); manager.machine:exit(); return end cur=trials[i]; manager.machine:load("s"..cur.s); t=0; ph="skate"; lt=0 end return end t=t+1 if t==2 then base=sc() end if t<3 then return end local y=w(0xffb04a+0x14); local x=w(0xffb04a) clr() if ph=="skate" then K.U:set_value(1) if cur.lat~="" and y>=cur.sy-60 and lt<15 then K[cur.lat]:set_value(1); lt=lt+1 end if y>=cur.sy or t>700 then ph="shoot"; shotf=0; sx=x; sy0=y end elseif ph=="shoot" then shotf=shotf+1 K.U:set_value(1); if cur.aim~="" then K[cur.aim]:set_value(1) end if shotf<=cur.ch then K.C:set_value(1) end if shotf>cur.ch+2 then ph="wait"; shotf=0 end else shotf=shotf+1 local g=(sc()~=base) if g or shotf>220 then if g then G=G+1 end lf:write(string.format("s%d sy=%d lat=%s aim=%s ch=%d from(%d,%d) d=%d flag=%d -> %s\n",cur.s,cur.sy,cur.lat,cur.aim,cur.ch,sx,sy0,w(0xfff000),sp:read_u8(0xfff002),g and "GOAL" or "no")) lf:flush(); t=-1; fr=0 end end end)