Macro Challenge: Floor Tile Puzzle

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Macro Challenge: Floor Tile Puzzle

Post by JamzTheMan »

OK, so RL is a real pain lately and don't have time to code this myself so thought I'd put it out there to see if anyone may have done something close or can whip it out, the code that is. :)


I wanted to put a floor tile puzzle in, DDO style. http://s28.photobucket.com/user/Gidgett ... e.jpg.html (working example https://www.youtube.com/watch?v=On4OcpV7k-k ).

It should be simple enough? The "Puzzle" token would need to know which sides have "openings" which would be 1-4 of them. On click, the tile would rotate clockwise. One tile would be a "Power" tile which emits power on 1-4 sides. If the Puzzle token has an opening to a Power token or another powered Puzzle token, change image (handout?) to powered version. A third token would be the "Finish" tile and once powered the puzzle is solved and lights up (image change on Finish tile).

I suppose the same logic could be used with tiles with "rails" and a cart can travel once solved. Could be used in a variety of games with a change of tiles. Bonus points for allowing a PC to only rotate tiles adjacent to his location.
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Macro Challenge: Floor Tile Puzzle

Post by wolph42 »

doable but not easy.

a breakdown of how it could be done

1. i assume that the gm lays out the puzzle solved (it could be done with a macro but then stuff really gets hairy)
2. next there is a randomize macro that rotates all tokens randomly
3. all the puzzle tokens (pt) have 5 properties (N)orth, (E)ast, (S)outh and (W)est. These properties can have the value -1 (no exit), 0 (exit, not yet checked) and 1 (exit, checked)
4. a simple getDistance() routine can check if the token is standing next to or onto the pt the player selects (and ignores rotation if too far)

now the lighting up part
1. for the lighting up part I would suggest using a transparent state that 'lights up' the token (and thus you know its powered)
2. the 'core power' token has a unique name e.g. 'Power Token' and has the 'lights up' state applied (and cannot be rotated?)
3. the 'finish power' token also has a special name e.g. 'finish token'
4. also add a property Power to track whether its powered on or off, this is faster than checking the state itself

solving the puzzle
1. a 'doIt()' routine is run every time a pt is selected
2. routine first checks distance if too far: abort
3. the pt is rotate 90 degrees clockwise
4. a routine goes through all pt's and sets all properties that are not -1 to 0 (including the property Power)
5. beenThere = getLibProperty("beenThere", "lib:Token") (an array that is initially empty).
6. checkToken("Power Token", 1) is called
7. foreach(tok, beenThere), token(tok), if(Power): setState("Power", 1) ; setState("Power", 0)

the check routine is the really hairy part. Point is that pt can have more then 2 exits, this means that (AFAIK) the only way to go through this is with a recursive routine where when an exit is found the adjacent token is checked by calling the routine itself with two parameters: 1.me=adjacent token, 2.exit location

I think the routine would look like this:
(determineExit() determines the actual location of the exit. E.g. a N exit rotated 90 CW actually points E.)

initial call: checkToken("Power Token", 1)

Code: Select all

<!--- checkToken(tokName:name of token to check, exitLocation:location to where the token is connected) -->
tokName            = arg(0)
exitLocation    = arg(1)

<!-- if its the 'finish token' then youre done  -->
IF(tokName == 'finish token'): you solved the puzzle, abort

<!-- first check whether this is the power token OR it has a connected exitLocation, depending on that determineExit() returns this should be e.g. given exit or its opposite (so if N is given, check for S exit)  -->
IF(exitLocation == 1 || hasExit(exitLocation)), CODE:{
    <!-- if its a pt then set the exitLocation to checked (=1) -->
    if(!isNumber(exitLocation)): set(exitLocation, 1)
    <!-- turn on the lights -->
    Power = 1
    <!-- add the token to the beenThere array, so its power will be checked in a later routine -->
    if(!json.contains(beenThere, tokName): beenThere = json.append(beenThere, tokName)
    IF N==0 THEN 
      N                = 1
      exitLocation    = determineExit(tokName, "N")
      tmpName        = getAdjacentTok(tokName, exitLocation)
    <!- some thought is required on what is actually pass on as exitLocation, either the exit of tokName OR the required exit of  tmpName which is opposite -->  
      IF(tmpName != ""): checkToken(tmpName, exitLocation)
    END IF N==0

    IF E==0 THEN same as N routine (but then with E)
    IF S==0 THEN dito
    IF W==0 THEN dito
}
end routine. 
I think that's it. Pls shoot.

Comments:
- the determineExit() and passing it on to the the recursive macro really needs some thought as you need to pass on the opposite exit AND ofcourse you also need to check the connection. This particular stuff always gives me an head-ache...on top of the head-aches I get from recursive routines.
- note that this routine is run EVERY TIME a token is rotated (selected). The 'beenThere' array will help a bit, but I fear that this might be REALLY slow, especially with many tokens puzzle.

edit: added 'beenThere' optimization routine and Power property so ONLY the states of the tokens are checked where the routine has actually been and it also prevents 'power flicker' (initially: first turn off all states and then turn them back on; now: only change state when something has changed.

User avatar
aliasmask
RPTools Team
Posts: 9029
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Macro Challenge: Floor Tile Puzzle

Post by aliasmask »

In all honesty, writing the code will be much harder than solving the puzzle unless you're going to limit the number tiles that can be turned. Here is an interesting link. It shows you how to create a maze and you can use the same algorithm to test to see if it is solved.

http://mazeworks.com/mazegen/mazetut/index.htm

Searching through a maze, the pseudo-code is pretty common if you do a search for it.

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Macro Challenge: Floor Tile Puzzle

Post by wolph42 »

aliasmask wrote:unless you're going to limit the number tiles that can be turned
why?

I agree that solving the puzzle will go faster then writing the code, but I don't see the point. I get that you want to provide the players with a puzzle and the 'lighting up' part is automated. Thats what this is about. But what has that to do with limiting the number of tiles??

Nice read btw about the maze, but I assume here that Jamz wants automization during gameplay (so light up tiles that are powered), not an entire 'create maze' routine which roughly doubles the amount of work described in my former post.

edit:

I was looking at the mazeGen pseudo code and was wondering: can't it be rewritten in a recursive function as well ?
So turn this
mazeGen

Code: Select all

create a CellStack (LIFO) to hold a list of cell locations  
set TotalCells = number of cells in grid  
choose a cell at random and call it CurrentCell  
set VisitedCells = 1  
   
while VisitedCells < TotalCells 
	find all neighbors of CurrentCell with all walls intact   
	if one or more found 
		choose one at random  
		knock down the wall between it and CurrentCell  
		push CurrentCell location on the CellStack  
		make the new cell CurrentCell  
		add 1 to VisitedCells
	else 
		pop the most recent cell entry off the CellStack  
		make it CurrentCell
	endIf
endWhile  
into this
checkCell(CurrentCell)

Code: Select all

done = 0
while !done
	find all neighbours of CurrentCell with all walls intact  (=neighBourArray)
	if(json.isEmpty(neighBourArray))
		done=1
	else
		choose one at random  (=nextCell)
		knock down the wall between it and CurrentCell  
		checkCell(nextCell)
	endIf
endwhile

User avatar
JamzTheMan
Great Wyrm
Posts: 1872
Joined: Mon May 10, 2010 12:59 pm
Location: Chicagoland
Contact:

Re: Macro Challenge: Floor Tile Puzzle

Post by JamzTheMan »

So ya, writing the code will be harder, but then again, pretty much every macro written is harder than doing the task, once. But if this was done, I'd probably use it a few times. A simple one that needs to be solved during combat, two that need to be solved at the same time, one with multiple power sources, a long hallway, etc.

It is a little more complicated than originally thought out, being that it needs to take turning an older tile off (at first I thought it would be one check to check for power then turn on but of course an earlier tile could be turned which cascades the tiles off).

Thanks Wolf for putting the initial psuedo code together. It definitely could be done easier in a higher language but we're stuck with macro code. :)

Would knowing the "solution" make the macro eaiser? ie Mark the tiles and orientation for the final solution? I'm guessing not because you would still need to light up/off "wrong" tiles as well anyway?
-Jamz
____________________
Custom MapTool 1.4.x.x Fork: maptool.nerps.net
Custom TokenTool 2.0 Fork: tokentool.nerps.net
More information here: MapTool Nerps! Fork

User avatar
aliasmask
RPTools Team
Posts: 9029
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Macro Challenge: Floor Tile Puzzle

Post by aliasmask »

wolph42 wrote:
aliasmask wrote:unless you're going to limit the number tiles that can be turned
why?

I agree that solving the puzzle will go faster then writing the code, but I don't see the point. I get that you want to provide the players with a puzzle and the 'lighting up' part is automated. Thats what this is about. But what has that to do with limiting the number of tiles??
I say that because I've played with this puzzle. Mass Effect and some horror board game use tile rotation puzzles, although the board game puzzle was much more interesting because of the limited number of moves you get and adding color matching for another dimension. Mass Effect had a time limit to make it more challenging. The puzzle essentially has 2 pieces, a turn and a straight piece. The puzzle usually offers many solutions, so limiting the number of times you can turn a tile would add a level of difficulty for a pretty straight forward solution.

Post Reply

Return to “Macros”