简单AI五子棋,js,canvas

新年第一篇博客,最近几天走亲访友的没有学习。今天开始进入学习模式。

<!DOCTYPE html>
<html>
<head>
    <title>五子棋</title>
    <link rel="stylesheet" type="text/css" href="./css/style.css">
</head>
<body>
    <canvas id="chess" width="450px" height="450px">

    </canvas>
    <script type="text/javascript" src="./js/script.js"></script>
</body>
</html>
canvas{
    display: block;
    margin: 50px auto;
    box-shadow: -2px -2px 2px #efefef,5px 5px 5px #b9b9b9;
}

接下来是js代码,也是精华

var over=false;//游戏是否结束

//构造赢法数组
var wins=[];
for(var i=0;i<15;i++){
    wins[i]=[];
    for(var j=0;j<15;j++){
        wins[i][j]=[]
    }
}

var count=0//赢法
//所有的竖行
for(var i=0;i<15;i++){
    for(var j=0;j<11;j++){
        for(var k=0;k<5;k++){
            wins[i][j+k][count]=true;
        }
        count++;
    }
}
//所有的横行
for(var i=0;i<15;i++){
    for(var j=0;j<11;j++){
        for(var k=0;k<5;k++){
            wins[j+k][i][count]=true;
        }
        count++;
    }
}

//所有的斜线
for(var i=0;i<11;i++){
    for(var j=0;j<11;j++){
        for(k=0;k<5;k++){
            wins[i+k][j+k][count]=true;
        }
        count++;
    }
}

//所有的反斜线
for(var i=0;i<11;i++){
    for(var j=14;j>3;j--){
        for(var k=0;k<5;k++){
            wins[i+k][j-k][count]=true;
        }
        count++;
    }
}

//赢法统计数组
var myWin=[]
var computerWin=[]
for(var i=0;i<count;i++){
    myWin[i]=0;
    computerWin=0;
}

var chessBorad=[]//标记棋盘是否使用过
for(var i=0;i<15;i++){
    chessBorad[i]=[];
    for(var j=0;j<15;j++){
        chessBorad[i][j]=0;
    }
}

var me=true;

var chess=document.getElementById(‘chess‘);
var context=chess.getContext(‘2d‘);

context.strokeStyle="#bfbfbf";

var logo=new Image();
logo.src="bg.jpg";
logo.onload=function(){
    context.drawImage(logo,0,0,450,450);
    drawChessBoard();

    // oneStep(0,0,1)
    // oneStep(0,1,0)
}
var drawChessBoard=function(){
    for(var i=0;i<15;i++){
        context.moveTo(15+i*30,15)
        context.lineTo(15+i*30,435)
        context.stroke();

        context.moveTo(15,15+i*30)
        context.lineTo(435,15+i*30)
        context.stroke();
    }
}

var oneStep=function(i,j,me){
    context.beginPath();
    context.arc(15+i*30,15+j*30,13,0,2*Math.PI);
    context.closePath();

    var gradient=context.createRadialGradient(15+i*30+2,15+j*30+2,13,15+i*30+2,15+j*30+2,0);
    if(me){
        gradient.addColorStop(0,"#0a0a0a");
        gradient.addColorStop(1,"#636766");
    }else{
        gradient.addColorStop(0,"#d1d1d1");
        gradient.addColorStop(1,"#f9f9f9");
    }
    context.fillStyle=gradient;
    context.fill();

}

chess.onclick=function(e){
    if(over) return;
    var x=e.offsetX;
    var y=e.offsetY;
    var i=Math.floor(x/30);
    var j=Math.floor(y/30);
    if(!chessBorad[i][j]){
        if(!me) return;
        if(me){
            oneStep(i,j,me);
            chessBorad[i][j]=1;
        }else{
            oneStep(i,j,me);
            chessBorad[i][j]=2;
        }
        for(var k=0;k<count;k++){
            if(wins[i][j][k]) {
                myWin[k]++;
                computerWin[k]=6;//表示该赢法舍弃
            }
            if(myWin[k]==5){
                window.alert(k);
                over=true;
            }
        }
        if(!over){
            me=!me;
            computerAI();
        }
    }
}

computerAI=function(){
    var myScore=[];
    var computerScore=[];
    var max=0,u=0,v=0;
    for(var i=0;i<15;i++){
        myScore[i]=[];
        computerScore[i]=[];
        for(var j=0;j<15;j++){
            myScore[i][j]=0;
            computerScore[i][j]=0;
        }
    }

    //遍历棋盘计算分数
    for(var i=0;i<15;i++){
        for(var j=0;j<15;j++){
            if(chessBorad[i][j]==0){
                for(var k=0;k<count;k++){
                    if(wins[i][j][k]){
                        if(myWin[k]==1){
                            myScore[i][j]+=200;
                        }else if(myWin[k]==2){
                            myScore[i][j]+=400;
                        }else if(myWin[k]==3){
                            myScore[i][j]+=2000;
                        }else if(myWin[k]==4){
                            myScore[i][j]+=100000;
                        }
                        if(computerWin[k]==1){
                            computerScore[i][j]+=220;
                        }else if(computerWin[k]==2){
                            computerScore[i][j]+=420;
                        }else if(computerWin[k]==3){
                            computerScore[i][j]+=2100;
                        }else if(computerWin[k]==4){
                            computerScore[i][j]+=200000;
                        }
                    }
                }
                if(myScore[i][j]>max){
                    max=myScore[i][j];
                    u=i;
                    v=j;
                }else if(myScore==max){
                    if(computerScore[i][j]>max){
                        u=i;
                        v=j;
                    }
                }
                if(computerScore[i][j]>max){
                    max=cmputerScore[i][j];
                    u=i;
                    v=j;
                }else if(computerScore==max){
                    if(myScore[i][j]>max){
                        u=i;
                        v=j;
                    }
                }

            }
        }
    }

    //计算机落子
    oneStep(u,v,false);
    chessBorad[u][v]=2;
    for(var k=0;k<count;k++){
            if(wins[u][v][k]) {
                computerWin[k]++;
                myWin[k]=6;//表示该赢法舍弃
            }
            if(computerWin[k]==5){
                window.alert("你输了");
                over=true;
            }
        }
        if(!over){
            me=!me;
        }
}

关键是每次计算机落子的时候,遍历棋盘上的所有点,计算出该点落子的得分。

得分有两种,一种是阻击对方胜利,一种是己方胜利得分。

按代码逻辑来说,应该是计算机主动攻击,不过在实际过程中倒是计算机一直在被动防御。

这里有几个比较吊的地方。首先是在canvas上面进行绘制棋盘和棋子。

var drawChessBoard=function(){
    for(var i=0;i<15;i++){
        context.moveTo(15+i*30,15)
        context.lineTo(15+i*30,435)
        context.stroke();

        context.moveTo(15,15+i*30)
        context.lineTo(435,15+i*30)
        context.stroke();
    }
}

绘制棋子使用渐变色填充

var oneStep=function(i,j,me){
    context.beginPath();
    context.arc(15+i*30,15+j*30,13,0,2*Math.PI);
    context.closePath();

    var gradient=context.createRadialGradient(15+i*30+2,15+j*30+2,13,15+i*30+2,15+j*30+2,0);
    if(me){
        gradient.addColorStop(0,"#0a0a0a");
        gradient.addColorStop(1,"#636766");
    }else{
        gradient.addColorStop(0,"#d1d1d1");
        gradient.addColorStop(1,"#f9f9f9");
    }
    context.fillStyle=gradient;
    context.fill();

}

然后是点击事件的捕捉和处理:

chess.onclick=function(e){
    if(over) return;
    var x=e.offsetX;
    var y=e.offsetY;
    var i=Math.floor(x/30);
    var j=Math.floor(y/30);

捕捉到canvas上面的点击事件,及鼠标点击位置,将其转化成棋盘上面的坐标。简直神奇。

其实我很想骂人的,但我忍住了,,

时间: 2024-10-15 14:15:35

简单AI五子棋,js,canvas的相关文章

简单程序设计-五子棋

<程序设计-五子棋> 作者:蜡笔小黑(原创博文,转载请说明) 前言:很多刚刚接触编程的人都不知道怎么下手编写程序,特别是学习了新的知识点,不知道有什么用,那么本文将以简单的存储结构及简单的运算,条件语句,分支语句,循环语句结合,带来一个双人对战版五子棋,这是一个简单的模型,实现了五子棋最最基本的功能,还有好多地方需要补全,如边界问题,设计问题,游戏逻辑问题,希望读者阅读后能够注意,通过自己的努力来完善它,还能扩展各种功能,如悔棋,网络对战等,有时候写程序和小生命一样,慢慢会成长,而我们作为&q

人机ai五子棋 ——五子棋AI算法之Java实现

人机ai五子棋 下载:chess.jar (可直接运行) 源码:https://github.com/xcr1234/chess 其实机器博弈最重要的就是打分,分数也就是权重,把棋子下到分数大的地方,我获胜的概率就更大. 而在下棋过程中,大部分的点的得分都很小,或者接近,因此无需对每一个点都打分,只需要在我方附近(进攻)或者敌方附近(防守)的几个点进行打分. 具体原理大家可以看源码中的注释,说明的很清楚. 参考 http://blog.csdn.net/pi9nc/article/details

【转】简单了介绍js中的一些概念(词法结构) 和 数据类型(部分)。

1 , javascript字符集: javascript采用的是Unicode字符集编码. 为什么要采用这个编码呢? 原因很简单,16位的Unicode编码可以表示地球人的任何书面语言.这是语言 国际化的一个重要特征.(大家也许见过用中文写脚本,比如:function 我的函数() {} ); Javascript中每个字符都是用2个字节表示的.(因为是16位编码) 2 ,大小写敏感: js是一种区分大小写的语言. 注意下:以前我也犯过的错误. HTML是不区分大小写的.经常看见有人这么写, 

NodeJS 入门 - 1 搭建简单的node js应用

关于如何搭建一个简单的 node.js应用,找到了如下几种攻略. 从零搭建node.js服务 搭建一个node.js+express.js服务 从零搭建一个简单的node.js + express.js + handlerbars服务 从零搭建node.js服务 摘自Node即学即用 Code如下: $ node > var http = require('http'); > http.createServer(function(req, res){ res.writeHead(200, {'

AI五子棋-第三周-需求改进&amp;系统设计

1. 需求&原型改进 根据组内成员的讨论以及老师和同学的建议,本周进行了以下的改进: 1. 改进了游戏UI的界面设计,并且对前端代码进行模块化整理,增强可读性和可维护性. 2. 对后台的游戏引擎进行改进设计,完善了游戏调度机制 3. 对人工智能算法进行了优化和改进,原先的算法因为其所需要的计算资源过大,当前场景难以达到其性能要求,无法发挥出算法的最大实力,所以完全基于AlphaZero模型算法的AI五子棋难以实现,因此我们采取了人工规则的辅助方式实现AI 2. 系统设计 系统设计如图所示 3. 

JS+canvas实现人机大战之五子棋

效果图: html代码如下: <!DOCTYPE html><html>    <head>        <meta charset="utf-8" />        <title>五子棋</title>        <link rel="stylesheet" type="text/css" href="css/style.css"/>

用原生js+canvas实现五子棋

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>五子棋</title> 6 <link rel="stylesheet" href="css/style.css" /> 7 </head> 8 <body> 9 <h3 id="r

AI五子棋------------初探

最近在研究AI贪吃蛇,昨天写了一天代码实在头昏脑涨,想起之前在慕课网上看到一个关于五子棋AI的视频,加起来也就一个钟头,所以今天抽了点时间学习了一下,逻辑还是很简单的,但是如果自己想肯定是一时半会想不出这么好的方法,也对自己的学习以及最近对AI贪吃蛇的思考有所启发,还是很有收获的(为数不多觉得还可以的视频教程). 关于具体的思路,视频讲的很清楚,也可以找到观看,就不一一分析了.主要是记录一下代码(因为视频没源码下载),以及自己的感想. 文件结构(sublime 截图) index.html代码

原生js canvas 碰撞游戏的开发笔记

-----------------------------------------------福利--------------------------------------------- -----------------------------------------------分割线--------------------------------------------- 今天 我们研究下碰撞游戏 什么是碰撞游戏? 当然是东西碰到在一起啦 用前端逻辑来说 就是2个物品互相碰撞产生的事件 问