您的位置:首页 > Web前端 > JavaScript

JavaScript-实现五子棋的简单整体设计

2018-02-28 18:54 453 查看
这个程序界面大体是参考B站上的视频"B站技术最屌的程序员,30分钟java开发人工智能五子棋,看完我是服气"算法部分视频中没解释,我是参考网上的各种资源选定的一个比较简单的算法.

先上代码,我把自己修改的和之前的都保存着.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>

<style>
*{margin:0;}/*解决浏览器的兼容性问题*/
body{background:url("http://pic.58pic.com/58pic/15/24/50/43Q58PICkj4_1024.jpg");background-size:cover;}
canvas{background:#fff;margin:100px auto;display:block;/*border:10px solid #ccff33;*/box-shadow:0px 0px 0px #000}/*margin 上下 左右*/

</style>
</head>
<body>
<canvas id="myCanvas" width="450" height="450"></canvas>

<script>

var me = true;
var over = false;
var chessBox = [];
var wins = [];         //定义三维数组
//赢法统计数组
var myWin = [];
var computerWin = [];

/*这是表征棋盘的二维数组*/
for(i=0;i<15;i++){
chessBox[i]=[];
for(j=0;j<15;j++){
chessBox[i][j]=0;
}
}

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++){

/*这五种表示赢法0
*
//执行1次
// wins[0][0][0]=true;
// wins[0][1][0]=true;
// wins[0][2][0]=true;
// wins[0][3][0]=true;
// wins[0][4][0]=true;
*
*/
//执行2次
// wins[0][1][1]=true;
// wins[0][2][1]=true;
// wins[0][3][1]=true;
// wins[0][4][1]=true;
// wins[0][5][1]=true;
for(var k=0; k<5;k++){

wins[i][j+k][count] = true;  //这里的count的放入是干啥呢???
}
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++;
}
}

console.log(count);  //统计有多少种赢法
for (var i=0;i<count;i++) {
myWin[i] = 0;
computerWin[i] = 0;
}

var chess = document.getElementById('myCanvas');
var context = chess.getContext('2d');
context.strokeStyle = "#BFBFBF";
//var logo= new Image();
//logo.src = "img/木头.jpg";
//logo.onload = function(){
// context.drawImage(logo,0,0,450,450);
//drawChessBoard();
//  oneStep(0,0,true);
//  oneStep(1,1,false);
//}

/*
*
function drawChessBoard(){
for(var i=0;i<15;i++){
context.moveTo(15+i*30,15);
context.lineTo(15+i*30,435);
context.moveTo(15,15+i*30);
context.lineTo(435,15+i*30);
context.stroke();
}

}
*
*/

/*这是画线的*/
var drawChessBoard = function(){

for(var i=0;i<15;i++){
context.moveTo(15+30*i,15);
context.lineTo(15+30*i,435);
context.stroke();

context.moveTo(15,15+30*i);
context.lineTo(435,15+30*i);
context.stroke();
}
}

window.onload = function(){
drawChessBoard();
//onStep(1,2,true);
}

/*画棋子*/
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,15+j*30,13,15+i*30,15+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;
}
if(!me){   //不是我
return;
}
var x = e.offsetX;
var y = e.offsetY;
var i = Math.floor(x/30);  //i,j为索引序列号
var j = Math.floor(y/30);
if(chessBox[i][j]==0){  //这个判定就把
oneStep(i,j,me);

chessBox[i][j]=1;

for(var k=0;k < count; k++){
if(wins[i][j][k]) {  //表示第k种赢法且棋的坐标位置是i,j,之前已经通过全范围的扫描确定了所有有效的位置
myWin[k]++;      //第6=k种赢法的标志加1,表示有几颗棋子连线了
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(chessBox[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;
//  computerScore[i][j]+= 180;
}else if(computerWin[k]==2){
computerScore[i][j]+= 420;
//computerScore[i][j]+= 380;
}else if(computerWin[k]==3){
computerScore[i][j]+= 2020;
//computerScore[i][j]+= 1880;
}else if(computerWin[k]==4){
computerScore[i][j]+= 10020;
//computerScore[i][j]+= 9800;
}
}
}
//i,j和u,v互换是要干什么,u,v是白棋的坐标,通过上面危险度的比较,确定一个有危险的位置,像现在设定的危险系数,电脑会优先考虑自己的连线
//???这样是否会造成电脑会优先不管怎样先自己连成四颗子?
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);  //画白棋
chessBox[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;
}
}
</script>
</body>
</html>

这是我第一次接触人工智能的写法,可以看出这种带系数的AI设定是比较简单的.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JavaScrip