diff --git a/luprex/core/lua/basics.lua b/luprex/core/lua/basics.lua index 589fe582..c838bd52 100644 --- a/luprex/core/lua/basics.lua +++ b/luprex/core/lua/basics.lua @@ -1,10 +1,11 @@ makeclass('NilIsZero') -- This is intended to be used as a metatable +makeclass('login') function NilIsZero.__index(t,k) - return 0 - end + return 0 + end function NilIsZero.__newindex(t,k,v) - if v~=nil and v~=0 then rawset(t,k,v) end - end + if v~=nil and v~=0 then rawset(t,k,v) end + end diff --git a/luprex/core/lua/horps.lua b/luprex/core/lua/horps.lua index 0020bf0c..0b567126 100644 --- a/luprex/core/lua/horps.lua +++ b/luprex/core/lua/horps.lua @@ -1,6 +1,6 @@ makeclass('player') makeclass('army') - +makeclass('orchard') -- -- HORPS game: Walk around the board collecting armies and buffs @@ -52,7 +52,8 @@ function army.interface(actor,place) -- Spock vaporizes Rock 3 -- Spock dismantles Scissors 2 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 }, -- 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 }, @@ -112,45 +113,61 @@ function MakeMap() end end end end + + -- -- 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 - if not rules then rules={} end +function army.fight0(ak,ac,dk,dc,tweekdefender) -- returns number of attacker casualties, defender casualties local adv0=advantage[ak][dk] local adv1=advantage[dk][ak] - if rules.counterattack=='one' then adv1=1 - elseif rules.counterattack=='best' then adv1=adv1<1 and 1 or 1 - end - local rval0=(ac*adv0-dc)/adv0 - if rval0<0 then rval0=0 end - local rval1=(dc*adv1-rval0)/adv1 - return rval0,rval1 + if not tweekdefender then tweekdefender=function(adv) return adv end end + adv1=tweekdefender(adv1) + local losstotal=(ac+dc)/2 + local power0=ac*adv0 + local power1=dc*adv1 + local powertotal=power0+power1 + local loss0=math.min(ac,math.floor(losstotal*power1/powertotal)) + local loss1=math.min(dc,math.floor(losstotal*power0/powertotal)) + return loss0,loss1 end + + function player:fight(enemy) + local rval={} for ak,ac in pairs(self.Count) do -- Should randomize the order local enemyk, enemyc - local acas - local maxcas=-1 - local Loss0,Loss1 + local useloss0 + local useloss1=-1 + local loss0,loss1 local whichdk, whichdc for dk,dc in pairs(enemy.Count) do - Loss0,Loss1=army.fight0(ak,ac,dk,dc) - print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..Loss1.." and suffer "..Loss0) - if Loss1>maxcas then + loss0,loss1=army.fight0(ak,ac,dk,dc) + print("When "..ac.." "..ak.." fight "..dc.." "..dk.." they kill "..loss1.." and suffer "..loss0) + if loss1>useloss1 then enemyk=dk enemyc=dc - maxcas=Loss1 - acas=Loss1 + useloss1=loss1 + useloss0=loss0 end end 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 + 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 + function player:cb_droprock(actor) player:droparmy(actor,'r') end function player:cb_droppaper(actor) player:droparmy(actor,'p') 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 pprint(t) end - + +function orchard:gather(actor) + actor.food[self.kind]=actor.inventory[self.kind]+self.count + end + function player:newlocation() 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 function player:printanimstate() @@ -175,28 +203,36 @@ function player:printanimstate() print("Resulting state: ", graphic, plane, x, y, z, facing) 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() - tangible.animate(self, {action="walk", dy=1}) - self:cb_map() - self:newlocation() + self:walk(0,1) end function player:cb_south() - tangible.animate(self, {action="walk", dy=-1}) - self:cb_map() - self:newlocation() + self:walk(0,-1) end function player:cb_east() - tangible.animate(self, {action="walk", dx=1}) - self:cb_map() - self:newlocation() + self:walk(1,0) end function player:cb_west() - tangible.animate(self, {action="walk", dx=-1}) - self:cb_map() - self:newlocation() + self:walk(0,1) end @@ -230,6 +266,7 @@ function player.cb_emit_buff(actor,place,dialog) makeclass('army') makeclass('buff') + 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 diff --git a/luprex/core/lua/login.lua b/luprex/core/lua/login.lua index 08180efa..d0904e77 100644 --- a/luprex/core/lua/login.lua +++ b/luprex/core/lua/login.lua @@ -3,11 +3,13 @@ makeclass('login') function login.interface(actor, place) gui.menu_item("cb_becomeplayer", "Become a Player") gui.menu_item("cb_p123", "Print 1, 2, 3") + gui.menu_item("cb_uglytimedaemon","Start the Time Daemon") end function login.cb_becomeplayer(actor, place, dialog) actor.kind='P' actor.Count={} setmetatable(actor.Count,NilIsZero) + actor.Food={} setmetatable(actor.Food,NilIsZero) tangible.setclass(actor, player) tangible.animate(actor,{action="warp",plane="main",x=0,y=0,z=0}) end diff --git a/luprex/core/lua/uglyglobals.lua b/luprex/core/lua/uglyglobals.lua index a6a6d2d5..63bfe737 100644 --- a/luprex/core/lua/uglyglobals.lua +++ b/luprex/core/lua/uglyglobals.lua @@ -18,3 +18,12 @@ function ug.get(var) return ug.the()[var] 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