广工人工智能实验报告.docx

上传人:b****7 文档编号:8977874 上传时间:2023-02-02 格式:DOCX 页数:19 大小:26.49KB
下载 相关 举报
广工人工智能实验报告.docx_第1页
第1页 / 共19页
广工人工智能实验报告.docx_第2页
第2页 / 共19页
广工人工智能实验报告.docx_第3页
第3页 / 共19页
广工人工智能实验报告.docx_第4页
第4页 / 共19页
广工人工智能实验报告.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

广工人工智能实验报告.docx

《广工人工智能实验报告.docx》由会员分享,可在线阅读,更多相关《广工人工智能实验报告.docx(19页珍藏版)》请在冰豆网上搜索。

广工人工智能实验报告.docx

广工人工智能实验报告

实验课程名称:

__人工智能

实验项目名称

井子棋AIalpha-beta剪枝算法

实验成绩

实验者

叶海恒

专业班级

计科8班

学号

3114006156

实验日期

2016.11

一、实验内容

设计具有AI的井子棋游戏(采用js)

AI采用α-β剪枝算法

二、实验设计(原理分析及流程)

min电脑AI下棋时,如果考虑步数为0,则代表直接返回当前棋盘估值w(值越大代表对max越有优势,越小则代表对min越有优势,w=maxW-minW)。

如果考虑步数为N,先获取min电脑可以下棋的位置steps。

对于可以下棋的一步step,电脑AI下棋到step的第row行,第column列。

如果这时候min电脑已经赢了,则把棋盘回退一步,返回棋盘估值和下棋位置,不用再考虑其他走法了。

否则,min需要在每一种走法里面,选择一种走法,令max人类走N-1步之后,自己的优势保持最大(即w值最小)。

什么是alpha-beta剪枝呢?

就是如果max人类当前一种走法1至少可以获取alpha优势,而另一种走法2,min电脑的一步棋则可能让人类获取比alpha更小的优势,那么max人类肯定不会选择走法2,所以计算在计算min电脑的走法时,min电脑的其他走法就不用再计算了。

最后min电脑经过steps.length种走法对比之后,选择w值最小的一种走法,把棋盘回退一步,并返回棋盘估值和下棋位置。

max走法类似,人类会选择w值最大的走法下棋,所以max函数和min函数分别代表人和AI下棋,互相递归调用,直到递归到步数为0时返回N步之后的估值。

 

三、实验代码及数据记录

1.代码

/**

*[Matrix矩阵]

*@param{[type]}arr[矩阵二维数组]

*/

varMatrix=function(arr){

this.data=arr;

this.row=arr.length;

this.column=arr.length?

arr[0].length:

0;

};

/**

*[multiply矩阵乘法转换]

*@param{[type]}matrix[转换矩阵]

*@return{[type]}[description]

*/

Matrix.prototype.multiply=function(matrix){

if(this.column==matrix.row){

varrow=this.row,

column=matrix.column,

arr=[];

for(vari=0;i

arr[i]=[];

for(varj=0;j

varsum=0;

for(varn=0;n

sum+=(this.data[i][n]*matrix.data[n][j]);

}

arr[i][j]=sum;

}

}

returnnewMatrix(arr);

}

};

/**

*[Chessboard棋盘]

*@param{[type]}row[description]

*@param{[type]}column[description]

*/

varChessboard=function(row,column){

this.data=[];

this.row=row;

this.column=column;

for(vari=0;i

this.data[i]=[];

for(varj=0;j

this.data[i][j]=Chessboard.NONE;

}

}

this.stack=[];

this.is_ended=false;

};

/**

*[toString输出棋盘信息]

*@return{[type]}[description]

*/

Chessboard.prototype.toString=function(){

returnthis.data.map(function(data){

returndata.toString();

}).join('\n');

};

/**

*[put下棋]

*@param{[type]}row[行]

*@param{[type]}column[列]

*@param{[type]}type[人还是AI下棋]

*@return{[type]}[description]

*/

Chessboard.prototype.put=function(row,column,type){

if(this.data[row][column]==Chessboard.NONE){

this.data[row][column]=type;

this.stack.push({

row:

row,

column:

column,

type:

type

});

if(this.stack.length==this.row*this.column){

this.is_ended=true;

}

}

returnthis;

};

/**

*[rollback悔棋]

*@param{[type]}n[后退n步]

*@return{[type]}[description]

*/

Chessboard.prototype.rollback=function(n){

n=n||1;

for(vari=0;i

varstep=this.stack.pop();

if(step){

this.data[step.row][step.column]=Chessboard.NONE;

}

}

this.is_ended=false;

returnthis;

};

/**

*[reset重置棋盘]

*@return{[type]}[description]

*/

Chessboard.prototype.reset=function(){

for(vari=0,n=this.row;i

for(varj=0,m=this.column;j

this.data[i][j]=Chessboard.NONE;

}

}

this.stack=[];

this.is_ended=false;

};

/**

*[availableSteps获取可走的位置]

*@return{[type]}[description]

*/

Chessboard.prototype.availableSteps=function(){

varavailableSteps=[];

for(vari=0,n=this.row;i

for(varj=0,m=this.column;j

if(this.data[i][j]==Chessboard.NONE){

availableSteps.push({

row:

i,

column:

j

});

}

}

}

returnavailableSteps;

};

/**

*[rotate把棋盘旋转90度]

*@return{[type]}[description]

*/

Chessboard.prototype.rotate=function(){

varboard=newChessboard(this.row,this.column),

dx=Math.floor(this.column/2),

dy=Math.floor(this.row/2);

for(vari=0;i

for(varj=0;j

vartype=this.data[i][j];

varmatrix=newMatrix([

[i,j,1]

]);

vartranslateMatrix1=newMatrix([

[1,0,0],

[0,1,0],

[-dx,-dy,1]

]);

vartranslateMatrix2=newMatrix([

[1,0,0],

[0,1,0],

[dx,dy,1]

]);

varrotateMatrix=newMatrix([

[0,-1,0],

[1,0,0],

[0,0,1]

]);

varres=matrix.multiply(translateMatrix1).multiply(rotateMatrix).multiply(translateMatrix2);

board.put(res.data[0][0],res.data[0][1],type);

}

}

returnboard;

};

/**

*[hash给棋盘一个编码]

*@param{[type]}sourceRadix[来源进制]

*@param{[type]}targetRadix[目的进制]

*@return{[type]}[description]

*/

Chessboard.prototype.hash=function(sourceRadix,targetRadix){

varstr=this.data.map(function(arr){

returnarr.join('');

}).join('');

returnparseInt(str,sourceRadix).toString(targetRadix);

};

/**

*[evaluate计算当前棋盘的估值]

*@return{[type]}[description]

*/

Chessboard.prototype.evaluate=function(){

//max,min权重,max连棋数,min连棋数

varmaxW=minW=0,

maxCount,minCount;

//横向计算

for(vari=0;i

//当前这一行,max连棋数,min连棋数

maxCount=minCount=0;

for(varj=0;j

vartype=this.data[i][j];

if(type==Chessboard.MAX){

maxCount++;

}else{

if(type==Chessboard.MIN){

minCount++;

}

}

}

//如果连成3子

if(maxCount==3){

returnInfinity;

}else{

if(minCount==3){

return-Infinity;

}else{

//如果没有max的棋子,则min可能连成3子

if(!

maxCount){

minW++;

}

//如果没有min的棋子,则max可能连成3子

if(!

minCount){

maxW++;

}

}

}

}

//纵向计算

for(vari=0;i

//当前这一列,max连棋数,min连棋数

maxCount=minCount=0;

for(varj=0;j

vartype=this.data[j][i];

if(type==Chessboard.MAX){

maxCount++;

}else{

if(type==Chessboard.MIN){

minCount++;

}

}

}

//如果连成3子

if(maxCount==this.row){

returnInfinity;

}else{

if(minCount==this.row){

return-Infinity;

}else{

//如果没有max的棋子,则min可能连成3子

if(!

maxCount){

minW++;

}

//如果没有min的棋子,则max可能连成3子

if(!

minCount){

maxW++;

}

}

}

}

//右斜下方向计算

maxCount=minCount=0;

for(vari=0;i

vartype=this.data[i][i];

if(type==Chessboard.MAX){

maxCount++;

}else{

if(type==Chessboard.MIN){

minCount++;

}

}

}

//如果连成3子

if(maxCount==this.row){

returnInfinity;

}else{

if(minCount==this.row){

return-Infinity;

}else{

//如果没有max的棋子,则min可能连成3子

if(!

maxCount){

minW++;

}

//如果没有min的棋子,则max可能连成3子

if(!

minCount){

maxW++;

}

}

}

//左斜下方向计算

maxCount=minCount=0;

for(vari=0;i

vartype=this.data[i][this.column-i-1];

if(type==Chessboard.MAX){

maxCount++;

}else{

if(type==Chessboard.MIN){

minCount++;

}

}

}

if(maxCount==this.row){

returnInfinity;

}else{

if(minCount==this.row){

return-Infinity;

}else{

//如果没有max的棋子,则min可能连成3子

if(!

maxCount){

minW++;

}

//如果没有min的棋子,则max可能连成3子

if(!

minCount){

maxW++;

}

}

}

//返回双方实力差

returnmaxW-minW;

};

/**

*[isMaxWin人是否赢了]

*@return{Boolean}[description]

*/

Chessboard.prototype.isMaxWin=function(){

varw=this.evaluate();

returnw==Infinity?

true:

false;

};

/**

*[isMinWinAI是否赢了]

*@return{Boolean}[description]

*/

Chessboard.prototype.isMinWin=function(){

varw=this.evaluate();

returnw==-Infinity?

true:

false;

};

/**

*[end结束游戏]

*@return{[type]}[description]

*/

Chessboard.prototype.end=function(){

this.is_ended=true;

returnthis;

};

/**

*[isEnded游戏是否结束]

*@return{Boolean}[description]

*/

Chessboard.prototype.isEnded=function(){

returnthis.is_ended;

};

/**

*[maxmax下棋]

*@param{[type]}currentChessboard[当前棋盘]

*@param{[type]}depth[考虑深度]

*@return{[type]}[description]

*/

varmax=function(currentChessboard,depth,beta){

//记录优势值,应该下棋的位置

varrow,column,alpha=-Infinity;

//什么都不下,直接返回当前棋盘评估值

if(depth==0){

alpha=currentChessboard.evaluate();

return{

w:

alpha

};

}else{

//获取每一步可以走的方案

varsteps=currentChessboard.availableSteps();

//console.log('搜索MAX'+steps.length+'个棋局');

if(steps.length){

//对于每一种走法

for(vari=0,l=steps.length;i

varstep=steps[i];

//下棋

currentChessboard.put(step.row,step.column,Chessboard.MAX);

//如果已经赢了,则直接下棋,不再考虑对方下棋

if(currentChessboard.isMaxWin()){

alpha=Infinity;

row=step.row;

column=step.column;

//退回上一步下棋

currentChessboard.rollback();

break;

}else{

//考虑对方depth-1步下棋之后的优势值,如果对方没棋可下了,则返回当前棋盘估值

varres=min(currentChessboard,depth-1)||{

w:

currentChessboard.evaluate()

};

//退回上一步下棋

currentChessboard.rollback();

if(res.w>alpha){

//选择最大优势的走法

alpha=res.w;

row=step.row;

column=step.column;

}

//如果人可以获得更好的走法,则AI必然不会选择这一步走法,所以不用再考虑人的其他走法

if(alpha>=beta){

//console.log('MAX节点'+l+'个棋局,剪掉了'+(l-1-i)+'个MIN棋局');

break;

}

}

}

return{

w:

alpha,

row:

row,

column:

column

};

}

}

};

/**

*[minmin下棋]

*@param{[type]}currentChessboard[当前棋盘]

*@param{[type]}depth[考虑深度]

*@return{[type]}[权重和当前推荐下棋的位置]

*/

varmin=function(currentChessboard,depth,alpha){

varrow,column,beta=Infinity;

if(depth==0){

beta=currentChessboard.evaluate();

return{

w:

beta

};

}else{

//获取每一步可以走的方案

varsteps=currentChessboard.availableSteps();

//console.log('搜索MIN'+steps.length+'个棋局');

if(steps.length){

//对于每一种走法

for(vari=0,l=steps.length;i

varstep=steps[i];

//下棋

currentChessboard.put(step.row,step.column,Chessboard.MIN);

//如果已经赢了,则直接下棋,不再考虑对方下棋

if(currentChessboard.isMinWin()){

beta=-Infinity;

row=step.row;

column=step.column;

//退回上一步下棋

currentChessboard.rollback();

break;

}else{

//考虑对方depth-1步下棋之后的优势值,如果对方没棋可下了,则返回当前棋盘估值

varres=max(currentChessboard,depth-1,beta)||{

w:

currentChessboard.evaluate()

};

//退回上一步下棋

currentChessboard.rollback();

if(res.w

//选择最大优势的走法

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1