大富翁元胞自动机

2023-11-21 16:40
文章标签 元胞 自动机 大富翁

本文主要是介绍大富翁元胞自动机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

请添加图片描述
结论:第一个抛色子的玩家赢得概率最大

这篇关于大富翁元胞自动机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/403638

相关文章

hdu 3065 AC自动机 匹配串编号以及出现次数

题意: 仍旧是天朝语题。 Input 第一行,一个整数N(1<=N<=1000),表示病毒特征码的个数。 接下来N行,每行表示一个病毒特征码,特征码字符串长度在1—50之间,并且只包含“英文大写字符”。任意两个病毒特征码,不会完全相同。 在这之后一行,表示“万恶之源”网站源码,源码字符串长度在2000000之内。字符串中字符都是ASCII码可见字符(不包括回车)。

POJ 1625 自动机

给出包含n个可见字符的字符集,以下所提字符串均由该字符集中的字符构成。给出p个长度不超过10的字符串,求长为m且不包含上述p个字符串的字符串有多少个。 g++提交 int mat[108][108] ;int matn ;int N ;map<char ,int> to ;//ACconst int maxm = 108 ;const int kin

zoj 3228 ac自动机

给出一个字符串和若干个单词,问这些单词在字符串里面出现了多少次。单词前面为0表示这个单词可重叠出现,1为不可重叠出现。 Sample Input ab 2 0 ab 1 ab abababac 2 0 aba 1 aba abcdefghijklmnopqrstuvwxyz 3 0 abc 1 def 1 jmn Sample Output Case 1 1 1 Case 2

正规式与有限自动机例题

答案:D 知识点: 正规式 正规集 举例 ab 字符串ab构成的集合 {ab} a|b 字符串a,b构成的集合 {a,b} a^* 由0或者多个a构成的字符串集合 {空,a,aa,aaa,aaaa····} (a|b)^* 所有字符a和b构成的串的集合 {空,a,b,ab,aab,aba,aaab····} a(a|b)^* 以a为首字符的a,b字符串的集

Day17_0.1基础学习MATLAB学习小技巧总结(17)——字符向量元胞数组

利用空闲时间把碎片化的MATLAB知识重新系统的学习一遍,为了在这个过程中加深印象,也为了能够有所足迹,我会把自己的学习总结发在专栏中,以便学习交流。 素材来源“数学建模清风” 特此说明:本博客的内容只在于总结在使用matlab中的一些小技巧,并非教程,若想系统的学习MATLAB,也可以移步去链接中的视频,观看学习。也欢迎各位在留言区补充,纠错,讨论。 原素材和学习视频地址:MATLAB教程

AC自动机 - 多模式串的匹配运用 --- HDU 3065

病毒侵袭持续中  Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=3065   Mean:  略 analyse:  AC自动机的运用. 这一题需要将模式串都存储下来,还有就是base的取值一定要弄清楚,由于这题的模式串都是大写字母所以我们可以通过剪枝来加速。 Time complexity:o(n)+o(m

AC自动机 - 多模式串的匹配运用 --- HDU 2896

病毒侵袭 Problem's Link:http://acm.hdu.edu.cn/showproblem.php?pid=2896   Mean:   略 analyse: AC自动机的运用,多模式串匹配。就是有几个细节要注意,在这些细节上卡了半天了。 1)输出的网站编号和最终的病毒网站数不是一样的; 2)next指针要设128,不然会爆栈; 3)同理,char转换为i

[置顶]论如何优雅的处理回文串 - 回文自动机详解

写在前面 最近无意中看到了这个数据结构,顺便也就学习了一下。 而且发现网上关于这个算法的描述有很多地方是错的,在这里做了一些更正。 处理字符串的算法很多:     KMP,E-KMP,AC自动机,后缀三兄弟:后缀树、后缀数组、后缀自动机,Trie树、Trie图,符串hash... 但以上数据结构在处理回文串上还是稍有欠缺,用这些来处理回文显得太小题大做。 于是有了Manacher算

[置顶]AC自动机-算法详解

What's Aho-Corasick automaton?   一种多模式串匹配算法,该算法在1975年产生于贝尔实验室,是著名的多模式匹配算法之一。   简单的说,KMP用来在一篇文章中匹配一个模式串;但如果有多个模式串,需要在一篇文章中把出现过的模式串都匹配出来,就需要Aho-Corasick automaton算法了。 My Understanding About Aho-Coras

【HDU】3065 病毒侵袭持续中 AC自动机

病毒侵袭持续中 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5766    Accepted Submission(s): 2028 Problem Description 小t非常感谢大家帮忙解决了他的上一个