/[enigma]/enigma/data/levels/ralf_sokoban.lua
ViewVC logotype

Diff of /enigma/data/levels/ralf_sokoban.lua

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.6 by reallysoft, Sat Mar 29 17:07:25 2003 UTC revision 1.7 by reallysoft, Sun Mar 30 20:15:49 2003 UTC
# Line 18  dofile(enigma.FindDataFile("levels/ralf. Line 18  dofile(enigma.FindDataFile("levels/ralf.
18  --  --
19  -- '!'      space outside level  -- '!'      space outside level
20  -- ' '      normalfloor  -- ' '      normalfloor
21    -- '_'      normalfloor (unreachable after pushing all boxes)
22  -- '#'      walls  -- '#'      walls
23  -- 'o'      boxes  -- 'o'      boxes
24  -- '.'      targets  -- '.'      targets
# Line 43  oxyd_flavors = { "a", "b", "c", "d" } Line 44  oxyd_flavors = { "a", "b", "c", "d" }
44    
45  shogunLaser = 0 -- if set to 1 then lasers are used to activate oxyds (this only works with shogun stones)  shogunLaser = 0 -- if set to 1 then lasers are used to activate oxyds (this only works with shogun stones)
46    
47  -- some counters  -- global variables
48  triggers = 0  triggers = 0
49  doors = 0  doors = 0
50  lasers = 0  lasers = 0
# Line 51  space_count = 0 -- count occurances of s Line 52  space_count = 0 -- count occurances of s
52    
53  triggerstate = "" -- current state of the triggers  triggerstate = "" -- current state of the triggers
54  shuffle = {} -- contains random permutation (to select trigger targets)  shuffle = {} -- contains random permutation (to select trigger targets)
55    shuffletrig = {} -- contains random permutation (to select triggers)
56    
57    position = {} -- positions of doors
58    positions = 0
59    
60    locked_door_triggered = 0 -- one of the doors is locked until ALL targets are covered
61    locked_door = 1
62    
63    function init_globals()
64       triggers = 0
65       doors = 0
66       lasers = 0
67       space_count = 0
68       triggerstate = ""
69       shuffle = {}
70       shuffletrig = {}
71       position = {}
72       positions = 0
73       locked_door_triggered = 0
74       locked_door = 1
75    
76    end
77    
78    -----------------------------------------
79    
80  function init_shuffle()  function init_shuffle()
81     local set = {}     local set = {}
82     for i=1,doors do     for i=1,doors do set[i] = i end
       set[i] = i  
    end  
83    
84     local left = doors     local left = doors
85     for count=1,doors do     for count=1,doors do
# Line 66  function init_shuffle() Line 89  function init_shuffle()
89        left = left-1        left = left-1
90        debug("shuffle["..count.."]="..shuffle[count])        debug("shuffle["..count.."]="..shuffle[count])
91     end     end
 end  
92    
93  function yep(who)     local settrig = {}
94     debug("level done");     for i=1,triggers do settrig[i] = i end
 end  
95    
96  locked_door_triggered = 0 -- one of the doors is locked until ALL targets are covered     left = triggers
97       for count=1,triggers do
98          local sel = random(1,left)
99          shuffletrig[count] = settrig[sel]
100          settrig[sel] = settrig[left]
101          left = left-1
102          debug("shuffletrig["..count.."]="..shuffletrig[count])
103       end
104    end
105    
106  function trig_laser(which)  function trig_laser(which)
107       which = shuffletrig[which]
108     local state = strsub(triggerstate,which,which)     local state = strsub(triggerstate,which,which)
109     if (state == "0") then state = "1" else state = "0" end     if (state == "0") then state = "1" else state = "0" end
110     triggerstate = strsub(triggerstate,1,which-1)..state..strsub(triggerstate,which+1)     triggerstate = strsub(triggerstate,1,which-1)..state..strsub(triggerstate,which+1)
# Line 88  function trig_laser(which) Line 118  function trig_laser(which)
118  end  end
119    
120  function trig_door(which)  function trig_door(which)
121       which = shuffletrig[which]
122     local state = strsub(triggerstate,which,which)     local state = strsub(triggerstate,which,which)
123     if (state == "0") then state = "1" else state = "0" end     if (state == "0") then state = "1" else state = "0" end
124    
# Line 125  function trig_door(which) Line 156  function trig_door(which)
156     debug(triggerstate)     debug(triggerstate)
157    
158     if (trig_door ~= -1) then     if (trig_door ~= -1) then
159        if (trig_door ~= 1) then        if (trig_door ~= locked_door) then
160           enigma.SendMessage(enigma.GetNamedObject("door"..shuffle[trig_door]), "openclose", nil)           enigma.SendMessage(enigma.GetNamedObject("door"..shuffle[trig_door]), "openclose", nil)
161        end        end
162     end     end
163    
164     if (all_covered) then     if (all_covered) then
165        if (locked_door_triggered==0) then        if (locked_door_triggered==0) then
166           enigma.SendMessage(enigma.GetNamedObject("door"..shuffle[1]), "open", nil)           enigma.SendMessage(enigma.GetNamedObject("door"..shuffle[locked_door]), "open", nil)
167           locked_door_triggered = 1           locked_door_triggered = 1
168        end        end
169     else     else
170        if (locked_door_triggered==1) then        if (locked_door_triggered==1) then
171           enigma.SendMessage(enigma.GetNamedObject("door"..shuffle[1]), "close", nil)           enigma.SendMessage(enigma.GetNamedObject("door"..shuffle[locked_door]), "close", nil)
172           locked_door_triggered = 0           locked_door_triggered = 0
173        end        end
174     end     end
# Line 168  function set_actor_on_trigger(x,y) Line 199  function set_actor_on_trigger(x,y)
199     set_soko_trigger(x,y)     set_soko_trigger(x,y)
200  end  end
201    
202  spacemod = 2  --spacemod = 2
203    
204  function set_spacecell(x,y)  function set_spacecell(x,y)
205     space_count = space_count+1     space_count = space_count+1
# Line 176  function set_spacecell(x,y) Line 207  function set_spacecell(x,y)
207  end  end
208    
209  function init(num)  function init(num)
210       init_globals()
211    
212     local first = 0     local first = 0
213     if (num == -1) then     if (num == -1) then
214        first = 1        first = 1
# Line 217  function init(num) Line 250  function init(num)
250     cells={}     cells={}
251     cells["!"] = cell{parent = {set_spacecell}}     cells["!"] = cell{parent = {set_spacecell}}
252     cells[" "] = floorcell     cells[" "] = floorcell
253       cells["_"] = floorcell
254     cells["#"] = cell{parent = floorcell, stone = {face = wallface}}     cells["#"] = cell{parent = floorcell, stone = {face = wallface}}
255    
256     cells["o"] = cell{parent = floorcell, stone = {face = boxface}}     cells["o"] = cell{parent = floorcell, stone = {face = boxface}}
# Line 249  function peek(x,y) Line 283  function peek(x,y)
283     return strsub(level[y],x,x)     return strsub(level[y],x,x)
284  end  end
285    
286    function rpeek(rx,ry)
287       return peek(rx-xlo+1,ry-ylo+1)
288    end
289    
290  function adjacent(x1,y1,x2,y2) -- returns TRUE if the two positions are adjacent  function adjacent(x1,y1,x2,y2) -- returns TRUE if the two positions are adjacent
291     local dx,dy = abs(x1-x2),abs(y1-y2)     local dx,dy = abs(x1-x2),abs(y1-y2)
292     return (dx==0 and dy==1) or (dx==1 and dy==0)     return (dx==0 and dy==1) or (dx==1 and dy==0)
# Line 263  end Line 301  end
301  xoff = { -1,  1,  0,  0 }  xoff = { -1,  1,  0,  0 }
302  yoff = {  0,  0, -1,  1 }  yoff = {  0,  0, -1,  1 }
303    
304  function install_oxyds(w,h) -- uses Nat's method (see nat7.lua)  function is_in_restricted_area(p)
305     local position = {}     local xd,yd = position[p][1],position[p][2]
306     local positions = 0     local xo,yo = position[p][3],position[p][4]
307       local xf,yf = xd+(xd-xo),yd+(yd-yo)
308    
309       debug("xf="..xf.." yf="..yf)
310    
311       local c = rpeek(xf,yf)
312       if (c==' ') then return 0 end
313       if (c=='_') then return 1 end
314    
315       return 2 -- unknown
316    end
317    
318    function install_oxyds(w,h) -- uses Nat's method (see nat7.lua)
319     for x=1,w do     for x=1,w do
320        for y=1,h do        for y=1,h do
321           if (peek(x,y)=='#') then           if (peek(x,y)=='#') then
# Line 288  function install_oxyds(w,h) -- uses Nat' Line 337  function install_oxyds(w,h) -- uses Nat'
337                       spacehere = -1                       spacehere = -1
338                    end                    end
339                 end                 end
340                 if (state[n]=='o' or state[n]==' ' or state[n]=='@') then  
341                   if (state[n]=='o' or state[n]==' ' or state[n]=='@' or state[n]=='_') then
342                    if (reachable == 0) then                    if (reachable == 0) then
343                       reachable = n                       reachable = n
344                    else                    else
# Line 393  function install_oxyds(w,h) -- uses Nat' Line 443  function install_oxyds(w,h) -- uses Nat'
443     return 0     return 0
444  end  end
445    
446    function correct_locked_door_position()
447       while (locked_door <= doors) do
448          local ld = shuffle[locked_door]
449          local restricted = is_in_restricted_area(ld)
450    
451          local xd,yd = position[ld][1],position[ld][2]
452          debug("[locked door] ld="..ld.." xd="..xd.." yd="..yd.." restricted="..restricted)
453    
454          if (restricted == 0) then return 1 end
455          locked_door = locked_door+1
456       end
457       debug("Could not correct position of locked door. Not playable!");
458       return 0
459    end
460    
461    function correct_multi_trigger_doors()
462       if (doors == triggers) then return 1 end -- 1 triggers <-> 1 door => no problem
463    
464       local multiTriggeredDoors = triggers-doors
465       if (multiTriggeredDoors > doors) then multiTriggeredDoors = doors end
466       for mtd=1,multiTriggeredDoors do
467          local ld = shuffle[mtd]
468          local restricted = is_in_restricted_area(ld)
469    
470          local xd,yd = position[ld][1],position[ld][2]
471          debug("[multit door] ld="..ld.." xd="..xd.." yd="..yd.." restricted="..restricted)
472    
473          if (restricted ~= 0) then return 0 end
474       end
475       return 1
476    end
477    
478    function correct_door_positions()
479       if (shogunLaser==1) then return 1 end -- doesn't matter in shogunLaser mode
480    
481       local ok = correct_locked_door_position()
482       if (ok==1) then ok = correct_multi_trigger_doors() end
483    
484       return ok
485    end
486    
487  function play_sokoban(level,num)  function play_sokoban(level,num)
488     local w,h = get_map_size(level)     local w,h = get_map_size(level)
489     init(num-1)     local tries = 100
490     randomseed(enigma.GetTicks())     local ok = 0
 --   rs_create_world(level,cells,spacecell,spacecell)  
    rs_create_world(level,cells,set_spacecell,set_spacecell)  
491    
492     if (xlo > 0) then     while (tries > 0 and ok == 0) do
493        spl = 1 -- there's space at the left side        init(num-1)
494        space_count = space_count + maph        randomseed(enigma.GetTicks())
495     end        --   rs_create_world(level,cells,spacecell,spacecell)
496     if (ylo > 0) then        rs_create_world(level,cells,set_spacecell,set_spacecell)
497        spt = 1 -- there's space at the top side  
498        space_count = space_count + mapw        if (xlo > 0) then
499     end           spl = 1 -- there's space at the left side
500     if ((xlo+mapw) < 20) then           space_count = space_count + maph
501        spr = 1 -- there's space at the right side        end
502        space_count = space_count + maph        if (ylo > 0) then
503     end           spt = 1 -- there's space at the top side
504     if ((ylo+maph) < 13) then           space_count = space_count + mapw
505        spb = 1 -- there's space at the bottom side        end
506        space_count = space_count + mapw        if ((xlo+mapw) < 20) then
507     end           spr = 1 -- there's space at the right side
508             space_count = space_count + maph
509          end
510          if ((ylo+maph) < 13) then
511             spb = 1 -- there's space at the bottom side
512             space_count = space_count + mapw
513          end
514    
515     debug("Space aside: spl="..spl.." spr="..spr.." spt="..spt.." spb="..spb);        debug("Space aside: spl="..spl.." spr="..spr.." spt="..spt.." spb="..spb);
516    
517     -- install oxyds        -- install oxyds
518     install_oxyds(w,h)        install_oxyds(w,h)
519          init_shuffle() -- mix trigger-door associations
520          ok = correct_door_positions()
521          if (ok == 0) then debug("re-initializing.."); end
522          tries = tries - 1
523       end
524    
525     init_shuffle() -- mix trigger-door associations     if (ok==0) then
526          error("Sorry - couldn't correct door positions. Avoiding deadlock (try again)");
527       end
528    
529     triggerstate = strrep("0",triggers)     triggerstate = strrep("0",triggers)
530     display.SetFollowMode(display.FOLLOW_SCROLLING)     display.SetFollowMode(display.FOLLOW_SCROLLING)

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26