美文网首页
使用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