This commit is contained in:
2022-04-25 12:20:29 -04:00
parent b791cdc606
commit 6ee56bac61
4 changed files with 87 additions and 38 deletions

View File

@@ -1,10 +1,11 @@
makeclass('NilIsZero') -- This is intended to be used as a metatable makeclass('NilIsZero') -- This is intended to be used as a metatable
makeclass('login')
function NilIsZero.__index(t,k) function NilIsZero.__index(t,k)
return 0 return 0
end end
function NilIsZero.__newindex(t,k,v) function NilIsZero.__newindex(t,k,v)
if v~=nil and v~=0 then rawset(t,k,v) end if v~=nil and v~=0 then rawset(t,k,v) end
end end

View File

@@ -1,6 +1,6 @@
makeclass('player') makeclass('player')
makeclass('army') makeclass('army')
makeclass('orchard')
-- --
-- HORPS game: Walk around the board collecting armies and buffs -- HORPS game: Walk around the board collecting armies and buffs
@@ -52,7 +52,8 @@ function army.interface(actor,place)
-- Spock vaporizes Rock 3 -- Spock vaporizes Rock 3
-- Spock dismantles Scissors 2 -- Spock dismantles Scissors 2
armytypes={'r','p','s'} armytypes={'r','p','s'}
armynames={r="Rock Golem",p="Paper Dragon",s="Scissor Beast",l="Fire Lizzard",v="Mr. Spock"} armynames={r="Rock Golem" ,p="Paper Dragon",s="Scissor Beast",l="Fire Lizzard",v="Mr. Spock"}
foodnames={r="Raspberry" ,p="Pomegranite" ,s="Strawberry" ,l="Lemon" ,v="Mango" }
--advantage={ r={ r=1, p=1/2, s=3, l=2, v=1/3 }, --advantage={ r={ r=1, p=1/2, s=3, l=2, v=1/3 },
-- p={ r=2, p=1, s=1/2, l=1/3, v=3 }, -- p={ r=2, p=1, s=1/2, l=1/3, v=3 },
-- s={ r=1/3, p=2, s=1, l=3, v=1/2 }, -- s={ r=1/3, p=2, s=1, l=3, v=1/2 },
@@ -112,45 +113,61 @@ function MakeMap()
end end end end end end
end end
-- --
-- For each creature type, select the optimal target. Select randomly among identical targets. -- For each creature type, select the optimal target. Select randomly among identical targets.
-- --
function army.fight0(ak,ac,dk,dc,rules) -- returns number of attacker casualties, defender casualties function army.fight0(ak,ac,dk,dc,tweekdefender) -- returns number of attacker casualties, defender casualties
if not rules then rules={} end
local adv0=advantage[ak][dk] local adv0=advantage[ak][dk]
local adv1=advantage[dk][ak] local adv1=advantage[dk][ak]
if rules.counterattack=='one' then adv1=1 if not tweekdefender then tweekdefender=function(adv) return adv end end
elseif rules.counterattack=='best' then adv1=adv1<1 and 1 or 1 adv1=tweekdefender(adv1)
end local losstotal=(ac+dc)/2
local rval0=(ac*adv0-dc)/adv0 local power0=ac*adv0
if rval0<0 then rval0=0 end local power1=dc*adv1
local rval1=(dc*adv1-rval0)/adv1 local powertotal=power0+power1
return rval0,rval1 local loss0=math.min(ac,math.floor(losstotal*power1/powertotal))
local loss1=math.min(dc,math.floor(losstotal*power0/powertotal))
return loss0,loss1
end end
function player:fight(enemy) function player:fight(enemy)
local rval={}
for ak,ac in pairs(self.Count) do -- Should randomize the order for ak,ac in pairs(self.Count) do -- Should randomize the order
local enemyk, enemyc local enemyk, enemyc
local acas local useloss0
local maxcas=-1 local useloss1=-1
local Loss0,Loss1 local loss0,loss1
local whichdk, whichdc local whichdk, whichdc
for dk,dc in pairs(enemy.Count) do for dk,dc in pairs(enemy.Count) do
Loss0,Loss1=army.fight0(ak,ac,dk,dc) loss0,loss1=army.fight0(ak,ac,dk,dc)
print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..Loss1.." and suffer "..Loss0) print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..loss1.." and suffer "..loss0)
if Loss1>maxcas then if loss1>useloss1 then
enemyk=dk enemyk=dk
enemyc=dc enemyc=dc
maxcas=Loss1 useloss1=loss1
acas=Loss1 useloss0=loss0
end end end end
if enemyk then if enemyk then
print("Army of "..ac.." "..ak.." fights "..enemyc.." "..enemyk..", killing "..Loss1.." and suffering "..Loss0) print("Army of "..ac.." "..ak.." fights "..enemyc.." "..enemyk..", killing "..useloss1.." and suffering "..useloss0)
rval[1+#rval]={'fight',ak,ac,useloss0,enemyk,enemyc,useloss1}
enemy.Count[enemyk]=enemy.Count[enemyk]-useloss1
self.Count[ak]=self.Count[ak]-useloss0
end end
end end
local enemyleft=0
local playerleft=0
for dk,dc in pairs(enemy.Count) do enemyleft=enemyleft+dc end
for ak,ac in pairs(self.Count) do playerleft=playerleft+ac end
rval.enemyleft=enemyleft
return rval
end end
function player:cb_droprock(actor) player:droparmy(actor,'r') end function player:cb_droprock(actor) player:droparmy(actor,'r') end
function player:cb_droppaper(actor) player:droparmy(actor,'p') end function player:cb_droppaper(actor) player:droparmy(actor,'p') end
function player:cb_dropscissor(actor) player:droparmy(actor,'s') end function player:cb_dropscissor(actor) player:droparmy(actor,'s') end
@@ -164,10 +181,21 @@ function player:droparmy(actor,kind)
t.Count[kind]=t.Count[kind]+1 t.Count[kind]=t.Count[kind]+1
pprint(t) pprint(t)
end end
function orchard:gather(actor)
actor.food[self.kind]=actor.inventory[self.kind]+self.count
end
function player:newlocation() function player:newlocation()
local lis=tangible.near(self,0,true,true) local lis=tangible.near(self,0,true,true)
for _,t in ipairs(lis) do self:fight(t) end local count={} setmetatable(count,NilIsZero)
local count0=0
local result={}
for _,t in ipairs(lis) do if tangible.getclass(t)=='army' then result[1+#result]=self:fight(t) end end
if #result==1 and result[1].enemyleft>0 then
for _,t in ipairs(lis) do if tangible.getclass(t)=='orchard' then t:gather(self) end end
end
return result
end end
function player:printanimstate() function player:printanimstate()
@@ -175,28 +203,36 @@ function player:printanimstate()
print("Resulting state: ", graphic, plane, x, y, z, facing) print("Resulting state: ", graphic, plane, x, y, z, facing)
end end
function player:walk(dx,dy)
tangible.animate(self,{action='walk',dx=dx,dy=dy})
local result=self:newlocation()
pprint(result)
if #result>1 then print("Error: multiple armies at one location")
elseif #result==1 then
if result[1].enemyleft>0 then tangible.animate(self,{action='walk',dx=-dx,dy=-dy}) end
end
-- self:cb_map()
if #result==1 then
for i,v in ipairs(result[1]) do
if v[1]=='fight' then print(v[3]..v[2].." attacks "..v[6]..v[5]..", killing "..v[7].." while losing "..v[4]) end
end
end
end
function player:cb_north() function player:cb_north()
tangible.animate(self, {action="walk", dy=1}) self:walk(0,1)
self:cb_map()
self:newlocation()
end end
function player:cb_south() function player:cb_south()
tangible.animate(self, {action="walk", dy=-1}) self:walk(0,-1)
self:cb_map()
self:newlocation()
end end
function player:cb_east() function player:cb_east()
tangible.animate(self, {action="walk", dx=1}) self:walk(1,0)
self:cb_map()
self:newlocation()
end end
function player:cb_west() function player:cb_west()
tangible.animate(self, {action="walk", dx=-1}) self:walk(0,1)
self:cb_map()
self:newlocation()
end end
@@ -230,6 +266,7 @@ function player.cb_emit_buff(actor,place,dialog)
makeclass('army') makeclass('army')
makeclass('buff') makeclass('buff')
function seq(a,b,c) return a<=b and b<=c or false end function seq(a,b,c) return a<=b and b<=c or false end
function num2(a) if a<=9 then return " "..a else return a end end function num2(a) if a<=9 then return " "..a else return a end end

View File

@@ -3,11 +3,13 @@ makeclass('login')
function login.interface(actor, place) function login.interface(actor, place)
gui.menu_item("cb_becomeplayer", "Become a Player") gui.menu_item("cb_becomeplayer", "Become a Player")
gui.menu_item("cb_p123", "Print 1, 2, 3") gui.menu_item("cb_p123", "Print 1, 2, 3")
gui.menu_item("cb_uglytimedaemon","Start the Time Daemon")
end end
function login.cb_becomeplayer(actor, place, dialog) function login.cb_becomeplayer(actor, place, dialog)
actor.kind='P' actor.kind='P'
actor.Count={} setmetatable(actor.Count,NilIsZero) actor.Count={} setmetatable(actor.Count,NilIsZero)
actor.Food={} setmetatable(actor.Food,NilIsZero)
tangible.setclass(actor, player) tangible.setclass(actor, player)
tangible.animate(actor,{action="warp",plane="main",x=0,y=0,z=0}) tangible.animate(actor,{action="warp",plane="main",x=0,y=0,z=0})
end end

View File

@@ -18,3 +18,12 @@ function ug.get(var)
return ug.the()[var] return ug.the()[var]
end end
function login.cb_uglytimedaemon()
if not ug.get('time') then ug.set('time',0) end
while true do
wait(1)
ug.set('time',ug.get('time')+1)
end
end
function time() return ug.get('time') end