当前位置:   article > 正文

MATLAB 人机对弈黑白棋_matlab实现人机对战

matlab实现人机对战

界面展示

在这里插入图片描述

人机实现思路

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

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

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

function reversi_Man_Machine
%图形界面初始化:
    axis equal
    axis([-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.2667
    0.3843    0.1569    0.0078
    0.7882    0.7647    0.4196
    0.6353    0.5451    0.3333
    0.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:8
            text(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'); 
        
    end
    function 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();end
            if strcmp(get(gcf,'SelectionType'),'extend'),init();end
            redraw()
        end
    end

    function set_piece(~,~)
        if ~isempty(intersect(postion,arrivable,'rows'))&&turn==1
            black=[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()         
                end
            end
            turn=mod(turn+1,2);
            arrivable=get_arrivable(checher_board,turn);
        end
    end

    function change_color(~,~)
        switch turn
            case 1,t=1;
            case 0,t=-1;
        end
        dir=[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:8
            temp_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)==-t
                    cumpoint=find(temp_value~=-t,1);
                    if ~isempty(cumpoint)
                        if temp_value(cumpoint)==t
                            exchange_set=[exchange_set;temp_set(1:cumpoint-1,:)];
                        end
                    end
                end  
            end
        end
        exchange_set=unique(exchange_set,'rows');
        switch turn
            case 1
                black=[black;exchange_set];
                checher_board(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=1;
                [~,w,~]=intersect(white,exchange_set,'rows');
                white(w,:)=[];
            case 0
                white=[white;exchange_set];
                checher_board(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=-1;
                [~,b,~]=intersect(black,exchange_set,'rows');
                black(b,:)=[]; 
        end
    end


    function 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==0
            judge()
        end
    end

    function judge()
        switch 1
            case (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;
        end
        if winner~=0
            redraw()
            switch winner
            case 1
                buttonName1=questdlg('黑棋胜利','black win','关闭','重新开始','关闭');
                if isempty(buttonName1),buttonName1='end';end
                if strcmp(buttonName1,'重新开始'),init();
                elseif strcmp(buttonName1,'关闭'),close;
                end
            case -1
                buttonName1=questdlg('白棋胜利','white win','关闭','重新开始','关闭');
                if isempty(buttonName1),buttonName1='end';end
                if strcmp(buttonName1,'重新开始'),init();
                elseif strcmp(buttonName1,'关闭'),close;
                end
            case 3
                buttonName1=questdlg('平局','tie','关闭','重新开始','关闭');
                if isempty(buttonName1),buttonName1='end';end
                if strcmp(buttonName1,'重新开始'),init();
                elseif strcmp(buttonName1,'关闭'),close;
                end
            end
        end
    end

end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202

功能函数(计算可行点)

function outcome=get_arrivable(board,t)
outcome=[0 0];
outcome(1,:)=[];
switch t
    case 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:8
        temp_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)==-t
                temp_set(temp_value==-t,:)=[];
                temp_value(temp_value==-t)=[];
                if ~isempty(temp_set)
                    if temp_value(1)==0
                        outcome=[outcome;temp_set(1,:)];
                    end  
                end
            end  
        end
    end
end
end
outcome=unique(outcome,'rows');
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

机器端口

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),:);
else
    imagineBoard=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));
        end
    end
    [~,whiteBestIndex]=max(whiteSums);
    whiteBestIndex=whiteBestIndex(1);
    exportPos=arrivable(whiteBestIndex,:);
end
function outputBoard=imagine_change_color(inputBoard,postion,turn)
        switch turn
            case 1,t=1;
            case 0,t=-1;
        end
        dir=[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:8
            temp_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)==-t
                    cumpoint=find(temp_value~=-t,1);
                    if ~isempty(cumpoint)
                        if temp_value(cumpoint)==t
                            exchange_set=[exchange_set;temp_set(1:cumpoint-1,:)];
                        end
                    end
                end  
            end
        end
        exchange_set=unique(exchange_set,'rows');
        switch turn
            case 1
                inputBoard(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=1;
            case 0
                inputBoard(exchange_set(:,1)+(exchange_set(:,2)-1).*8)=-1;
        end
        outputBoard=inputBoard;
end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
代码使用方式

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/135295
推荐阅读
相关标签
  

闽ICP备14008679号