Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect loops in computer player in a cardgame

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 :)

like image 542
Einar Egilsson Avatar asked Nov 08 '10 07:11

Einar Egilsson


1 Answers

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.

like image 162
Peer Stritzinger Avatar answered Sep 17 '22 15:09

Peer Stritzinger