机器人之JS实现人机大战之五子棋AI算法优化
小标 2018-10-17 来源 : 阅读 1472 评论 0

摘要:本文主要向大家介绍了机器人之JS实现人机大战之五子棋AI算法优化,通过具体的内容向大家展现,希望对大家学习机器人有所帮助。

本文主要向大家介绍了机器人之JS实现人机大战之五子棋AI算法优化,通过具体的内容向大家展现,希望对大家学习机器人有所帮助。


对老师的代码增加了一个新的算法,原来的算法不能够判断黑棋下一个子就能产生两个三连的情况,这种情况在五子棋中非常的常见,而白棋不知道去围堵,这样游戏的难度性降低了,所以增加了一个黑棋下一步能够产生多个三连的位置的判断,会增加那个位置的分值,保证计算机能够准确的先发制人占领那个位置,这个还有很多不足,里面引用了一个音乐文件,你们可以随便弄一个.mp3文件就可以了。无视前面那些变量名,后来定义的我自己都头晕了,索性就不用了...


我的思路是这样的,当计算机要落子的时候,会检测棋盘上每一个点,他的上下左右,左上,左下,右上,右下,有没有符合win.js里面定义的规则,规则我是这么想的假设黑棋现在上方有两个子,左边也有两个子,这样黑棋如果在中间落一个子那么黑棋就会产生两个三连,这样就没办法堵了,于是我就写一个这样的规则[0,1,1,0] 如果x,y这个点往上查找符合这个规则,0代表没有子,这个规则的大概 意思就是,xy点的八个方位符不符合它本身没有子,然后接着又一个黑子,又一个黑子,接着是一个没有棋子。这样就符合了我们的要求,当然要满足两个这样的条件才可以,于是就增加判断,八个方位里面同一个点如果满足两个方位的规则,那么就说明这个点下一次黑棋一旦落子白棋就输了。


如果有兴趣的同学还可以给它增加更加高级的算法,之前我拿这个和一切五子棋上段位的人下,我发现只能对一般的新手管用,高手通常能够使用套路,让你一路围堵,最终产生四连的情况就输了,这样的话,可以增加一个大的数组包含整个棋盘子的情况,并且记录下每一个位置下子是第一步,并且记录是不是用来围堵对方,等输的时候倒序检查这个数组发现从第几步开始我们是一路被牵着走的,然后就可以得出一个大概的模型,当然这是一个全新的算法,之前的那个规则算法是不可以的,这样计算机就能够得到新的模型,通过这个模型他就可以进行学习,下次一旦对手摆出这样的模型,他就在关键的位置阻断,这只是我的一个想法,有兴趣的可以试一下,也可以与我进行交流。


index.html


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>五子棋</title>
    <link rel="stylesheet" type="text/css" href="index.css" />
</head>
<body>
    <audio id="downChess" src="tweet.wav" preload="preload">
        您的浏览器不支持audio,请使用其他浏览器或极速模式。
    </audio>
    <canvas id="chess" width="450px" height="450px" class="chess">
        您的浏览器不支持canvas,请使用其他浏览器或极速模式。
    </canvas>
    <script src="win.js"></script>
    <script src="chess.js"></script>
</body>
</html>


index.css


.chess{
    display: block;
    margin: 50px auto;
    box-shadow: -2px -2px 2px #EFEFEF, 5px 5px 5px #B9B9B9;
}


chess.js


/**
 * Created by Administrator on 2016/3/31.
 */
var chess;              //canvas对象
var downChess;          //audio对象
var CHESS_WIDTH;      //棋盘的高度
var CHESS_HEIGTH;    //棋盘的宽度
var over = false;   //表示是否有人赢了
var chessPen;
var LINE;  //一共有棋盘有多少行多少列
var LINTTOPADDIN;  //棋盘的线距离棋盘左右上下的距离
var LINE_SIZEPX;  //棋盘每条线的间隔
var isBlack = true; //用来存储下一个棋子的颜色,true为黑棋,默认为黑棋先下
var chessMap = [];  //存储棋盘的棋子,0代表当前位置没有棋子,1代表黑棋,2代表白棋
var wins = [];  //赢法数组      [x][y][k]   x y 代表棋盘上的一个点 k代表第几种赢法
var myWin = []; //我方的赢法统计数组
var comWin = [];//计算机方的赢法统计数组

var count = 0;      //代表有多少种赢法

/** wins start **/
//初始化数组
for(var x = 0; x < 15;x++){
    wins[x] = [];
    for(var y = 0; y<15;y++){
        wins[x][y] = [];
    }
}

//横排的赢法
for(var x = 0; x < 15; x++){
    for(var y = 0; y<11;y++){
        for(var k = 0; k<5;k++){
            wins[x][y+k][count] = true;
        }
        count++;
    }
}

//竖排的赢法
for(var x = 0; x < 15; x++){
    for(var y = 0; y<11;y++){
        for(var k = 0; k<5;k++){
            wins[y+k][x][count] = true;
        }
        count++;
    }
}

//正斜线的赢法
for(var x = 0; x < 11; x++){
    for(var y = 0; y<11;y++){
        for(var k = 0; k<5;k++){
            wins[x+k][y+k][count] = true;
        }
        count++;
    }
}

//反斜线的赢法
for(var x = 0; x < 11; x++){
    for(var y = 14; y>3;y--){
        for(var k = 0; k<5;k++){
            wins[x+k][y-k][count] = true;
        }
        count++;
    }
}
/** wins end **/

/** 赢法统计数组初始化开始 **/

for(var i = 0; i < count;i++){
    myWin[i] = 0;
    comWin[i] = 0;
}

/** 赢法统计数组初始化结束 **/

console.log("五子棋一共有 " + count + "种赢法");     //打印日志

window. = function () {
    infoStart();
}

var infoStart = function(){
    chess = document.getElementById("chess");
    downChess = document.getElementById("downChess");
    chessPen = chess.getContext("2d");
    chessPen.strokeStyle = "#B9B9B9";
    CHESS_WIDTH = chess.width;      //棋盘的高度
    CHESS_HEIGTH = chess.height;    //棋盘的宽度
    LINE = 15;  //一共有棋盘有多少行多少列
    LINTTOPADDIN = 15;  //棋盘的线距离棋盘左右上下的距离
    LINE_SIZEPX = 30;  //棋盘每条线的间隔
    drawCheckerBoard(); //初始化棋盘
    reloadBoard();      //初始化棋子
    //棋盘单击事件
    chess. = function(e){
        //如果已经有人获胜,就不处理
        if(over){
            return;
        }
        //只有黑棋才能手动下棋
        if(!isBlack){
            return;
        }
        var x = Math.floor(e.offsetX / LINE_SIZEPX);
        var y = Math.floor(e.offsetY / LINE_SIZEPX);
        if(chessMap[x][y] == 0){
            drawOneChess(x, y, isBlack);
            chessMap[x][y] = 1;    //黑棋
        }else{
            return;
        }
        //遍历所有的赢法
        for(var k=0;k<count;k++){
            //如果为true说明我们在K种赢法上面胜算大了一步
            if(wins[x][y][k]){
                myWin[k]++; //我方胜算统计增加
                comWin[k] = 6;  //计算机在这种赢法就不可能赢,设置一个异常的值6
                //说明黑棋已经赢了
                if(myWin[k] == "5"){
                    window.alert("恭喜你获胜!");
                    over = true;
                }
            }
        }
        //如果还没有结束,我们让计算机下棋
        if(!over){
            isBlack = !isBlack;    //下一个棋
            computerAI();
        }
    };
}

//初始化棋子
var reloadBoard = function(){
    for(var i =0;i<LINE;i++){
        chessMap[i] = [];
        for(var j = 0;j<LINE;j++){
            chessMap[i][j] = 0;
        }
    }
}

//计算机AI下棋
var computerAI = function(){
    var myScore = [];   //用户棋盘上点的得分
    var comScore = [];  //电脑棋盘上点的得分
    var max = 0;        //保存最高的分数
    var maxX = 0,maxY = 0;       //最高分的点的坐标
    var myK = 0;    //用户下了某一个点之后,将会产生多少个符合赢得条件
    var comK = 0;   //计算机下了某一个点之后,将会产生多少个符合赢得条件
    var ruleCount = 0;

    for(var x = 0;x<15;x++){
        myScore[x]<span    

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标人工智能智能机器人频道!


本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved