Advertisement
Guest User

15 puzzle relay

a guest
Oct 20th, 2012
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.28 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5.  
  6. <!--
  7. Fifteen Puzzle
  8. Version: 0.101
  9. Date: 2012-02-25
  10. Author: Alberto Burgos <albertoburgosmh@gmail.com>
  11. An online version can be found at:
  12. http://albertoonsoftware.com/fifteenpuzzle
  13. -->
  14.  
  15. <meta charset="utf-8" />
  16.  
  17. <title>Fifteen Puzzle</title>
  18.  
  19. <style type="text/css">
  20.  
  21. body {
  22. font-family: Arial, Serif;
  23. margin: 0;
  24. }
  25. .container {
  26. margin: 20px auto 35px;
  27. width: 500px;
  28. }
  29. #board {
  30. margin: 0 auto;
  31. font-size: 20px;
  32. }
  33. .infoPanel {
  34. margin-top: 50px;
  35. }
  36. .odd, .even {
  37. float: left;
  38. width: 60px;
  39. height: 60px;
  40. margin: 2px;
  41.  
  42. line-height: 60px;
  43. text-align: center;
  44.  
  45. border: 1px solid black;
  46. -webkit-border-radius: 7px;
  47. -moz-border-radius: 7px;
  48. border-radius: 7px;
  49. }
  50. .even {
  51. background-color: #FF00FF;
  52. }
  53. .odd {
  54. background-color: #FF7F00;
  55. }
  56. #times {
  57. width: 500px;
  58. max-width: 500px;
  59. min-height: 80px;
  60. }
  61. #state {
  62. color: #007700;
  63. }
  64. #state, #time, #movs {
  65. font-weight: bold;
  66. }
  67. .simpleTable {
  68. border-spacing: 0;
  69. border-collapse: collapse;
  70. }
  71. .simpleTable td {
  72. padding: 0 10px 0 0;
  73. }
  74. .right {
  75. float: right;
  76. }
  77. .left {
  78. float: left;
  79. }
  80. .clear {
  81. clear: both;
  82. }
  83. </style>
  84.  
  85. <script type="text/javascript">
  86.  
  87. var puzzle;
  88. var tiles;
  89. var labels;
  90. var solves;
  91. var loopcount=7;
  92.  
  93. function init(side)
  94. {
  95. Array.prototype.avg = function() {
  96. for(var i=0, sum=0; i < this.length; sum += this[i++]);
  97. return sum/this.length;
  98. }
  99.  
  100. labels =
  101. {
  102. state: document.getElementById('state'),
  103. movs: document.getElementById('movs'),
  104. time: document.getElementById('time'),
  105. best: document.getElementById('best'),
  106. worst: document.getElementById('worst'),
  107. tps: document.getElementById('tps')
  108. };
  109.  
  110. document.addEventListener('keydown', keyHandler);
  111.  
  112. reset(side);
  113. }
  114.  
  115. function reset(side)
  116. {
  117. puzzle =
  118. {
  119. side: parseInt(side),
  120. lastTile: side*side,
  121. gap: side*side,
  122. state: 'solved',
  123. };
  124.  
  125. labels.state.textContent = 'Solved';
  126. labels.state.style.color = '#007700';
  127.  
  128. if(loopcount==7)
  129. {
  130. solves =
  131. {
  132. // Last solve data
  133. movs: -1,
  134. iniTime: -1,
  135. endTime: -1,
  136.  
  137. // All solves data
  138. best: null,
  139. worst: null,
  140. times: new Array()
  141. }
  142. }
  143.  
  144. var board = document.getElementById('board');
  145. board.innerHTML = '';
  146. board.style.width = puzzle.side*66+'px';
  147. board.style.height = puzzle.side*66+'px';
  148.  
  149. tiles = new Array();
  150. var tile;
  151.  
  152. for(var i = 1; i <= puzzle.lastTile; i++)
  153. {
  154. tiles[i] = document.createElement('div');
  155. tiles[i].className = i % 2 != 0 ? 'odd' : 'even';
  156. tiles[i].id = 't'+i;
  157. tiles[i].textContent = i;
  158. board.appendChild(tiles[i]);
  159. }
  160. tiles[puzzle.lastTile].style.visibility = 'hidden';
  161. }
  162.  
  163. function solve()
  164. {
  165. for(var i=1; i <= puzzle.lastTile; i++)
  166. {
  167. tiles[i].textContent = i;
  168. tiles[i].className = i % 2 != 0 ? 'odd' : 'even';
  169. tiles[i].style.visibility = 'visible';
  170. }
  171. tiles[puzzle.lastTile].style.visibility = 'hidden';
  172.  
  173. puzzle.gap = puzzle.lastTile;
  174. puzzle.state = 'solved';
  175. labels.state.textContent = 'Solved';
  176. labels.state.style.color = '#007700';
  177. }
  178.  
  179. function keyHandler(e)
  180. {
  181. var keyCode = e.keyCode;
  182.  
  183.  
  184. if (keyCode > 36 && keyCode < 41 || keyCode == 32)
  185. e.preventDefault();
  186.  
  187. if (keyCode == 37 || keyCode == 68)
  188. move(2);
  189. else if (keyCode == 38 || keyCode == 71)
  190. move(3);
  191. else if (keyCode == 39 || keyCode == 84)
  192. move(0);
  193. else if (keyCode == 40 || keyCode == 72)
  194. move(1);
  195. else if (keyCode == 32 && puzzle.state == 'solved')
  196. scramble();
  197. else if (keyCode == 27)
  198. solve();
  199. }
  200.  
  201. function scramble()
  202. {
  203. var max = Math.pow(puzzle.side, 4);
  204. var count = 0, movement, forbidden=0;
  205. while (count < max)
  206. {
  207. movement = Math.floor(Math.random()*4);
  208. if (movement != forbidden && move(movement) == true)
  209. {
  210. count++;
  211. forbidden = (movement+2) % 4;
  212. }
  213. }
  214. puzzle.state = 'scrambled';
  215. labels.state.textContent = 'Scrambled';
  216. labels.state.style.color = '#0055dd';
  217. if (loopcount==7){timerstart()};
  218.  
  219. }
  220.  
  221.  
  222. function timerstart()
  223. {
  224. var timerstart = setInterval(function() {Timer()}, 1);
  225. }
  226.  
  227. function Timer()
  228. {
  229.  
  230. solves.curTime = new Date();
  231. var curTime = (solves.curTime.getTime() - solves.iniTime.getTime())/1000;
  232. var curmin = Math.floor(curTime / 60)
  233. var prettycur
  234. if (curTime > 60)
  235. {
  236. prettycur = curmin+':'+(curTime - curmin*60).toFixed(3);
  237. }
  238. else
  239. {
  240. prettycur = curTime
  241. }
  242.  
  243. labels.time.textContent = prettycur;
  244. labels.movs.textContent = solves.movs;
  245.  
  246. }
  247.  
  248. function move(m)
  249. {
  250. if(m == 0) // Left
  251. {
  252. if (puzzle.gap % puzzle.side == 0) return false;
  253. else swapTiles(puzzle.gap+1, puzzle.gap);
  254. }
  255. else if (m == 1) // Up
  256. {
  257. if (puzzle.gap > puzzle.side*(puzzle.side-1)) return false;
  258. else swapTiles(puzzle.gap+puzzle.side, puzzle.gap);
  259. }
  260. else if (m == 2) // Right
  261. {
  262. if ((puzzle.gap+puzzle.side-1) % puzzle.side == 0) return false;
  263. else swapTiles(puzzle.gap-1, puzzle.gap);
  264. }
  265. else if (m == 3) // Down
  266. {
  267. if (puzzle.gap < puzzle.side+1) return false;
  268. else swapTiles(puzzle.gap-puzzle.side, puzzle.gap);
  269. }
  270.  
  271. if(puzzle.state == 'scrambled')
  272. {
  273. puzzle.state = 'solving';
  274. labels.state.textContent = 'Solving';
  275. labels.state.style.color = "#aa0000";
  276. if(loopcount==7)
  277. {
  278. solves.movs = 0;
  279. solves.iniTime = new Date();
  280. }
  281. }
  282.  
  283. if(puzzle.state == 'solving')
  284. {
  285. solves.movs++;
  286. if (isSolved())
  287. {
  288.  
  289.  
  290. puzzle.state = 'solved';
  291.  
  292. loopcount--;
  293. if(loopcount==1)
  294. {
  295. solves.endTime = new Date();
  296. clearInterval(timerstart);
  297.  
  298. var newTime = (solves.endTime.getTime() - solves.iniTime.getTime())/1000;
  299. solves.times.push(newTime);
  300.  
  301. var min = Math.floor(newTime / 60)
  302. var prettynew
  303. if (newTime > 60){
  304. prettynew = min+':'+(newTime - min*60).toFixed(3);
  305. }
  306. else{
  307. prettynew = newTime
  308. }
  309.  
  310.  
  311. if(solves.best == null)
  312. labels.best.textContent = labels.worst.textContent
  313. = solves.best = solves.worst = newTime;
  314. else if(solves.best > newTime)
  315. labels.best.textContent = solves.best = newTime;
  316. else if(solves.worst < newTime)
  317. labels.worst.textContent = solves.worst = newTime;
  318.  
  319. labels.state.textContent = 'Solved';
  320. labels.state.style.color = '#007700';
  321. labels.movs.textContent = solves.movs;
  322. labels.tps.textContent = (solves.movs / newTime).toFixed(2);
  323.  
  324. document.getElementById('average').textContent = solves.times.avg().toFixed(3);
  325. loopcount=7
  326. init(7)
  327. }
  328. else
  329. {
  330. init(loopcount);
  331. scramble();
  332. }
  333.  
  334.  
  335. }
  336. }
  337. return true;
  338. }
  339.  
  340. function isSolved()
  341. {
  342. for (var i = 1; i < puzzle.lastTile; i++)
  343. if (i != tiles[i].textContent)
  344. return false;
  345. return true;
  346. }
  347.  
  348. function swapTiles(a, b)
  349. {
  350. var aux = tiles[a].textContent;
  351. tiles[a].textContent = tiles[b].textContent;
  352. tiles[b].textContent = aux;
  353. tiles[a].style.visibility = 'hidden';
  354. tiles[b].style.visibility = 'visible';
  355. tiles[a].className = tiles[a].textContent % 2 != 0 ? 'odd' : 'even';
  356. tiles[b].className = tiles[b].textContent % 2 != 0 ? 'odd' : 'even';
  357. puzzle.gap = a;
  358. }
  359.  
  360.  
  361. </script>
  362.  
  363. </head>
  364.  
  365. <body onload="init(7); var loopcount=7">
  366.  
  367. <div class="container">
  368.  
  369. <div id="board"></div>
  370.  
  371. <div class="infoPanel">
  372.  
  373. <div class="right">
  374.  
  375. Puzzle side:
  376.  
  377. <select onchange="reset(this.value)">
  378. <option value="2">2</option>
  379. <option value="3">3</option>
  380. <option value="4">4</option>
  381. <option value="5">5</option>
  382. <option value="6">6</option>
  383. <option value="7"selected="selected">7</option>
  384. <option value="8">8</option>
  385. <option value="9">9</option>
  386. <option value="10">10</option>
  387. <option value="11">11</option>
  388. <option value="12">12</option>
  389. </select>
  390.  
  391. </div>
  392.  
  393. <table class="simpleTable left">
  394.  
  395. <tr>
  396. <td>State:</td>
  397. <td id="state" style="width: 120px">solved</td>
  398. </tr>
  399.  
  400. <tr>
  401. <td>Time:</td>
  402. <td id="time"></td>
  403. </tr>
  404.  
  405. <tr>
  406. <td>Moves:</td>
  407. <td id="movs"></td>
  408. </tr>
  409.  
  410. </table>
  411.  
  412. <table class="simpleTable left">
  413.  
  414. <tr>
  415. <td>Best:</td>
  416. <td id="best"></td>
  417. </tr>
  418.  
  419. <tr>
  420. <td>Worst:</td>
  421. <td id="worst"></td>
  422. </tr>
  423.  
  424. <tr>
  425. <td>Mean:</td>
  426. <td id="average"></td>
  427. </tr>
  428.  
  429. <tr>
  430. <td>TPS:</td>
  431. <td id="tps"></td>
  432. </tr>
  433.  
  434. </table>
  435.  
  436. <div class="clear"></div>
  437.  
  438. <br/>
  439.  
  440. Times:<br/><textarea id="times" readonly="readonly" cols="1" rows="1"></textarea>
  441.  
  442. <br/>
  443. <br/>
  444.  
  445. <b>Controls</b>
  446.  
  447. <table class="simpleTable">
  448.  
  449. <tr>
  450. <td>Move tile:</td>
  451. <td>Arrows or WASD</td>
  452. </tr>
  453.  
  454. <tr>
  455. <td>Scramble:</td>
  456. <td>Space</td>
  457. </tr>
  458.  
  459. <tr>
  460. <td>Solve:</td>
  461. <td>Escape</td>
  462. </tr>
  463.  
  464. </table>
  465.  
  466. </div> <!-- End of infoPanel -->
  467.  
  468. </div> <!-- End of container -->
  469.  
  470. </body>
  471.  
  472. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement