广工人工智能实验报告.docx
- 文档编号:10126710
- 上传时间:2023-02-08
- 格式:DOCX
- 页数:20
- 大小:26.78KB
广工人工智能实验报告.docx
《广工人工智能实验报告.docx》由会员分享,可在线阅读,更多相关《广工人工智能实验报告.docx(20页珍藏版)》请在冰豆网上搜索。
广工人工智能实验报告
实验课程名称:
__人工智能
实验项目名称
井子棋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 //选择最大优势的走法
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 工人 智能 实验 报告