【玩具】ANU Matlab Game Simulation

这段代码模拟了警察抓小偷,密室之中,小偷想偷到珠宝,自己有个探测器,警察也有探测器,不过是探测小偷用的,警察之间可以相互传递消息。

下面是程序的输入文件parameter.txt

# Size of side of square room (even integer), in m
2
# Radius of entry circle, in m 
0.6
# Position of treasure (x and y coords), in m 
0.5 0.5
# Range of anti-cloaking device, in cm 
150
# Position of the escape route (x and y coords), in m
0.5 -0.5
# Time limit for simulation, integer 
1000
# Time limit for each person's entry (max time steps), integer 
100
# Thief sensor range (radius), in cms 
5
# Number of cops, k, an integer 
3
# Cop1 sensor range (radius), in cms 
50
# Cop2 sensor range (radius), in cms 
50
# Cop3 sensor range (radius), in cms 
50

程序文件crgame.m

% crgame.m

function crgame
clc
clear
close all
%%
fidin=fopen('parameter.txt');               %read the data from the txt file
fgetl(fidin);
f1=fscanf(fidin,'%f');%Size of side of square room
fgetl(fidin);
f2=fscanf(fidin,'%f');%Radius of entry circle
fgetl(fidin);
f3=fscanf(fidin,'%f');%Position of treasure x,y
fgetl(fidin);
f4=fscanf(fidin,'%f');%Range of anti-cloaking device
fgetl(fidin);
fesp=fscanf(fidin,'%f');%Position of the escape route
fgetl(fidin);
f5=fscanf(fidin,'%f');%Time limit for simulation
fgetl(fidin);
f6=fscanf(fidin,'%f');%Time limit for each person's entry
fgetl(fidin);
f7=fscanf(fidin,'%f');%Thief sensor range
fgetl(fidin);
f8=fscanf(fidin,'%f');%number of police.
fgetl(fidin);
f9=fscanf(fidin,'%f');%cop1 sensor range.
fgetl(fidin);
f10=fscanf(fidin,'%f');%cop2 sensor range.
fgetl(fidin);
f11=fscanf(fidin,'%f');%cop3 sensor range.
fgetl(fidin);
fclose(fidin);
% u=importdata('parameter.txt')
u=[f1;f2;f3;f4;f5;f6;f7;f8;f9;f10;f11;fesp];
%%
%parameters

step_max=u(6,:);                           %define the data in the txt file
L=u(1,:);                                  %into the description used in
enter_r=u(2,:);                            %the main program
enter_xy=[0;0];                            %The data includes the size of
treasure=[u(3,:);u(4,:)];                  %the room, the radius of the 
thief_treasure_sensor_radius=u(5,:)*0.01;  %entry circle, the sensor radius
step_size_thief=0.01;                      %of thief and police, maximum
thief_sensor_radius=u(8,:)*0.01;           %number of step etc.
step_size_police=[0.01,0.01,0.01];
police_sensor_radius=[u(10,:)*0.01,u(11,:)*0.01,u(12,:)*0.01];
delta_step=[rand*100+10,rand*200+10,rand*300+10];
escape_slot = [u(13,:);u(14,:)];
%%
%main
%status for cop find thief, thief find cop, thief find treasture
s_ct = [0;0;0] % the cop find thief is off.
s_tc = 0 % the thief find cop is off.
s_tt = 0 % the thief find treasure is off.
s_ttd = 0 % the thief got the treasure is off.
s_cc = 0 % the cop find another cop is off.
c_flag = 0 % when find the thief the cop's drection
t_flag = 0 % thied find the treasure. 
td_flag = 0 % thief got the treasure.
% some important time point
when_got_treasure = step_max;

current_thife_pos = [0;0]; % curent_thife_position
thief_position{1}=enter_game(enter_r); %in this section, we designed the main program
for h_1=1:length(step_size_police)                      %that manipulate the overall movement and actions
    for h_2=1:delta_step(h_1)-1                         %of the thief, cops and the treasure.
        police_position{h_1}{h_2}=[-1.5;0];
    end
    %here we made a design that let the police to be the
    enter_pos = enter_game(enter_r);
    police_position{h_1}{h_2+1}=enter_pos;              %backup that stands outside of the room. 
end                                                     %Instead of appearing suddenly, the cops were waiting
caught=0;                                               %outside of the room and come inside when required.
for i=2:step_max+1
    thief_position{i}=rnd_move(thief_position{i-1},L,step_size_thief);
    current_thife_pos = thief_position{i};
    for h_1=1:length(step_size_police)                  %
        if i>delta_step(h_1)
           police_position{h_1}{i}=cop_rnd_move(police_position{h_1}{i-1},...
               L,step_size_police(h_1),h_1);
        end
    end
    if s_ttd == 0
        if sum((thief_position{i}-treasure).^2) <= thief_treasure_sensor_radius^2 % when thief caught the treture.
            if s_tt == 0
                disp('thief find the treasure');
                s_tt = 1;% turn on the status.
            end
        end
        if sum((thief_position{i}-treasure).^2)<0.001
            disp('thief got the treasure'); 
            when_got_treasure = i;
            s_ttd = 1;
        end
    end
    if s_ttd == 1 
        if sum((thief_position{i}-escape_slot).^2)<0.001
            disp('thief succeed!!'); 
            step_num=i;
            break;
        end
    end
    for h_1=1:length(step_size_police)
        if sum((police_position{h_1}{i}-thief_position{i}).^2)...
                <= police_sensor_radius(h_1)^2
            % cops find the thief.
            if s_ct(h_1,:) == 0
                fprintf('cop %d find the thief\n',h_1);
                s_ct(h_1,:) = 1;% turn on the status.
            end
        end
        % pass on the message
        for hh=1:length(step_size_police)
            if h_1 == hh 
                continue;
            end
            if s_ct(hh) == 1
                continue;
            end
            % cop h_1 find his colleague, then pass on the message to
            % another cop hh
            if sum((police_position{h_1}{i}-police_position{hh}{i}).^2)...
                <= police_sensor_radius(h_1)^2 && ...
                sum((police_position{h_1}{i}-police_position{hh}{i}).^2)...
                <= police_sensor_radius(hh)^2
                %fprintf('cop %d find cop %d \n',h_1,hh);
                s_ct(hh) = s_ct(h_1);
                %fprintf('cop %d know the thief position %d \n',hh);
            end
        end
        if sum((police_position{h_1}{i}-thief_position{i}).^2)...
                < 0.001
        fprintf('cop %d catch the thief\n',h_1);                  %the result will display on the screen when the thief
        step_num=i;                                     %finds the treasure or get caught by the cops.
        caught=1;
        end
    end
    if caught==1
        break
    end       
    if i==step_max+1                                    %when the total step reaches the maximum value set
        disp('time is up')                              %by the customer, the screen will display the time
        step_num=i;                                     %is up.
    end
end
%%
%%plot
figure                                                      %This section contains how we plot the room,
for i=1:step_num                                            %the thief and the cops, as well as their sensor
     hold on                                                %radius. Here we added a name tag for the thief,
     cir_xy=crl(enter_xy(1),enter_xy(2),enter_r);           %the police and the treasure.
     plot(cir_xy(1,:),cir_xy(2,:),'k')                      
     text(enter_r,0,'entrence')                       %
     plot(treasure(1),treasure(2),'yo')                     %position of the treasure 
     text(treasure(1)+0.02,treasure(2)+0.02,'treasure')               %
     plot(escape_slot(1),escape_slot(2),'gx');              %escape slot
     text(escape_slot(1)+0.02,escape_slot(2)+0.02,'escape');
     if i >= when_got_treasure
        p = plot(thief_position{i}(1),thief_position{i}(2),'.');   %position of the thief
        set(p,'color',[1, 0.6732, 0]);
     else 
        plot(thief_position{i}(1),thief_position{i}(2),'r.')   %position of the thief
        cir_xy=crl(thief_position{i}(1),thief_position{i}(2),...
         thief_treasure_sensor_radius);
        plot(cir_xy(1,:),cir_xy(2,:),'c');
     end
     cir_xy=crl(thief_position{i}(1),thief_position{i}(2),...
         thief_sensor_radius);
     plot(cir_xy(1,:),cir_xy(2,:),'r')
     text(thief_position{i}(1)+0.02,thief_position{i}(2)+0.02,'theif')     
     for h_1=1:length(step_size_police)                     %here controls how the police appears
        plot(police_position{h_1}{i}(1)+0.01,police_position{h_1}{i}(2)+0.01,'b.')
        cir_xy=crl(police_position{h_1}{i}(1),...           %the cops apprear one by one with the randomed
            police_position{h_1}{i}(2),police_sensor_radius(h_1));
        plot(cir_xy(1,:),cir_xy(2,:),'b')                   %time intervals.
        str=['cop' num2str(h_1)];
        text(police_position{h_1}{i}(1)+0.02,police_position{h_1}{i}(2)+0.02,str)
     end
     axis([-0.6*L,0.6*L,-0.6*L,0.6*L])
     axis equal
     if i == step_num
        plot([-0.5*L,-0.5*L],[0.5*L,-0.5*L],'k-')         %this is how we plot
        plot([0.5*L,-0.5*L],[0.5*L,0.5*L],'k-')           %the size of the room
        plot([0.5*L,0.5*L],[-0.5*L,0.5*L],'k-')
        plot([-0.5*L,0.5*L],[-0.5*L,-0.5*L],'k-')
     else
        plot([-0.5*L,-0.5*L],[0.5*L,-0.5*L],'m-')         %this is how we plot
        plot([0.5*L,-0.5*L],[0.5*L,0.5*L],'m-')           %the size of the room
        plot([0.5*L,0.5*L],[-0.5*L,0.5*L],'m-')
        plot([-0.5*L,0.5*L],[-0.5*L,-0.5*L],'m-')
     end
     pause(0.01)
     if i<step_num
        clf
     end
end

%% enter function   
function enter_pst=enter_game(enter_r)  %the function that determines the entrance
    rand_ang=rand*2*pi;
    x=100*enter_r*cos(rand_ang);
    y=100*enter_r*sin(rand_ang);
    enter_pst = [round(x)/100;round(y)/100];
end
%% thief move function 
function thief_position_new=rnd_move(thief_position_now,L,step_size_thief)
    dir = 0;
    dir_ps=[1,2,3,4];
    if thief_position_now(1)+step_size_thief>0.5*L          %this is the movement of the thief.
        dir_ps(1)=0;                                        %the thief can move to one of the four
    end                                                     %directions randomly
    if thief_position_now(2)+step_size_thief>0.5*L
        dir_ps(2)=0;
    end
    if thief_position_now(1)-step_size_thief<-0.5*L
        dir_ps(3)=0;
    end   
    if thief_position_now(2)-step_size_thief<-0.5*L
        dir_ps(4)=0;
    end
    % go to the escape
    if s_ttd == 1
        if abs(escape_slot(1) - thief_position_now(1)) < 0.001
            td_flag = 1;
        end
        if abs(escape_slot(2) - thief_position_now(2)) < 0.001  
            td_flag = 0;
        end
        if td_flag == 0
            if escape_slot(1) - thief_position_now(1) > 0
                dir = 1;td_flag = 1;
            elseif escape_slot(1) - thief_position_now(1) < 0
                dir = 3;td_flag = 1;
            end
        else
            if escape_slot(2) - thief_position_now(2) > 0
                dir = 2;td_flag =0;
            elseif escape_slot(2) - thief_position_now(2) < 0
                dir = 4;td_flag =0;
            end
        end
    end
    % go to the treasture.
    if s_tt ==1 && s_ttd == 0
        if abs(treasure(1) - thief_position_now(1)) < 0.001
            t_flag = 1;
        end
        if abs(treasure(2) - thief_position_now(2)) < 0.001
            t_flag = 0;
        end
        if t_flag == 0
        if treasure(1) - thief_position_now(1) > 0
            dir = 1;t_flag = 1;
        elseif treasure(1) - thief_position_now(1) < 0
            dir = 3;t_flag = 1;
        end
        
        else
        if treasure(2) - thief_position_now(2) > 0
            dir = 2;t_flag =0;
        elseif treasure(2) - thief_position_now(2) < 0
            dir = 4;t_flag =0;
        end
        
        end
    elseif s_ttd == 0
    % random steps
        dir_ps(find(dir_ps==0))=[];
        dir=dir_ps(ceil(rand*length(dir_ps)));                  %this is the movement of the police
    end
    if dir==1                                                           %the four directions that can be 
        thief_position_new=thief_position_now+[step_size_thief;0];      %influenced by the movement of the
    end                                                                 %thief
    if dir==2
        thief_position_new=thief_position_now+[0;step_size_thief];
    end
    if dir==3
        thief_position_new=thief_position_now+[-step_size_thief;0];
    end
    if dir==4
        thief_position_new=thief_position_now+[0;-step_size_thief];
    end
end
%% police move function 
function thief_position_new=cop_rnd_move(thief_position_now,L,step_size_thief,h)
    dir = 0;
    dir_ps=[1,2,3,4];
    if thief_position_now(1)+step_size_thief>0.5*L          %this is the movement of the thief.
        dir_ps(1)=0;                                        %the thief can move to one of the four
    end                                                     %directions randomly
    if thief_position_now(2)+step_size_thief>0.5*L
        dir_ps(2)=0;
    end
    if thief_position_now(1)-step_size_thief<-0.5*L
        dir_ps(3)=0;
    end   
    if thief_position_now(2)-step_size_thief<-0.5*L
        dir_ps(4)=0;
    end
    
    if s_ct(h) ==1
        if abs(current_thife_pos(1) - thief_position_now(1)) < 0.001
            c_flag =1;
        end
        if abs(current_thife_pos(2) - thief_position_now(2)) < 0.001
            c_flag = 0;
        end
        if c_flag == 0  
        if current_thife_pos(1) - thief_position_now(1) > 0
            dir = 1;c_flag = 1;
        elseif current_thife_pos(1) - thief_position_now(1) < 0
            dir = 3;c_flag = 1;
        end
        
        else
        if current_thife_pos(2) - thief_position_now(2) > 0
            dir = 2;c_flag =0;
        elseif current_thife_pos(2) - thief_position_now(2) < 0
            dir = 4;c_flag =0;
        end
        
        end
    else
    % random steps
        dir_ps(find(dir_ps==0))=[];
        dir=dir_ps(ceil(rand*length(dir_ps)));                  %this is the movement of the police
    end
    if dir==1                                                           %the four directions that can be 
        thief_position_new=thief_position_now+[step_size_thief;0];      %influenced by the movement of the
    end                                                                 %thief
    if dir==2
        thief_position_new=thief_position_now+[0;step_size_thief];
    end
    if dir==3
        thief_position_new=thief_position_now+[-step_size_thief;0];
    end
    if dir==4
        thief_position_new=thief_position_now+[0;-step_size_thief];
    end
end
%% circle function
function cir=crl(c_x,c_y,r)                     %this is how we design the circle,
      theta=0:0.1:2*pi;                         %which made use of the polar coordinates 
      x=cos(theta)*r+c_x;                       %to calculate the value of the x and y 
      y=sin(theta)*r+c_y;                       %axis
      cir=[x;y];
end        
end

posted @ 2013-05-23 17:56  花考拉  阅读(380)  评论(0编辑  收藏  举报