完整版可運(yùn)行代碼
我根據(jù)老師的代碼和邏輯補(bǔ)充和稍有修改的代碼,老師沒有講的地方都有詳細(xì)的注釋,其中的search函數(shù)在我的代碼中,用自己寫的函數(shù)find代替了,但是應(yīng)該跟老師的search函數(shù)的功能是一樣的。經(jīng)測(cè)試,功能也沒有問題。大家可以參考一下,有什么問題,歡迎指出。?
<!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">請(qǐng)輸入X和Y坐標(biāo)(0-300),然后點(diǎn)擊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(){
? ? //這個(gè)Node類在外星人游戲中需要添加一個(gè)selected,表示該節(jié)點(diǎn)是否被選中,即該結(jié)點(diǎn)是否是外星人當(dāng)前的橫坐標(biāo)
? ? var Node=function(key){
? ? this.key=key;
? ? this.left=null;
? ? this.right=null;
? ? this.selected=false;
? ? };
? ? ? ? ? ? //插入非根結(jié)點(diǎn)的方法
? ? ? ? ? ? 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);
? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ?};
? ? ? ? ?
? ? ? ? ? ? //創(chuàng)建樹的接口
? ? 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);
? ? } ?
? ? ? ? //求最小值,即求二叉樹的最左邊的結(jié)點(diǎn)
? ? ? ?var minNode=function(node){
? ? ? ? ?if(node){
? ? ? ? ? while(node&&node.left!=null){
? ? ? ? ? node=node.left;
? ? ? ? ? }
? ? ? ? ? ? return node.key; ? ?
? ? ? ? ?}
? ? ? ?}
? ? ? ? ?//求最小值的接口
? ? ? ? this.min=function(){
? ? ? ? return minNode(root);
? ? ? ? }
? ? ? ?
? ? ? //查找x結(jié)點(diǎn)的方法,原來的方法是返回true,或者false,但是在外星人游戲中應(yīng)該返回的是結(jié)點(diǎn)
? ? ? 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;
? ? ? }
? ? ? //查找某個(gè)結(jié)點(diǎn)的接口
? ? ? this.find=function(key){
? ? ? ? ? ?return findKey(root,key);
? ? ? }
? ? ? //前序遍歷的算法
? ? ? var preOrderTraverseNode=function(node,callback){
? ? ? if(node!==null){
? ? ? //原來的前序遍歷是callback(node.key),但是我們這里要存入nodesForAlien數(shù)組的是結(jié)點(diǎn)值所以改成callback(node)
? ? ? callback(node);
? ? ? preOrderTraverseNode(node.left,callback);
? ? ? preOrderTraverseNode(node.right,callback);
? ? ? }
? ? ? }
? ? ? //前序遍歷的接口
? ? ? this.preOrderTraverse=function(callback){
? ? ? preOrderTraverseNode(root,callback);
? ? ? }
? ? }//function BinaryTree()
?
? ? ??
? ? ? ? //二叉樹的初始化,首先初始化nodes數(shù)組中的值,在外星人游戲中也是nodesForAlien數(shù)組的結(jié)點(diǎn)的key值
? ? var nodes=[];
? ? //往nodes數(shù)值注入9個(gè)在0-281這個(gè)區(qū)間的值,這個(gè)9個(gè)數(shù)也是9個(gè)可能出現(xiàn)的外星人橫坐標(biāo)
? ? for(var i=0;i<10;i++){
? ? nodes.push(Math.floor(Math.random()*281));
? ? }
? ? //按照nodes數(shù)組的值創(chuàng)建二叉樹
? ? var binaryTree=new BinaryTree();
? ? nodes.forEach(function(key){
? ? binaryTree.insert(key);
? ? })
? ? ? ??
? ? ? ? //定義一個(gè)數(shù)組nodesForAlien
? ? ? ? var nodesForAlien=[];
? ? ? ? //定義一個(gè)回調(diào)函數(shù),把當(dāng)前訪問的二叉樹結(jié)點(diǎn)存入數(shù)組
? ? var callback=function(node){
? ? nodesForAlien.push(node);
? ? }
? ? //調(diào)用二叉樹的前序便遍歷,訪問二叉樹,按照前序遍歷的順序把二叉樹所有的結(jié)點(diǎn)存入nodesForAlien數(shù)組中
? ? //這一步也就是初始化nodesForAlien數(shù)組,以后外星人的橫坐標(biāo)也就只能是在這個(gè)數(shù)組中的值。
? ? ? ?binaryTree.preOrderTraverse(callback);
? ? ? ?//把0-9中的一個(gè)隨機(jī)的整數(shù)復(fù)制給alienNodeSelect
? ? ? ?var alienNodeSelect=Math.floor(Math.random()*9);
? ? ? ?//讓數(shù)組中下標(biāo)為alienNodeSelect的元素的selected為true,即表示這個(gè)結(jié)點(diǎn)的key值就是外星人當(dāng)前的橫坐標(biāo)
? ? ? ?nodesForAlien[alienNodeSelect].selected=true;
? ? ? ?//當(dāng)前選擇的結(jié)點(diǎn)key值就是當(dāng)前外星人的橫坐標(biāo)
? ? ? ?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="請(qǐng)輸入坐標(biāo)";
? ? ? }else if(guessX>300||guessY>300){
? ? ? output.innerHTML="坐標(biāo)不能大于300";
? ? ? }else{
? ? ? playGame();
? ? ? }
? ? ? }
? ? ? function playGame(){
? ? ? shotsRemaning =shotsRemaning-1;
? ? ? shotsMade=shotsMade+1;
? ? ? gameState="炮彈:"+",數(shù)量:"+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>"+"你發(fā)射了炮彈"+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>
2017-12-23
我根據(jù)老師的代碼和邏輯補(bǔ)充和稍有修改的代碼,老師沒有講的地方都有詳細(xì)的注釋,其中的search函數(shù)在我的代碼中,用自己寫的函數(shù)find代替了,但是應(yīng)該跟老師的search函數(shù)的功能是一樣的。經(jīng)測(cè)試,功能也沒有問題。大家可以參考一下,有什么問題,歡迎指出。?