zoukankan      html  css  js  c++  java
  • JavaScript一个猜数字游戏

    效果图:

    代码:

    <body>
    <script type="text/javascript">
    window.onload = newgame;		//页面载入的时候就开始一个新的游戏
    window.onpopstate = popState;	//处理历史记录相关事件
    var state,ui;			//全局变量,在newgame()方法中会对其初始化
    
    function newgame( playagin ){	//开始一个新的猜数字游戏
    	//初始化一个包含需要的文档元素的对象
    	ui ={
    		heading: null,	//文档最上面的<h1>元素
    		prompt : null,	//要求用户输入一个猜测数字
    		input : null,	//用户输入猜测数字的地方
    		low : null,	//可视化的三个表单单元格
    		mid : null,	//猜测的数字范围
    		high : null
    	};
    
    	//查询这些元素中每个元素的id
    	for(var id in ui)
    		ui[id] = document.getElementById(id);
    
    	//给input字段定义一个事件处理程序函数
    	ui.input.onchange = handleGuess;
    
    	//生成一个随机的数字并初始化游戏状态
    	state ={
    		n : Math.floor(99*Math.random())+1,	//整数: 0<n<100
    		low : 0,		//可猜测数字范围的下限
    		high : 100,		//可猜测数字范围的上限
    		guessnum : 0 ,	//猜测次数
    		guess : undefined //最后一次猜测
    	};
    
    	//修改文档内容来显示该初始状态
    	display(state);
    
    	/**
    	 * 此函数会作为onload事件处理程序调用,
    	 * 同时当单机显示在游戏最后的“再玩一次”按钮时候,也会调用它
    	 * 在第二种调用情况下,playagain参数值为true
    	 * 如果playagain为true,则保存新的游戏状态
    	 * 但是如果是作为onload事件处理程序调用的情况下,则不保存状态
    	 * 这是因为,当通过浏览器历史记录从其他文档状态回退到当前的游戏状态时,
    	 * 也会出发load事件,如果这种情况下,也保存状态的话
    	 * 会将真正的游戏历史状态记录覆盖掉
    	 * 在支持pushState()方法的浏览器中,load事件之后总是有一个popstate事件
    	 * 因此,这里的处理方式是,等待popstate事件而不是之间进行状态保存
    	 * 如果该事件提供一个状态对象,则直接使用该对象即可
    	 * 如果该事件没有状态对象,就表示这实际上是一个新的游戏
    	 * 则使用replaceState来保存最新的游戏状态
    	 */
    	if(playagin ==true)
    		save(state);
    }
    
    //如果支持的话,就使用pushState()方法将游戏状态保存到浏览器历史记录中
    function save(state){
    	if(!history.pushState)
    		return;		//如果pushState()方法没有定义的话,则什么也不做
    
    	//这里会将一个保存的状态和URL关联起来
    	//该URL显示猜测的数字,但是不对游戏状态进行编码
    	//因此,这对于书签是没有用的
    	//不能简单地游戏状态写到URL中,因为这会将游戏一些机密数字暴露在地址栏中
    	var url = "#guess"+state.guessnum;
    	//保存状态对象和URL
    	history.pushState(state,	//要保存的状态对象
    			"",					//状态标题,当前浏览器会忽略它
    			url 				//状态URL:对书签是没有用的
    		);
    }
    
    //这是onpopstate的事件处理程序,用于恢复历史状态
    function popState(event){
    	if(event.state){	//如果事件有一个状态对象,则恢复该状态
    		//要注意的是,event.state是对已保存状态对象的一个深拷贝
    		//因此无须改变保存的值就可以修改该对象
    		state = event.state;		//恢复历史状态
    		display(state);				//显示恢复的状态
    	}else{
    		//当第一次载入页面时,会触发一个没有状态的popstate事件
    		//用真实的状态将null状态替换掉: 参见newgame()方法中的注释
    		//这里不需要调用display()方法
    		history.replaceState(state,"","#guess"+state.guessnum);
    	}
    };
    
    //每次用户猜测一个数字的时候,都会调用此事件处理程序
    //此处处理程序用于更新游戏的状态、保存游戏状态并显示游戏游戏状态
    function handleGuess(){
    	//从input字段中获取用户猜测的数字
    	var g = parseInt(this.value);
    	//如果该值是限定范围中的一个数字
    	if((g > state.low)&&(g<state.high)){
    		//对应的更新状态对象
    		if(g < state.n)
    			state.low = g;
    		else
    			if(g > state.n)
    				state.high = g;
    	state.guess = g;
    	state.guessnum++;
    	//在浏览器历史记录中保存新的状态
    	save(state);
    	//根据用户猜测情况来修改文档
    	display(state);
    	}
    	else{		//无效的猜测
    		alert("请输入一个比"+state.low+",并且比"+state.high+"大的数。");
    	}
    }
    
    //修改文档显示游戏当前状态
    function display(state){
    	//显示文档的导航和标题
    	ui.heading.innerHTML =document.title="我认为这个数字是"+state.low+"~"+state.high+"之间。";
    
    	//使用一个表格来显示数字的取值范围
    	ui.low.style.width = state.low+"%";
    	ui.mid.style.width = (state.high-state.low)+"%";
    	ui.high.style.width = (100-state.high)+"%";
    
    	//根据用户最近的猜测,设置提示
    	if(state.guess===undefined)
    		ui.prompt.innerHTML = "你的输入有误!";
    	else if(state.guess < state.n)
    		ui.prompt.innerHTML = state.guess + "太小了,请重新输入:";
    	else if(state.guess > state.n)
    		ui.prompt.innerHTML = state.guess + "太大了,请重新输入:";
    	else{
    		//当才对了的时候,就隐藏input字段并显示“再玩一次”按钮
    		ui.input.style.visibility = "hidden"; 	//不需要再猜了
    		ui.heading.innerHTML = document.title = state.guess+"命中答案。"
    		ui.prompt.innerHTML = "你赢了,<button onclick='newgame(true)'>再玩一次</button>";
    	}
    }
    </script>
    <style type="text/css">
    #prompt {font-size: 16pt;}
    table{ 90%; margin: 10px; margin-left: 5%;}
    #low,#high{ background: lightgray; height: 1em; }
    #mid{background-color: green;}
    </style>
    	<h1 id="heading">我在等一个数:</h1>
    	<table>
    		<tr>
    			<td id="low"></td>
    			<td id="mid"></td>
    			<td id="high"></td>
    		</tr>
    	</table>
    	<label id="prompt"></label><input type="text" id="input">
    </body>
    

      

  • 相关阅读:
    js---查找数组中的最大值(最小值),及相应的下标
    JS数组遍历的几种方法
    在 forEach 中使用 async/await 遇到的问题
    js 事件冒泡和事件捕获
    JS中dom0级事件和dom2级事件的区别介绍
    Vue集成Ueditor
    vue富文本编辑器 Vue-Quill-Editor
    Redis问题1---redis满了怎么办
    jQuery火箭图标返回顶部代码
    遇到的小问题
  • 原文地址:https://www.cnblogs.com/ctsch/p/6935453.html
Copyright © 2011-2022 走看看