Schalter in bestimmter Reihenfolge betätigen
Aus EnigmaWiki
Verfügbare Sprachen: Deutsch, English, Русский
Inhaltsverzeichnis |
Problemstellung
Es gibt einen Haufen Schalter und der Spieler soll sie in einer gewissen, vorher festgelegten Reihenfolge betätigen, damit eine Aktion ausgelöst wird. Bei der falschen Reihenfolge geschieht nichts.
Lösungsansatz
Wir halten die Lösung als String fest, der durch aneinaderfügen der Namen der Schalter in der Soll-Reihenfolge entsteht. Dann nehmen wir einen 2. leeren String und jeder Schalter, der betätigt wird hängt seinen Namen hinten an. Jedes mal, wenn das geschieht wird dann überprüft, ob der so entstandene String der Lösung entspricht. Natürlich könnte man dieses Überprüfen auch einem speziellen Schalter überlassen, den der Spieler einzeln betätigen muss.
Da es möglich ist, einen String zu erstellen, der nicht der Lösung entspricht, und man keine Chnace hat, diesen String wieder zu verkürzen, wird er länger und länger ... Deshalb bauen wir noch einen Schalter ein, der den Lösungsversuch zurücksetzt. Man könnte den String auch automatisch zurücksetzten (auf ""), sobald er länger als der vorgegebene String wird.
Lösungsbeispiel
local names = {"a","b","c","d","e","f","g","h","i"} local num_trigger = table.getn(names) local solution = "acbdegfhii" local buffer = "" -- Set the swithes for i=1, num_trigger do set_stone("st-switch",1+i,2,{name=names[i], action="callback", target="evaluate"}) end -- Reset the buffer set_stone("st-switch",1,1,{name="reset", action="callback", target="reset"}) function reset() buffer = "" end function evaluate(onoff, sender) local code = enigma.GetAttrib(sender,"name") buffer = buffer..code check_result(solution, buffer) end function check_result(sollwert, istwert) if istwert == sollwert then foo() end end function foo() print("foo!") end
Analyse
Weiteres Lösungsbeispiel
-- Set a field with triggers: function set_switchfield(top_left, fieldsize) local field_w, field_h = fieldsize[1]-1, fieldsize[2]-1 local i, j local k=0 for i=0, field_h do for j=0, field_w do set_item("it-trigger", top_left[1]+j, top_left[2]+i, {name="switch"..tostring(k), action="callback", target="evaluate", _ID=tostring(k)}) k = k+1 end end end -- solution and buffer -- If both strings are identical, we reached our goal: -- The player hit the triggers in the desired order. -- solution: the ID-values of all triggers concatenated in the desired order: local solution = "0123491413121110152021222324" -- initially, buffer is empty: local buffer = "" -- if this is true, we will evaluate: local must_evaluate = true -- After each hit of a trigger, we evaluate ... function evaluate(value, sender) -- but only, when we enter it, not when we leave it: if value == 1 and must_evaluate then local code = enigma.GetAttrib(sender,"_ID") buffer = buffer..code check_result(solution, buffer) end end -- ... if the solution is reached just now: function check_result(sollwert, istwert) if istwert == sollwert then -- We don't want to evaluate further when the goal is reached. -- if we want, we have also to comment out then autoreset. must_evaluate = false foo() else unfoo() end -- autoreset: -- the buffer string is bigger than the solution string. -- there is NO chance to solve, clear the buffer: if string.len(sollwert) < string.len(istwert) then buffer = "" end end function foo() -- "solution" is reached! Success! enigma.SendMessage(enigma.GetNamedObject("door1"), "open", nil) end function unfoo() -- Add here what to do when the "solution" is not (or not yet!) reached end set_switchfield({2,2}, {5,5})

