目录

  • 界面展示
  • 人机实现思路
  • 完整代码
  • 代码使用方式
界面展示

人机实现思路

这个机器输出接口只有短短的80行,并没有用人工智能的库,而只是给予其简单的规则,令其取满足规则的最好的点罢了。两条规则如下:

  • 优先占取四角,并且有多个可占角时,选择占领后使棋盘上白子最多的一个角。
  • 假设黑子在接下来一步会做出局部最好的选择(最贪婪的选择),尽量使棋盘上仍能保留尽可能多的白子。
完整代码

主体部分(运行时要运行这个函数)

function reversi_Man_Machine
%图形界面初始化:axis equalaxis([-0.2 9.2,-0.2 9.2])set(gca,'xtick',[],'ytick',[],'xcolor','w','ycolor','w')set(gca,'color',[0.6353 0.5451 0.3333])hold on[0.2235    0.4902    0.26670.3843    0.1569    0.00780.7882    0.7647    0.41960.6353    0.5451    0.33330.1373    0.2902    0.1686];
%按键函数初始化设置:set(gcf,'KeyPressFcn',@key,'tag','keyset')set(gcf,'WindowButtonDownFcn',@buttondown)
%全局变量:
global winner;
global turn;
global checher_board
global black;
global white;global plotblack;
global plotwhite;global postion;
global arrivable;
global plotpostion;
global plotarrivable;
init()function init()%初始化前清除原有图像:delete(findobj('tag','piece'));delete(findobj('tag','gc'));delete(findobj('tag','rx'));delete(findobj('type','line'));delete(findobj('type','patch'));%棋盘绘制:fill([-0.1;9.1;9.1;-0.1;-0.1],[-0.1;-0.1;9.1;9.1;-0.1],[0.3843 0.1569 0.0078])fill([0.5;8.5;8.5;0.5;0.5],[0.5;0.5;8.5;8.5;0.5],[0.2235 0.4902 0.2667])plot([1.5:1:7.5;1.5:1:7.5],[ones(1,7).*0.5;ones(1,7).*8.5],'color',[0.1373 0.2902 0.1686],'linewidth',0.75)plot([ones(1,7).*0.5;ones(1,7).*8.5],[1.5:1:7.5;1.5:1:7.5],'color',[0.1373 0.2902 0.1686],'linewidth',0.75)scatter([2.5,6.5,2.5,6.5],[2.5,2.5,6.5,6.5],30,'filled','CData',[0.1373 0.2902 0.1686]);numberset={'A','B','C','D','E','F','G','H'};for i=1:8text(0.2,9-i,num2str(i),...'HorizontalAlignment','center',...'color',[0.6353 0.5451 0.3333],...'FontWeight','bold',...'FontSize',12)text(i,8.83,numberset{i},...'HorizontalAlignment','center',...'color',[0.6353 0.5451 0.3333],...'FontWeight','bold',...'FontSize',12)end%棋子棋盘数值初始化:winner=0;turn=1;black=[4 4;5 5];white=[4 5;5 4];checher_board=zeros(8,8);checher_board(black(:,1)+(black(:,2)-1).*8)=1;checher_board(white(:,1)+(white(:,2)-1).*8)=-1;postion=[0 0];postion(1,:)=[];arrivable=[5 3;6 4;3 5;4 6];%绘制函数初始化:plotblack=scatter(gca,black(:,1),black(:,2),450,'o','filled','CData',[0.1 0.1 0.1],'tag','piece');plotwhite=scatter(gca,white(:,1),white(:,2),450,'o','filled','CData',[0.9 0.9 0.9],'tag','piece');plotpostion=scatter(gca,postion(:,1),postion(:,2),50,'o','CData',[0.5059 0.6078 0.3529],'LineWidth',1.5,'tag','gc'); plotarrivable=scatter(gca,arrivable(:,1),arrivable(:,2),150,'x',...'CData',[0.7843 0.3412 0.3098].*0.9,'LineWidth',1.5,'tag','rx'); endfunction buttondown(~,~)xy=get(gca,'CurrentPoint');xp=xy(1,2);yp=xy(1,1);pos=[yp,xp];pos=round(pos);if all(abs(pos)<=9)postion=round(pos);if strcmp(get(gcf,'SelectionType'),'normal'),set_piece();endif strcmp(get(gcf,'SelectionType'),'extend'),init();endredraw()endendfunction set_piece(~,~)if ~isempty(intersect(postion,arrivable,'rows'))&&turn==1black=[black;postion];checher_board(postion(1),postion(2))=1;change_color()turn=mod(turn+1,2);if ~isempty(get_arrivable(checher_board,turn))arrivable=get_arrivable(checher_board,turn);redraw()pause(1)postion=Machine_output(checher_board);white=[white;postion];checher_board(postion(1),postion(2))=-1;change_color() redraw()while(isempty(get_arrivable(checher_board,1))&&winner==0)arrivable=get_arrivable(checher_board,turn);redraw()pause(1)postion=Machine_output(checher_board);white=[white;postion];checher_board(postion(1),postion(2))=-1;change_color()         endendturn=mod(turn+1,2);arrivable=get_arrivable(checher_board,turn);endendfunction change_color(~,~)switch turncase 1,t=1;case 0,t=-1;enddir=[1 0;-1 0;0 1;0 -1;1 1;-1 -1;1 -1;-1 1];exchange_set=[0 0];exchange_set(1,:)=[];for j=1:8temp_set=postion+((1:7)')*dir(j,:);temp_set(temp_set(:,1)>8|temp_set(:,1)<1,:)=[];temp_set(temp_set(:,2)>8|temp_set(:,2)<1,:)=[];if ~isempty(temp_set)temp_value=checher_board(temp_set(:,1)+(temp_set(:,2)-1).*8);if temp_value(1)==-tcumpoint=find(temp_value~=-t,1);if ~isempty(cumpoint)if temp_value(cumpoint)==texchange_set=[exchange_set;temp_set(1:cumpoint-1,:)];endendend  endendexchange_set=unique(exchange_set,'rows');switch turncase 1black=[black;exchange_set];checher_board(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=1;[~,w,~]=intersect(white,exchange_set,'rows');white(w,:)=[];case 0white=[white;exchange_set];checher_board(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=-1;[~,b,~]=intersect(black,exchange_set,'rows');black(b,:)=[]; endendfunction redraw(~,~)set(plotblack,'XData',black(:,1),'YData',black(:,2))set(plotwhite,'XData',white(:,1),'YData',white(:,2))set(plotpostion,'XData',postion(:,1),'YData',postion(:,2))set(plotarrivable,'XData',arrivable(:,1),'YData',arrivable(:,2))if all(all(abs(checher_board)))&&winner==0judge()endendfunction judge()switch 1case (all(all(abs(checher_board)))&&size(black,1)>size(white,1))||isempty(white)winner=1;case (all(all(abs(checher_board)))&&size(white,1)>size(black,1))||isempty(black)winner=-1;case (all(all(abs(checher_board)))&&size(white,1)==size(black,1))winner=3;endif winner~=0redraw()switch winnercase 1buttonName1=questdlg('黑棋胜利','black win','关闭','重新开始','关闭');if isempty(buttonName1),buttonName1='end';endif strcmp(buttonName1,'重新开始'),init();elseif strcmp(buttonName1,'关闭'),close;endcase -1buttonName1=questdlg('白棋胜利','white win','关闭','重新开始','关闭');if isempty(buttonName1),buttonName1='end';endif strcmp(buttonName1,'重新开始'),init();elseif strcmp(buttonName1,'关闭'),close;endcase 3buttonName1=questdlg('平局','tie','关闭','重新开始','关闭');if isempty(buttonName1),buttonName1='end';endif strcmp(buttonName1,'重新开始'),init();elseif strcmp(buttonName1,'关闭'),close;endendendendend

功能函数(计算可行点)

function outcome=get_arrivable(board,t)
outcome=[0 0];
outcome(1,:)=[];
switch tcase 1,t=1;case 0,t=-1;
end
[x,y]=find(board==t);
collection=[x,y];
dir=[1 0;-1 0;0 1;0 -1;1 1;-1 -1;1 -1;-1 1];
if ~isempty(collection)
for i=1:size(collection,1)for j=1:8temp_set=collection(i,:)+((1:7)')*dir(j,:);temp_set(temp_set(:,1)>8|temp_set(:,1)<1,:)=[];temp_set(temp_set(:,2)>8|temp_set(:,2)<1,:)=[];if ~isempty(temp_set)temp_value=board(temp_set(:,1)+(temp_set(:,2)-1).*8);if temp_value(1)==-ttemp_set(temp_value==-t,:)=[];temp_value(temp_value==-t)=[];if ~isempty(temp_set)if temp_value(1)==0outcome=[outcome;temp_set(1,:)];end  endend  endend
end
end
outcome=unique(outcome,'rows');
end

机器端口

function exportPos=Machine_output(checher_board)
arrivable=get_arrivable(checher_board,0);
angleDetect=((arrivable(:,1)==1)|(arrivable(:,1)==8))&...((arrivable(:,2)==1)|(arrivable(:,2)==8));
if any(angleDetect)angleIndex=find(angleDetect);imagineBoard=zeros([8,8,length(angleIndex)]);whiteSums=zeros(length(angleIndex),1);for i=1:length(angleIndex)imagineBoard(:,:,i)=checher_board;imagineBoard(arrivable(angleIndex(i),1),arrivable(angleIndex(i),2),i)=-1;imagineBoard(:,:,i)=imagine_change_color(imagineBoard(:,:,i),...[arrivable(angleIndex(i),1),arrivable(angleIndex(i),2)],0);whiteSums(i)=sum(sum(imagineBoard(:,:,i)==-1));end[~,whiteBestIndex]=max(whiteSums);whiteBestIndex=whiteBestIndex(1);exportPos=arrivable(angleIndex(whiteBestIndex),:);
elseimagineBoard=zeros([8,8,size(arrivable,1)]);whiteSums=zeros(size(arrivable,1),1);for i=1:size(arrivable,1)imagineBoard(:,:,i)=checher_board;imagineBoard(arrivable(i,1),arrivable(i,2),i)=-1;imagineBoard(:,:,i)=imagine_change_color(imagineBoard(:,:,i),...[arrivable(i,1),arrivable(i,2)],0);tempArrivable=get_arrivable(imagineBoard(:,:,i),1);tempChecherBoard=imagineBoard(:,:,i);if ~isempty(tempArrivable)imagineOppBoard=zeros([8,8,size(tempArrivable,1)]);blackSums=zeros(size(tempArrivable,1),1);for ii=1:size(tempArrivable,1)imagineOppBoard(:,:,ii)=tempChecherBoard;imagineOppBoard(tempArrivable(ii,1),tempArrivable(ii,2),ii)=1;imagineOppBoard(:,:,ii)=imagine_change_color(imagineOppBoard(:,:,ii),...[tempArrivable(ii,1),tempArrivable(ii,2)],1);blackSums(ii)=sum(sum(imagineOppBoard(:,:,ii)==1));end[~,blackBestIndex]=max(blackSums);blackBestIndex=blackBestIndex(1);blackBestBoard=imagineOppBoard(:,:,blackBestIndex);whiteSums(i)=sum(sum(blackBestBoard==-1));endend[~,whiteBestIndex]=max(whiteSums);whiteBestIndex=whiteBestIndex(1);exportPos=arrivable(whiteBestIndex,:);
end
function outputBoard=imagine_change_color(inputBoard,postion,turn)switch turncase 1,t=1;case 0,t=-1;enddir=[1 0;-1 0;0 1;0 -1;1 1;-1 -1;1 -1;-1 1];exchange_set=[0 0];exchange_set(1,:)=[];for j=1:8temp_set=postion+((1:7)')*dir(j,:);temp_set(temp_set(:,1)>8|temp_set(:,1)<1,:)=[];temp_set(temp_set(:,2)>8|temp_set(:,2)<1,:)=[];if ~isempty(temp_set)temp_value=inputBoard(temp_set(:,1)+(temp_set(:,2)-1).*8);if temp_value(1)==-tcumpoint=find(temp_value~=-t,1);if ~isempty(cumpoint)if temp_value(cumpoint)==texchange_set=[exchange_set;temp_set(1:cumpoint-1,:)];endendend  endendexchange_set=unique(exchange_set,'rows');switch turncase 1inputBoard(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=1;case 0inputBoard(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=-1;endoutputBoard=inputBoard;
end
end
代码使用方式

需将三段代码分别复制到不同m文件中,并放在同一文件夹里,运行时调用reversi_Man_Machine函数(主体部分)。

MATLAB 人机对弈黑白棋相关推荐

  1. Python实现黑白棋人机对弈

    Python实现黑白棋人机对弈 简书:Python实现黑白棋人机对弈https://www.jianshu.com/p/37191dffbe07 规则 黑白棋的每颗棋子由黑白两色组成,一面白,一面黑. ...

  2. 黑白棋python代码框架_Python实现黑白棋人机对弈

    Python实现黑白棋人机对弈 规则 黑白棋的每颗棋子由黑白两色组成,一面白,一面黑.每次落子,把本方颜色的棋子放在棋盘的空格上,若在横.竖.斜八个方向的任一方向上有本方棋子,则被夹在中间的对手棋子全 ...

  3. python大作业黑白棋记分_Python实现黑白棋人机对弈

    Python实现黑白棋人机对弈 规则 黑白棋的每颗棋子由黑白两色组成,一面白,一面黑.每次落子,把本方颜色的棋子放在棋盘的空格上,若在横.竖.斜八个方向的任一方向上有本方棋子,则被夹在中间的对手棋子全 ...

  4. JAVA黑白棋之算法浅析

     引言   本为主要对我在开发JAVA黑白棋人机算法过程中所用的博弈思想.估值函数.搜索算法分3个方面进行了阐述,由于本人水平有限,如果大家希望了解更多有关黑白棋博弈策略以及人机算法的深入的理论研究, ...

  5. [Python] 黑白棋(翻转棋)小游戏

    [Python] 黑白棋(翻转棋)小游戏 游戏介绍 黑白棋(Reversi or Othello)在西方和日本很流行.游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负. 规则 黑白棋的每颗 ...

  6. Python 实现黑白棋

    Python实现黑白棋 题目要求 电脑的策略 游戏结束的条件 解题思路 关键逻辑 关键函数 Init_board: printBoard: computer_move: human_move: che ...

  7. 黑白棋出现pass 的条件 java_JAVA黑白棋之学习感悟

    前言 这是我来到蓝杰之后的第一个学习感悟,阶段成果也是我第一个觉得小有成就的作品,不在于所用的知识有多么高深,而在与这是第一个凝结了失败.努力.成功这样颇有曲折经历的项目,使我收获颇多. 下面切入正题 ...

  8. 人工智能导论实验2——野人渡河黑白棋问题

    人工智能导论实验2--野人渡河&黑白棋问题 实验目的及要求: 本项目要求能够理解人工智能的基本原理,理解状态空间的概念.原理和方法,掌握用状态空间表示问题的步骤,掌握搜索方法的基本原理,并能够 ...

  9. 黑白棋算法简单实现与基于Qt的GUI编程的综合应用

    一.序言: 最近学习了Qt的界面编程,包括了QObject.QWidget.QIODevice.QMessageBox.QTcpSockt.QTcpServer.QFile.QFileInfo.QDa ...

最新文章

  1. Silverlight导航应用程序Uri映射问题的分析与解决
  2. 深入理解 Java 内存模型(转载)
  3. 在MyEclipse中添加 XML Catalog (xwork-validator dtd )
  4. Java中栈和队列的用法 Stack And Queue
  5. Eclipse Juno在ubuntud的安装(SVN)
  6. 微信终端自研 C++协程框架的设计与实现
  7. iPhone设备分辨率及尺寸
  8. 打车业务下单高并发解决方案
  9. 网络游戏中网络模块浅析
  10. 非阻塞式编程 php,简单介绍PHP非阻塞模式
  11. STM32F103mini教程学习总结与心得(二)---->串口通信
  12. Angualr routerLink 两种传参方法及参数的使用
  13. java 线程池不抛异常 异常捕获失败问题
  14. AUTOCAD——图块批量改名
  15. 香橙派更改中文界面以及安装输入法
  16. mysql oracle minus_Oracle minus使用
  17. 求勾股数c语言OJ,C语言求勾股数(详解版)
  18. 如何关闭联想台式机电脑USB键盘的FN功能
  19. 设置linux kernel 日志打印方法
  20. 帝国php漏洞,帝国cms远程代码执行漏洞-1

热门文章

  1. 总结一下刚刚参加了今日头条的线上前端笔试
  2. MO3音频文件格式可以用XMplay打开并转换格式
  3. virtualBox提高性能方法
  4. 关于openfire支持视频聊天
  5. MacBookPro M1芯片安装brew
  6. 计算机组成原理实验存储器部件实验,实验4存储器部件实验.doc
  7. 来自Naval Ravikant 的十句话
  8. DC故障,在使用缓存登录的错误理解的解释
  9. Python爬虫(5)
  10. windows无法连接到共享打印机,错误码:0x0000011b