完整版可运行代码

来源:-

qq_晨曦_60

2017-12-23 13:17

我根据老师的代码和逻辑补充和稍有修改的代码,老师没有讲的地方都有详细的注释,其中的search函数在我的代码中,用自己写的函数find代替了,但是应该跟老师的search函数的功能是一样的。经测试,功能也没有问题。大家可以参考一下,有什么问题,欢迎指出。 

<!DOCTYPE html>

<html>

<head>

<title>Binary  Tree</title>

    <STYLE TYPE="text/css">

     #stage{

      width: 300px;

      height: 300px;

      position: relative;

     }


     #background {

      width: 300px;

      height: 300px;

      position: absolute;

      top: 0px;

      left: 0px;

      background: url(./images/background.jpg);

     }


     

     #cannon{

      width: 20px;

      height: 20px;

      position: absolute;

      top: 270px;

      left: 140px; 

      background-image: url(./images/cannon.jpg);

     }

    


    #alien{

    width: 20px;

    height: 20px;

    position: absolute;

    top: 20px;

    left: 80px;

    background-image: url(./images/alien.jpg);

    }




    #missile{

    width: 10px;

    height: 10px;

    position: absolute;

    top: 270px;

    left: 140px;

    }

    


    #explosion{

    width: 20px;

    height: 20px;

    position: absolute;

    top: 0px;

    left: 0px;

    background-image: url(./images/explosion.jpg);

    display: none;

    }


 


    </STYLE>

</head>

<body>

    <div id="stage">

    <div id="background"></div>

    <div id="cannon"></div>

    <div id="missile"></div>

    <div id="alien"></div>

    <div id="explosion"></div>

    </div><!--<div id="stage">-->

    

    <p id="output">请输入X和Y坐标(0-300),然后点击fire.</p>

   <input  id="inputX" type="text" placeholder="X...">

   <input  id="inputY" type="text" placeholder="Y...">

   <button>fire!</button>

    <script type="text/javascript">

    function BinaryTree(){

    //这个Node类在外星人游戏中需要添加一个selected,表示该节点是否被选中,即该结点是否是外星人当前的横坐标

    var Node=function(key){

    this.key=key;

    this.left=null;

    this.right=null;

    this.selected=false;

    };


            //插入非根结点的方法

            var insertNode= function(node,newNode){

            if(newNode.key<node.key){

            if(node.left==null){

            node.left=newNode;

            }else{

            insertNode(node.left,newNode);

            }

            }else{

            if(node.right==null){

            node.right=newNode;

            }

            else{

            insertNode(node.right,newNode);

            }

            }

           };

         


            //创建树的接口

    var root=null;

    this.insert=function(key){

    var newnode=new Node(key);

    if(root==null){

    root=newnode;

    }else{

                    insertNode(root,newnode)

    };

    }


       

        //中序遍历的方法

       var inOrderTraverseNode=function(node,callback){

        if(node!=null){

        inOrderTraverseNode(node.left,callback);

           callback(node.key);

           inOrderTraverseNode(node.right,callback);

        }

       }

         

        //中序遍历的接口

    this.inOrderTraverse=function(callback){

    inOrderTraverseNode(root,callback);

    }  



        //求最小值,即求二叉树的最左边的结点

       var minNode=function(node){

         if(node){

          while(node&&node.left!=null){

          node=node.left;

          }


            return node.key;    


         }

       }


         //求最小值的接口

        this.min=function(){

        return minNode(root);

        }


       


      //查找x结点的方法,原来的方法是返回true,或者false,但是在外星人游戏中应该返回的是结点

      var  findKey=function(node,key){

      if(node!=null){

      if(node.key==key){

      return node;

      }

      if(node.key<key){

      return findKey(node.right,key);

      }else{

      return findKey(node.left,key);

      }

      }

      return null;

      }

      //查找某个结点的接口

      this.find=function(key){

           return findKey(root,key);

      }

      //前序遍历的算法

      var preOrderTraverseNode=function(node,callback){

      if(node!==null){

      //原来的前序遍历是callback(node.key),但是我们这里要存入nodesForAlien数组的是结点值所以改成callback(node)

      callback(node);

      preOrderTraverseNode(node.left,callback);

      preOrderTraverseNode(node.right,callback);

      }

      }

      //前序遍历的接口

      this.preOrderTraverse=function(callback){

      preOrderTraverseNode(root,callback);

      }


    }//function BinaryTree()

 


      

        //二叉树的初始化,首先初始化nodes数组中的值,在外星人游戏中也是nodesForAlien数组的结点的key值

    var nodes=[];

    //往nodes数值注入9个在0-281这个区间的值,这个9个数也是9个可能出现的外星人横坐标

    for(var i=0;i<10;i++){

    nodes.push(Math.floor(Math.random()*281));

    }

    //按照nodes数组的值创建二叉树

    var binaryTree=new BinaryTree();

    nodes.forEach(function(key){

    binaryTree.insert(key);

    })

        



        //定义一个数组nodesForAlien

        var nodesForAlien=[];

        //定义一个回调函数,把当前访问的二叉树结点存入数组

    var callback=function(node){

    nodesForAlien.push(node);

    }

    //调用二叉树的前序便遍历,访问二叉树,按照前序遍历的顺序把二叉树所有的结点存入nodesForAlien数组中

    //这一步也就是初始化nodesForAlien数组,以后外星人的横坐标也就只能是在这个数组中的值。

       binaryTree.preOrderTraverse(callback);

       //把0-9中的一个随机的整数复制给alienNodeSelect

       var alienNodeSelect=Math.floor(Math.random()*9);

       //让数组中下标为alienNodeSelect的元素的selected为true,即表示这个结点的key值就是外星人当前的横坐标

       nodesForAlien[alienNodeSelect].selected=true;

       //当前选择的结点key值就是当前外星人的横坐标

       var alienX=nodesForAlien[alienNodeSelect].key;




       // console.log("the minNode is  "+binaryTree.min()) ;

       // console.log("the node is in the tree:"+binaryTree.find(12));

    //binaryTree.inOrderTraverse(callback)



      //Game section

      var alienY=0;

      var guessX=0;

      var guessY=0;

      var shotsRemaning=8;

      var shotsMade=0;

      var gameState="";

      var gameWon=false;

      

      var cannon=document.querySelector("#cannon");

      var alien=document.querySelector("#alien");

      var missile=document.querySelector("#missile");

      var explosion=document.querySelector("#explosion");


      var inputX=document.querySelector("#inputX");

      var inputY=document.querySelector("#inputY");

      var output=document.querySelector("#output");


      var button=document.querySelector("button");

      button.style.cursor="pointer";

      button.addEventListener("click",clickHandler,false);

      window.addEventListener("keydown",keydownHandler,false);


      function clickHandler(){

      validateInput();

      }


      function keydownHandler(event){

      if(event.keyCode===13){

      validateInput();

      }

      }


      function validateInput(){

      guessX=parseInt(inputX.value);

      guessY=parseInt(inputY.value);


      if(isNaN(guessX)||isNaN(guessY)){

      output.innerHTML="请输入坐标";

      }else if(guessX>300||guessY>300){

      output.innerHTML="坐标不能大于300";

      }else{

      playGame();

      }

      }



      function playGame(){

      shotsRemaning =shotsRemaning-1;

      shotsMade=shotsMade+1;

      gameState="炮弹:"+",数量:"+shotsRemaning;


      guessX=parseInt(inputX.value);

      guessY=parseInt(inputY.value);

      var alienNode=binaryTree.find(guessX);

      if(alienNode!=null&&alienNode.selected==true){

      if(guessY>=alienY&&guessY<=alienY+20){

      gameWon=true;

      endGame();

      }

      }else{

      output.innerHTML="没有击中!"+"<br>"+gameState;

      if(shotsRemaning<1){

      endGame();

      }

      }


      if(!gameWon){

      nodesForAlien[alienNodeSelect].selected=false;

      alienNodeSelect=Math.floor(Math.random()*9);

      nodesForAlien[alienNodeSelect].selected=true;

      alienX=nodesForAlien[alienNodeSelect].key;

      alienY+=30;

      }

      render();

      console.log("X: "+alienX);

      console.log("Y: "+alienY);

      };



      function render(){

      alien.style.left=alienX+"px";

      alien.style.top=alienY+"px";


      cannon.style.left=guessX+"px";


      missile.style.left=guessX+"px";

      missile.style.top=guessY+"px";


      if(gameWon){

      explosion.style.display="block";

      explosion.style.left=alienX+"px";

      explosion.style.top=alienY+"px";


      alien.style.display="none";

      missile.style.display="none";

      }

      }


     function endGame(){

      if(gameWon){

      output.innerHTML="Hit! 你拯救了地球"+"<br>"+"你发射了炮弹"+shotsMade+"枚."

      }else{

      output.innerHTML="失败了!"+"<br>"+"地球被外星人侵略!";

      }


      button.removeEventListener("click",clickHandler,false);

      button.disabled=true;


      window.removeEventListener("keydown",keydownHandler,false);

      inputX.disabled=true;

      inputY.disabled=true;

     }


    </script>

</body>

</html>



写回答 关注

1回答

  • qq_晨曦_60
    2017-12-23 13:23:38

    我根据老师的代码和逻辑补充和稍有修改的代码,老师没有讲的地方都有详细的注释,其中的search函数在我的代码中,用自己写的函数find代替了,但是应该跟老师的search函数的功能是一样的。经测试,功能也没有问题。大家可以参考一下,有什么问题,欢迎指出。 

Javascript实现二叉树算法

感受JS与数据结构的魅力。

46934 学习 · 97 问题

查看课程

相似问题