JavaScript写的一个带AI的井字棋
2018-06-24 02:07:00来源:未知 阅读 ()
最近有一门课结束了,需要做一个井字棋的游戏,我用JavaScript写了一个。首先界面应该问题不大,用html稍微写一下就可以。主要是人机对弈时的ai算法,如何使电脑方聪明起来,是值得思考一下的。开始游戏后,由玩家先行。那么站在计算机的角度,可以对多种情况进行分析,并按照重要程度赋予权值。
情况如下:
1、同一排(行。列。对角线)有且只有两个棋子,并且都是自己的,只要再进一步就能获胜,那么剩下的那个位置权值最高,优先级最大。赋予一级权值。
2、同一排(行。列。对角线)有且只有两个棋子,并且都是对方的(也就是玩家的),只要再进一步,玩家就会成功,所以“我”要堵住,剩下的那个位置赋予二级权值。
3、因为电脑方后行,如果聪明点,需要一直堵玩家方,所以当一排只有一个棋,且是玩家的棋子,那么该排其他位置的权值设为三级。
4、四级权值:一排只有己方(电脑方)的棋子。
5、五级权限:同排没有棋子,包括对方和己方。
实现的时候,每个位置的棋子,可以用二维数组full表示,每个位置的权值大小也用一个二维数组val来表示。玩家方下完后,调用AI方的函数,AI方行棋前,先更新一下权值,然后选出权值最大的位置落子(最优解)。无论是ai还是玩家方,每次落子后都要判断有没有产生输赢。用alert()函数输出结果。
为了表示权值的大小,规定按照一级到五级顺序,依次加 10000、1000、10、5、3
注:由于可能要提交源码,我没有分离出css样式和js文件,不过最好还是分开写更规范。如有不足之处,欢迎批评指正。
源码如下:
<html>
<head>
<meta charset="utf-8">
<title>井字棋</title>
<script>
//定义全局变量
var full=[[0,0,0],[0,0,0],[0,0,0]];//0表示null,1表示我下的,2表示电脑下的
var val=[[1,1,1],[1,1,1],[1,1,1]];//表示每个位置的权值
function judge(){
//检测是否有人赢
//行
for(var i=0;i<3;i++){
if(full[i][0]==full[i][1]&&full[i][1]==full[i][2]&&full[i][0]!=0){
if(full[i][0]==1){
window.alert("you win!");
return true;
}
else {
window.alert("you lose");
return true;
}
}
}
//列
for(var i=0;i<3;i++){
if(full[0][i]==full[1][i]&&full[1][i]==full[2][i]&&full[0][i]!=0){
if(full[0][i]==1){
window.alert("you win!");
return true;
}
else {
window.alert("you lose");
return true;
}
}
}
//主对角线
if(full[0][0]==full[1][1]&&full[1][1]==full[2][2]&&full[0][0]!=0){
if(full[0][0]==1){
window.alert("you win!");
return true;
}
else {
window.alert("you lose");
return true;
}
}
if(full[0][2]==full[1][1]&&full[2][0]==full[1][1]&&full[0][2]!=0){
if(full[0][2]==1){
window.alert("you win!");
return true;
}
else {
window.alert("you lose");
return true;
}
}
for(var i=0;i<3;i++){
for(var j=0;j<3;j++){
if(full[i][j]==0)
return false;//说明还没结束
if(i==2&&j==2)
{window.alert("平局!");
return true;
}
}
}
return false;//无结果
}
function bn(i,j){
//如果已经下过,则无效
if(full[i][j]!=0){
return 0;
}else{
//没下过
full[i][j]=1;
num1=(i*3+j+1)+"";
document.getElementById(num1).value="X";
if(judge()==true){
return;
}
ai();//切换
}
}
//重置权值:
function resetValue(){
for(var i=0;i<3;i++){
for(var j=0;j<3;j++){
if(full[i][j]!=0)
val[i][j]=0;
else{
//看行和列:
//最高权值
if(((full[0][j]+full[1][j]+full[2][j])==4)&&(full[0][j]*full[1][j]*full[2][j])==0
&&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==-1)
val[i][j]=val[i][j]+10000;
if(((full[i][0]+full[i][1]+full[i][2])==4)&&(full[i][0]*full[i][1]*full[i][2])==0
&&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==-1)
val[i][j]=val[i][j]+10000;
//次级权值
if(((full[0][j]+full[1][j]+full[2][j])==2)&&(full[0][j]*full[1][j]*full[2][j])==0
&&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==0)
val[i][j]=val[i][j]+1000;
if(((full[i][0]+full[i][1]+full[i][2])==2)&&(full[i][0]*full[i][1]*full[i][2])==0
&&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==0)
val[i][j]=val[i][j]+1000;
//三级权值(一排只有一个X)
if(((full[0][j]+full[1][j]+full[2][j])==1)&&(full[0][j]*full[1][j]*full[2][j])==0
&&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==0)
val[i][j]=val[i][j]+10;
if(((full[i][0]+full[i][1]+full[i][2])==1)&&(full[i][0]*full[i][1]*full[i][2])==0
&&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==0)
val[i][j]=val[i][j]+10;
//四级权值(一排只有一个O)
if(((full[0][j]+full[1][j]+full[2][j])==2)&&(full[0][j]*full[1][j]*full[2][j])==0
&&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==1)
val[i][j]=val[i][j]+5;
if(((full[i][0]+full[i][1]+full[i][2])==2)&&(full[i][0]*full[i][1]*full[i][2])==0
&&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==1)
val[i][j]=val[i][j]+5;
//五级权限(该行没有X或O)
if(((full[0][j]+full[1][j]+full[2][j])==0)&&(full[0][j]*full[1][j]*full[2][j])==0
&&((full[0][j]-1)*(full[1][j]-1)*(full[2][j]-1))==-1)
val[i][j]=val[i][j]+2;
if(((full[i][0]+full[i][1]+full[i][2])==0)&&(full[i][0]*full[i][1]*full[i][2])==0
&&((full[i][0]-1)*(full[i][1]-1)*(full[i][2]-1))==-1)
val[i][j]=val[i][j]+2;
//主对角线:同上
if((i==0&&j==0)||(i==2&&j==2)||(i==1&&j==1)){
if(((full[0][0]+full[1][1]+full[2][2])==4)&&(full[0][0]*full[1][1]*full[2][2])==0
&&((full[0][0]-1)*(full[1][1]-1)*(full[2][2]-1))==-1)
val[i][j]=val[i][j]+10000;
//次级权值
if(((full[0][0]+full[1][1]+full[2][2])==2)&&(full[0][0]*full[1][1]*full[2][2])==0
&&((full[0][0]-1)*(full[1][1]-1)*(full[2][2]-1))==0)
val[i][j]=val[i][j]+1000;
//三级权值(一排只有一个X)
if(((full[0][0]+full[1][1]+full[2][2])==1)&&(full[0][0]*full[1][1]*full[2][2])==0
&&((full[0][0]-1)*(full[1][1]-1)*(full[2][2]-1))==0)
val[i][j]=val[i][j]+10;
//四级权值(一排只有一个O)
if(((full[0][0]+full[1][1]+full[2][2])==2)&&(full[0][0]*full[1][1]*full[2][2])==0
&&((full[0][0]-1)*(full[1][1]-1)*(full[2][2]-1))==1)
val[i][j]=val[i][j]+5;
//五级权值(该行没有X或O)
if(((full[0][0]+full[1][1]+full[2][2])==0)&&(full[0][0]*full[1][1]*full[2][2])==0
&&((full[0][0]-1)*(full[1][1]-1)*(full[2][2]-1))==-1)
val[i][j]=val[i][j]+2;
}
//副对角线(同上)
if((i==0&&j==2)||(i==2&&j==0)||(i==1&&j==1)){
//一级
if(((full[0][2]+full[1][1]+full[2][0])==4)&&(full[0][2]*full[1][1]*full[2][0])==0
&&((full[0][2]-1)*(full[1][1]-1)*(full[2][0]-1))==-1)
val[i][j]=val[i][j]+10000;
//二级
if(((full[0][2]+full[1][1]+full[2][0])==2)&&(full[0][2]*full[1][1]*full[2][0])==0
&&((full[0][2]-1)*(full[1][1]-1)*(full[2][0]-1))==0)
val[i][j]=val[i][j]+1000;
//三级权值(一排只有一个X)
if(((full[0][2]+full[1][1]+full[2][0])==1)&&(full[0][2]*full[1][1]*full[2][0])==0
&&((full[0][2]-1)*(full[1][1]-1)*(full[2][0]-1))==0)
val[i][j]=val[i][j]+10;
//四级权值(一排只有一个O)
if(((full[0][2]+full[1][1]+full[2][0])==2)&&(full[0][2]*full[1][1]*full[2][0])==0
&&((full[0][2]-1)*(full[1][1]-1)*(full[2][0]-1))==1)
val[i][j]=val[i][j]+5;
//五级权值(该行没有X或O)
if(((full[0][2]+full[1][1]+full[2][0])==0)&&(full[0][2]*full[1][1]*full[2][0])==0
&&((full[0][2]-1)*(full[1][1]-1)*(full[2][0]-1))==-1)
val[i][j]=val[i][j]+2;
}
}
}
}
}
function ai(){
if(judge()==true){
return;
}
//挑选权值最大的
resetValue();
var mi=0,mj=0,temp=0;
for(var i=0;i<3;i++)
for(var j=0;j<3;j++){
if(val[i][j]>temp){
temp=val[i][j];
mi=i;
mj=j;
}
}
full[mi][mj]=2;
num1=(mi*3+mj+1)+"";
document.getElementById(num1).value="O";
if(judge()==true){
return;
}
}
function lose(){
window.alert("you lose");
location.reload();
}
</script>
</head>
<body>
<h1 align=center> 井字棋</h1>
<table border=2px bordercolor="blue"width="300"height="300" style="font-size:50 " align=center>
<tr>
<td><input type="button" id="1" Style="width:100px;height:100px;" value=" " onclick="bn(0,0)"/></td>
<td><input type="button" id="2" Style="width:100px;height:100px;" value=" " onclick="bn(0,1)"/></td>
<td><input type="button" id="3" Style="width:100px;height:100px;" value=" " onclick="bn(0,2)"/></td>
</tr>
<tr>
<td><input type="button" id="4" Style="width:100px;height:100px;" value=" " onclick="bn(1,0)"/></td>
<td><input type="button" id="5" Style="width:100px;height:100px;" value=" " onclick="bn(1,1)"/></td>
<td><input type="button" id="6" Style="width:100px;height:100px;" value=" " onclick="bn(1,2)"/></td>
</tr>
<tr >
<td><input type="button" id="7" Style="width:100px;height:100px;" value=" " onclick="bn(2,0)"/></td>
<td><input type="button" id="8" Style="width:100px;height:100px;" value=" " onclick="bn(2,1)"/></td>
<td><input type="button" id="9" Style="width:100px;height:100px;" value=" " onclick="bn(2,2)"/></td>
</tr>
</table>
<div ><input type="button" style="position:relative;left:500px;top:5px;width:100px;height:50px;" value="重新开始" onclick="location.reload() "/>
<input type="button" style="position:relative;left:550px;top:5px;width:100px;height:50px;" value="认 输" onclick="lose()"/>
</div>
<body>
</html>
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- javascript面向对象入门基础详细介绍 2020-03-29
- JavaScript函数表达式详解及实例 2020-03-25
- 如何用javascript连接access数据库 2020-03-20
- js中去掉字串左右空格 2020-03-20
- Javascript中的经典技巧 2020-03-20
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash