Some text-based rogue-likes don't let you walk into walls, and give you your move back if you try to. Why do that when you can make the player move in the closest valid direction?
The challenge
Write a program of function that, given a direction and a 3 by 3 grid of characters, outputs the same grid after the player has taken a step.
For example,
9
#..
.@#
#.#
becomes
#.@
..#
#.#
Input
The direction is given by a single digit from 1 to 9, each corresponding to 8 cardinal directions and standing still. This is derived from the relative locations of the numbers on a keypad:
NW N NE ..\ | / ...7 8 9 W- 4 5 6 -E ...1 2 3 ../ | \ SW S SE
However, you may also use the numbers 123, 456, 789 instead of 789, 456, 123. In other words, you may swap the top and bottom 2 rows or numbers if you so choose. These are the only 2 acceptable index combinations.The 3 by 3 grid will consist of 3 distinct, printable ASCII characters representing walkable floor, walls, and the player. (In the test cases,
.
is used for floor,#
s are walls, and@
is the player)- You may choose what characters your program uses, but you must state them in your answer and they must be consistent over multiple trials.
- The character representing the character will always be in the middle of the 3 by 3 grid, and the direction will always be between 1 and 9 (incl.)
- You may take input in any order
- The 3 by 3 grid can be input as a char array, a string array, a 9 length string, or another reasonable alternative.
Output
- Return from a function, or output to StdOut or closest alternative
- Trailing spaces and newlines are allowed
- You must use the same character representations as the input
- The same formats allowed for inputs are allowed for outputs
How the player moves
If the specified direction is blocked by a wall (e.g. if the above example had direction 6), then look at the 2 closest directions:
- If one (and only one) direction is free, move the player in that direction.
- If no directions are free, look at the next closest 2 directions (excluding direction 5). If you have wrapped all the way around and found no open direction (player surrounded by walls), do not move the player
- If both of the directions are open, pick one to move to at random (although not necessarily uniformly).
If the given direction is a 5, do not move the player
Test cases
(#
= wall, .
= floor, @
= player)
Input: 9 #.. .@# #.# Output: #.@ ..# #.# Input: 3 #.. .@# #.# Output: #.. ..# #@# Input: 7 ##. #@# ..# Output: ##@ ##. #.# or #.# ..# @.# Input: 5 ... .@. ... Output: ... .@. ... Input: 2 ### #@# ### Output: ### #@# ###
Scoring
This is code-golf, so the shortest answer in bytes wins.
yuhjklbn
? RIP. \$\endgroup\$123;456;789
instead of789;456;123
? \$\endgroup\$