Advertisement
Guest User

Untitled

a guest
Nov 14th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 26.66 KB | None | 0 0
  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>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement