美文网首页
使用canvas基于AI算法实现人机对战之五子棋

使用canvas基于AI算法实现人机对战之五子棋

作者: 伯纳乌的追风少年 | 来源:发表于2018-04-08 07:32 被阅读0次

    这是我使用canvas基于AI算法实现的人机对战之五子棋


    黑棋是我

    下了几局,真心下不过啊!!!

    不说了,源码奉上:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>人机大战之五子棋</title>
        <style>
            canvas{
                display: block;
                margin:50px auto;
                box-shadow: -2px -2px 2px #efefef,5px 5px 5px #b9b9b9;
            }
        </style>
    </head>
    <body>
        <canvas id="chess" width="450px" height="450px"></canvas>
        <script>
            var chess=document.getElementById("chess")
            var context=chess.getContext("2d")
            var over=false
            var me=true
            var chessBoard=[]
            for(var i=0;i<15;i++){
                chessBoard[i]=[];
                for(var j=0;j<15;j++){
                    chessBoard[i][j]=0;
                }
            }
    
            var logo=new Image()
            logo.src="image/logo.png"
            logo.onload=function(){
                context.drawImage(logo,0,0,450,450);
                drawChessBoard()
            }
            
            // 画棋盘
            var drawChessBoard=function(){
                context.strokeStyle="#bfbfbf"
                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(17+i*30,13+j*30,13,17+i*30,13+j*30,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(chessBoard[i][j]==0){
                    oneStep(i,j,me) 
                    if (me) {
                        chessBoard[i][j]=1
                    }else{
                        chessBoard[i][j]=2
                    }
                    
                    for (var k = 0; k < count; k++) {
                        //每点击一次,遍历一次赢法数组,
                        //一般有20个赢法数组被匹配到,
                        //将对应匹配到的赢法数组匹配次数加一,
                        //当某一个赢法数组被触发5次成功的匹配后,表示该赢法数组匹配成功,游戏胜利!
                        if (win[i][j][k]) {
                            myWin[k]++;
                            computerWin[k]=6;
                            if(myWin[k]==5&&me){
                                window.alert("你赢了")
                                over=true
                                break
                            }
                        }
                    }
    
                    if(!over){
                        me=!me
                        computerAI()
                    }
                }
            }
    
    
    
            // AI篇
    
            //赢法数组
            var win=[]
            for (var i = 0; i < 15; i++) {
                win[i]=[]
                for (var j = 0; j < 15; j++) {
                    win[i][j]=[]
                }   
            }
    
            var count=0
    
            // 横向赢法
            for (var i = 0; i < 11; i++) {
                for (var j = 0; j < 15; j++) {
                    for (var k = 0; k < 5; k++) {
                        win[i+k][j][count]=true;
                    }
                    count++ 
                }
            }
    
            // 纵向赢法
            for (var i = 0; i < 15; i++) {
                for (var j = 0; j < 11; j++) {
                    for (var k = 0; k < 5; k++) {
                        win[i][j+k][count]=true;
                    }
                    count++ 
                }
            }
    
            //斜线赢法
            for (var i = 14; i > 3; i--) {
                for (var j = 0; j < 11; j++) {
                    for (var k = 0; k < 5; k++) {
                        win[i-k][j+k][count]=true;
                    }
                    count++ 
                }
            }
    
            // 反斜线赢法
            for (var i = 0; i < 11; i++) {
                for (var j = 0; j <11; j++) {
                    for (var k = 0; k < 5; k++) {
                        win[i+k][j+k][count]=true;
                    }
                    count++ 
                }
            }
    
            // 统计赢法数组个数为572
            console.log(count)
    
            // 赢法的统计数组
            //统计我方赢法的情况
            var myWin=[]
            //统计计算机方的赢法情况
            var computerWin=[]
    
            for (var i = 0; i < count; i++) {
                myWin[i]=0
                computerWin[i]=0
            }
    
            //计算机AI算法
            var 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 (chessBoard[i][j]==0) {
                            for (var k = 0; k < count; k++) {
                                if(win[i][j][k]){
                                    // 根据第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]+=10000
                                    }
    
                                    // 根据第k个赢法中白棋已落子的个数,判断落子在此处白子获得的分数
                                    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]+=20000
                                    }
                                }
                            }
    
                            //计算落在此点时的最大得分
                            if(myScore[i][j]>max){
                                max=myScore[i][j]
                                u=i;
                                v=j;
                            }else if(myScore[i][j]==max){
                                if(computerScore[i][j]>computerScore[u][v]){
                                    u=i;
                                    v=j;
                                }
                            }
    
                            if(computerScore[i][j]>max){
                                max=computerScore[i][j]
                                u=i;
                                v=j;
                            }else if(computerScore[i][j]==max){
                                if(myScore[i][j]>myScore[u][v]){
                                    u=i;
                                    v=j;
                                }
                            }
    
    
                        }
                    }
                }
    
                oneStep(u,v,me);
                chessBoard[u][v]=2
    
                //判断计算机是否赢了
                for (var k = 0; k < count; k++) {
                    if (win[u][v][k]) {
                        computerWin[k]++;
                        myWin[k]=6;
                        if(computerWin[k]==5&&!me){
                            window.alert("计算机赢了")
                            over=true
                            break
                        }
                    }
                }
                if (!over) {
                    me=!me  
                }
    
            }
    
    
        </script>
    </body>
    </html>
    

    后面的小猫咪背景图:


    logo.png

    把代码保存成index.html,
    把图片保存成logo.png,放在image目录下即可



    不说了,下围棋去了

    相关文章

      网友评论

          本文标题:使用canvas基于AI算法实现人机对战之五子棋

          本文链接:https://www.haomeiwen.com/subject/skzuhftx.html