JavaScript实现一个带AI的井字棋游戏源码

 更新时间:2018年05月21日 09:40:17   作者:小楼夜听雨QAQ  
这篇文章主要介绍了基于JavaScript实现一个带AI的井字棋游戏源码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下

最近有一门课结束了,需要做一个井字棋的游戏,我用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>

总结

以上所述是小编给大家介绍的JavaScript实现一个带AI的井字棋游戏源码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 利用JS来控制键盘的上下左右键(示例代码)

    利用JS来控制键盘的上下左右键(示例代码)

    这篇文章主要介绍了利用JS来控制键盘的上下左右键示例代码。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • JavaScript实现循环轮播图

    JavaScript实现循环轮播图

    这篇文章主要为大家详细介绍了JavaScript实现循环轮播图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • 微信小程序点击列表跳转到对应详情页过程解析

    微信小程序点击列表跳转到对应详情页过程解析

    这篇文章主要介绍了微信小程序点击列表跳转到对应详情页过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • JavaScript内置对象之Array的使用小结

    JavaScript内置对象之Array的使用小结

    这篇文章主要介绍了JavaScript内置对象之Array的使用小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-05-05
  • Javascript 篱式条件判断

    Javascript 篱式条件判断

    我们已经知道,null 没有任何的属性值,并且无法获取其实体(existence)值。所以 null.property 返回的是错误(error)而不是 undefined 。
    2008-08-08
  • javascript 正则表达式触发函数进行高级替换

    javascript 正则表达式触发函数进行高级替换

    如果在正则表达式中定义了子匹配,那么参数的长度会随着子匹配的个数改变,如果没有定义子匹配,那么长度是固定的。
    2010-03-03
  • JS操作JSON要领详细总结

    JS操作JSON要领详细总结

    JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包,下面与大家分享下JSON操作的相关知识
    2013-08-08
  • js数组去重的方法汇总

    js数组去重的方法汇总

    本文给大家汇总介绍了3种javascript数组去重的方法以及示例,十分的简单实用,有需要的小伙伴可以参考下。
    2015-07-07
  • Javascript 浅拷贝、深拷贝的实现代码

    Javascript 浅拷贝、深拷贝的实现代码

    Javascript中的对像赋值与Java中是一样的,都为引用传递.就是说,在把一个对像赋值给一个变量时,那么这个变量所指向的仍就是原来对像的地址.那怎么来做呢 答案是克隆.
    2008-12-12
  • 通过正则表达式实现表单验证是否为中文

    通过正则表达式实现表单验证是否为中文

    正如标题所言判断一个输入量是否为中文,通过正则表达式实现,需要的朋友可以参考下
    2014-02-02

最新评论