数学建模纸牌游戏21点(蒙特卡罗法)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• 第10步 判断y2的值是否为1,若等于1将 其值改为11,重新计算SUM2,并判断 SUM2是否大于21,若大于21则将y2改为1, 并重新计算SUM2,若没有大于21则继续第 12步;若y2不为1,直接进行第12步. • 第11步 玩家判断SUM1是否大于等于18 或大于庄家第一张牌y1的两倍,若是则玩家 停止取牌,跳到第14步;若没有则继续取 牌,得到[1,13]内的随机数xi,进行第13步.
• • • • • • • •
else if 21>totw && totw==totz SCORE=0; end end end end end SUM=SUM+SCORE;%fprintf('玩家得分 SCORE=%d\n',SCORE); • end • fprintf('玩家得分平均值SCORE=%d\n',SUM/n); • 保存为dian21.m
• totw=totw+pw(numw); • end • end • while 1 • if (totz>=17)&(totz<=21) • break; • end • if totz<17 • [numz,pz,a]=choose(numz,pz,a); • totz=totz+pz(numz); • else • b=0; • for i=1:numz
数学建模
纸牌游戏21点
一.21点的蒙特卡罗算法 • 第1步 初始化:COUNTER=0. • 第2步 得到[1,13]内的随机数x1,x2,y1,y2 计算x1,x2的和SUM1(玩家总点数 ), 的 和SUM2(庄家总点数);同时庄家现出自 己的第一张牌 . • 第3步 判断x1的值,若>10,则将其值 改为10,并重新计算SUM1. • 第4步 判断x2的值,若>10,则将其值 改为10,并重新计算SUM1.
• 第12步 同第4步和第8步,判断xi的值, 若>10,则将其值改为10,并将其值加到 SUM1;接着判断xi的值是否为1,若等于1 将其值改为11,重新计算SUM1,并判断 SUM1是否大于21,若大于21则将xi改为1, 并重新计算SUM1,若没有大于21则回到第 12步;若xi不为1,直接进行第12步. • 第13步 庄家判断SUM2是否大于16,若 是则庄家不取牌,则跳到第16步;否则庄 家取牌,得到[1,13]内的随机数yi,进行第 15步.
• 第8步 判断x2的值是否为1,若等于1将 其值改为11,重新计算SUM1,并判断 SUM1是否大于21,若大于21则将x2改为1, 并重新计算SUM1,若没有大于21则继续第 10步;若x2不为1,直接进行第10步. • 第9步 判断y1的值是否为1,若等于1将 其值改为11,重新计算SUM2,并判断 SUM2是否大于21,若大于21则将y1改为1, 并重新计算SUM2,若没有大于21则继续第 11步;若y1不为1,直接进行第11步.
二.Matlab程序
• • • • • • • • • function y=dian21() a=ones(8,13); %产生8*13的矩阵 numz=0; numw=0; pz=[]; pw=[]; totz=0; %庄家总点数 totw=0; %玩家总点数 [numz,pz,a]=choose(numz,pz,a);
• 第5步 判断y1的值,若>10,则将其值改 为10,并重新计算SUM2. • 第6步 判断y2的值,若>10,则将其值改 为10,并重新计算SUM2. • 第7步 判断x1的值是否为1,若等于1将其 值改为11,重新计算SUM1,并判断SUM1 是否大于21,若大于21则将x1改为1,并重 新计算SUM1,若没有大于21则继续第9步; 若x1不为1,直接进行第9步.
• function [num,p,a]=choose(num,p,a) • while 1 • m=fix(rand(1)*8)+1; • n=fix(rand(1)*13)+1; • if a(m,n)==1 • a(m,n)=0; • num=num+1; • if n==1 • if num<21 • n=11; • end • end
• if pz(i)==11 • pz(i)=1; • totz=totz-10; • b=1; • break; • end • end • if b==0 • break; • end • end • end
wk.baidu.com
• • • • • • • •
%fprintf('玩家总点数=%d,',totw); %fprintf('庄家总点数=%d\n',totz); SCORE=0; if (totw>21 && totz>21) || (totz==21&&totw==21) SCORE=0; else if (totw==21 && totz~=21) SCORE=3; else if (totz==21&&totw~=21) || (21>totz && totz>totw) ||(totw>21 && totz<21) • SCORE=-2; • else if (21>totw && totw>totz) ||(totz>21 && totw<21) • SCORE=2;
• • • • • • • • • • • • •
[numz,pz,a]=choose(numz,pz,a); totz=totz+pz(numz); [numz,pz,a]=choose(numz,pz,a); totz=totz+pz(numz); [numw,pw,a]=choose(numw,pw,a); totw=totw+pw(numw); [numw,pw,a]=choose(numw,pw,a); totw=totw+pw(numw); while 1 if (totw>flag)%|(totw> (2*pz(1)) ) break; else [numw,pw,a]=choose(numw,pw,a);
• if pz(i)==11
• pz(i)=1; • totz=totz-10; • b=1; • break; • end • end • if b==0 • break; • end • end • end
• • • • • • • •
fprintf('玩家总点数SUM1=%d\n',totw); fprintf('玩家总点数SUM1=%d\n',totz); SCORE=0; if (totw>21 && totz>21) || (totz==21&&totw==21) SCORE=0; else if (totw==21 && totz~=21) SCORE=3; else if (totz==21&&totw~=21) || (21>totz && totz>totw) • SCORE=-2; • else if 21>totw && totw>totz • SCORE=2;
>> dian21 玩家总点数SUM1=15 玩家总点数SUM1=22 玩家得分SCORE=0 >> dian21 玩家总点数SUM1=19 玩家总点数SUM1=19 玩家得分SCORE=0 >> dian21 玩家总点数SUM1=14 玩家总点数SUM1=18 玩家得分SCORE=-2
这些数据都是随机出现的。 这种方法并不是很好,下面对上述游戏策略进 行该进。
• 第14步 同第6步和第10步,判断yi的值, 若>10,则将其值改为10,并将其值加到 SUM2;接着判断yi的值是否为1,若等于1 将其值改为11,重新计算SUM1,并判断 SUM2是否大于21,若大于21则将yi改为1, 并重新计算SUM2,若没有大于21则回到第 14步;若yi不为1,直接回到第14步. • 第15步 比较SUM1和SUM2的大小, If ( SUM1>21&&SUM2>21) or (SUM1=21&&SUM2=21),则为平局,得 分SCORE=0;
If SUM1=21&&UM2≠21,则玩家赢, 得分SCORE=3; If (SUM2=21&&SUM2≠21) or (21>SUM2>SUM1),则庄家赢,得分 SCORE=-2; If 21>SUM1>SUM2 则玩家赢,得 分SCORE=2; If 21>SUM1=SUM2 则为平局, SCORE =0. • 第16步 输出得分SCORE. 停止.
• • • • • • • • • • • •
function y=dian21() n=input('请输入局数:'); SUM=0; flag=input('请输入决策数:'); %这是一个决策数, 我们可以改变其值,测试哪一个值最优 for i=1:n a=ones(8,13); %产生8*13的矩阵 numz=0; numw=0; pz=[]; pw=[]; totz=0; %庄家总点数 totw=0; %玩家总点数
• end
• end • while 1 • if (totz>=17)&(totz<=21) • break; • end • if totz<17 • [numz,pz,a]=choose(numz,pz,a); • totz=totz+pz(numz); • else • b=0; • for i=1:numz
• if n>10 • n=10; • end • p=[p n]; • break; • end • end 保存为choose.m 然后在matlab中输入dian21
• • • • • • • • • • • • • • • •
>> dian21 请输入局数:100000 请输入决策数:21 玩家得分平均值SCORE=1.351880e+00 >> dian21 请输入局数:100000 请输入决策数:20 玩家得分平均值SCORE=9.434000e-01 >> dian21 请输入局数:100000 请输入决策数:19 玩家得分平均值SCORE=3.226500e-01 >> dian21 请输入局数:100000 请输入决策数:18 玩家得分平均值SCORE=1.038300e-01
• • • • • • • • • • • • •
totz=totz+pz(numz); [numz,pz,a]=choose(numz,pz,a); totz=totz+pz(numz); [numw,pw,a]=choose(numw,pw,a); totw=totw+pw(numw); [numw,pw,a]=choose(numw,pw,a); totw=totw+pw(numw); while 1 if (totw>18)|(totw> (2*pz(1)) ) break; else [numw,pw,a]=choose(numw,pw,a); totw=totw+pw(numw);
• if n>10 • n=10; • end • p=[p n]; • break; • end • end • 保存为choose.m 然后在matlab中输入dian21,就可以得到如 下数据
• • • • • • • • • • • •
>> dian21 玩家总点数SUM1=20 玩家总点数SUM1=17 玩家得分SCORE=2 >> dian21 玩家总点数SUM1=20 玩家总点数SUM1=22 玩家得分SCORE=0 >> dian21 玩家总点数SUM1=20 玩家总点数SUM1=19 玩家得分SCORE=2
• • • • • • • • •
else if 21>totw && totw==totz SCORE=0; end end end end end fprintf('玩家得分SCORE=%d\n',SCORE); 保存为dian21.m
• function [num,p,a]=choose(num,p,a) • while 1 • m=fix(rand(1)*8)+1; • n=fix(rand(1)*13)+1; • if a(m,n)==1 • a(m,n)=0; • num=num+1; • if n==1 • if num<21 • n=11; • end • end