Break limit on script execution time for statistic gathering
authorOleksandr Gavenko <gavenkoa@gmail.com>
Wed, 24 Sep 2014 19:17:52 +0300
changeset 129 e0958e521716
parent 128 673743a1290d
child 130 28694f058ea4
Break limit on script execution time for statistic gathering (dom.max_script_run_time for Firefox).
2048.html
--- a/2048.html	Wed Sep 24 18:45:46 2014 +0300
+++ b/2048.html	Wed Sep 24 19:17:52 2014 +0300
@@ -280,9 +280,9 @@
   <div id="report-area" class="area">
     <h1>Reports</h1>
     <div class="control">
-      <div class="option"><input type="text" id="stat-count-limit" value="100"> times</div>
-      <div class="option">limit to <input type="text" id="stat-time-limit" value="10"> sec</div>
-      <button id="statistic">Start</button>
+      <div class="option">up to <input type="text" id="stat-count-limit" value="100"> times</div>
+      <div class="option">up to <input type="text" id="stat-time-limit" value="10"> sec</div>
+      <button id="statistic-start">Start</button>
       <button id="statistic-clean">Clean</button>
       <div class="option"><input type="checkbox" id="report-score"/> score</div>
       <div class="option"><input type="checkbox" id="report-turn"/> turn</div>
@@ -888,20 +888,18 @@
       reportDom.appendChild(tableDom);
       reportsDom.insertBefore(reportDom, reportsDom.firstChild);
     }
-    ui.report.stat = function() {
-      /* console.profile(); */
+    ui.report.start = function() {
       var histo = {};
-      var cnt = parseInt(document.getElementById('stat-count-limit').value);
-      if (isNaN(cnt) || !isFinite(cnt) || cnt < 1)
-        cnt = 100;
+      var gameCntLimit = parseInt(document.getElementById('stat-count-limit').value);
+      if (isNaN(gameCntLimit) || !isFinite(gameCntLimit) || gameCntLimit < 1)
+        gameCntLimit = 100;
       var tsLimit = parseFloat(document.getElementById('stat-count-limit').value);
       if (isNaN(tsLimit) || !isFinite(tsLimit) || tsLimit < 1 || tsLimit > 60)
         tsLimit = 1000 * 10;
       else
         tsLimit = 1000 * tsLimit;
       var safeBdr = board.create();
-      var tsLimitFrom = new Date().getTime();
-      for (var gameCnt = 0; gameCnt++ < cnt; void(0)) {
+      function play() {
         var turn = 0;
         var brd = board.create();
         board.putRandom(brd);
@@ -911,35 +909,53 @@
           var move = ui.ai.current.analyse(safeBdr);
           if (ui.game.dirs.indexOf(move) < 0) {
             ui.game.setMessage("I don't know how to move!");
-            return;
+            throw Error("AI make illegal move '" + move + "'...");
           }
           var updated = board.move[move].call(null, brd);
           if (!updated) {
             ui.game.setMessage("Wrong move!");
-            return;
+            throw Error("AI make illegal move '" + move + "'...");
           }
           board.putRandom(brd);
           turn++;
         }
         var tsTo = new Date().getTime();
         ui.report.update(histo, brd, tsTo-tsFrom, turn);
-        if (tsTo - tsLimitFrom >= tsLimit)
-          break;
       }
-      ui.report.fix(histo);
-      ui.report.show(histo, gameCnt);
-      /* console.profileEnd(); */
+      var gameCnt = 0;
+      var tsFrom = new Date().getTime(), tsFrame = tsFrom;
+      function batch() {
+        /* console.profile(); */
+        while (gameCnt++ < gameCntLimit) {
+          play();
+          var tsTo = new Date().getTime();
+          if (tsTo - tsFrame > 7000) {
+            tsFrame = tsTo;
+            break;
+          }
+          if (tsTo - tsFrom >= tsLimit)
+            break;
+        }
+        /* console.profileEnd(); */
+        if (tsTo - tsFrom >= tsLimit || gameCnt >= gameCntLimit) {
+          ui.report.fix(histo);
+          ui.report.show(histo, gameCnt);
+        } else {
+          setTimeout(batch, 10);
+        }
+      }
+      batch();
     }
-    var statisticBtn = document.getElementById('statistic');
-    statisticBtn.addEventListener("click", ui.report.stat, false);
+    var statisticStartBtn = document.getElementById("statistic-start");
+    statisticStartBtn.addEventListener("click", ui.report.start, false);
 
-    ui.report.statClean = function() {
+    ui.report.clean = function() {
       while (reportsDom.hasChildNodes()) {
         reportsDom.removeChild(reportsDom.lastChild);
       }
     }
     var statisticCleanBtn = document.getElementById('statistic-clean');
-    statisticCleanBtn.addEventListener("click", ui.report.statClean, false);
+    statisticCleanBtn.addEventListener("click", ui.report.clean, false);
 
     ////////////////////////////////////////////////////////////////
     // Initialise game.