Browse Source

Implemented basic AI

main
Jo Jerrica Decker 4 months ago
parent
commit
a268903466
  1. 104
      beamclsh.p8

104
beamclsh.p8

@ -10,9 +10,9 @@ function _init()
-- 1: action -- 1: action
-- 2: score -- 2: score
-- 3: over -- 3: over
if debounce==nil then if debounce==nil then debounce=0 end
debounce=0 if timer==nil then timer=0 end
end
cur_state=0 cur_state=0
init_field() init_field()
init_player() init_player()
@ -24,7 +24,11 @@ function _update()
ply:title_input() ply:title_input()
elseif cur_state==1 then elseif cur_state==1 then
for p in all(plys) do for p in all(plys) do
if p.human then
p:input() p:input()
else
p:think()
end
p:update() p:update()
p:check() p:check()
end end
@ -35,6 +39,7 @@ function _update()
ply:end_input() ply:end_input()
end end
ply:tick_debounce() ply:tick_debounce()
timer+=1
end end
function _draw() function _draw()
@ -136,6 +141,7 @@ function init_player()
ply={ ply={
id=1, id=1,
human=true,
scrx=10, scrx=10,
scry=1, scry=1,
x=pfield.x1, x=pfield.x1,
@ -159,6 +165,92 @@ function init_player()
end end
end end
function ply:think()
if rndint(100)<5 then
self:check_around()
else
self:check_ahead()
end
end
function ply:check_ahead()
if self.xspd!=0 then
if self:check_x(self.xspd) then self:check_around() end
else
if self:check_y(self.yspd) then self:check_around() end
end
end
function ply:check_x(spd)
return sget(self.x+spd,self.y)!=0 or self.x+spd<pfield.x1 or self.x+spd>pfield.x2
end
function ply:check_y(spd)
return sget(self.x,self.y+spd)!=0 or self.y+spd<pfield.y1 or self.y+spd>pfield.y2
end
function ply:check_around()
-- basically narrow down the list of possible directions and randomly select a random remaining one.
local possible_dirs={
{spd=-1,axis="y"}, -- north
{spd=1,axis="y"}, -- south
{spd=1,axis="x"}, -- east
{spd=-1,axis="x"} -- west
}
local available_dirs={}
for d in all(possible_dirs) do
d.spd=self:check_dir(d)
if d.spd!=0 then
add(available_dirs,d)
end
end
local count=0
for d in all(available_dirs) do
count+=1
end
if count>0 then
self:favour_direction(available_dirs, count)
end
end
function ply:check_dir(dir)
for c=1,2 do
local spd=0
if dir.spd!=0 then
spd=(c*dir.spd)
end
if dir.axis=="x" then
if self:check_x(spd) then
return 0
end
elseif dir.axis=="y" then
if self:check_y(spd) then
return 0
end
end
end
return dir.spd
end
function ply:favour_direction(dirs, length)
dir=dirs[rndint(length)]
if dir.axis=="x" then
self.xspd=dir.spd
self.yspd=0
else
self.xspd=0
self.yspd=dir.spd
end
end
function ply:score_input() function ply:score_input()
if btn(🅾️) and debounce==0 then if btn(🅾️) and debounce==0 then
next_round() next_round()
@ -169,6 +261,7 @@ function init_player()
function ply:title_input() function ply:title_input()
if btn(🅾️) and debounce==0 then if btn(🅾️) and debounce==0 then
cur_state=1 cur_state=1
srand(timer)
debounce=10 debounce=10
end end
end end
@ -231,6 +324,7 @@ function init_player()
p2=plys[2] p2=plys[2]
p2.scrx=74 p2.scrx=74
p2.id=2 p2.id=2
p2.human=false
p2.x=pfield.x2 p2.x=pfield.x2
p2.xspd=-1 p2.xspd=-1
p2.col=12 p2.col=12
@ -258,7 +352,9 @@ function next_round()
pfield:clear() pfield:clear()
init_field() init_field()
init_player() init_player()
cur_state=1 cur_state=1
srand(timer)
for p in all(plys) do for p in all(plys) do
if scores[p.id]>=win_limit then if scores[p.id]>=win_limit then
@ -319,7 +415,7 @@ function report_winner(id)
end end
function draw_title() function draw_title()
print("beam",64-(4*4),60,11) print("beam",64-(4*4),60,10)
print("clash",64-(4*2),70,12) print("clash",64-(4*2),70,12)
print("press 🅾️",64-(4*4),80,7) print("press 🅾️",64-(4*4),80,7)

Loading…
Cancel
Save