SHARE
TWEET

Untitled

a guest Nov 14th, 2019 109 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <HTML>
  3. <HEAD>
  4. <META NAME="description" content="Hnefatafl written in HTML and JavaScript by adapting the code of Checkers">
  5. <META NAME="author" content="Lutz Tautenhahn">
  6. <META NAME="keywords" content="Hnefatafl, Tablut, JavaScript">
  7. <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
  8. <title>Hnefatafl</title>
  9. <script language="JavaScript">
  10. var i, j, k, Start, Start0=true, MoveCount, MaxMoveCount, MaxMove=490, MaxSize=11, Size=9;
  11. var I_Sel0, J_Sel0, I_Sel1, J_Sel1, IsOver=true, Center, Rand=0;
  12. IsPlayer = new Array(2);
  13. IsPlayer[0]=1;
  14. IsPlayer[1]=0;
  15. Fld = new Array(MaxSize);
  16. for (i=0; i < MaxSize; i++)
  17.   Fld[i]=new Array(MaxSize);
  18. for (i=0; i < MaxSize; i++)
  19. { for (j=0; j < MaxSize; j++)
  20.     Fld[i][j]=new Array(2);
  21. }
  22. King = new Array(2);
  23. for (i=0; i<2; i++)
  24.   King[i]=new Array(2);
  25. History=new Array(MaxMove);
  26. for (i=0; i<MaxMove; i++) History[i]=new Array();
  27. Pic= new Array(5);
  28. for (i=0; i<5; i++)
  29.   Pic[i]=new Array(2);
  30. for (i=0; i<5; i++)
  31. { for (j=0; j<2; j++)
  32.   { Pic[i][j] = new Image();
  33.     Pic[i][j].src = "hnefatafl"+i+j+".gif";
  34.   }
  35. }
  36. Transparent=new Image();
  37. if (document.layers)
  38.   Transparent.src="hnefatafln4.gif";
  39. else
  40.   Transparent.src="transparent.gif";
  41.  
  42. function Init()
  43. { var ii, jj, dd=1;
  44.   if (Size==11) dd=2;
  45.   if (Start0) Start=0;
  46.   else Start=1;
  47.   Rand=1-Rand;
  48.   MoveCount=0;
  49.   MaxMoveCount=0;
  50.   Center=(Size-1)/2;
  51.   for (ii=0; ii < Size; ii++)
  52.   { for (jj=0; jj < Size; jj++)
  53.       Fld[ii][jj][0]=-1;
  54.   }
  55.   for (ii=Center-dd; ii<=Center+dd; ii++)
  56.   { Fld[0][ii][0]=0;
  57.     Fld[Size-1][ii][0]=0;
  58.     Fld[ii][0][0]=0;
  59.     Fld[ii][Size-1][0]=0;
  60.   }
  61.   Fld[1][Center][0]=0;
  62.   Fld[Size-2][Center][0]=0;
  63.   Fld[Center][1][0]=0;
  64.   Fld[Center][Size-2][0]=0;
  65.  
  66.   if (Size==11)
  67.   { if (Rand==0)
  68.     { for (ii=Center-1; ii<=Center+1; ii++)
  69.       { for (jj=Center-1; jj<=Center+1; jj++)
  70.           Fld[ii][jj][0]=1;
  71.       }
  72.     }
  73.     else
  74.     { Fld[Center-3][Center][0]=1;
  75.       Fld[Center+3][Center][0]=1;
  76.       Fld[Center][Center-3][0]=1;
  77.       Fld[Center][Center+3][0]=1;
  78.     }
  79.   }
  80.   for (ii=Center-2; ii<=Center+2; ii++)
  81.   { Fld[ii][Center][0]=1;
  82.     Fld[Center][ii][0]=1;
  83.   }  
  84.   Fld[Center][Center][0]=2;
  85.   King[0][0]=Center;
  86.   King[1][0]=Center;
  87.   I_Sel0=-1; J_Sel0=-1;
  88.   I_Sel1=-1; J_Sel1=-1;
  89.   IsOver=false;
  90.   RefreshScreen();
  91.   window.document.OptionsForm.Moves.value=" 0 ";
  92. }
  93. function SetSize(ss)
  94. { Size=parseInt(ss);
  95.   Init();
  96. }
  97. function SetPlayer(nn, mm)
  98. { IsPlayer[nn]=mm;
  99. }
  100. function SetStart0(bb)
  101. { Start0=bb;
  102. }
  103. function Timer()
  104. { if (IsOver) return;
  105.   var mm=(MoveCount+Start)%2;
  106.   if (I_Sel1>=0) { MakeMove(); return; }
  107.   if (IsPlayer[mm]) return;
  108.   GetBestMove(mm);
  109.   if (I_Sel0>=0) RefreshFld(I_Sel0, J_Sel0);
  110. }
  111.  
  112. function Back()
  113. { if (MoveCount==0) return;
  114.   if (I_Sel1>=0) return;
  115.   IsOver=false;
  116.   MoveCount--;
  117.   var nn, mm, ii, jj;
  118.   ii=History[MoveCount][0];
  119.   jj=History[MoveCount][1];
  120.   nn=History[MoveCount][2];
  121.   mm=History[MoveCount][3];    
  122.   Fld[ii][jj][0]=Fld[nn][mm][0];
  123.   Fld[nn][mm][0]=-1;
  124.   if (Fld[ii][jj][0]==2)
  125.   { King[0][0]=ii;
  126.     King[1][0]=jj;
  127.   }
  128.   for (nn=4; nn<History[MoveCount].length; nn+=3)
  129.   { ii=History[MoveCount][nn];
  130.     jj=History[MoveCount][nn+1];
  131.     Fld[ii][jj][0]=History[MoveCount][nn+2];
  132.   }
  133.   RefreshScreen();
  134. }
  135. function Replay()
  136. { if (I_Sel1>=0) return;
  137.   if (MoveCount<MaxMoveCount)
  138.   { I_Sel0=History[MoveCount][0];
  139.     J_Sel0=History[MoveCount][1];
  140.     I_Sel1=History[MoveCount][2];
  141.     J_Sel1=History[MoveCount][3];    
  142.     MakeMove();
  143.   }
  144. }
  145.  
  146. function GetBestMove(cc)
  147. { var ii, jj, ii0=-1, jj0, ii1, jj1, kk, vv, cc1=1-cc, vv_best=-10000;
  148.   for (ii=0; ii<Size; ii++)
  149.   { for (jj=0; jj<Size; jj++)
  150.     { if (Fld[ii][jj][0]==cc)
  151.       { kk=1;
  152.         while (GetFld(ii+kk, jj, 0)==-1)
  153.         { if (!IsHostile(ii+kk, jj))
  154.           { vv=MakeVirtualMove(ii,jj,ii+kk,jj,cc,1);
  155.             if (vv>vv_best)
  156.             { vv_best=vv; ii0=ii; jj0=jj; ii1=ii+kk; jj1=jj;
  157.             }
  158.           }  
  159.           kk++;
  160.         }
  161.         kk=1;
  162.         while (GetFld(ii-kk, jj, 0)==-1)
  163.         { if (!IsHostile(ii-kk, jj))
  164.           { vv=MakeVirtualMove(ii,jj,ii-kk,jj,cc,1);
  165.             if (vv>vv_best)
  166.             { vv_best=vv; ii0=ii; jj0=jj; ii1=ii-kk; jj1=jj;
  167.             }
  168.           }  
  169.           kk++;
  170.         }
  171.         kk=1;
  172.         while (GetFld(ii, jj+kk, 0)==-1)
  173.         { if (!IsHostile(ii, jj+kk))
  174.           { vv=MakeVirtualMove(ii,jj,ii,jj+kk,cc,1);
  175.             if (vv>vv_best)
  176.             { vv_best=vv; ii0=ii; jj0=jj; ii1=ii; jj1=jj+kk;
  177.             }
  178.           }
  179.           kk++;
  180.         }
  181.         kk=1;
  182.         while (GetFld(ii, jj-kk, 0)==-1)
  183.         { if (!IsHostile(ii, jj-kk))
  184.           { vv=MakeVirtualMove(ii,jj,ii,jj-kk,cc,1);
  185.             if (vv>vv_best)
  186.             { vv_best=vv; ii0=ii; jj0=jj; ii1=ii; jj1=jj-kk;
  187.             }
  188.           }
  189.           kk++;
  190.         }    
  191.       }
  192.     }
  193.   }
  194.   if (cc==1)
  195.   { ii=King[0][0];
  196.     jj=King[1][0];
  197.     kk=1;
  198.     while(GetFld(ii+kk, jj, 0)==-1)
  199.     { vv=MakeVirtualMove(ii,jj,ii+kk,jj,cc,1);
  200.       if (vv>vv_best)
  201.       { vv_best=vv; ii0=ii; jj0=jj; ii1=ii+kk; jj1=jj;
  202.       }
  203.       kk++;
  204.     }
  205.     kk=1;
  206.     while(GetFld(ii-kk, jj, 0)==-1)
  207.     { vv=MakeVirtualMove(ii,jj,ii-kk,jj,cc,1);
  208.       if (vv>vv_best)
  209.       { vv_best=vv; ii0=ii; jj0=jj; ii1=ii-kk; jj1=jj;
  210.       }
  211.       kk++;
  212.     }
  213.     kk=1;
  214.     while(GetFld(ii, jj+kk, 0)==-1)
  215.     { vv=MakeVirtualMove(ii,jj,ii,jj+kk,cc,1);
  216.       if (vv>vv_best)
  217.       { vv_best=vv; ii0=ii; jj0=jj; ii1=ii; jj1=jj+kk;
  218.       }
  219.       kk++;
  220.     }
  221.     kk=1;
  222.     while(GetFld(ii, jj-kk, 0)==-1)
  223.     { vv=MakeVirtualMove(ii,jj,ii,jj-kk,cc,1);
  224.       if (vv>vv_best)
  225.       { vv_best=vv; ii0=ii; jj0=jj; ii1=ii; jj1=jj-kk;
  226.       }
  227.       kk++;
  228.     }          
  229.   }
  230.   if (ii0>=0)
  231.   { I_Sel0=ii0;
  232.     J_Sel0=jj0;
  233.     I_Sel1=ii1;
  234.     J_Sel1=jj1;
  235.   }
  236.   else
  237.   { IsOver=true;
  238.     alert("It's a stalemate.");
  239.   }  
  240. }
  241.  
  242. function MakeVirtualMove(ii0,jj0,ii1,jj1,cc,ll)
  243. { var ii, jj, vv=0, kk=0, nn;
  244.   for (ii=0; ii<Size; ii++)
  245.   { for (jj=0; jj<Size; jj++)
  246.       Fld[ii][jj][ll]=Fld[ii][jj][ll-1];
  247.   }
  248.   if (Fld[ii0][jj0][ll]==2)
  249.   { if (IsHostile(ii1, jj1)==2)
  250.       return(1000-Math.random()-ll);
  251.     King[0][ll]=ii1;
  252.     King[1][ll]=jj1;  
  253.   }
  254.   else
  255.   { King[0][ll]=King[0][ll-1];
  256.     King[1][ll]=King[1][ll-1];
  257.   }
  258.   Fld[ii1][jj1][ll]=Fld[ii0][jj0][ll];
  259.   Fld[ii0][jj0][ll]=-1;
  260.   if (cc==0)
  261.   { ii=ii1; jj=jj1;
  262.     if (GetFld(ii1+1,jj1,ll)==2) ii++;
  263.     if (GetFld(ii1,jj1+1,ll)==2) jj++;
  264.     if (GetFld(ii1-1,jj1,ll)==2) ii--;
  265.     if (GetFld(ii1,jj1-1,ll)==2) jj--;
  266.     if ((ii!=ii1)||(jj!=jj1))  
  267.     { if (Math.abs(ii-Center)+Math.abs(jj-Center)==0)
  268.       { if ((Fld[ii-1][jj][ll]==0)&&
  269.             (Fld[ii+1][jj][ll]==0)&&
  270.             (Fld[ii][jj-1][ll]==0)&&
  271.             (Fld[ii][jj+1][ll]==0))
  272.           return(1000-Math.random()-ll);
  273.       }
  274.       else
  275.       { if (Math.abs(ii-Center)+Math.abs(jj-Center)==1)
  276.         { if (Fld[ii-1][jj][ll]==0) kk++;
  277.           if (Fld[ii+1][jj][ll]==0) kk++;
  278.           if (Fld[ii][jj-1][ll]==0) kk++;
  279.           if (Fld[ii][jj+1][ll]==0) kk++;
  280.           if (kk==3) return(1000+Math.random()-ll);
  281.         }
  282.         else
  283.         { if ((GetFld(2*ii-ii1,2*jj-jj1,ll)==0)||(IsHostile(2*ii-ii1,2*jj-jj1)))
  284.             return(1000-Math.random()-ll);
  285.         }      
  286.       }
  287.     }
  288.   }
  289.   if ((GetFld(ii1+1,jj1,ll)==1-cc)&&((sign(GetFld(ii1+2,jj1,ll))==cc)||IsHostile(ii1+2,jj1)))
  290.     Fld[ii1+1][jj1][ll]=-1;
  291.   if ((GetFld(ii1-1,jj1,ll)==1-cc)&&((sign(GetFld(ii1-2,jj1,ll))==cc)||IsHostile(ii1-2,jj1)))
  292.     Fld[ii1-1][jj1][ll]=-1;
  293.   if ((GetFld(ii1,jj1+1,ll)==1-cc)&&((sign(GetFld(ii1,jj1+2,ll))==cc)||IsHostile(ii1,jj1+2)))
  294.     Fld[ii1][jj1+1][ll]=-1;
  295.   if ((GetFld(ii1,jj1-1,ll)==1-cc)&&((sign(GetFld(ii1,jj1-2,ll))==cc)||IsHostile(ii1,jj1-2)))
  296.     Fld[ii1][jj1-1][ll]=-1;
  297. //The computer strength can probably be improved
  298. //by carefully adapting the parameters.
  299.   vv=0;
  300.   ii=King[0][ll];
  301.   kk=0;
  302.   for (jj=0; jj<King[1][ll]; jj++)
  303.   { if (Fld[ii][jj][ll]>=0) kk++; }
  304.   if (kk>=1) kk=1;
  305.   else
  306.   { if ((ii==1)&&(Fld[2][0][ll]>=0)) vv+=90+cc*85*(Fld[2][0][ll]-1);
  307.     if ((ii==Size-2)&&(Fld[Size-3][0][ll]>=0)) vv+=90+cc*85*(Fld[Size-3][0][ll]-1);
  308.     if (((ii!=1)||(!CanMoveTo(2,0,0,ll)))&&((ii!=Size-2)||(!CanMoveTo(Size-3,0,0,ll))))
  309.     {  if(CanMoveFromTo(0,0,Size-2,0,ll)) vv+=90-cc*85;
  310.     }
  311.   }  
  312.   nn=0;
  313.   for (jj=King[1][ll]+1; jj<Size; jj++)
  314.   { if (Fld[ii][jj][ll]>=0) nn++; }
  315.   if (nn>=1) nn=1;
  316.   else
  317.   { if ((ii==1)&&(Fld[2][Size-1][ll]>=0)) vv+=90+cc*85*(Fld[2][Size-1][ll]-1);
  318.     if ((ii==Size-2)&&(Fld[Size-3][Size-1][ll]>=0)) vv+=90+cc*85*(Fld[Size-3][Size-1][ll]-1);
  319.     if (((ii!=1)||(!CanMoveTo(2,Size-1,0,ll)))&&((ii!=Size-2)||(!CanMoveTo(Size-3,Size-1,0,ll))))    
  320.     { if (CanMoveFromTo(0,Size-1,Size-2,Size-1,ll)) vv+=90-cc*85;
  321.     }
  322.   }
  323.   kk+=nn;
  324.   if ((ii==0)||(ii==Size-1))
  325.   { vv++;
  326.     if (kk==0) vv+=100;
  327.     if (kk==1) vv+=99*(1-cc)+1;
  328.   }
  329.   else vv-=kk*2;
  330.   jj=King[1][ll];
  331.   kk=0;
  332.   for (ii=0; ii<King[0][ll]; ii++)
  333.   { if (Fld[ii][jj][ll]>=0) kk++; }
  334.   if (kk>=1) kk=1;
  335.   else
  336.   { if ((jj==1)&&(Fld[0][2][ll]>=0)) vv+=90+cc*85*(Fld[0][2][ll]-1);
  337.     if ((jj==Size-2)&&(Fld[0][Size-3][ll]>=0)) vv+=90+cc*85*(Fld[0][Size-3][ll]-1);
  338.     if (((jj!=1)||(!CanMoveTo(0,2,0,ll)))&&((jj!=Size-2)||(!CanMoveTo(0,Size-3,0,ll))))
  339.     { if (CanMoveFromTo(0,0,0,Size-2,ll)) vv+=90-cc*85;
  340.     }
  341.   }    
  342.   nn=0;
  343.   for (ii=King[0][ll]+1; ii<Size; ii++)
  344.   { if (Fld[ii][jj][ll]>=0) nn++; }
  345.   if (nn>=1) nn=1;
  346.   else
  347.   { if ((jj==1)&&(Fld[Size-1][2][ll]>=0)) vv+=90+cc*85*(Fld[Size-1][2][ll]-1);
  348.     if ((jj==Size-2)&&(Fld[Size-1][Size-3][ll]>=0)) vv+=90+cc*85*(Fld[Size-1][Size-3][ll]-1);
  349.     if (((jj!=1)||(!CanMoveTo(Size-1,2,0,ll)))&&((jj!=Size-2)||(!CanMoveTo(Size-1,Size-3,0,ll))))
  350.     { if (CanMoveFromTo(Size-1,0,Size-1,Size-2,ll)) vv+=90-cc*85;        
  351.     }
  352.   }  
  353.   kk+=nn;  
  354.   if ((jj==0)||(jj==Size-1))
  355.   { vv++;    
  356.     if (kk==0) vv+=100;
  357.     if (kk==1) vv+=99*(1-cc)+1;
  358.   }
  359.   else vv-=kk;  
  360.   ii=King[0][ll];
  361.   if (((ii==0)||(ii==Size-1))&&((jj==1)||(jj==Size-2))) vv+=40;
  362.   if (((ii==1)||(ii==Size-2))&&((jj==0)||(jj==Size-1))) vv+=40;
  363.   kk=0;
  364.   if (Math.abs(ii-Center)+Math.abs(jj-Center)<=1)
  365.   { if ((Fld[ii+1][jj][ll]==0)||(ii+1==Center)) kk++; else nn=0;
  366.     if ((Fld[ii-1][jj][ll]==0)||(ii-1==Center)) kk++; else nn=1;
  367.     if ((Fld[ii][jj+1][ll]==0)||(jj+1==Center)) kk++; else nn=2;
  368.     if ((Fld[ii][jj-1][ll]==0)||(jj-1==Center)) kk++; else nn=3;
  369.     if (kk==3)
  370.     { if ((nn==0)&&(Fld[ii+1][jj][ll]==-1)) vv-=100*CanMoveTo(ii+1,jj,0,ll)*(cc+0.05);
  371.       if ((nn==1)&&(Fld[ii-1][jj][ll]==-1)) vv-=100*CanMoveTo(ii-1,jj,0,ll)*(cc+0.05);
  372.       if ((nn==2)&&(Fld[ii][jj+1][ll]==-1)) vv-=100*CanMoveTo(ii,jj+1,0,ll)*(cc+0.05);
  373.       if ((nn==3)&&(Fld[ii][jj-1][ll]==-1)) vv-=100*CanMoveTo(ii,jj-1,0,ll)*(cc+0.05);
  374.     }
  375.   }
  376.   else
  377.   { if ((GetFld(ii+1,jj,ll)==0)||IsHostile(ii+1,jj)) kk++; else nn=0;
  378.     if ((GetFld(ii-1,jj,ll)==0)||IsHostile(ii-1,jj)) kk++; else nn=1;
  379.     if (kk==1)
  380.     { if ((nn==0)&&(GetFld(ii+1,jj,ll)==-1)) vv-=100*CanMoveTo(ii+1,jj,0,ll)*(cc+0.05);
  381.       if ((nn==1)&&(GetFld(ii-1,jj,ll)==-1)) vv-=100*CanMoveTo(ii-1,jj,0,ll)*(cc+0.05);
  382.     }
  383.     if (kk==2)
  384.     { if ((IsHostile(ii+1,jj))||(IsHostile(ii-1,jj))) vv+=200;
  385.     }
  386.     kk=0;
  387.     if ((GetFld(ii,jj+1,ll)==0)||IsHostile(ii,jj+1)) kk++; else nn=0;
  388.     if ((GetFld(ii,jj-1,ll)==0)||IsHostile(ii,jj-1)) kk++; else nn=1;
  389.     if (kk==1)
  390.     { if ((nn==0)&&(GetFld(ii,jj+1,ll)==-1)) vv-=100*CanMoveTo(ii,jj+1,0,ll)*(cc+0.05);
  391.       if ((nn==1)&&(GetFld(ii,jj-1,ll)==-1)) vv-=100*CanMoveTo(ii,jj-1,0,ll)*(cc+0.05);
  392.     }
  393.     if (kk==2)
  394.     { if ((IsHostile(ii,jj+1))||(IsHostile(ii,jj-1))) vv+=200;
  395.     }        
  396.   }
  397.  
  398.   if (cc==0) vv*=-0.5;
  399.   for (ii=0; ii<Size; ii++)
  400.   { nn=0;
  401.     for (jj=0; jj<Size; jj++)
  402.     { kk=Fld[ii][jj][ll];
  403.       if (kk==cc) vv+=10-3*IsVulnerable(ii, jj, 1-cc, ll);
  404.       if (kk==1-cc) vv-=10-IsVulnerable(ii, jj, cc, ll);
  405.       if (kk==0) nn++;
  406.     }
  407.     if (nn==0) vv+=cc;
  408.     else vv+=(1-cc)*(1+nn/4);
  409.   }
  410.   for (jj=0; jj<Size; jj++)
  411.   { nn=0;
  412.     for (ii=0; ii<Size; ii++)
  413.     { if (Fld[ii][jj][ll]==0) nn++;
  414.     }
  415.     if (nn==0) vv+=cc;
  416.     else vv+=(1-cc)*(1+nn/4);
  417.   }
  418.   if (MoveCount>7)
  419.   { if(((History[MoveCount-4][0]==ii0)&&
  420.         (History[MoveCount-4][1]==jj0)&&
  421.         (History[MoveCount-4][2]==History[MoveCount-2][0])&&
  422.         (History[MoveCount-4][3]==History[MoveCount-2][1]))||
  423.        ((History[MoveCount-8][0]==ii0)&&
  424.         (History[MoveCount-8][1]==jj0)&&
  425.         (History[MoveCount-8][2]==ii1)&&
  426.         (History[MoveCount-8][3]==jj1))) vv-=3;
  427.   }
  428.   vv+=Math.random()/4;
  429.   return(vv);
  430. }
  431.  
  432. function IsVulnerable(ii1, jj1, cc, ll)
  433. { var kk, nn;
  434.   kk=GetFld(ii1+1,jj1,ll);
  435.   nn=GetFld(ii1-1,jj1,ll);
  436.   if ((nn==-1)&&((sign(kk)==cc)||IsHostile(ii1+1,jj1)))
  437.   { if (CanMoveTo(ii1-1, jj1, cc, ll)) return(1);
  438.   }
  439.   if ((kk==-1)&&((sign(nn)==cc)||IsHostile(ii1-1,jj1)))
  440.   { if (CanMoveTo(ii1+1, jj1, cc, ll)) return(1);
  441.   }
  442.   kk=GetFld(ii1,jj1+1,ll);
  443.   nn=GetFld(ii1,jj1-1,ll);
  444.   if ((nn==-1)&&((sign(kk)==cc)||IsHostile(ii1,jj1+1)))
  445.   { if (CanMoveTo(ii1, jj1-1, cc, ll)) return(1);
  446.   }
  447.   if ((kk==-1)&&((sign(nn)==cc)||IsHostile(ii1,jj1-1)))
  448.   { if (CanMoveTo(ii1, jj1+1, cc, ll)) return(1);
  449.   }
  450.   return(0);
  451. }
  452.  
  453. function CanMoveFromTo(ii0, jj0, ii1, jj1, ll)
  454. { var kk;
  455.   if ((ii0!=ii1)&&(jj0!=jj1)) return(0);
  456.   if (ii0<ii1)
  457.   { for (kk=ii0+1; kk<=ii1; kk++)
  458.     { if (Fld[kk][jj0][ll]!=-1) return(0);
  459.     }
  460.     return(1);
  461.   }  
  462.   if (ii0>ii1)
  463.   { for (kk=ii0-1; kk>=ii1; kk--)
  464.     { if (Fld[kk][jj0][ll]!=-1) return(0);
  465.     }
  466.     return(1);
  467.   }
  468.   if (jj0<jj1)
  469.   { for (kk=jj0+1; kk<=jj1; kk++)
  470.     { if (Fld[ii0][kk][ll]!=-1) return(0);
  471.     }
  472.     return(1);
  473.   }
  474.   if (jj0>jj1)
  475.   { for (kk=jj0-1; kk>=jj1; kk--)
  476.     { if (Fld[ii0][kk][ll]!=-1) return(0);
  477.     }
  478.     return(1);
  479.   }  
  480.   return(0);
  481. }  
  482.  
  483. function CanMoveTo(ii0, jj0, cc0, ll)
  484. { var bb, cc, ii, jj;
  485.   bb=true;
  486.   for (ii=ii0+1; (ii<Size)&&bb; ii++)
  487.   { cc=sign(Fld[ii][jj0][ll]);
  488.     if (cc==cc0) return(1);
  489.     if (cc!=-1) bb=false;
  490.   }
  491.   bb=true;
  492.   for (ii=ii0-1; (ii>=0)&&bb; ii--)
  493.   { cc=sign(Fld[ii][jj0][ll]);
  494.     if (cc==cc0) return(1);
  495.     if (cc!=-1) bb=false;
  496.   }  
  497.   bb=true;
  498.   for (jj=jj0+1; (jj<Size)&&bb; jj++)
  499.   { cc=sign(Fld[ii0][jj][ll]);
  500.     if (cc==cc0) return(1);
  501.     if (cc!=-1) bb=false;
  502.   }
  503.   bb=true;
  504.   for (jj=jj0-1; (jj>=0)&&bb; jj--)
  505.   { cc=sign(Fld[ii0][jj][ll]);
  506.     if (cc==cc0) return(1);
  507.     if (cc!=-1) bb=false;
  508.   }
  509.   return(0);  
  510. }
  511.  
  512. function IsHostile(ii, jj)
  513. { if (ii==0)
  514.   { if (jj==0) return(2);
  515.     if (jj==Size-1) return(2);
  516.     return(0);
  517.   }  
  518.   if (ii==Size-1)
  519.   { if (jj==0) return(2);
  520.     if (jj==Size-1) return(2);
  521.     return(0);
  522.   }
  523.   if ((ii==Center)&&(jj==Center))
  524.     return(1);
  525.   return(0);  
  526. }
  527.  
  528. function MakeMove()
  529. { var ii, jj, vv1, vv2, hh=0;
  530.   Fld[I_Sel1][J_Sel1][0]=Fld[I_Sel0][J_Sel0][0];
  531.   Fld[I_Sel0][J_Sel0][0]=-1;
  532.   RefreshFld(I_Sel0, J_Sel0);
  533.   RefreshFld(I_Sel1, J_Sel1);
  534.   if ((History[MoveCount][0]!=I_Sel0)||
  535.       (History[MoveCount][1]!=J_Sel0)||
  536.       (History[MoveCount][2]!=I_Sel1)||
  537.       (History[MoveCount][3]!=J_Sel1))
  538.   { History[MoveCount][0]=I_Sel0;
  539.     History[MoveCount][1]=J_Sel0;
  540.     History[MoveCount][2]=I_Sel1;
  541.     History[MoveCount][3]=J_Sel1;
  542.     History[MoveCount].length=4;
  543.     hh=4;
  544.     MaxMoveCount=MoveCount+1;
  545.   }  
  546.   if (MoveCount<9)
  547.     window.document.OptionsForm.Moves.value=" "+eval(MoveCount+1)+" ";
  548.   else
  549.     window.document.OptionsForm.Moves.value=eval(MoveCount+1);
  550.   if (Fld[I_Sel1][J_Sel1][0]==2)
  551.   { King[0][0]=I_Sel1;
  552.     King[1][0]=J_Sel1;
  553.   }  
  554.   if (Fld[I_Sel1][J_Sel1][0]==0)
  555.   { for (ii=-1; ii<=1; ii++)
  556.     { for (jj=-1; jj<=1; jj++)
  557.       { if ((ii+jj+2)%2==1)
  558.         { vv1=GetFld(I_Sel1+ii, J_Sel1+jj, 0);
  559.           if (vv1>0)
  560.           { vv2=GetFld(I_Sel1+2*ii, J_Sel1+2*jj, 0);
  561.             if ((vv1==1)||(Math.abs(I_Sel1+ii-Center)+Math.abs(J_Sel1+jj-Center)>1))
  562.             { if ((vv2==0)||(IsHostile(I_Sel1+2*ii, J_Sel1+2*jj)))
  563.               { if (vv1==2)
  564.                 { IsOver=true;
  565.                   setTimeout("alert('Black has won !')",100);
  566.                 }
  567.                 else
  568.                 { Fld[I_Sel1+ii][J_Sel1+jj][0]=-1;
  569.                   RefreshFld(I_Sel1+ii, J_Sel1+jj);
  570.                   if (hh>0)
  571.                   { History[MoveCount][hh]=I_Sel1+ii;
  572.                     History[MoveCount][hh+1]=J_Sel1+jj;
  573.                     History[MoveCount][hh+2]=vv1;
  574.                     hh+=3;
  575.                   }
  576.                 }
  577.               }
  578.             }
  579.             else
  580.             { if (((Fld[I_Sel1+ii-1][J_Sel1+jj][0]==0)||((I_Sel1+ii-1==Center)&&(J_Sel1+jj==Center)))&&
  581.                   ((Fld[I_Sel1+ii+1][J_Sel1+jj][0]==0)||((I_Sel1+ii+1==Center)&&(J_Sel1+jj==Center)))&&
  582.                   ((Fld[I_Sel1+ii][J_Sel1+jj-1][0]==0)||((I_Sel1+ii==Center)&&(J_Sel1+jj-1==Center)))&&
  583.                   ((Fld[I_Sel1+ii][J_Sel1+jj+1][0]==0)||((I_Sel1+ii==Center)&&(J_Sel1+jj+1==Center))))
  584.               { IsOver=true;
  585.                 setTimeout("alert('Black has won !')",100);
  586.               }  
  587.             }
  588.           }
  589.         }
  590.       }
  591.     }    
  592.   }
  593.   else
  594.   { for (ii=-1; ii<=1; ii++)
  595.     { for (jj=-1; jj<=1; jj++)
  596.       { if ((ii+jj+2)%2==1)
  597.         { if (GetFld(I_Sel1+ii, J_Sel1+jj, 0)==0)
  598.           { vv2=GetFld(I_Sel1+2*ii, J_Sel1+2*jj, 0);
  599.             if ((vv2>0)||(IsHostile(I_Sel1+2*ii, J_Sel1+2*jj)))
  600.             { Fld[I_Sel1+ii][J_Sel1+jj][0]=-1;
  601.               RefreshFld(I_Sel1+ii, J_Sel1+jj);
  602.               if (hh>0)
  603.               { History[MoveCount][hh]=I_Sel1+ii;
  604.                 History[MoveCount][hh+1]=J_Sel1+jj;
  605.                 History[MoveCount][hh+2]=0;
  606.                 hh+=3;
  607.               }  
  608.             }
  609.           }    
  610.         }
  611.       }
  612.     }    
  613.     if ((Fld[I_Sel1][J_Sel1][0]==2)&&(IsHostile(I_Sel1, J_Sel1)==2))
  614.     { IsOver=true;
  615.       setTimeout("alert('White has won !')",100);
  616.     }
  617.   }  
  618.   I_Sel0=-1;
  619.   J_Sel0=-1;
  620.   I_Sel1=-1;
  621.   J_Sel1=-1;
  622.   MoveCount++;
  623.   if (MaxMoveCount<MoveCount)
  624.     MaxMoveCount=MoveCount;
  625.   if (MoveCount==MaxMove)
  626.   { IsOver=true;
  627.     alert("It's a stalemate.");
  628.   }        
  629.   if ((IsOver)||(MoveCount<12)) return;
  630.   for (ii=0; ii<8; ii++)
  631.   { if ((History[MoveCount-1-ii][0]!=History[MoveCount-5-ii][0])||
  632.         (History[MoveCount-1-ii][1]!=History[MoveCount-5-ii][1])||
  633.         (History[MoveCount-1-ii][2]!=History[MoveCount-5-ii][2])||
  634.         (History[MoveCount-1-ii][3]!=History[MoveCount-5-ii][3])) return;
  635.   }      
  636.   IsOver=true;
  637.   alert("It's a stalemate.");  
  638. }
  639. function GetFld(nn, mm, ll)
  640. { if (nn<0) return(-2);
  641.   if (mm<0) return(-2);
  642.   if (nn>Size-1) return(-2);
  643.   if (mm>Size-1) return(-2);
  644.   return(Fld[nn][mm][ll]);
  645. }
  646. function sign(nn)
  647. { if (nn<0) return(-1);
  648.   if (nn>0) return(1);
  649.   return(0);
  650. }
  651. function Clicked(nn, mm)
  652. { if (IsOver) return;
  653.   var cc=(MoveCount+Start)%2;
  654.   if (! IsPlayer[cc]) return;
  655.   if (I_Sel1>0) return;
  656.   var dd=(MaxSize-Size)/2, ii=nn-dd, jj=mm-dd;
  657.   if ((ii<0)||(jj<0)||(ii>Size-1)||(jj>Size-1))
  658.     return;
  659.   if (I_Sel0<0)
  660.   { if (sign(Fld[ii][jj][0])!=cc) return;
  661.     I_Sel0=ii;
  662.     J_Sel0=jj;
  663.     RefreshFld(ii, jj);
  664.     return;
  665.   }
  666.   if ((I_Sel0==ii)&&(J_Sel0==jj))
  667.   { I_Sel0=-1;
  668.     J_Sel0=-1;
  669.     RefreshFld(ii, jj);
  670.     return;
  671.   }
  672.   if ((ii-I_Sel0!=0)&&(jj-J_Sel0!=0)) return;
  673.   if (Fld[ii][jj][0]>=0) return;
  674.   if (Fld[I_Sel0][J_Sel0][0]<2)
  675.   { if ((ii==0)&&(jj==0)) return;
  676.     if ((ii==0)&&(jj==Size-1)) return;
  677.     if ((ii==Size-1)&&(jj==0)) return;
  678.     if ((ii==Size-1)&&(jj==Size-1)) return;
  679.     if ((ii==Center)&&(jj==Center)) return;
  680.   }
  681.   var kk;
  682.   if (ii==I_Sel0)
  683.   { dd=sign(jj-J_Sel0);
  684.     for (kk=J_Sel0; kk!=jj; kk+=dd)
  685.     { if (Fld[ii][kk+dd][0]>=0) return;
  686.     }
  687.   }
  688.   else  
  689.   { dd=sign(ii-I_Sel0);
  690.     for (kk=I_Sel0; kk!=ii; kk+=dd)
  691.     { if (Fld[kk+dd][jj][0]>=0) return;
  692.     }
  693.   }
  694.   I_Sel1=ii;
  695.   J_Sel1=jj;
  696. //  alert(MakeVirtualMove(I_Sel0, J_Sel0, ii, jj, cc, 1));
  697.   MakeMove();
  698. }
  699. function RefreshFld(ii, jj)
  700. { var nn=ii+(MaxSize-Size)/2, mm=jj+(MaxSize-Size)/2;
  701.   if (((ii%(Size-1)==0)&&(jj%(Size-1)==0))||((ii==Center)&&(jj==Center)))
  702.   { if (Fld[ii][jj][0]==-1)
  703.       document.images[mm*MaxSize+nn].src=Pic[0][1].src;
  704.     else
  705.     { if ((ii==I_Sel0)&&(jj==J_Sel0))
  706.         document.images[mm*MaxSize+nn].src=Pic[4][1].src;
  707.       else
  708.         document.images[mm*MaxSize+nn].src=Pic[4][0].src;
  709.     }
  710.   }  
  711.   else
  712.   { if ((ii==I_Sel0)&&(jj==J_Sel0)&&(Fld[ii][jj][0]>=0))
  713.       document.images[mm*MaxSize+nn].src=Pic[Fld[ii][jj][0]+1][1].src;
  714.     else
  715.       document.images[mm*MaxSize+nn].src=Pic[Fld[ii][jj][0]+1][0].src;
  716.   }
  717. }
  718. function RefreshScreen()
  719. { var ii, jj, dd=(MaxSize-Size)/2;
  720.   for (ii=0; ii < MaxSize; ii++)
  721.   { for (jj=0; jj < MaxSize; jj++)
  722.     { if ((ii<dd)||(jj<dd)||(ii>MaxSize-1-dd)||(jj>MaxSize-1-dd))
  723.         document.images[jj*MaxSize+ii].src=Transparent.src;
  724.       else RefreshFld(ii-dd, jj-dd);
  725.     }
  726.   }
  727.   if (MoveCount<10) window.document.OptionsForm.Moves.value=" "+MoveCount+" ";
  728.   else window.document.OptionsForm.Moves.value=MoveCount;
  729.   window.document.OptionsForm.Moves.blur();
  730. }
  731. function Help()
  732. { alert("Hnefatafl means King's table. It is an ancient game of"+
  733.        "\nthe Vikings and was known in Scandinavia before 400 A. D."+
  734.        "\nand was carried by the Vikings to Greenland, Iceland,"+
  735.        "\nIreland, Britain, Wales and as far east as the Ukraine."+
  736.        "\nIt was played on odd-sized boards as small as 7 x 7 and"+
  737.        "\nas large as 19 x 19. Here are 2 variants implemented:"+
  738.        "\nTablut, the Finnish variant, which was played on a 9x9 board"+
  739.        "\nand Hnefatafl, the Norse variant, wich was played either on"+
  740.        "\na 11x11 board or 13x13 board. Tawlbyund (Tawl Bwrdd ="+
  741.        "\n'Throw Board'), the Welsh variant, was played on an 11x11"+
  742.        "\nboard. It dates back at least to the Xth century."+
  743.        "\nThe object for the player with the black pieces (attacker)"+
  744.        "\nis to prevent the opponent's king from escaping, and ultimately"+
  745.        "\nto capture it. The object for the player with the white pieces"+
  746.        "\n(defender) is to escape with the king to one of the corner spaces."+
  747.        "\nA piece can move horizontally or vertically any number of spaces,"+
  748.        "\nlike a chess rook. Only the king may land on the throne (the center)"+
  749.        "\nor on the corner squares. Either player's pieces may pass over the"+
  750.        "\nthrone as part of a move. Pieces are captured by flanking opponent's"+
  751.        "\npieces on two opposite sides (custodial capture). Up to three pieces"+
  752.        "\ncan be captured in a single turn. The corner and throne count as a"+
  753.        "\npiece for capturing. Pieces can safely move between two other pieces."+
  754.        "\nThe king is captured like nother pieces, except when he is on the"+
  755.        "\nthrone or in one of the four spaces next to the throne, then he must"+
  756.        "\nbe surrounded on four sides to be captured, either by four enemy"+
  757.        "\npieces or by three enemy pieces and the throne itself.");
  758. }
  759.  
  760. function Resize()
  761. { if(navigator.appName == "Netscape") history.go(0);
  762. }
  763. </script>
  764. </HEAD>
  765. <BODY bgcolor=#bb8866 text=#000000 onResize="javascript:Resize()">
  766. <DIV ALIGN=center>
  767. <form name="OptionsForm">
  768. <table noborder>
  769. <tr><td><script language="JavaScript">
  770. document.open();
  771. document.writeln("<table border=2 cellpadding=4 cellspacing=3  bgcolor=#cccccc><tr><td><table border=0 cellpadding=0 cellspacing=0>");
  772. for (j=0; j < MaxSize; j++)
  773. { document.write("<tr>");
  774.   for (i=0; i < MaxSize; i++)
  775.   { if ((i+j)%2==0)
  776.       document.write("<td bgcolor=#bb8866><IMG src=\"hnefatafl00.gif\" border=0 onMouseDown=\"javascript:Clicked("+i+","+j+")\"></td>");
  777.     else
  778.       document.write("<td bgcolor=#eeddbb><IMG src=\"hnefatafl00.gif\" border=0 onMouseDown=\"javascript:Clicked("+i+","+j+")\"></td>");
  779.   }
  780.   document.write("</tr>");
  781. }
  782. document.writeln("</table></td></tr></table>");
  783. document.close();
  784. </script>
  785. </td>
  786. <td>&nbsp;</td><td>&nbsp;</td>
  787. <td><table noborder cellpadding=3 cellspacing=3>
  788. <tr><td><table border cellpadding=1 cellspacing=1 width=100% bgcolor=#eeddbb>
  789. <tr><td><input type=radio name="White" value="Player" onClick="javascript:SetPlayer(1,1)"> <b>White: Player</b></td></tr>
  790. <tr><td><input type=radio name="White" checked value="Computer" onClick="javascript:SetPlayer(1,0)"> <b>White: Computer</b></td></tr>
  791. </table>      
  792. </td></tr>
  793. <tr><td><table border cellpadding=1 cellspacing=1 width=100% bgcolor=#eeddbb>
  794. <tr><td><input type=radio name="Black" checked value="Player" onClick="javascript:SetPlayer(0,1)"> <b>Black: Player</b></td></tr>
  795. <tr><td><input type=radio name="Black" value="Computer" onClick="javascript:SetPlayer(0,0)"> <b>Black: Computer</b></td></tr>
  796. </table>
  797. </td></tr>      
  798. <tr><td><table border cellpadding=1 cellspacing=1 width=100% bgcolor=#eeddbb>
  799. <tr><td><input type=radio name="Start" value="White" onClick="javascript:SetStart0(false)"> <b>White begins</b></td></tr>
  800. <tr><td><input type=radio name="Start" checked value="Black" onClick="javascript:SetStart0(true)"> <b>Black begins</b></td></tr>
  801. </table>
  802. </td></tr>
  803. <tr><td><table border cellpadding=1 cellspacing=1 width=100% bgcolor=#eeddbb>
  804. <tr><td>
  805. <input type=radio name="Size" value="9" checked onClick="javascript:SetSize(9)"><b>9x9</b>
  806. <input type=radio name="Size" value="11" onClick="javascript:SetSize(11)"><b>11x11</b>
  807. </td></tr>
  808. </table>
  809. </td></tr>
  810. <tr><td><table border cellpadding=1 cellspacing=1 width=100% bgcolor=#eeddbb>
  811. <tr><td colspan=5 align=center><input type=button value="NEW GAME" style="width:168" width=172 onClick="javascript:Init()"></td></tr>
  812. <tr>
  813. <td align=center><input type=button value="&nbsp;&lt;&lt;&nbsp;" style="width:30" onClick="javascript:Back();Back()" title="two moves back"></td>
  814. <td align=center><input type=button value="&nbsp;&lt;&nbsp;" style="width:27" onClick="javascript:Back()" title="one move back"></td>
  815. <td align=center><input type=button value="&nbsp;&nbsp;&nbsp;&nbsp;" width=35 style="width:34;background-color:#FFFFFF;font-weight:bold" disabled name="Moves"></td>
  816. <td align=center><input type=button value="&nbsp;&gt;&nbsp;" style="width:27" onClick="javascript:Replay()" title="one move forward"></td>
  817. <td align=center><input type=button value="&nbsp;&gt;&gt;&nbsp;" style="width:30" onClick="javascript:Replay();Replay()" title="two moves forward"></td>
  818. </tr>
  819. <tr><td colspan=5 align=center><input type=button value="HELP" style="width:168" width=172 onClick="javascript:Help()"></td></tr>
  820. </table></td></tr>
  821. </table>
  822. </td>
  823. </tr>
  824. </table>
  825. </form>
  826. </DIV>
  827. <script language="JavaScript">
  828.   Init();
  829.   setInterval("Timer()",540);
  830. </script>
  831. </BODY>
  832. </HTML>
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top