本文主要是介绍大富翁元胞自动机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
main.m
clear;clc;
dbstop if error
%% 模拟大富翁
tic
ITER = 2000;
winer = cell(ITER,11);
for TIMES = 1:ITER% 定义地图D.placedata = [2400,200,1200,6000,11000,1000,1200;3000,300,1600,7000,13000,1500,1500;2600,300,1600,7000,13000,1500,1300;2800,300,1600,7000,13000,1500,1400;2600,300,1600,7000,13000,1500,1300;3200,400,2000,8000,16000,2000,1600;3600,400,2000,8000,16000,2000,1800;2200,200,1200,6000,11000,1000,1100;3400,400,2000,8000,16000,2000,1700;2200,200,1200,6000,11000,1000,1100;2400,200,1200,6000,11000,1000,1200;3200,400,2000,8000,16000,2000,1600;2800,300,1600,7000,13000,1500,1400;3400,400,2000,8000,16000,2000,1700;3000,300,1600,7000,13000,1500,1500;3600,400,2000,8000,16000,2000,1800;2000,3000,6000,9000,12000,+inf,1000;2000,3000,6000,9000,12000,+inf,1000;2000,3000,6000,9000,12000,+inf,1000;2000,3000,6000,9000,12000,+inf,1000;];% 0表示起始地,+2000,1-16表示地点索引,17-20表示连锁地点,-1表示机会和命运,-2表示获得一枚幸运星,-3表示什么也不做D.map = [0,1,17,2,-1,3,4,-1,5,-2,-1,6,7,18,8,-3,-1,9,10,11,12,19,-1,20,-3,13,14,-1,15,16];% 第一列为目前所在地,第二列为目前所有金钱,第三列为目前持有空地,目前持有一星地,二星地,三星地,现状态 0为正常,1为跳过% 第八列为幸运星个数 第九列为在抵押房产,第十列为是否已经遍历,第十一列为玩家索引D.N = 4;%N个玩家D.starts = 7;%幸运星个数为7D.people = cell(D.N,11);%初始化目前所在地for i = 1:size(D.people,1)D.people{i,1} = 1;D.people{i,2} = 15000;D.people{i,7} = 0;D.people{i,10} = 0;D.people{i,11} = i;endturns = 0;while true%一局%循环遍历每个玩家player = 1;while true%一轮if size(D.people,1)==1breakendD.people{player,10} = 1;%如果要跳过,则跳过if D.people{player,7}==1D.people{player,7} = 0;if sum(cell2mat(D.people(:,10))) ~= size(D.people,1)player = find(cell2mat(D.people(:,10)) == 0);player = player(1);continueelsebreakendend%随机抛色子dian = randperm(6,1);[D.people{player,1},tf] = chulidian(D.people{player,1}+dian);%得到现在地点是什么内容if tf == 1 %如果经历了原点D.people{player,2} = D.people{player,2}+2000;endcontent = D.map(D.people{player,1});% D = contentcheck(D);if content == 0elseif content == -2D.people{player,8} = D.people{player,8}+1;D = xingyunxingcheck(D,player);elseif content == -1D = destinyandchance(D,player);elseif content == -3else[D,tf] = paycheck(D,player);if tf ~= 1%如果没有破产则进行购买检测D = buycheck(D,player);% else%如果破产则找到下一个玩家% if sum(cell2mat(D.people(:,10))) ~= size(D.people,1)% player = find(cell2mat(D.people(:,10)) == 0);% player = player(1);% else% break% endendend
% disp(sum(cell2mat(D.people(:,10))))
% disp(size(D.people,1))
% disp('-----------------------------------')if sum(cell2mat(D.people(:,10))) ~= size(D.people,1)player = find(cell2mat(D.people(:,10)) == 0);player = player(1);elsebreakendend% for i = 1:size(D.people,1)% if isempty(D.people(i,1))% D.people(i,:) = [];% end% end%将所有玩家的被访问信息置零for i = 1:size(D.people,1)D.people{i,10} = 0;endturns = turns+1;if size(D.people,1) == 1breakendendwiner(TIMES,:) = D.people;clear Ddisp(TIMES)
end
%% 结果分析
%检查最后获胜玩家和投色子的先后顺序的关系
win = zeros(ITER,1);
money = zeros(ITER,1);
for i = 1:size(winer,1)win(i) = winer{i,11};money(i) = winer{i,2};
end
figure(1)
histogram(win)
figure(2)
histogram(money)
toc
xingyunxing.m
function Dout = xingyunxingcheck(D,player)
%得到所有玩家的幸运星列表
startslist = cell2mat(D.people(:,8));
% 如果幸运星被分配完,则选取最多的几位玩家随机在自己地盘上盖房子
if sum(startslist)==D.starts%统计该玩家有多少块地以及可以建房屋的地di = D.people(player,3:5);%统计这些地建一所房屋需要花费多少钱,优先建造有2所房屋的地方for i = 3:-1:1if isempty(di(i))continueelsehouseidx = cell2mat(di(i));houseconprice = D.placedata(houseidx,6);houseconprice(houseconprice==+inf) = [];if isempty(houseconprice)continueelse%取最大的一个建造价格,造房子[house,houseidx] = find(houseconprice==max(houseconprice));house = house(1);houseidx = houseidx(1);D.people{player,i}(houseidx) = [];D.people{player,i+1}(end+1) = house;breakendendend%将所有玩家幸运星清零for i = 1:size(D.people,1)D.people{i,8} = 0;endendDout = D;
destinyandchance.m
function Dout = destinyandchance(D,player)
object = [1,1,2,2,3,3,4,4,5,6,7,8,9,10,11,11];
len = length(object);
r = randperm(len,1);
event = object(r);
if event == 1%减一个幸运星D.people{player,8} = D.people{player,8}-1;
elseif event == 2%加一个幸运星D.people{player,8} = D.people{player,8}+1;D = xingyunxingcheck(D,player);
elseif event == 3%让该玩家与另一玩家减500tempplayer = randperm(size(D.people,1),1);while tempplayer == playertempplayer = randperm(size(D.people,1),1);end%找到tempplayer的初始编号startind = D.people{tempplayer,11};D.people{player,2} = D.people{player,2}-500;D.people{tempplayer,2} = D.people{tempplayer,2}-500;D = breakcheck(D,player);[~,row] = ismember(startind,cell2mat(D.people(:,11)));D = breakcheck(D,row);
elseif event == 4%让该玩家减750D.people{player,2} = D.people{player,2}-750;D = breakcheck(D,player);
elseif event == 5%让该玩家减100D.people{player,2} = D.people{player,2}-100;D = breakcheck(D,player);
elseif event == 6%让该玩家减200D.people{player,2} = D.people{player,2}-200;D = breakcheck(D,player);
elseif event == 7%让该玩家减500D.people{player,2} = D.people{player,2}-500;D = breakcheck(D,player);
elseif event == 8%让该玩家加1850D.people{player,2} = D.people{player,2}-1850;
elseif event == 9%让该玩家加1000D.people{player,2} = D.people{player,2}-1850;
elseif event == 10%加3000停一轮D.people{player,2} = D.people{player,2}+3000;D.people{player,7} = 1;
elseif event == 11%2/3 stop 1/3 nothingif rand()<2/3D.people{player,7} = 1;end
end
Dout = D;
paycheck.m
function [Dout,tf] = paycheck(D,player)
%支付玩家过路费
%得到玩家到达地点
dian = D.map(D.people{player,1});
%判断地点的归属
tempplayer = 0;
for i = 1:size(D.people,1)for j = 3:6if ismember(dian,D.people{i,j})tempplayer = i;breakendendif tempplayer ~=0breakend
end
if tempplayer ~= 0 %支付玩家乾D.people{tempplayer,2} = D.people{tempplayer,2}+D.placedata(dian,j-1);D.people{player,2} = D.people{player,2}-D.placedata(dian,j-1);[D,tf] = breakcheck(D,player);
elsetf = 0;
end
Dout = D;
buycheck.m
function Dout = buycheck(D,player)
%选择是否购买该地
%得到该土地购买价格
dian = D.map(D.people{player,1});
price = D.placedata(dian,1);
%得到该玩家剩余乾数量
res = D.people{player,2};
%如果剩余乾数量大于土地购买价格则购买土地
%判断地点的归属
tempplayer = 0;
for i = 1:size(D.people,1)for j = 3:6if ismember(dian,D.people{i,j})tempplayer = i;breakendendif tempplayer ~=0breakend
end
%如果没有人拥有这件地产则选择够不够买
if tempplayer == 0 if price<resD.people{player,2} = D.people{player,2}-price;D.people{player,3}(end+1) = dian;end
end
%如果土地是自己的则选择是不是购买绿房子
if tempplayer == playerif j ~= 6upgradeprice = D.placedata(dian,6);upgradeprice(upgradeprice==+inf) = [];if ~isempty(upgradeprice)if upgradeprice<res%升级房屋D.people{player,j}(D.people{player,j}==dian) = [];D.people{player,j+1}(end+1) = dian;endendend
end
Dout = D;
breakcheck.m
function [Dout,tf] = breakcheck(D,player)
tf = 0;
%找到破产的玩家
own = D.people{player,2};
if own<0%得到该玩家欠债数%清算该玩家的房产house = D.people(player,3:6);%先卖房屋数量少的房产for i = 1:4payoff = 0;h = house{i};if ~isempty(h)%将抵押费从小到大排序hmortgage = D.placedata(h,7);hmortgage(hmortgage == +inf) = [];[val,ind] = sort(hmortgage,'ascend');hmortgage = val;j = 1;while true%首先卖掉所有房子own = own+(i-1)*0.5*D.placedata(ind(j),6);%将该房产绿色房子数量减至0D.people{player,i+2}(ind(j)) = [];D.people{player,3}(end+1) = h(ind(j));if own < 0%卖掉该房屋own = own+D.placedata(ind(j),7);D.people{player,3}(end) = [];D.people{player,9}(end+1) = h(ind(j));endif own >0payoff = 1;breakendhmortgage(j) = [];if isempty(hmortgage)breakelse[val,ind] = sort(hmortgage,'ascend');hmortgage = val;endendif payoff == 1breakendendendif payoff == 1D.people{player,2} = own;elseD.people(player,:) = [];tf = 1;endend
Dout = D;
chulidian.m
function [dian,tf] = chulidian(data)
if sum(data>30)>0tf = 1;
elsetf = 0;
enddata(data>30) = data(data>30)-30;dian = data;
end
结论:第一个抛色子的玩家赢得概率最大
这篇关于大富翁元胞自动机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!