效果图:

html代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>五子棋</title>
        <link rel="stylesheet" type="text/css" href="css/style.css"/>
    </head>
    <body>
        <canvas id="chess" width="450px" height="450px"></canvas>
        <div id='restart' class="restart">
            <span>重新开始</span>
        </div>
        <script src="js/script.js" type="text/javascript" charset="utf-8"></script>
    </body>
</html>

css代码如下:

canvas{
    display: block;
    margin: 50px auto;
    box-shadow: -2px -2px 2px #efefef, 5px 5px 5px #b9b9b9;
}
.restart{
    text-align: center;
}
.restart>span{
    display: inline-block;
    padding: 10px 20px;
    color: #fff;
    background-color: #45c01a;
    border-radius: 5px;
}
js代码如下:

var over = false;
var me = true; //我

var chressBord = [];//棋盘
for(var i = 0; i < 15; i++){
    chressBord[i] = [];
    for(var j = 0; j < 15; j++){
        chressBord[i][j] = 0;
    }
}

//赢法的统计数组
var myWin = [];
var computerWin = [];

//赢法数组
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(var 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++;
    }
}

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

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

context.strokeStyle = '#bfbfbf'; //边框颜色

var logo = new Image();
logo.src = 'img/logo.png';
logo.onload  = function(){
    context.drawImage(logo,0,0,450,450);
    drawChessBoard();
}

document.getElementById("restart").onclick = function(){
    window.location.reload();
}
chess.onclick = function(e){
    if(over){
        return;
    }
    if(!me){
        return;
    }
    var x = e.offsetX;
    var y = e.offsetY;
    var i = Math.floor(x / 30);
    var j = Math.floor(y / 30);
    if(chressBord[i][j] == 0){
        oneStep(i,j,me);
        chressBord[i][j] = 1;//我        
                    
        for(var k = 0; k < count; k++){
            if(wins[i][j][k]){
                myWin[k]++;
                computerWin[k] = 6;//这个位置对方不可能赢了
                if(myWin[k] == 5){
                    window.alert('你赢了');
                    over = true;
                }
            }
        }
        if(!over){
            me = !me;
            computerAI();
        }
    }
    
}
//计算机下棋
var computerAI = function (){
    var myScore = [];
    var computerScore = [];
    var max = 0;
    var 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(chressBord[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] += 10000;
                        }
                        
                        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,false);
    chressBord[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;
    }
}

//绘画棋盘
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();
}

JS+canvas实现人机大战之五子棋的更多相关文章

  1. 【微信小程序项目实践总结】30分钟从陌生到熟悉 web app 、native app、hybrid app比较 30分钟ES6从陌生到熟悉 【原创】浅谈内存泄露 HTML5 五子棋 - JS/Canvas 游戏 meta 详解,html5 meta 标签日常设置 C#中回滚TransactionScope的使用方法和原理

    [微信小程序项目实践总结]30分钟从陌生到熟悉 前言 我们之前对小程序做了基本学习: 1. 微信小程序开发07-列表页面怎么做 2. 微信小程序开发06-一个业务页面的完成 3. 微信小程序开发05- ...

  2. [JS,Canvas]日历时钟

    [JS,Canvas]日历时钟 Html: <!doctype html> <html> <head> <meta charset="UTF-8&q ...

  3. 利用js+canvas实现的时钟效果图

    canvas+js时钟特效 运用js+canvas方面的知识完成一个时钟的效果图,再利用for循环实现指针的转动效果: <!--网页文档的声明--> <!doctype html&g ...

  4. 随便谈谈alphago与人机大战

    3月16日历时8天的人机大战终于落下帷幕,alphago以4:1的比分击败了当年如日中天的李世石.这个结果让我这个围棋爱好者+计算机爱好者百感交集…… ——一个时代落幕了,一个新的时代开启了. 这次人 ...

  5. 介绍一款Android小游戏--交互式人机对战五子棋

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6589025 学习Android系统开发之余,编 ...

  6. 转 原生js canvas实现苹果电脑mac OS窗口最小化效果

    http://www.17sucai.com/pins/demo-show?id=2459 http://www.17sucai.com/pins/demo-show?id=2458  很多资料 ,前 ...

  7. js canvas游戏初级demo-躲避障碍物

    在线演示地址 http://200ok.fun:3100/html/game_demo.html 继上次js canvas游戏初级demo-上下左右移动(https://www.cnblogs.com ...

  8. chart.js & canvas

    chart.js & canvas https://www.chartjs.org/samples/latest/ https://www.chartjs.org/samples/latest ...

  9. Canvas:飞机大战 -- 游戏制作

    Canvas:飞机大战 最开始我们要初始化信息,我们有五个状态:游戏封面,加载状态,运行状态,游戏暂停,游戏结束. 我们还需要  得分--score,生命--life. var START = 1;/ ...

随机推荐

  1. CSS转载备忘

    原文地址:http://www.cnblogs.com/coffeedeveloper/p/3145790.html#html 转载内容: 对CSS中的Position.Float属性的一些深入探讨 ...

  2. Cortex-M3学习日志(三)-- 外部中断0

    无论是哪款单片机应该都有对应的中断的功能,中断在嵌入式系统的地位毋庸置疑.LPC1768微处理器包括4个外部中断,分别是EINT0.EINT1.EINT2.EINT3对应的引脚分别是P2.10~P2. ...

  3. poj1862---变形虫(贪心)

    题意:两条虫之间碰在一起,质量变为2*sqrt(m1*m2) 求怎么结合,能使最后的一只虫质量最小 分析:如果让按从大到小的顺序依次结合,可以使大的数被开方的次数最多,得到的结果更小 4 3 2 1 ...

  4. saiku安装方法总结

    最近研究pentaho和saiku,在网上搜集了一些安装和配置的方法,亲测有效,在这分享总结一下方便日后使用. Saiku主要提供两种安装方式,独立运行和集成在Pentaho BI平台上,本文会简单介 ...

  5. 代码中添加事务控制 VS(数据库存储过程+事务) 保证数据的完整性与一致性

    做人事档案的系统考虑到数据的安全性与一致性,毕竟是要对外上线.真正投入使用的项目,数据库的可靠性与安全性上我们开发人员要考虑的就很多了,记得做机房收费系统时注册新卡是自己为了简单,写成了一个存储过程( ...

  6. 网页播放音频、视频文件——基于web的html 5的音乐播放器(转载)

    文章转载自:开源中国社区 [http://www.oschina.net] 想通过手机客户端(支持 Android.iPhone 和 Windows Phone)访问开源中国:请点这里 HTML5 是 ...

  7. 浅谈SpringMVC(一)

    一.SpringMVC引言 Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 MV ...

  8. BZOJ 1935: [Shoi2007]Tree 园丁的烦恼( 差分 + 离散化 + 树状数组 )

    假如矩阵范围小一点就可以直接用二维树状数组维护. 这道题,  差分答案, 然后一维排序, 另一维离散化然后树状数组维护就OK了. ----------------------------------- ...

  9. Windows上部署Redis

    http://www.cnblogs.com/gaobing/p/5026136.html

  10. linux杂记(八)linux压缩与打包

    linux系统常见的压缩指令 一般被压缩过的档案,通常其附档名都是[*.tar,*.tar.gz,*.tgz,*.gz,*.Z,*.bz2]等等. *.tar:tar程序打包的数据.并没有压缩过 *. ...