Mahjong - Arrange tiles to ensure at least one path to victory, regardless of layout - algorithm

Regardless of the layout being used for the tiles, is there any good way to divvy out the tiles so that you can guarantee the user that, at the beginning of the game, there exists at least one path to completing the puzzle and winning the game?
Obviously, depending on the user's moves, they can cut themselves off from winning. I just want to be able to always tell the user that the puzzle is winnable if they play well.
If you randomly place tiles at the beginning of the game, it's possible that the user could make a few moves and not be able to do any more. The knowledge that a puzzle is at least solvable should make it more fun to play.

Place all the tiles in reverse (ie layout out the board starting in the middle, working out)
To tease the player further, you could do it visibly but at very high speed.

Play the game in reverse.
Randomly lay out pieces pair by pair, in places where you could slide them into the heap. You'll need a way to know where you're allowed to place pieces in order to end up with a heap that matches some preset pattern, but you'd need that anyway.

I know this is an old question, but I came across this when solving the problem myself. None of the answers here are quite perfect, and several of them have complicated caveats or will break on pathological layouts. Here is my solution:
Solve the board (forward, not backward) with unmarked tiles. Remove two free tiles at a time. Push each pair you remove onto a "matched pair" stack. Often, this is all you need to do.
If you run into a dead end (numFreeTiles == 1), just reset your generator :) I have found I usually don't hit dead ends, and have so far have a max retry count of 3 for the 10-or-so layouts I have tried. Once I hit 8 retries, I give up and just randomly assign the rest of the tiles. This allows me to use the same generator for both setting up the board, and the shuffle feature, even if the player screwed up and made a 100% unsolvable state.
Another solution when you hit a dead end is to back out (pop off the stack, replacing tiles on the board) until you can take a different path. Take a different path by making sure you match pairs that will remove the original blocking tile.
Unfortunately, depending on the board, this may loop forever. If you end up removing a pair that resembles a "no outlet" road, where all subsequent "roads" are a dead end, and there are multiple dead ends, your algorithm will never complete. I don't know if it is possible to design a board where this would be the case, but if so, there is still a solution.
To solve that bigger problem, treat each possible board state as a node in a DAG, with each selected pair being an edge on that graph. Do a random traversal, until you find a leaf node at depth 72. Keep track of your traversal history so that you never repeat a descent.
Since dead ends are more rare than first-try solutions in the layouts I have used, what immediately comes to mind is a hybrid solution. First try to solve it with minimal memory (store selected pairs on your stack). Once you've hit the first dead end, degrade to doing full marking/edge generation when visiting each node (lazy evaluation where possible).
I've done very little study of graph theory, though, so maybe there's a better solution to the DAG random traversal/search problem :)
Edit: You actually could use any of my solutions w/ generating the board in reverse, ala the Oct 13th 2008 post. You still have the same caveats, because you can still end up with dead ends. Generating a board in reverse has more complicated rules, though. E.g, you are guaranteed to fail your setup if you don't start at least SOME of your rows w/ the first piece in the middle, such as in a layout w/ 1 long row. Picking a completely random (legal) first move in a forward-solving generator is more likely to lead to a solvable board.

The only thing I've been able to come up with is to place the tiles down in matching pairs as kind of a reverse Mahjong Solitaire game. So, at any point during the tile placement, the board should look like it's in the middle of a real game (ie no tiles floating 3 layers up above other tiles).
If the tiles are place in matching pairs in a reverse game, it should always result in at least one forward path to solve the game.
I'd love to hear other ideas.

I believe the best answer has already been pushed up: creating a set by solving it "in reverse" - i.e. starting with a blank board, then adding a pair somewhere, add another pair in a solvable position, and so on...
If you a prefer "Big Bang" approach (generating the whole set randomly at the beginning), are a very macho developer or just feel masochistic today, you could represent all the pairs you can take out from the given set and how they depend on each other via a directed graph.
From there, you'd only have to get the transitive closure of that set and determine if there's at least one path from at least one of the initial legal pairs that leads to the desired end (no tile pairs left).
Implementing this solution is left as an exercise to the reader :D

Here are rules i used in my implementation.
When buildingheap, for each fret in a pair separately, find a cells (places), which are:
has all cells at lower levels already filled
place for second fret does not block first, considering if first fret already put onboard
both places are "at edges" of already built heap:
EITHER has at least one neighbour at left or right side
OR it is first fret in a row (all cells at right and left are recursively free)
These rules does not guarantee a build will always successful - it sometimes leave last 2 free cells self-blocking, and build should be retried (or at least last few frets)
In practice, "turtle" built in no more then 6 retries.
Most of existed games seems to restrict putting first ("first on row") frets somewhere in a middle. This come up with more convenient configurations, when there are no frets at edges of very long rows, staying up until last player moves. However, "middle" is different for different configurations.
Good luck :)
P.S.
If you've found algo that build solvable heap in one turn - please let me know.

You have 144 tiles in the game, each of the 144 tiles has a block list..
(top tile on stack has an empty block list)
All valid moves require that their "current__vertical_Block_list" be empty.. this can be a 144x144 matrix so 20k of memory plus a LEFT and RIGHT block list, also 20 k each.
Generate a valid move table from (remaning_tiles) AND ((empty CURRENT VERTICAL BLOCK LIST) and ((empty CURRENT LEFT BLOCK LIST) OR (empty CURRENT RIGHT BLOCK LIST)))
Pick 2 random tiles from the valid move table, record them
Update the (current tables Vert, left and right), record the Tiles removed to a stack
Now we have a list of moves that constitute a valid game. Assign matching tile types to each of the 72 moves.
for challenging games, track when each tile becomes available. find sets that have are (early early early late) and (late late late early) since it's blank, you find 1 EE 1 LL and 2 LE blocks.. of the 2 LE block, find an EARLY that blocks ANY other EARLY that (except rightblocking a left side piece)
Once youve got a valid game play around with the ordering.

Solitaire? Just a guess, but I would assume that your computer would need to beat the game(or close to it) to determine this.
Another option might be to have several preset layouts(that allow winning, mixed in with your current level.
To some degree you could try making sure that one of the 4 tiles is no more than X layers below another X.
Most games I see have the shuffle command for when someone gets stuck.
I would try a mix of things and see what works best.

Related

How to map out a maze as a robot?

First - I've looked through similar looking questions but they did not solve my problem, this is no repetition (I hope).
I'm building and programming a robot with an Arduino Nano that is supposed to solve a maze. It gets put somewhere in the maze and then has to find an item. The next time it is supposed to go straight to the item (it does not have to be the shortest way but no dead ends allowed).
It is not necessary to know the whole maze because as long as he has one way to the item it is good. As I said, I don't need the shortest way.
The maze is 2D, I just put black tape on a white table and the robot is supposed to use a line sensor to follow the lines.
There are no other sensors to orientate himself. First I thought of making an 2D array and each field of the maze a field in there. But since it's just a normal line sensor the robot doesn't know if a straight line is one or two fields long and the whole thing does not work.
I also tried DFS or something like that but a similar problem here. The maze is circular and how is the robot supposed to know the Node was already found before and it is the same?
It would be nice if anyone had an idea!
Although orientation is a little bit fuzzy it is possible by using the decisions. A decision has to be reproducable. It could be represented by a class:
public class Decision {
boolean[] directions = new boolean[2]; // 0 = left, 1 = straight, 2 = right
// at least 2 of them should be true or it is no decision
int path; // 0-2 to mark the current path
}
Create a stack of decisions.
If there is only one possible direction at the beginning (back doesn't count and is treated later), then move forward until you meet the first decision.
Push the decision with all possible directions on the stack.
Set path to the first possible direction and move that way.
If you end up with another decision: continue at 3.
If you find the token: abort, you found a reproducible way without dead-ends.
If it is a dead-end: return to the previous decision node (the first one one the way back) and continue with 6.
Pop the decision and try the next possible direction (set the new path and push the decision) and continue at 5.
Unless you have tried all directions, then move back another decision and continue with 6.
If there are no more decisions (the special case mentioned above, we went in the wrong direction at the beginning): move forward until you meet the first decision and continue at 3. This means you need another boolean variable to indicate if you should go backwards right at the beginning.
You have to be careful when coming back from left and want to try straight next you would have to turn left and don't go straight. So there is a little calculation involved.
The algorithm has a problem for loop shaped decisions if you start the wrong way at the beginning. I think this could be escaped by setting an upper boundary, e.g. if you still haven't found the token and met 30 decision nodes (going forward), then you are probably running in circles, so go back to start and now instead of trying the directions in increasing order, try them in decreasing order.

Dots and boxes, even chains for 1st player, suggest move

I got to know that on a board of 3x3 box, player 1 should try to make even number of long chains. (long chain is a chain of length 3 or more). source
To summarize: (credit)
I need an even number of chains
I am player one, as an even number of moves has been made, and there are an even number of dots.
(This is known as the chain rule, and anyone who is unfamiliar with it should learn it as it is a key to winning dots and boxes. The number of squares already in chains means the winner of the chains battle in this game wins the majority of the squares by sacrificing two at the end of each of the chains they are given.)
I have been trying to play the game on this site but have been unable to win so far.
Attaching the board configuration when I got an even number of chains and its my turn to move.
What should be my move?
Can you give a winning strategy against the bot on this site?
What am I missing here? It seems to me that even though I got even number of long chains, no matter what move I make I will end up losing.
I didn't follow the YouTube link (readable text preferred) and don't know about the long chains. E.g., shouldn't we treat cycles differently from paths?
Still, in the given position, you can move anywhere on the right, giving the three right squares to your opponent and then taking the remaining six squares after his move.

Is there a way to avoid unnecessary recursion?

I posted this question over at CodeReview, but I came to realize that it's not so much a Haskell question as it is an algorithm question.
The Haskell code can be found on my github repo but I think the code isn't as important as the general concept.
Basically the program figures out the optimal first set of moves in a game of Kalaha (the Swedish variation). Only the first "turn" is considered, so we assume that you get to start and that anything from the point of the opponent getting to move is not computed.
Kalaha board http://www.graf-web.at/mwm/kalaha.jpg
The board starts off with empty stores and a equal amount of marbles in each pot.
You start your turn by choosing a non-empty pot on your side, pick all of the marbles up from that pot and then move around the board by dropping one marble when passing a pot. If your last marble lands in the store, you get another turn. If you land in a non-empty, non-store pot, you pick up all of the contents of that pot and continue. Finally, if you land in an empty pot, the turn is passed to the opponent.
So far I've solved this by picking all possible paths and then sorting them according to the amount of marbles in the store by the end. A path would mean to start from one of your pots, do all the necessary pick-up-and-move-around and see if you either land in a store or in an empty pot. If you land in the store you get to continue, and now there are as many new branches as there are non-empty pots on your side.
The problem lies in the fact that if you start with five marbles in the pots, it's already quite a few paths. Jump up to six and ghci runs out of memory.
The reason I can't figure out how to make this less expensive is because I think that each path is necessary during computation. While I'll only need at most three paths (the best ones) out of the thousands (or millions) generated, the rest need to be run through to see if they're actually better than the previous ones.
If one is longer (generally better) then that's good but costly. If it's shorter than any previous path, then program still had to compute that path to find that out.
Is there any way around this, or is computing all the paths necessary by definition?
Just try them all out in order, recording your sequences of moves as sequences of numbers 1 through 6 (representing the pot that you pick the marbles from), each time replaying the whole sequence from the start. Keep and update just the three winners, plus the very last sequence of moves so you'd know what to try next. If there's no next legal moves, go back one notch.
It's going to be prohibitively slow perhaps, but will use very little memory. You don't store resulting positions, only numbers of pots picked from, and replay the sequence anew each time from the starting position, altering the very last move (instead of 2, next try 3, 4 etc.; if no more legal moves, backtrack one level). Or maybe store positions just for the very last sequence of moves tried, for easier backtracking.
It's a typical space for speed trade-of then.
You could try parallellizing using this parallel version of map:
parMap :: (a -> b) -> [a] -> Eval [b]
parMap f xs = map f xs `using` parList rseq
Then you will spark off a new thread for each choise in your branch.
if you use as parMap pathFunction kalahaPots as your recursion, it will spark a lot of threads, but it might be faster, you could chunk it but i'm not that good of a parallell haskeller.

Predator-prey simulation

I'm trying to implement a model of predator-prey.
It is agent-based model. Every few milliseconds is a new move. On the field there are two types of creatures: predator and prey. The behavior of each of them is given by the following rules:
Prey:
Just moved to an unoccupied cell
Every few steps creates offspring to his old cell
Life expectancy is limited by the number of moves
Predator:
Predator moves to the cell with prey. If such cells are not, in any
free neighboring cell
Same
Same
I have a problem with the choice of prey move.
For example, I have preys in cells 5 and 9.
Each of them can move to cell 6.
How can I resolve this conflict?
Thanks
Use asynchronous updating. Iterate through the prey in random order, having them decide in turn to which cell they should move.
This is a common approach in simulations. It has an additional benefit in that it eliminates limit cycles in the dynamics.
How long does 'moving' take? If you move one, then after the prey has moved, you move the next one, there is no conflict. The prey will simply see the space is already occupied and move elsewhere.
If moving takes time you might say the prey keep an eye on each other and see if some other prey is trying to move somewhere (like people watch cars in traffic). Then you would change the status of the target field to 'reserved for 5' when prey from 5 is trying to move there. Then prey from 9 can see this and decide if they want to collide with 5 (could be intresting :P) or avoid 5.
Depends on game logic. If preys can be on the same cell, so simply use indicator that show preys count. If you are using 2D array for representing current field state you can use such codes:
-1 - predator
n - preys
n >= 0, (n = 0 - cell is empty, n = 1 cell contains 1 prey and so on).
Otherwise (if preys can't appear on the same cell) use turn-based strategy. Save all your preys in array or give number to each prey. In that case preys' moves represents by simple loop (pseudocode):
for each prey in preys
move(prey)
end
where move logic describes algorithm how your prey moves.
Quite a few ways, depending on if you're deciding & moving as two steps or one, etc:
Keep track of each prey's intended moves, and prevent other prey from occupying those.
Check if another prey is already occupying the destination, and do nothing if so.
Remove one of the preys at random if they both try to occupy the same location.
Re-evaluate the move options if the destination is occupied.
There's not really a 'right' way to do it.
See this related question and my answer.
It describes a good collision detection mechanism.
Avoid O(n^2) complexity for collision detection

Optimizing Conway's 'Game of Life'

To experiment, I've (long ago) implemented Conway's Game of Life (and I'm aware of this related question!).
My implementation worked by keeping 2 arrays of booleans, representing the 'last state', and the 'state being updated' (the 2 arrays being swapped at each iteration). While this is reasonably fast, I've often wondered about how to optimize this.
One idea, for example, would be to precompute at iteration N the zones that could be modified at iteration (N+1) (so that if a cell does not belong to such a zone, it won't even be considered for modification at iteration (N+1)). I'm aware that this is very vague, and I never took time to go into the details...
Do you have any ideas (or experience!) of how to go about optimizing (for speed) Game of Life iterations?
I am going to quote my answer from the other question, because the chapters I mention have some very interesting and fine-tuned solutions. Some of the implementation details are in c and/or assembly, yes, but for the most part the algorithms can work in any language:
Chapters 17 and 18 of
Michael Abrash's Graphics
Programmer's Black Book are one of
the most interesting reads I have ever
had. It is a lesson in thinking
outside the box. The whole book is
great really, but the final optimized
solutions to the Game of Life are
incredible bits of programming.
There are some super-fast implementations that (from memory) represent cells of 8 or more adjacent squares as bit patterns and use that as an index into a large array of precalculated values to determine in a single machine instruction if a cell is live or dead.
Check out here:
http://dotat.at/prog/life/life.html
Also XLife:
http://linux.maruhn.com/sec/xlife.html
You should look into Hashlife, the ultimate optimization. It uses the quadtree approach that skinp mentioned.
As mentioned in Arbash's Black Book, one of the most simple and straight forward ways to get a huge speedup is to keep a change list.
Instead of iterating through the entire cell grid each time, keep a copy of all the cells that you change.
This will narrow down the work you have to do on each iteration.
The algorithm itself is inherently parallelizable. Using the same double-buffered method in an unoptimized CUDA kernel, I'm getting around 25ms per generation in a 4096x4096 wrapped world.
what is the most efficient algo mainly depends on the initial state.
if the majority of cells is dead, you could save a lot of CPU time by skipping empty parts and not calculating stuff cell by cell.
im my opinion it can make sense to check for completely dead spaces first, when your initial state is something like "random, but with chance for life lower than 5%."
i would just divide the matrix up into halves and start checking the bigger ones first.
so if you have a field of 10,000 * 10,000, you´d first accumulate the states of the upper left quarter of 5,000 * 5,000.
and if the sum of states is zero in the first quarter, you can ignore this first quarter completely now and check the upper right 5,000 * 5,000 for life next.
if its sum of states is >0, you will now divide up the second quarter into 4 pieces again - and repeat this check for life for each of these subspaces.
you could go down to subframes of 8*8 or 10*10 (not sure what makes the most sense here) now.
whenever you find life, you mark these subspaces as "has life".
only spaces which "have life" need to be divided into smaller subspaces - the empty ones can be skipped.
when you are finished assigning the "has life" attribute to all possible subspaces, you end up with a list of subspaces which you now simply extend by +1 to each direction - with empty cells - and perform the regular (or modified) game of life rules to them.
you might think that dividn up a 10,000*10,000 spae into subspaces of 8*8 is a lot os tasks - but accumulating their states values is in fact much, much less computing work than performing the GoL algo to each cell plus their 8 neighbours plus comparing the number and storing the new state for the net iteration somewhere...
but like i said above, for a random init state with 30% population this wont make much sense, as there will be not many completely dead 8*8 subspaces to find (leave alone dead 256*256 subpaces)
and of course, the way of perfect optimisation will last but not least depend on your language.
-110
Two ideas:
(1) Many configurations are mostly empty space. Keep a linked list (not necessarily in order, that would take more time) of the live cells, and during an update, only update around the live cells (this is similar to your vague suggestion, OysterD :)
(2) Keep an extra array which stores the # of live cells in each row of 3 positions (left-center-right). Now when you compute the new dead/live value of a cell, you need only 4 read operations (top/bottom rows and the center-side positions), and 4 write operations (update the 3 affected row summary values, and the dead/live value of the new cell). This is a slight improvement from 8 reads and 1 write, assuming writes are no slower than reads. I'm guessing you might be able to be more clever with such configurations and arrive at an even better improvement along these lines.
If you don't want anything too complex, then you can use a grid to slice it up, and if that part of the grid is empty, don't try to simulate it (please view Tyler's answer). However, you could do a few optimizations:
Set different grid sizes depending on the amount of live cells, so if there's not a lot of live cells, that likely means they are in a tiny place.
When you randomize it, don't use the grid code until the user changes the data: I've personally tested randomizing it, and even after a long amount of time, it still fills most of the board (unless for a sufficiently small grid, at which point it won't help that much anymore)
If you are showing it to the screen, don't use rectangles for pixel size 1 and 2: instead set the pixels of the output. Any higher pixel size and I find it's okay to use the native rectangle-filling code. Also, preset the background so you don't have to fill the rectangles for the dead cells (not live, because live cells disappear pretty quickly)
Don't exactly know how this can be done, but I remember some of my friends had to represent this game's grid with a Quadtree for a assignment. I'm guess it's real good for optimizing the space of the grid since you basically only represent the occupied cells. I don't know about execution speed though.
It's a two dimensional automaton, so you can probably look up optimization techniques. Your notion seems to be about compressing the number of cells you need to check at each step. Since you only ever need to check cells that are occupied or adjacent to an occupied cell, perhaps you could keep a buffer of all such cells, updating it at each step as you process each cell.
If your field is initially empty, this will be much faster. You probably can find some balance point at which maintaining the buffer is more costly than processing all the cells.
There are table-driven solutions for this that resolve multiple cells in each table lookup. A google query should give you some examples.
I implemented this in C#:
All cells have a location, a neighbor count, a state, and access to the rule.
Put all the live cells in array B in array A.
Have all the cells in array A add 1 to the neighbor count of their
neighbors.
Have all the cells in array A put themselves and their neighbors in array B.
All the cells in Array B Update according to the rule and their state.
All the cells in Array B set their neighbors to 0.
Pros:
Ignores cells that don't need to be updated
Cons:
4 arrays: a 2d array for the grid, an array for the live cells, and an array
for the active cells.
Can't process rule B0.
Processes cells one by one.
Cells aren't just booleans
Possible improvements:
Cells also have an "Updated" value, they are updated only if they haven't
updated in the current tick, removing the need of array B as mentioned above
Instead of array B being the ones with live neighbors, array B could be the
cells without, and those check for rule B0.

Resources