A while ago I created a small cardgame web app for fun. The player plays against the computer and mostly it works fine. Sometimes though the computer player gets into a loop, the point of the game is to lose all your cards and if you don't have a card to play you take the pile. Sometimes the computer plays x,y,z, takes the pile, plays x,yz, takes the pile etc.
I keep track of the moves I've made, so at any point I have an array that looks something like : [C2,D5,H2,S4,C5,H2,S4,C5,H2,S4,C5]
In this case I can see that I've gotten into a loop of playing H2,S4,C5, then taking the pile and then repeating.
So, the generalized problem is, what's the best way to detect repeating patterns in a list? I could probably whip something up using a simple for loop, trying to find the card I'm about to play and if I find that in position x then I could check whether the pattern from x to n repeats at position x-(n-x) to x, but this seems like the kind of problem that could have a nice algorithm for it. How would you code this given the following function signature:
function findLoops(previousMoves, nextMove, maxPatternLength) {
//Return [loopLength, loopCount] or null if there are no loops
}
p.s. this is not a homework assignment, the game exists and is at http://www.idiot-cardgame.com if anyone is interested :)
First the general question: Your suggested method
trying to find the card I'm about to play and if I find that in position x then I could check whether the pattern from x to n repeats at position x-(n-x) to x,
looks really good. I would suggest basically the same. It is O(n) and needs a fixed amount of storage, and is simple: what else would you wish for?
Second: You can check for repetition in games generally if you keep a hash table of all previous game states (complete state, nothing left out). Everytime you reach a new state look up if it is in the hashtable, if its in it: you game state is looping.
In Javascript you have builtin hastables so this is very easy to do with something similar like this:
new_state = next_move(old_state);
new_encoded_state = encode(new_state); // make it into a string
if (allstates[new_encoded_state]) {
// we are looping!
} else {
allstates[new_encoded_state] = 1;
// no looping
}
The variable allstates
is not an Array but of type Object. You can have array like access with strings and this uses the Object as hastable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With