本次版本包含人机对战(机器先手、机器后手)、人人模式(默认)、提示功能等。

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <style> *{ padding: 0;margin: 0; } html,body{width:100%;height: 100%;} div{ text-align: center; } div button{ line-height: 16px; font-size: 16px; padding: 5px 10px; border-radius: 5px; background: #e73480; color: white; border: none; } .canvas{ margin: 0 auto; } </style> </head> <body> <div class="canvas"> <canvas id="gobang"></canvas> </div> <div> <button id="requestSupport">提示</button> <button id="offense">先手人机</button> <button id="defense">后手人机</button> <button id="regret">悔棋</button> <button id="giveup">认输</button> <button id="restart">再来一局</button> <button id="negotiate">求和</button> </div> </body> <script src="man-machine4.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> var gobang = new Gobang("gobang"); // requestSupport document.getElementById("offense").addEventListener("click",()=>{ if(0 && gobang.canContinue){ alert("不可以中途开局,你可以先认输~~~"); }else{ gobang.machineFirst(); } },false); document.getElementById("defense").addEventListener("click",()=>{ if(0 && gobang.canContinue){ alert("不可以中途开局,你可以先认输~~~"); }else{ gobang.manFirst(); } },false); document.getElementById("requestSupport").addEventListener("click",()=>{ gobang.requestSupport && gobang.requestSupport(); },false); document.getElementById("regret").addEventListener("click",()=>{ gobang.regret(); },false); document.getElementById("giveup").addEventListener("click",()=>{ if(confirm("你确定认输吗?")){ gobang.giveUp(); } },false); document.getElementById("restart").addEventListener("click",()=>{ gobang.reStart(); },false); document.getElementById("negotiate").addEventListener("click",()=>{ if(confirm("你确定求和吗?")){ gobang.negotiate(); } },false); </script> </html>
// 五子棋
class Gobang {
constructor(canvasId, rowCount = 16) {
this.canvasId = canvasId;
this.rowCount = rowCount;
this.resetData();
}
// 渲染页面
renderUi() {
//清除之前的画布
this.ctx.clearRect(0, 0, this.width, this.height);
// 重绘画布
this.drawChessBoard();
this.drawPieces();
}
// 重置数据,再来一局
resetData() {
var body = document.documentElement || document.body;
var minWidth = Math.min(body.clientWidth,body.clientHeight-50);
// 属性
this.pieces = []; // 棋子数组 二位数组[[],[]] 0——空 1——白 2——黑
this.colCount = this.rowCount; // 列数
this.cellWidth = minWidth / (this.rowCount); //每个格子的宽
this.width = this.rowCount * this.cellWidth; // 棋盘的宽
this.height = this.width; // 棋盘的高
this.R = this.cellWidth * 0.4; // 棋子半径
this.hisStatus = []; // 历史记录 history status
this.active = 2; // 默认黑棋先走
this.manMachine = false; // true-人机模式 false-人人模式
this.machine = 2; // 机器人执棋 2-黑棋 1-白棋
this.canvas = document.getElementById(this.canvasId); // canvas DOM
this.ctx = this.canvas.getContext("2d"); // canvas环境
this.victor = 0; // 胜利方
this.canContinue = true; // 是否可以继续下棋(产生赢家以后不可以)
this.myPositions = []; // 我方的推荐位置数组 格式:{x:5,y:6,weight:8}
this.enemyPositions = []; // 敌方的推荐位置数组
this.init();
}
// 初始化数据
init() {
this.initCanvas();
this.initPiece();
this.renderUi();
}
// 暂时给棋盘中间加一个黑棋
first(){
var center = Math.floor((this.rowCount+1)/2);
this.pieces[center][center] = this.active;
this.hisStatus[1] = this.deepClone(this.pieces);
this.exchange();
}
// 设置棋盘的宽高
initCanvas() {
this.canvas.width = this.width;
this.canvas.height = this.height;
this.canvas.addEventListener("click",(e)=>{ // 小心this转移
var offset = this.canvas.getBoundingClientRect();
var x = Math.round((e.clientX - offset.left) / this.cellWidth);
var y = Math.round((e.clientY - offset.top) / this.cellWidth);
// console.log(x,y,"点击位置");
// 走棋
this.goStep(x,y);
},false);
}
// 高亮最近走的棋子
highLight(x,y,oneSide){
var anotherSide = oneSide == 1 ? 2 : 1;
var length = this.R*0.5;
this.ctx.beginPath();
this.ctx.moveTo(x * this.cellWidth - length, y * this.cellWidth);
this.ctx.lineTo(x * this.cellWidth + length, y * this.cellWidth);
this.ctx.moveTo(x * this.cellWidth, y * this.cellWidth - length);
this.ctx.lineTo(x * this.cellWidth, y * this.cellWidth + length);
this.ctx.strokeStyle = this.getColor(anotherSide);
this.ctx.stroke();
}
// 初始化棋子
initPiece() {
var initPieces = [];
for(let i = 0; i <= this.rowCount; i++) { // 行
initPieces.push([]);
for(let j = 0; j <= this.colCount; j++) { // 列
if(i==0 || j==0 || i==this.rowCount || j==this.rowCount){
initPieces[i].push(-1); // 不可以走的位置-1 空0 白1 黑2
}else{
initPieces[i].push(0); // 空0 白1 黑2
}
}
}
this.pieces = this.deepClone(initPieces);
this.hisStatus[0] = this.deepClone(initPieces);
//this.first();
}
// 获取某个棋子的颜色 0——空 1——白 2——黑
getColor (num){
var res = "";
console.trace();
// console.log(num);
switch(num){
case 0:
res = "";
break;
case 2:
res = "black";
break;
case 1:
res = "white";
break;
case -1:
res = "yellow";
break;
default:
res="red"; // 错误了
}
return res;
}
// 画棋盘
drawChessBoard() {
// 背景
this.ctx.beginPath();
this.ctx.rect(0, 0, this.width, this.height);
this.ctx.closePath();
this.ctx.fillStyle = "#0099CC";
this.ctx.fill();
// 画横线
this.ctx.beginPath();
for(let i = 0; i < this.rowCount; i++) {
this.ctx.moveTo(0, this.cellWidth * i);
this.ctx.lineTo(this.width, this.cellWidth * i);
}
this.ctx.strokeStyle = "#333";
this.ctx.stroke();
// 画纵线
this.ctx.beginPath();
for(let i = 0; i < this.colCount; i++) {
this.ctx.moveTo( this.cellWidth * i, 0);
this.ctx.lineTo( this.cellWidth * i, this.height);
}
this.ctx.strokeStyle = "#333";
this.ctx.stroke();
}
// 画一个棋子
drawDot(x, y, r, color) {
this.ctx.beginPath();
this.ctx.arc(x, y, r, 0, 2 * Math.PI);
this.ctx.closePath();
this.ctx.fillStyle = color;
this.ctx.fill();
}
// 画所有的棋子
drawPieces(x, y) {
//console.log(this.pieces)
for(var i = 0; i < this.pieces.length; i++) { // 边界线不让走棋
for(let j=0; j < this.pieces[i].length;j++){
// if(this.pieces[i][j] == 1 || this.pieces[i][j] == 2){
if(this.pieces[i][j] !== 0){
var x = i * this.cellWidth;
var y = j * this.cellWidth;
// var y = j * this.cellWidth - this.cellWidth/2;
this.drawDot(x,y,this.R,this.getColor(this.pieces[i][j]));
}
}
}
}
//
drawOnePiece(i,j){
var x = i * this.cellWidth;
var y = j * this.cellWidth;
this.drawDot(x,y,this.R,this.getColor(this.active));
}
// 判断是否可以走这一步
canGo(x, y) {
if(this.canContinue === false){
alert("游戏已结束");
return false;
}
if(x==0 || y==0 || x==this.rowCount || y==this.rowCount){
alert("边界上不可以走棋哦");
return false;
}
if(this.pieces[x][y]==0){
return true;
}else {
return false;
}
}
// 切换角色(换着走棋)
exchange(){
this.active = this.active == 1 ? 2 : 1;
}
manGoStep(x, y){
if(this.canGo(x,y)){
this.pieces[x][y] = this.active;//添加棋子
this.renderUi();
this.highLight(x,y,this.active);
this.hisStatus.push(this.deepClone(this.pieces));//历史记录(悔棋复盘功能使用)
this.getVictor();//这里有个坑,棋子还没有画上去,已经把输赢判断了????
this.exchange();
if(this.manMachine == true){
this.requestSupport();
}
}else{
// alert("这个位置已经被占领了,换个位置走吧");
}
}
// 走一步棋
goStep(x,y) {
// 判断这一步是否可以走
if(this.manMachine == true){
// 人机模式
if(this.machine == this.active){ // 轮到机器人走
this.requestSupport();
}else{ // 轮到人走
this.manGoStep(x, y);
}
}else{
// 人人模式
this.manGoStep(x, y);
}
}
// 任何时候点击提示后,给出一个推荐位置
requestSupport(){ // 请求支援
this.helpRecommend(this.active);
// console.log(this.myPositions,this.enemyPositions)
var p = this.bestPosition();
console.log(p);
if(Object.keys(p).length != 0){
}else{ // 第一次没有棋子,推荐的位置为空,默认推荐到中间
var x = parseInt(this.rowCount / 2);
var y = parseInt(this.rowCount / 2);
if(this.canGo(x, y)){
p.x = x;
p.y = y;
}else{
alert("没有有效位置了,自己随便走吧");
}
}
this.pieces[p.x][p.y] = this.active;
this.renderUi();
this.highLight(p.x,p.y,this.active);
this.getVictor();
this.exchange();
}
// 悔棋
regret() {
if(this.hisStatus.length<=1){
console.log("当前不可以悔棋了");
return;
}
this.canContinue = true;
this.victor = 0;
this.hisStatus.pop();
this.hisStatus.pop();
this.pieces = this.deepClone(this.hisStatus[this.hisStatus.length-1]);
// this.exchange();
this.renderUi();
}
// 重新开始
reStart(){
if(!this.victor){
alert("还没有结束,不能重新开始");
}else{
this.resetData();
}
}
// 求和
negotiate(){
alert("和棋");
this.resetData();
}
// 认输
giveUp(){
this.victor = this.active == 1 ? 2 : 1;
this.getWinner();
setTimeout(()=>{
this.resetData();
},60);
}
// 机器人先走
machineFirst(){
this.resetData();
this.manMachine = true;
this.machine = 2;
this.requestSupport();
}
// 机器人后走
manFirst(){
this.resetData();
this.manMachine = true;
this.machine = 1;
}
// 棋型判断 活三 死三等 都有对称情况
defineType (x,y){
// 类型 权重 棋型
// 活四 8 ?AAAA?
// 死四 7 BAAAA?——?AAAAB AA?AA
// 活三 6 ??AAA?——?AAA?? ?A?AA?——?AA?A?
// 死三 5 BAAA??——??AAAB BAA?A?——?A?AAB BA?AA?——?AA?AB
// 活二 4 ?AA???——???AA?
// 死二 3 BAA??? AA????
// 活一 2
// 死一 1
}
helpRecommend(oneSide){
var enemySide = oneSide == 1 ? 2 : 1;
this.myPositions = [];
this.enemyPositions = [];
var aimArr,standpoint;
for(let i=1;i<this.rowCount;i++){
for(let j=1;j<this.rowCount;j++){
// var arr = ["r","rd","d","ld","l","lt","t","rt"];
var arr = ["r","rd","d","ld"];
// 权重相关变量 forward backward center double null
var n2f1 = 0.2, // 两头空时 前面第一个空位置的权重
n2f2 = 0.2, // 两头空时 前面第二个空位置的权重
n2b1 = n2f1,
n2b2 = n2f2,
n1f1 = -0.8, // 一头空另一头是敌方或边界时 前面第一个空位置的权重
n1f2 = -0.8,
n1b1 = n1f1,
n1b2 = n1f2,
dn2c = 0.2, // 有两个片段时 两端都是空的时 中间位置的权重
dn2b1 = 0.2,// 有两个片段时 两端都是空的时 后方第一个位置的权重
dn2f1 = dn2b1,
dn1c = -0.5,
dn1b1 = -0.5,
dn1f1 = dn1b1;
if(this.pieces[i][j]==oneSide){ // 我方
aimArr = this.myPositions;
standpoint = oneSide;
}else if(this.pieces[i][j]==enemySide){ // 敌方
aimArr = this.enemyPositions;
standpoint = enemySide;
}else{
continue;
}
console.table([{i:i,j:j,qizi:this.pieces[i][j],standpoint:standpoint}])
for(var d =0;d<arr.length;d++){
var count = 0;
count = this.directionCount(arr[d],standpoint,i,j);
var nd = this.nd(arr[d]);
var h = nd.h;
var v = nd.v;
// 赢棋的单独写
if(count == 4){
if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
this.sumWeight(aimArr,i-1*h,j-1*v,10**5);
}else{
if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
this.sumWeight(aimArr,i+count*h,j+count*v,10**5);
}
}
continue;
}else{
}
// 某个方向的末端的推荐权重 (权重暂时认为后方第一个位置和第二位位置一样) 两头空的+0.2 一端空的+0 两端都死的考虑能否凑5个子
if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === 0){ //末2空
if(count>=3){
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+n2b1+0.3));
this.sumWeight(aimArr,i+(count+1)*h,j+(count+1)*v,10**(count+n2b2));
}else{
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+n2b1));
this.sumWeight(aimArr,i+(count+1)*h,j+(count+1)*v,10**(count+n2b2));
}
}else if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === standpoint){ // 末2己
let count2 = this.directionCount(arr[d],standpoint,i+(count+1)*h,j+(count+1)*v);
if(count+count2 >= 4){ // 可以赢的特殊算
this.sumWeight(aimArr,i+count*h,j+count*v,10**5);
}else{
if(this.pieces[i+(count+1+count2)*h] && this.pieces[i+(count+1+count2)*h][j+(count+1+count2)*v] === 0){
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+count2+dn2c));
this.sumWeight(aimArr,i+(count+1+count2)*h,j+(count+1+count2)*v,10**(count+count2+dn2b1));
}else {
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+count2+dn1c));
}
}
}else { //末2敌或边界
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+n1b1));
}
}else { // 末1敌或边界 末1不可能是己方的
// 末端没有推荐的位置
}
}else if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === standpoint){ // 前1己 这里已经计算过了,跳过逻辑
continue;
}else { // 前1 敌方或边界
if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === 0){ //末2空
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+n1b1));
this.sumWeight(aimArr,i+(count+1)*h,j+(count+1)*v,10**(count+n1b2));
}else if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === standpoint){ // 末2己
// this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+0.1));
let count2 = this.directionCount(arr[d],standpoint,i+(count+1)*h,j+(count+1)*v);
if(count+count2 >= 4){
this.sumWeight(aimArr,i+count*h,j+count*v,10**5);
}else{
if(this.pieces[i+(count+1+count2)*h] && this.pieces[i+(count+1+count2)*h][j+(count+1+count2)*v] === 0){
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+count2+dn1c));
this.sumWeight(aimArr,i+(count+1+count2)*h,j+(count+1+count2)*v,10**(count+count2+dn1b1));
}else {// 两端是死的 中间要么是5要么就没意义
if(count+1+count2 == 5){
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+count2+1));
}else{
this.sumWeight(aimArr,i+count*h,j+count*v,0);
//console.log("中间凑不够5个,中间权重是0");
}
}
}
}else { //末2敌或边界
if(count==4){ // 只有四颗子的时候这个位置才有意义
this.sumWeight(aimArr,i+count*h,j+count*v,10**(count+1));
}
}
}else { // 末1敌或边界 末1不可能是己方的
// 走不了了
}
}
// 某个方向的前端的推荐权重
if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 后1空
if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === 0){ //前2空
if(count>=3){
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+n2f1+0.3));
this.sumWeight(aimArr,i-2*h,j-2*v,10**(count+n2f2));
}else{
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+n2f1));
this.sumWeight(aimArr,i-2*h,j-2*v,10**(count+n2f2));
}
}else if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === standpoint){ // 前2己
// this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+0.3));
let count2 = this.directionCount(this.reverseDirection(arr[d]),standpoint,i-2*h,j-2*v);
if(count+count2 >= 4){
this.sumWeight(aimArr,i-1*h,j-1*v,10**5);
}else{
if(this.pieces[i-(1+count2)*h] && this.pieces[i-(1+count2)*h][j-(1+count2)*v] === 0){
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+count2+dn2c));
this.sumWeight(aimArr,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn2f1));
}else {
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+count2+dn1c));
this.sumWeight(aimArr,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn1f1));
}
}
}else { //前2敌或边界
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+n1f1));
}
}else { // 前1敌或边界 前1不可能是己方的
// 前端没有推荐的位置
}
}else if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === standpoint){ // 后1己 这里已经计算过了,跳过逻辑
continue;
}else { // 后1 敌方或边界
if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === 0){ //前2空
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+n1f1));
this.sumWeight(aimArr,i-2*h,j-2*v,10**(count+n1f2));
}else if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === standpoint){ // 前2己
// this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+0.1));
let count2 = this.directionCount(this.reverseDirection(arr[d]),standpoint,i-2*h,j-2*v);
if(count+count2 >= 4){
this.sumWeight(aimArr,i-1*h,j-1*v,10**5);
}else{
if(this.pieces[i-(1+count2)*h] && this.pieces[i-(1+count2)*h][j-(1+count2)*v] === 0){
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+count2+dn1c));
this.sumWeight(aimArr,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn1f1));
}else {
if(count+1+count2 == 5){
this.sumWeight(aimArr,i-1*h,j-1*v,10**(count+count2+1));
}else{
this.sumWeight(aimArr,i-1*h,j-1*v,0);
//console.log("中间凑不够5个,中间权重是0");
}
}
}
}else { //前2敌或边界
if(count==4){ // 只有四颗子的时候这个位置才有意义
this.sumWeight(aimArr,i-2*h,j-2*v,10**(count+1));
}
}
}else { // 前1敌或边界 前1不可能是己方的
// 前后都是敌,推荐个锤子
}
}
}
}
}
}
reverseDirection(direction){
var rd = "";
switch(direction){
case "r":
rd = "l";break;
case "rd":
rd = "lt";break;
case "d":
rd = "t";break;
case "ld":
rd = "rt";break;
case "l":
rd = "r";break;
case "lt":
rd = "rd";break;
case "t":
rd = "d";break;
case "rt":
rd = "ld";break;
default: console.error("输入方向不对,无法反转");
}
return rd;
}
// 方向数字化numberDirection r(1,0) rd(1,1) ld(-1,1)
nd(direction){
var res = {h:0,v:0}; // h horizontal v vertical
switch(direction){
case "r":
res.h = 1;
res.v = 0;
break;
case "rd":
res.h = 1;
res.v = 1;
break;
case "d":
res.h = 0;
res.v = 1;
break;
case "ld":
res.h = -1;
res.v = 1;
break;
case "l":
res.h = -1;
res.v = 0;
break;
case "lt":
res.h = -1;
res.v = -1;
break;
case "t":
res.h = 0;
res.v = -1;
break;
case "rt":
res.h = 1;
res.v = -1;
break;
default: console.error("方向输入有误");
}
return res;
}
// 合并同一个位置的权重
sumWeight(arr,x,y,weight){
weight = parseInt(weight); // 这里取一下整,小数看着不爽
var index = -1;
for(let i=0,len=arr.length;i<len;i++){
if(arr[i].x==x && arr[i].y==y){
index = i;
break;
}
}
if(index!=-1){ // 如果已存在则权重相加
arr[index].weight += weight;
}else{ // 如果不存在则添加一条
arr.push({x,y,weight});
}
}
// 从推荐位置中找出最佳位置 权重最大的位置
bestPosition (){
var myMax=0,myP={},myArr=[];
for(let i=0,len=this.myPositions.length;i<len;i++){
if(this.myPositions[i].weight>myMax){
myMax = this.myPositions[i].weight;
myP.x = this.myPositions[i].x;
myP.y = this.myPositions[i].y;
}
}
var enemyMax = 0, enemyP = {}, enemyArr = [];
for(let i=0,len=this.enemyPositions.length;i<len;i++){
if(this.enemyPositions[i].weight>enemyMax){
enemyMax = this.enemyPositions[i].weight;
enemyP.x = this.enemyPositions[i].x;
enemyP.y = this.enemyPositions[i].y;
}
}
// console.log(this.myPositions,this.ememyPositions);
//console.log("敌方权重最大:"+enemyMax,"我方权重最大:"+myMax);
for(let i=0,len=this.myPositions.length;i<len;i++){
if(this.myPositions[i].weight==myMax){
myArr.push(this.deepClone(this.myPositions[i]));
}
}
for(let i=0,len=this.enemyPositions.length;i<len;i++){
if(this.enemyPositions[i].weight==enemyMax){
enemyArr.push(this.deepClone(this.enemyPositions[i]));
}
}
console.log(myArr,enemyArr,"敌方权重最大:"+enemyMax,"我方权重最大:"+myMax)
if(enemyMax>myMax){
// 敌方权重最大的地方(有相同位置时,谋求自己的大权重位置)
var myMaxW = 0; // 我方在敌方最有位置处的最佳权重
var recommedP = enemyP;
for(let i=0, len=enemyArr.length;i<len;i++){
for(let j=0,len1=this.myPositions.length;j<len1;j++){
if(this.myPositions[j].x==enemyArr[i].x && this.myPositions[j].y==enemyArr[i].y){
if(this.myPositions[j].weight>myMaxW){
myMaxW = this.myPositions[j].weight;
recommedP.x = this.myPositions[j].x;
recommedP.y = this.myPositions[j].y;
}
}
}
}
return recommedP;
}else {
// 我方权重最大的地方(有相同位置时,占据敌方的相对大权重位置)
var enemyMaxW = 0; // 我方在敌方最有位置处的最佳权重
var recommedP = myP;
for(let i=0, len=myArr.length;i<len;i++){
for(let j=0,len1=this.enemyPositions.length;j<len1;j++){
if(this.enemyPositions[j].x==myArr[i].x && this.enemyPositions[j].y==myArr[i].y){
if(this.enemyPositions[j].weight>enemyMaxW){
enemyMaxW = this.enemyPositions[j].weight;
recommedP.x = this.enemyPositions[j].x;
recommedP.y = this.enemyPositions[j].y;
}
}
}
}
return recommedP;
}
}
// 获取赢家
getWinner(){
switch(this.victor){
case 0:
// console.log("还没产生赢家");
break;
case 1:
setTimeout(()=>{
alert("白棋赢");
this.canContinue = false;
},30);
break;
case 2:
setTimeout(()=>{
alert("黑棋赢");
this.canContinue = false;
},30);
break;
default:;
}
}
// 判断输赢
getVictor() { //1.找到一个当前棋子,2.判断它的右、右下、下、左下四个方向是否连成5个棋子
var dArr = ["r","rd","d","ld"];
for(var i=1;i<this.pieces.length;i++){
for(var j=1;j<this.pieces[i].length;j++){
if(this.pieces[i][j] == this.active){
for(let k =0;k<dArr.length;k++){
if(this.directionCount(dArr[k],this.active,i,j) == 5){// 右r 下d 左l 上t
this.victor = this.active;
this.getWinner();
return;
}
}
}
}
}
}
// 各个方向连珠数量判断
directionCount(direction,oneSide,i,j){
var count = 0;
var nd = this.nd(direction);
if(this.pieces[i][j] == oneSide){
count = 1;
for(let k=1;k<5;k++){
if(this.pieces[i+k*nd.h] && this.pieces[i+k*nd.h][j+k*nd.v] === oneSide){
count++;
continue;
}else {
break;
}
}
}
return count;
}
// 深拷贝
deepClone(values) {
var copy;
// Handle the 3 simple types, and null or undefined
if(null == values || "object" != typeof values) return values;
// Handle Date
if(values instanceof Date) {
copy = new Date();
copy.setTime(values.getTime());
return copy;
}
// Handle Array
if(values instanceof Array) {
copy = [];
for(var i = 0, len = values.length; i < len; i++) {
copy[i] = this.deepClone(values[i]);
}
return copy;
}
// Handle Object
if(values instanceof Object) {
copy = {};
for(var attr in values) {
if(values.hasOwnProperty(attr)) copy[attr] = this.deepClone(values[attr]);
}
return copy;
}
throw new Error("Unable to copy values! Its type isn't supported.");
}
}