title: Uncaught ReferenceError: AI is not defined at Object.play.AIPlay
body: <p>I have developed an AI HTML5 game.
  It could run well locally.
  But after deployed to github page, some js problems occurs.</p>
  <p>AI.js</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var AI = AI||{};
  
  AI.historyTable =   {};     //��ʷ��
  
  
  //�˹����ܳ�ʼ��
  AI.init = function(pace){
      var bill = AI.historyBill || com.gambit; //���ֿ�
      if (bill.length){
          var len=pace.length;
          var arr=[];
          //����������
          for (var i=0;i&lt; bill.length;i++){
              if (bill[i].slice(0,len)==pace) {
              arr.push(bill[i]);
              }
          }
          if (arr.length){
              var inx=Math.floor( Math.random() * arr.length );
              AI.historyBill = arr ;
              return arr[inx].slice(len,len+4).split("");
          }else{
              AI.historyBill = [] ;
          }
          
      }
       //�����������û�У��˹����ܿ�ʼ����
      var initTime = new Date().getTime();
      AI.treeDepth=play.depth;
      //AI.treeDepth=4;
      
      AI.number=0;
      AI.setHistoryTable.lenght = 0
  
      var val=AI.getAlphaBeta(-99999 ,99999, AI.treeDepth, com.arr2Clone(play.map),play.my);
      //var val = AI.iterativeSearch(com.arr2Clone(play.map),play.my)
      if (!val||val.value==-8888) {
          AI.treeDepth=2;
          val=AI.getAlphaBeta(-99999 ,99999, AI.treeDepth, com.arr2Clone(play.map),play.my);
      }
      //var val = AI.iterativeSearch(com.arr2Clone(play.map),play.my);
      if (val&amp;&amp;val.value!=-8888) {
          var man = play.mans[val.key];
          var nowTime= new Date().getTime();
          com.get("moveInfo").innerHTML='&lt;h3&gt;AI���������&lt;/h3&gt;����ŷ���'+
                                          com.createMove(com.arr2Clone(play.map),man.x,man.y,val.x,val.y)+
                                          '&lt;br /&gt;������ȣ�'+AI.treeDepth+'&lt;br /&gt;������֧��'+
                                          AI.number+'�� &lt;br /&gt;����ŷ�������'+
                                          val.value+'��'+
                                          ' &lt;br /&gt;������ʱ��'+
                                          (nowTime-initTime)+'����'
          return [man.x,man.y,val.x,val.y]
      }else {
          return false;   
      }
  }
  
  //�������������ŷ�
  AI.iterativeSearch = function (map, my){
      var timeOut=100;
      var initDepth = 1;
      var maxDepth = 8;
      AI.treeDepth=0;
      var initTime = new Date().getTime();
      var val = {};
      for (var i=initDepth; i&lt;=maxDepth; i++){
          var nowTime= new Date().getTime();
          AI.treeDepth=i;
          AI.aotuDepth=i;
          var val = AI.getAlphaBeta(-99999, 99999, AI.treeDepth , map ,my)
          if (nowTime-initTime &gt; timeOut){
              return val;
          }
      }
      return false;
  }
  
  //ȡ����������������
  AI.getMapAllMan = function (map, my){
      var mans=[];
      for (var i=0; i&lt;map.length; i++){
          for (var n=0; n&lt;map[i].length; n++){
              var key = map[i][n];
              if (key &amp;&amp; play.mans[key].my == my){
                  play.mans[key].x = n;
                  play.mans[key].y = i;
                  mans.push(play.mans[key])
              }
          }
      }
      return mans;
  }
  
  /*
  //ȡ���������м������ӵ��ŷ�
  AI.getMoves = function (map, my, txtMap){
      var highMores = [];   //���ȼ��ߵ��ŷ�
      var manArr = AI.getMapAllMan (map, my);
      var moves = [];
      var history=AI.historyTable[txtMap];
      for (var i=0; i&lt;manArr.length; i++){
          var man = manArr[i];
          var val=man.bl(map);
          for (var n=0; n&lt;val.length; n++){
              if (history){
                  highMores.push([man.x,man.y,val[n][0],val[n][1],man.key])
              }else{
                  moves.push([man.x,man.y,val[n][0],val[n][1],man.key])
              }
          }
      }
      return highMores.concat(moves);
  }
  */
  //ȡ���������м������ӵ��ŷ�
  AI.getMoves = function (map, my){
      var manArr = AI.getMapAllMan (map, my);
      var moves = [];
      var foul=play.isFoul;
      for (var i=0; i&lt;manArr.length; i++){
          var man = manArr[i];
          var val=man.bl(map);
          
          for (var n=0; n&lt;val.length; n++){
              var x=man.x;
              var y=man.y;
              var newX=val[n][0];
              var newY=val[n][1];
               //������ǳ����ŷ�
              if (foul[0]!=x || foul[1]!=y || foul[2]!=newX || foul[3]!=newY ){
                  moves.push([x,y,newX,newY,man.key])
              }
          }
      }
      return moves;
  }
  //A:��ǰ����value/B:����value/depth���㼶
  AI.getAlphaBeta = function (A, B, depth, map ,my) { 
      //var txtMap= map.join();
      //var history=AI.historyTable[txtMap];
      //  if (history &amp;&amp; history.depth &gt;= AI.treeDepth-depth+1){
      //      return  history.value*my;
      //}
      if (depth == 0) {
          return {"value":AI.evaluate(map , my)}; //�������ۺ���; 
  ��  }
  ��  var moves = AI.getMoves(map , my ); //����ȫ���߷�; 
  ��  //���������Ժ������Ч��
  
      for (var i=0; i &lt; moves.length; i++) {
          
          
  ����    //������߷�;
          var move= moves[i];
          var key = move[4];
          var oldX= move[0];
          var oldY= move[1];
          var newX= move[2];
          var newY= move[3];
          var clearKey = map[ newY ][ newX ]||"";
  
          map[ newY ][ newX ] = key;
          delete map[ oldY ][ oldX ];
          play.mans[key].x = newX;
          play.mans[key].y = newY;
          
      ����if (clearKey=="j0"||clearKey=="J0") {//�����Ͻ�,��������߷�; 
              play.mans[key]  .x = oldX;
              play.mans[key]  .y = oldY;
              map[ oldY ][ oldX ] = key;
              delete map[ newY ][ newX ];
              if (clearKey){
                   map[ newY ][ newX ] = clearKey;
                  // play.mans[ clearKey ].isShow = false;
              }
  
              return {"key":key,"x":newX,"y":newY,"value":8888};
              //return rootKey; 
      ����}else { 
      ����    var val = -AI.getAlphaBeta(-B, -A, depth - 1, map , -my).value; 
              //val = val || val.value;
      
      ����    //��������߷�;�� 
              play.mans[key]  .x = oldX;
              play.mans[key]  .y = oldY;
              map[ oldY ][ oldX ] = key;
              delete map[ newY ][ newX ];
              if (clearKey){
                   map[ newY ][ newX ] = clearKey;
                   //play.mans[ clearKey ].isShow = true;
              }
      ����    if (val &gt;= B) { 
                  //������߷���¼����ʷ����; 
                  //AI.setHistoryTable(txtMap,AI.treeDepth-depth+1,B,my);
                  return {"key":key,"x":newX,"y":newY,"value":B}; 
              } 
              if (val &gt; A) { 
      ��������    A = val; //��������߷�; 
                  if (AI.treeDepth == depth) var rootKey={"key":key,"x":newX,"y":newY,"value":A};
              } 
          } 
  ��  } 
      //������߷���¼����ʷ����; 
      //AI.setHistoryTable(txtMap,AI.treeDepth-depth+1,A,my);
      if (AI.treeDepth == depth) {//�Ѿ��ݹ�ظ���
          if (!rootKey){
              //AIû������߷���˵��AI�������ˣ�����false
              return false;
          }else{
              //�����������߷�;
              return rootKey;
          }
      }
  ��return {"key":key,"x":newX,"y":newY,"value":A}; 
  }
  
  //���ŷ���¼����ʷ��
  AI.setHistoryTable = function (txtMap,depth,value,my){
      AI.setHistoryTable.lenght ++;
      AI.historyTable[txtMap] = {depth:depth,value:value} 
  }
  
  //������� ȡ������˫�����Ӽ�ֵ��
  AI.evaluate = function (map,my){
      var val=0;
      for (var i=0; i&lt;map.length; i++){
          for (var n=0; n&lt;map[i].length; n++){
              var key = map[i][n];
              if (key){
                  val += play.mans[key].value[i][n] * play.mans[key].my;
              }
          }
      }
      //val+=Math.floor( Math.random() * 10);  //��AI�����������Ԫ��
      //com.show()
      //z(val*my)
      AI.number++;
      return val*my;
  }
  
  //������� ȡ������˫�����Ӽ�ֵ��
  AI.evaluate1 = function (map,my){
      var val=0;
      for (var i in play.mans){
          var man=play.mans[i];
          if (man.isShow){
              val += man.value[man.y][man.x] * man.my;
          }
      }
      //val+=Math.floor( Math.random() * 10);  //��AI�����������Ԫ��
      //com.show()
      //z(val*my)
      AI.number++;
      return val*my;
  }</code></pre>
  </div>
  </div>
  </p>
  <p>HTML:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  &lt;html xmlns="https://www.w3.org/1999/xhtml"&gt;
  &lt;head&gt;
  &lt;meta http-equiv="Content-Type" content="text/html; charset=gb2312" /&gt;
  &lt;title&gt;AI Chinese Chess Game&lt;/title&gt;
  
  &lt;link href="css/zzsc.css" type="text/css" rel="stylesheet" /&gt;
  
  &lt;/head&gt;
  &lt;body&gt;
  &lt;div class="box" id="box"&gt;
      &lt;H4&gt;AI Chinese chess game. Please use Chrome, Firefox, Safari or Opera browser.&lt;/H4&gt;
      &lt;embed src="/Greensleeves.mp3" loop="true" autostart="true" width="2" height="0"&gt;
      &lt;div class="chess_left"&gt;
          &lt;canvas id="chess"&gt;Sorry, please change to Chrome Browser！&lt;/canvas&gt;
          &lt;audio src="audio/click.wav" id="clickAudio" preload="auto"&gt;&lt;/audio&gt;
          &lt;!--&lt;audio src="audio/check.wav" id="checkAudio" preload="auto"&gt;&lt;/audio&gt;--&gt;
          &lt;audio src="audio/select.wav" id="selectAudio" preload="auto"&gt;&lt;/audio&gt;
          &lt;div&gt;
              &lt;div class="bn_box" id="bnBox"&gt;
                  &lt;input type="button" style="background:green; cursor:pointer" name="offensivePlay" id="tyroPlay" value="Beginner Level" /&gt;
                  &lt;input type="button" style="background:red; cursor:pointer" name="offensivePlay" id="superPlay" value="Advanced Level" /&gt;
  
                  &lt;!--input type="button" name="button" id="" value="大师水平" disabled /--&gt;
                  &lt;!--
              &lt;input type="button" name="offensivePlay" id="offensivePlay" value="先手开始" /&gt;
              &lt;input type="button" name="defensivePlay" id="defensivePlay" value="后手开始" /&gt;
              --&gt;
                  &lt;input type="button" style="background:yellow; cursor:pointer" name="regret" id="regretBn" value="Restart" /&gt;
                  &lt;input type="button" name="billBn" id="billBn" value="map" class="bn_box" /&gt;
                  &lt;!--input type="button" name="stypeBn" id="stypeBn" value="Change Background" /--&gt;
              &lt;/div&gt;
          &lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="chess_right" id="chessRight"&gt;
          &lt;select name="billList" id="billList"&gt;
          &lt;/select&gt;
          &lt;ol id="billBox" class="bill_box"&gt;
          &lt;/ol&gt;
      &lt;/div&gt;
      &lt;div id="moveInfo" class="move_info"&gt; &lt;/div&gt;
  &lt;/div&gt;
  &lt;script src="js/common.js"&gt;&lt;/script&gt; 
  &lt;script src="js/play.js"&gt;&lt;/script&gt; 
  &lt;script src="js/AI.js"&gt;&lt;/script&gt; 
  &lt;script src="js/bill.js"&gt;&lt;/script&gt; 
  &lt;script src="js/gambit.js"&gt;&lt;/script&gt;
  &lt;div style="text-align:center;clear:both"&gt;
  
  &lt;/div&gt;
  &lt;/body&gt;
  &lt;/html&gt;</code></pre>
  </div>
  </div>
  </p>
  <p>play.js:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>var play = play||{};
  
  play.init = function (){
      
      play.my             =   1;              //玩家方
      play.map            =   com.arr2Clone (com.initMap);        //初始化棋盘
      play.nowManKey      =   false;          //现在要操作的棋子
      play.pace           =   [];             //记录每一步
      play.isPlay         =   true ;          //是否能走棋
      play.mans           =   com.mans;
      play.bylaw          =   com.bylaw;
      play.show           =   com.show;
      play.showPane       =   com.showPane;
      play.isOffensive    =   true;           //是否先手
      play.depth          =   play.depth || 3;                //搜索深度
      
      play.isFoul         =   false;  //是否犯规长将
      
      
      
      com.pane.isShow     =    false;         //隐藏方块
      
      //初始化棋子
      for (var i=0; i&lt;play.map.length; i++){
          for (var n=0; n&lt;play.map[i].length; n++){
              var key = play.map[i][n];
              if (key){
                  com.mans[key].x=n;
                  com.mans[key].y=i;
                  com.mans[key].isShow = true;
              }
          }
      }
      play.show();
      
      //绑定点击事件
      com.canvas.addEventListener("click",play.clickCanvas)
      //clearInterval(play.timer);
      //com.get("autoPlay").addEventListener("click", function(e) {
          //clearInterval(play.timer);
          //play.timer = setInterval("play.AIPlay()",1000);
      //  play.AIPlay()
      //})
      /*
      com.get("offensivePlay").addEventListener("click", function(e) {
          play.isOffensive=true;
          play.isPlay=true ;  
          com.get("chessRight").style.display = "none";
          play.init();
      })
      
      com.get("defensivePlay").addEventListener("click", function(e) {
          play.isOffensive=false;
          play.isPlay=true ;  
          com.get("chessRight").style.display = "none";
          play.init();
      })
      */
      
      
      com.get("regretBn").addEventListener("click", function(e) {
          play.regret();
      })
      
      /*
      var initTime = new Date().getTime();
      for (var i=0; i&lt;=100000; i++){
          
          var h=""
          var h=play.map.join();
          //for (var n in play.mans){
          //  if (play.mans[n].show) h+=play.mans[n].key+play.mans[n].x+play.mans[n].y
          //}
      }
      var nowTime= new Date().getTime();
      z([h,nowTime-initTime])
      */
      
  }
  
  
  
  //悔棋
  play.regret = function (){
      var map  = com.arr2Clone(com.initMap);
      //初始化所有棋子
      for (var i=0; i&lt;map.length; i++){
          for (var n=0; n&lt;map[i].length; n++){
              var key = map[i][n];
              if (key){
                  com.mans[key].x=n;
                  com.mans[key].y=i;
                  com.mans[key].isShow = true;
              }
          }
      }
      var pace= play.pace;
      pace.pop();
      pace.pop();
      
      for (var i=0; i&lt;pace.length; i++){
          var p= pace[i].split("")
          var x = parseInt(p[0], 10);
          var y = parseInt(p[1], 10);
          var newX = parseInt(p[2], 10);
          var newY = parseInt(p[3], 10);
          var key=map[y][x];
          //try{
       
          var cMan=map[newY][newX];
          if (cMan) com.mans[map[newY][newX]].isShow = false;
          com.mans[key].x = newX;
          com.mans[key].y = newY;
          map[newY][newX] = key;
          delete map[y][x];
          if (i==pace.length-1){
              com.showPane(newX ,newY,x,y)    
          }
          //} catch (e){
          //  com.show()
          //  z([key,p,pace,map])
              
          //  }
      }
      play.map = map;
      play.my=1;
      play.isPlay=true;
      com.show();
  }
  
  
  
  //点击棋盘事件
  play.clickCanvas = function (e){
      if (!play.isPlay) return false;
      var key = play.getClickMan(e);
      var point = play.getClickPoint(e);
      
      var x = point.x;
      var y = point.y;
      
      if (key){
          play.clickMan(key,x,y); 
      }else {
          play.clickPoint(x,y);   
      }
      play.isFoul = play.checkFoul();//检测是不是长将
  }
  
  //点击棋子，两种情况，选中或者吃子
  play.clickMan = function (key,x,y){
      var man = com.mans[key];
      //吃子
      if (play.nowManKey&amp;&amp;play.nowManKey != key &amp;&amp; man.my != com.mans[play.nowManKey ].my){
          //man为被吃掉的棋子
          if (play.indexOfPs(com.mans[play.nowManKey].ps,[x,y])){
              man.isShow = false;
              var pace=com.mans[play.nowManKey].x+""+com.mans[play.nowManKey].y
              //z(bill.createMove(play.map,man.x,man.y,x,y))
              delete play.map[com.mans[play.nowManKey].y][com.mans[play.nowManKey].x];
              play.map[y][x] = play.nowManKey;
              com.showPane(com.mans[play.nowManKey].x ,com.mans[play.nowManKey].y,x,y)
              com.mans[play.nowManKey].x = x;
              com.mans[play.nowManKey].y = y;
              com.mans[play.nowManKey].alpha = 1
              
              play.pace.push(pace+x+y);
              play.nowManKey = false;
              com.pane.isShow = false;
              com.dot.dots = [];
              com.show()
              com.get("clickAudio").play();
              setTimeout("play.AIPlay()",500);
              if (key == "j0") play.showWin (-1);
              if (key == "J0") play.showWin (1);
          }
      // 选中棋子
      }else{
          if (man.my===1){
              if (com.mans[play.nowManKey]) com.mans[play.nowManKey].alpha = 1 ;
              man.alpha = 0.6;
              com.pane.isShow = false;
              play.nowManKey = key;
              com.mans[key].ps = com.mans[key].bl(); //获得所有能着点
              com.dot.dots = com.mans[key].ps
              com.show();
              //com.get("selectAudio").start(0);
              com.get("selectAudio").play();
          }
      }
  }
  
  //点击着点
  play.clickPoint = function (x,y){
      var key=play.nowManKey;
      var man=com.mans[key];
      if (play.nowManKey){
          if (play.indexOfPs(com.mans[key].ps,[x,y])){
              var pace=man.x+""+man.y
              //z(bill.createMove(play.map,man.x,man.y,x,y))
              delete play.map[man.y][man.x];
              play.map[y][x] = key;
              com.showPane(man.x ,man.y,x,y)
              man.x = x;
              man.y = y;
              man.alpha = 1;
              play.pace.push(pace+x+y);
              play.nowManKey = false;
              com.dot.dots = [];
              com.show();
              com.get("clickAudio").play();
              setTimeout("play.AIPlay()",500);
          }else{
              //alert("不能这么走哦！")  
          }
      }
      
  }
  
  //Ai自动走棋
  play.AIPlay = function (){
      //return
      play.my = -1 ;
      var pace=AI.init(play.pace.join(""))
      if (!pace) {
          play.showWin (1);
          return ;
      }
      play.pace.push(pace.join(""));
      var key=play.map[pace[1]][pace[0]]
          play.nowManKey = key;
      
      var key=play.map[pace[3]][pace[2]];
      if (key){
          play.AIclickMan(key,pace[2],pace[3]);   
      }else {
          play.AIclickPoint(pace[2],pace[3]); 
      }
      com.get("clickAudio").play();
      
      
  }
  
  //检查是否长将
  play.checkFoul = function(){
      var p=play.pace;
      var len=parseInt(p.length,10);
      if (len&gt;11&amp;&amp;p[len-1] == p[len-5] &amp;&amp;p[len-5] == p[len-9]){
          return p[len-4].split("");
      }
      return false;
  }
  
  
  
  play.AIclickMan = function (key,x,y){
      var man = com.mans[key];
      //吃子
      man.isShow = false;
      delete play.map[com.mans[play.nowManKey].y][com.mans[play.nowManKey].x];
      play.map[y][x] = play.nowManKey;
      play.showPane(com.mans[play.nowManKey].x ,com.mans[play.nowManKey].y,x,y)
      
      com.mans[play.nowManKey].x = x;
      com.mans[play.nowManKey].y = y;
      play.nowManKey = false;
      
      com.show()
      if (key == "j0") play.showWin (-1);
      if (key == "J0") play.showWin (1);
  }
  
  play.AIclickPoint = function (x,y){
      var key=play.nowManKey;
      var man=com.mans[key];
      if (play.nowManKey){
          delete play.map[com.mans[play.nowManKey].y][com.mans[play.nowManKey].x];
          play.map[y][x] = key;
          
          com.showPane(man.x,man.y,x,y)
          
      
          man.x = x;
          man.y = y;
          play.nowManKey = false;
          
      }
      com.show();
  }
  
  
  play.indexOfPs = function (ps,xy){
      for (var i=0; i&lt;ps.length; i++){
          if (ps[i][0]==xy[0]&amp;&amp;ps[i][1]==xy[1]) return true;
      }
      return false;
      
  }
  
  //获得点击的着点
  play.getClickPoint = function (e){
      var domXY = com.getDomXY(com.canvas);
      var x=Math.round((e.pageX-domXY.x-com.pointStartX-20)/com.spaceX)
      var y=Math.round((e.pageY-domXY.y-com.pointStartY-20)/com.spaceY)
      return {"x":x,"y":y}
  }
  
  //获得棋子
  play.getClickMan = function (e){
      var clickXY=play.getClickPoint(e);
      var x=clickXY.x;
      var y=clickXY.y;
      if (x &lt; 0 || x&gt;8 || y &lt; 0 || y &gt; 9) return false;
      return (play.map[y][x] &amp;&amp; play.map[y][x]!="0") ? play.map[y][x] : false;
  }
  
  play.showWin = function (my){
      play.isPlay = false;
      if (my===1){
          alert("Congratulations, You win me!");
      }else{
          alert("Haha you are beaten up by AI, please try again later^^.");
      }
  }</code></pre>
  </div>
  </div>
  </p>
  <p>error occurs at this line: <code>var pace=AI.init(play.pace.join(&quot;&quot;))</code></p>
  <p>error details:</p>
  <pre><code>  Uncaught ReferenceError: AI is not defined
  at Object.play.AIPlay 
  </code></pre>
  <p>when I run it in my local computer, it could run well. But after deployed to github page, it could not run the js script well. Why get this not defined error after deployment?</p>