Any tips or idea how to play this combinatorial game?

150 Views Asked by At

There is this puzzle called Chomp. You can play and read about it here if you don't know it:

https://www.math.ucla.edu/~tom/Games/chomp.html

enter image description here

It is well-known that Chomp has a winning strategy for the first player, except for the case of $1*1$. The proof is brilliant, but it is non-constructive, using a strategy-stealing argument.

Imagine you are playing it with friends, who don't know about the winning strategy. He can be the first player, but he doesn't necessarily play the best move. Then, how should you respond? Is there a good strategy/heuristic to help us win?

1

There are 1 best solutions below

2
On BEST ANSWER

I haven't analyzed it for the strategy, but the page source on your link has the java script it uses to find moves:

var c=7;                //c = # columns.  Require 6 <= c <= 10.
var x,y;
var ppos=[1,12,23,34,45,56,113,122,224,235,246,336,355,1114,1125,1133,1222,2226,2255,2335];
    //perfect play for c=7 is achieved by adding 
    //67,257,347,477,2237,2357,2447,3377,3457,4557 to ppos. 
    //but ppos must be arranged in increasing order. 
    //For c=8, add 78,268,448,2248,2368,2458,2588,3338.
var n = [];
var box = [];

for (var i=1;i<=4;i++) {
    box[i]=[];
}

function yourChoice(u,v) {
    if (box[u][v]==1) {
        Move(u,v);
        encode();
        if (n[1]+n[2]==1) {
           alert("Good work!\n You won!");
           return;
        }
        x=findMove();
        Move(x,y+1);
        if (box[1][2]+box[2][1]==0) alert("Nice try,\n but I won!");
    }    
}

function Move(x,y) {
    for (var k1=x;k1<=4;k1++) {
        for (var k2=y;k2<=c;k2++) {
            document.images[(4-k1)*c+k2-1].src=blank;
            box[k1][k2]=0;
        }
    }
}

function encode() {               //maps position into n[1],n[2],n[3],n[4]
    for (var i=1;i<5;i++) {
        n[i]=0;
        for (var j=1;j<=c;j++) {
            n[i]=n[i]+box[i][j];
        }
    }
    n[1]=n[1]+1;
}

function findMove() {
    var t=10
    var k=ppos.length-1;
    for (y=n[1]-1;y>=n[2];y--) {
        val=y+t*(n[2]+t*(n[3]+t*n[4]));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 1};
    }
    for (y=n[2]-1;y>=n[3];y--) {
        val=n[1]+t*(y+t*(n[3]+t*n[4]));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 2};
        val=y+t*(y+t*(n[3]+t*n[4]));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 1};
    }
    for (y=n[3]-1;y>=n[4];y--) {
        val=n[1]+t*(n[2]+t*(y+t*n[4]));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 3};
        val=n[1]+t*(y+t*(y+t*n[4]));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 2};
        val=y+t*(y+t*(y+t*n[4]));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 1};
    }
    for (y=n[4]-1;y>=0;y--) {
        val=n[1]+t*(n[2]+t*(n[3]+t*y));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 4};
        val=n[1]+t*(n[2]+t*(y+t*y));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 3};
        val=n[1]+t*(y+t*(y+t*y));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 2};
        val=y+t*(y+t*(y+t*y));
        while (val<ppos[k]) k--;
        if (val==ppos[k]) {return 1};
    }
   if ((Math.random()>.4) && (n[4]>0)) {
       y=n[4]-1;
       return 4;
   } else if ((Math.random()>.5) && (n[3]>0)) {
       y=n[3]-1;
       return 3;
   } else if ((Math.random()>.67) && (n[2]>0)) {
       y=n[2]-1;
       return 2;
   } else {
       y=n[1]-1;
       return 1;
   }
}

Edit: Here are the winning 4 by 7 positions encoded or mentioned in the comment: