2048.html
changeset 25 2ef10a49a28f
parent 21 ed0292f0c7c6
child 26 fba85224a8f0
equal deleted inserted replaced
24:079bcd734b68 25:2ef10a49a28f
     9   <script src="board.js"></script>
     9   <script src="board.js"></script>
    10   <script src="perf.js"></script>
    10   <script src="perf.js"></script>
    11   <script src="ai.js"></script>
    11   <script src="ai.js"></script>
    12 
    12 
    13   <style>
    13   <style>
    14     body {
       
    15       width: 100%;
       
    16     }
       
    17     h1, div.area {
    14     h1, div.area {
    18       text-align: center;
    15       text-align: center;
    19       margin: 10px auto;
    16       margin: 10px auto;
    20     }
    17     }
    21     #board {
    18     #board {
    28       margin: 0;
    25       margin: 0;
    29       text-align: center;
    26       text-align: center;
    30     }
    27     }
    31     .report > .name {
    28     .report > .name {
    32       font-weight: bold;
    29       font-weight: bold;
       
    30     }
       
    31     div.ai {
       
    32       border: 1px red solid;
       
    33       margin-top: 20px;
       
    34       padding: 2px;
       
    35       position: relative;
       
    36       background-color: cornsilk;
       
    37     }
       
    38     div.ai.enabled {
       
    39       background-color: wheat;
       
    40     }
       
    41     div.ai > h5 {
       
    42       margin: 2px 0;
       
    43     }
       
    44     button.ai {
       
    45       position: absolute;
       
    46       left: 1em;
       
    47       top: -1em;
    33     }
    48     }
    34   </style>
    49   </style>
    35 </head>
    50 </head>
    36 <body>
    51 <body>
    37 
    52 
    80       <button id="up">up</button>
    95       <button id="up">up</button>
    81       <button id="down">down</button>
    96       <button id="down">down</button>
    82       <button id="right">right</button>
    97       <button id="right">right</button>
    83       <button id="test">test</button>
    98       <button id="test">test</button>
    84     </div>
    99     </div>
    85     <h1>AI</h1>
   100     <h1>AIs</h1>
    86     <div>
   101     <div>
    87       <button id="ai-random">random</button>
   102       <div class="ai" id="ai-random">
    88       <button id="ai-next-max-score">next max score</button>
   103         <button class="ai">enable</button>
    89       <button id="ai-next-max-value">next max value</button>
   104         <h5>bling random</h5>
    90       <button id="ai-deep-max-score">deep max score</button>
   105       </div>
    91       <button id="ai-deep-max-score-corner">deep max score corner</button>
   106       <div class="ai" id="ai-next-max-score">
    92       <button id="ai-expectimax">expectimax</button>
   107         <button class="ai">enable</button>
       
   108         <h5>next merge makes max score</h5>
       
   109       </div>
       
   110       <div class="ai" id="ai-next-max-value">
       
   111         <button class="ai">enable</button>
       
   112         <h5>next merge makes max value</h5>
       
   113       </div>
       
   114       <div class="ai enabled" id="ai-deep-max-score">
       
   115         <button class="ai">enable</button>
       
   116         <h5>deep merges without simulation make max score</h5>
       
   117       </div>
       
   118       <div class="ai" id="ai-deep-max-score-corner">
       
   119         <button class="ai">enable</button>
       
   120         <h5>deep merges without simulation make max score + bonus if max value at corner/edge</h5>
       
   121       </div>
       
   122       <div class="ai" id="ai-expectimax">
       
   123         <button class="ai">enable</button>
       
   124         <h5>expectimax</h5>
       
   125       </div>
    93     </div>
   126     </div>
    94   </div>
   127   </div>
    95 
   128 
    96   <div id="report-area" class="area">
   129   <div id="report-area" class="area">
    97     <h1>Reports</h1>
   130     <h1>Reports</h1>
   290         ui.message.set("Game over!");
   323         ui.message.set("Game over!");
   291         return;
   324         return;
   292       }
   325       }
   293       var tmpBrd = board.create();
   326       var tmpBrd = board.create();
   294       board.copy(board.current, tmpBrd);
   327       board.copy(board.current, tmpBrd);
   295       var move = ui.ai.analyse(tmpBrd);
   328       var move = ui.ai.current.analyse(tmpBrd);
   296       if (typeof move === 'undefined') {
   329       if (typeof move === 'undefined') {
   297         ui.message.set("I don't know how to move!");
   330         ui.message.set("I don't know how to move!");
   298         return;
   331         return;
   299       }
   332       }
   300       var updated = board.move[move].call(null, board.current);
   333       var updated = board.move[move].call(null, board.current);
   313       var step = 0;
   346       var step = 0;
   314       var tsFrom = new Date().getTime();
   347       var tsFrom = new Date().getTime();
   315       while (!board.gameOver(board.current)) {
   348       while (!board.gameOver(board.current)) {
   316         var tmpBrd = board.create();
   349         var tmpBrd = board.create();
   317         board.copy(board.current, tmpBrd);
   350         board.copy(board.current, tmpBrd);
   318         var move = ui.ai.analyse(tmpBrd);
   351         var move = ui.ai.current.analyse(tmpBrd);
   319         if (typeof move === 'undefined') {
   352         if (typeof move === 'undefined') {
   320           ui.message.set("I don't know how to move!");
   353           ui.message.set("I don't know how to move!");
   321           return;
   354           return;
   322         }
   355         }
   323         var updated = board.move[move].call(null, board.current);
   356         var updated = board.move[move].call(null, board.current);
   340     document.getElementById("finish").addEventListener("click", finish);
   373     document.getElementById("finish").addEventListener("click", finish);
   341 
   374 
   342     ////////////////////////////////////////////////////////////////
   375     ////////////////////////////////////////////////////////////////
   343     // Register AIs.
   376     // Register AIs.
   344 
   377 
       
   378     ui.ai = {};
       
   379     ui.ai.current = null;
       
   380     ui.ai.algList = {
       
   381       "ai-random": function() {
       
   382         return new ai.random(ui.brdEngine);
       
   383       },
       
   384       "ai-next-max-score": function() {
       
   385         return new ai.nextMaxScore(ui.brdEngine);
       
   386       },
       
   387       "ai-next-max-value": function() {
       
   388         return new ai.nextMaxValue(ui.brdEngine);
       
   389       },
       
   390       "ai-deep-max-score": function() {
       
   391         return new ai.deepMaxScore(ui.brdEngine);
       
   392       },
       
   393       "ai-deep-max-score-corner": function() {
       
   394         return new ai.deepMaxScoreCorner(ui.brdEngine);
       
   395       },
       
   396       "ai-expectimax": function() {
       
   397         return new ai.expectimax(ui.brdEngine);
       
   398       },
       
   399       // "": function() {
       
   400       //   return new ai.(ui.brdEngine);
       
   401       // },
       
   402     };
       
   403     ui.ai.domList = document.querySelectorAll('div.ai');
       
   404     for (var i = 0; i < ui.ai.domList.length; i++) {
       
   405       ui.ai.domList[i].querySelectorAll('button.ai')[0].addEventListener("click", function (event) {
       
   406         ui.ai.enable(event.target.parentNode);
       
   407       });
       
   408     }
       
   409 
       
   410     ui.ai.moveToTop = function(aiDom) {
       
   411       for (var i = 0; i < ui.ai.domList.length; i++) {
       
   412         ui.ai.domList[i].classList.remove('enabled');
       
   413       }
       
   414       var rootDom = aiDom.parentNode;
       
   415       rootDom.removeChild(aiDom);
       
   416       rootDom.insertBefore(aiDom, rootDom.firstChild);
       
   417       aiDom.classList.add('enabled');
       
   418     }
       
   419     ui.ai.enable = function(aiDom) {
       
   420       if (ui.ai.current)
       
   421         ui.ai.current.cleanup();
       
   422       var ai = ui.ai.algList[aiDom.id];
       
   423       ui.ai.moveToTop(aiDom);
       
   424       ui.ai.current = ai();
       
   425     }
       
   426 
   345     ui.brdEngine = BoardArr2d; // TODO make user selectable
   427     ui.brdEngine = BoardArr2d; // TODO make user selectable
   346 
       
   347     document.getElementById("ai-random").addEventListener("click", function() {
       
   348       ui.ai = new ai.random(ui.brdEngine);
       
   349     });
       
   350     document.getElementById("ai-next-max-score").addEventListener("click", function() {
       
   351       ui.ai = new ai.nextMaxScore(ui.brdEngine);
       
   352     });
       
   353     document.getElementById("ai-next-max-value").addEventListener("click", function() {
       
   354       ui.ai = new ai.nextMaxValue(ui.brdEngine);
       
   355     });
       
   356     document.getElementById("ai-deep-max-score").addEventListener("click", function() {
       
   357       ui.ai = new ai.deepMaxScore(ui.brdEngine);
       
   358     });
       
   359     document.getElementById("ai-deep-max-score-corner").addEventListener("click", function() {
       
   360       ui.ai = new ai.deepMaxScoreCorner(ui.brdEngine);
       
   361     });
       
   362     document.getElementById("ai-expectimax").addEventListener("click", function() {
       
   363       ui.ai = new ai.expectimax(ui.brdEngine);
       
   364     });
       
   365 
   428 
   366   </script>
   429   </script>
   367   
   430   
   368 </body>
   431 </body>
   369 </html>
   432 </html>