%playgame.m       WCR 2012-12-25
%play a game with 14 marbles on 15 spots.
%One-player game. Goal is to make moves until only 1 marble is left and it
%is in the position that was originally unoccupied.
resultsfilespec=input('File name for saving results: ','s');
f1=fopen(resultsfilespec,'at');
fprintf(f1,['playgame at ',datestr(now),'\n']);
outcomes=zeros(14,1);
numgames=88890000;
tic
for n=1:numgames
  m=[1 1 1 1 0 1 1 1 1 1 1 1 1 1 1]; %initial occupancy of sites
  moved=true;
  nummoves=0;
  allmovestr='';
  while moved
      moved=false;
      nottriedyet=m; %marbles not tested yet on this round
      while ((sum(nottriedyet)>0)&&~moved)
          i=randi(sum(nottriedyet));
          ind1=find(nottriedyet);  %indices of non-zero elements of nottriedyet()
          marbletotry=ind1(i);
          %fprintf('Try m%.0f. ',marbletotry);
          nottriedyet(marbletotry)=0;
          moveoptions=[0 0 0 0];
          movestr='';
          switch marbletotry 
              case 1
                  if (m(2)&&~m(4)), moveoptions(1)=1; end
                  if (m(3)&&~m(6)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(2)=0; m(4)=1;
                          movestr=[num2str(marbletotry),'>4\n'];
                      elseif movetomake==2
                          m(3)=0; m(6)=1;
                          movestr=[num2str(marbletotry),'>6\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 2
                  if (m(4)&&~m(7)), moveoptions(1)=1; end
                  if (m(5)&&~m(9)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(4)=0; m(7)=1;
                          movestr=[num2str(marbletotry),'>7\n'];
                      elseif movetomake==2
                          m(5)=0; m(9)=1;
                          movestr=[num2str(marbletotry),'>9\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 3
                  if (m(5)&&~m(8)), moveoptions(1)=1; end
                  if (m(6)&&~m(10)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(5)=0; m(8)=1;
                          movestr=[num2str(marbletotry),'>8\n'];
                      elseif movetomake==2
                          m(6)=0; m(10)=1;
                          movestr=[num2str(marbletotry),'>10\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 4
                  if (m(2)&&~m(1)), moveoptions(1)=1; end
                  if (m(5)&&~m(6)), moveoptions(2)=1; end
                  if (m(8)&&~m(13)), moveoptions(3)=1; end
                  if (m(7)&&~m(11)), moveoptions(4)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(2)=0; m(1)=1;
                          movestr=[num2str(marbletotry),'>1\n'];
                      elseif movetomake==2
                          m(5)=0; m(6)=1;
                          movestr=[num2str(marbletotry),'>6\n'];
                      elseif movetomake==3
                          m(8)=0; m(13)=1;
                          movestr=[num2str(marbletotry),'>13\n'];
                      elseif movetomake==4
                          m(7)=0; m(11)=1;
                          movestr=[num2str(marbletotry),'>11\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 5
                  if (m(8)&&~m(12)), moveoptions(1)=1; end
                  if (m(9)&&~m(14)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(8)=0; m(12)=1;
                          movestr=[num2str(marbletotry),'>12\n'];
                      elseif movetomake==2
                          m(9)=0; m(14)=1;
                          movestr=[num2str(marbletotry),'>14\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 6
                  if (m(3)&&~m(1)), moveoptions(1)=1; end
                  if (m(5)&&~m(4)), moveoptions(2)=1; end
                  if (m(9)&&~m(13)), moveoptions(3)=1; end
                  if (m(10)&&~m(15)), moveoptions(4)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(3)=0; m(1)=1;
                          movestr=[num2str(marbletotry),'>1\n'];
                      elseif movetomake==2
                          m(5)=0; m(4)=1;
                          movestr=[num2str(marbletotry),'>4\n'];
                      elseif movetomake==3
                          m(9)=0; m(13)=1;
                          movestr=[num2str(marbletotry),'>13\n'];
                      elseif movetomake==4
                          m(10)=0; m(15)=1;
                          movestr=[num2str(marbletotry),'>15\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 7
                  if (m(4)&&~m(2)), moveoptions(1)=1; end
                  if (m(8)&&~m(9)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(4)=0; m(2)=1;
                          movestr=[num2str(marbletotry),'>2\n'];
                      elseif movetomake==2
                          m(8)=0; m(9)=1;
                          movestr=[num2str(marbletotry),'>9\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 8
                  if (m(5)&&~m(3)), moveoptions(1)=1; end
                  if (m(9)&&~m(10)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(5)=0; m(3)=1;
                          movestr=[num2str(marbletotry),'>3\n'];
                      elseif movetomake==2
                          m(9)=0; m(10)=1;
                          movestr=[num2str(marbletotry),'>1\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 9
                  if (m(8)&&~m(7)), moveoptions(1)=1; end
                  if (m(5)&&~m(2)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(8)=0; m(7)=1;
                          movestr=[num2str(marbletotry),'>7\n'];
                      elseif movetomake==2
                          m(5)=0; m(2)=1;
                          movestr=[num2str(marbletotry),'>2\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 10
                  if (m(6)&&~m(3)), moveoptions(1)=1; end
                  if (m(9)&&~m(8)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(6)=0; m(3)=1;
                          movestr=[num2str(marbletotry),'>3\n'];
                      elseif movetomake==2
                          m(9)=0; m(8)=1;
                          movestr=[num2str(marbletotry),'>8\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 11
                  if (m(7)&&~m(4)), moveoptions(1)=1; end
                  if (m(12)&&~m(13)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(7)=0; m(4)=1;
                          movestr=[num2str(marbletotry),'>4\n'];
                      elseif movetomake==2
                          m(12)=0; m(13)=1;
                          movestr=[num2str(marbletotry),'>13\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 12
                  if (m(8)&&~m(5)), moveoptions(1)=1; end
                  if (m(13)&&~m(14)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(8)=0; m(5)=1;
                          movestr=[num2str(marbletotry),'>5\n'];
                      elseif movetomake==2
                          m(13)=0; m(14)=1;
                          movestr=[num2str(marbletotry),'>14\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 13
                  if (m(8)&&~m(4)), moveoptions(1)=1; end
                  if (m(9)&&~m(6)), moveoptions(2)=1; end
                  if (m(12)&&~m(11)), moveoptions(3)=1; end
                  if (m(14)&&~m(15)), moveoptions(4)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(8)=0; m(4)=1;
                          movestr=[num2str(marbletotry),'>4\n'];
                      elseif movetomake==2
                          m(9)=0; m(6)=1;
                          movestr=[num2str(marbletotry),'>6\n'];
                      elseif movetomake==3
                          m(12)=0; m(11)=1;
                          movestr=[num2str(marbletotry),'>11\n'];
                      elseif movetomake==4
                          m(14)=0; m(15)=1;
                          movestr=[num2str(marbletotry),'>15\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 14
                  if (m(9)&&~m(5)), moveoptions(1)=1; end
                  if (m(13)&&~m(12)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(9)=0; m(5)=1;
                          movestr=[num2str(marbletotry),'>5\n'];
                      elseif movetomake==2
                          m(13)=0; m(12)=1;
                          movestr=[num2str(marbletotry),'>12\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
              case 15
                  if (m(10)&&~m(6)), moveoptions(1)=1; end
                  if (m(14)&&~m(13)), moveoptions(2)=1; end
                  if sum(moveoptions)>0
                      j=randi(sum(moveoptions));
                      ind2=find(moveoptions);
                      movetomake=ind2(j);
                      m(marbletotry)=0;
                      if movetomake==1
                          m(10)=0; m(6)=1;
                          movestr=[num2str(marbletotry),'>6\n'];
                      elseif movetomake==2
                          m(14)=0; m(13)=1;
                          movestr=[num2str(marbletotry),'>13\n'];
                      end
                      moved=true;
                      nummoves=nummoves+1;
                  end
          end
          %fprintf(movestr);
          if moved
              allmovestr=[allmovestr,',',movestr(1:length(movestr)-2)];
          end
      end
  end
  marblesleft=sum(m);
  outcomes(marblesleft)=outcomes(marblesleft)+1;
  %fprintf('\nGame %0d: %.0f moves; %0d marbles left.\n',n,nummoves,marblesleft);
  if marblesleft==1
      fprintf(f1,'G%0d %s\n',n,allmovestr(2:end));
  end
  if mod(n,100000)==0, fprintf('%d ',n); end
end
toc;
fprintf('\n');
fprintf(f1,'Outcomes: %0d %0d %0d %0d %0d %0d %0d %0d %0d %0d %0d %0d %0d %0d\n',outcomes);
fclose(f1);
