效果图:

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. 【Chromium中文文档】跨进程通信 (IPC)

    跨进程通信 (IPC) 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/I ...

  2. [问题解决] ubuntu server12.04 按ctrl+alt+F1没用

    错误: ubuntu server12.04 想从图形化界面变成命令行界面时候,按ctrl+alt+F1没用 发生场景: 虚拟机下的ubuntu server12.04 解决方案: 因为ctrl+al ...

  3. IE添加信任站点并设置允许ActiveX控件的VBS脚本

    Set objFSO = CreateObject("Scripting.FileSystemObject") Set WSHShell = CreateObject(" ...

  4. 分析java中clone()方法 (转载+修改)

    Java中的clone() 方法 java所有的类都是从java.lang.Object类继承而来的,而Object类提供下面的方法对对象进行复制. protected native Object c ...

  5. Xcode 4.1~4.6 + iOS 5、iOS 6免证书(iDP)开发+真机调试+生成IPA全攻略

    原创文章,欢迎分享:未经许可,不得转载:版权所有,侵权必究 开发环境使用的是目前为止最新的稳定版软件:Mac OS X Lion 10.7 + Xcode 4.1 目前Xcode 4.2 Previe ...

  6. [虚拟化/云][全栈demo] 为qemu增加一个PCI的watchdog外设(二)

    这篇文章的理解,需要一些专业知识了. 我们可以创建模拟自己的外设吗? 我们已经知道什么是qemu了,我们可以通过qmeu的提供的外设,DIY一个计算机了. 但是我们可能还不满足,我们可以自己制造一个外 ...

  7. [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so

    0:前言 1:本文主要作为丙方android公司的身份来写 2:作者有不对的地方,请指出,谢谢 [第一篇:android利用jni调用第三方库——编写库libhello.so] [第二篇:androi ...

  8. MapReduce实现矩阵相乘

    矩阵相乘能够查看百度百科的解释http://baike.baidu.com/view/2455255.htm?fr=aladdin 有a和b两个矩阵 a:                1   2   ...

  9. 【和我一起学习Unity3D】Unity3D的坐标控制

    坐标这个东西,在Unity3D里面是分为几个类的,各自是Vector2,Vector3.Vector4:含义各自是:二维坐标系,三维坐标系,四维坐标系.一般做游戏呢,用到的最多的就是Vector3了. ...

  10. Android @+id与@id的区别

      Android中的组件需要用一个int类型的值来表示,这个值也就是组件标签中的id属性值.id属性只能接受资源类型的值,也就是必须以@开头的值,例如,@id/abc.@+id/xyz等. 如果在@ ...