21点游戏.docx

上传人:b****7 文档编号:9027494 上传时间:2023-02-02 格式:DOCX 页数:15 大小:28.24KB
下载 相关 举报
21点游戏.docx_第1页
第1页 / 共15页
21点游戏.docx_第2页
第2页 / 共15页
21点游戏.docx_第3页
第3页 / 共15页
21点游戏.docx_第4页
第4页 / 共15页
21点游戏.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

21点游戏.docx

《21点游戏.docx》由会员分享,可在线阅读,更多相关《21点游戏.docx(15页珍藏版)》请在冰豆网上搜索。

21点游戏.docx

21点游戏

纸牌游戏21点

摘要

大多数赌场使用6副牌或8副牌玩这种游戏,以防止“数牌点”,在你的模拟中使用两副牌(共104张)。

只有2位参与者,你和庄家。

游戏开始时每人得到两张牌,对于牌面为2~10的牌,点数和面数相同;对于为人脸(J、Q、K)的牌,点数为10;牌面为A的牌,点数为1或者11.游戏的目的是得到总数尽量接近21点的牌,不得超过(超过称“爆了”),并使你得到的总点数多于庄家。

在21点游戏的赌桌前,往往一套牌(由四到六副组成)在用掉一半左右之后,才会换一副洗过的新牌。

这一规则使得21点游戏中有了“算牌”的机会,玩家可以记住前面几局中哪些牌已经打出,哪些牌还留在剩下的牌里。

因此在21点游戏中,玩家并不只是听天由命,可以主动做出很多决定。

比如,手里有一张10,一张5,是否继续要牌呢?

最后获胜的概率各是多少呢?

这要受很多变数影响。

除了刚刚提到的算牌(正在使用的这一套扑克牌打出哪些牌,还剩哪些牌)以外,还要考虑到目前其他玩家手里都有什么牌,做出这个选择后其他玩家怎样回应……这个概率的计算很复杂,不像骰子、轮盘那样直接容易。

我们可以在电脑上使用一种名为“蒙特卡洛模拟”的方法来帮助我们。

在进行21点的纸牌游戏过程中玩家总是受到各种因素的影响,因此,我们所得到的模型以及模型得到的结果都是一个平均的趋势,不能用来说明玩家的真正得分,不能确定玩家每一次的得分。

关键词:

纸牌游戏21点、蒙特卡洛模拟

 

一、问题重述

纸牌游戏21点(Blackjack).构造并实施21点游戏的蒙特卡洛模拟。

21点游戏规则如下:

大多数赌场使用6副牌或8副牌玩这种游戏,以防止“数牌点”,在你的模拟中使用两副牌(共104张)。

只有2位参与者,你和庄家。

游戏开始时每人得到两张牌,对于牌面为2~10的牌,点数和面数相同;对于为人脸(J、Q、K)的牌,点数为10;牌面为A的牌,点数为1或者11.游戏的目的是得到总数尽量接近21点的牌,不得超过(超过称“爆了”),并使你得到的总点数多于庄家。

如果开始两张牌的总点数恰为21(A-10或A-人脸),称为21点,自动成为胜者(若你和庄家都得到21点,则为平局,你的赌注仍在台上)。

靠21点赢时,付给你3赔2,即1.5赔1(1元赌注赢1.5元,且1元赌注仍保留)。

如果你和庄家都未得到21点,你想要多少张牌就可以取多少张牌,一次一张,使总数尽量接近21点,如果你超过了21点,就输了,游戏结束。

一旦你对牌的点数满意,你就“打住”,然后庄家按照下列规则取牌:

当庄家牌的点数为17、18、19、20和21时,就打住。

若庄家牌的点数小于或等于16,必然取牌。

庄家总把A的点数记为11,除非这样使他或她爆了(这时A的点数记为1)。

例如,庄家的A-6组合是17点,不是7点(庄家没有选择权),且庄家必须打住在17点上。

而若庄家有A-4组合(15点),又拿了一张K,那么新的总点数是15,因为A回到点数1(使之不超过21点),庄家还要再取牌。

如果庄家超过21点,你就赢了(赢赌注的钱,每1元赌注赢1元)。

如果庄家的总点数超过你,你将输掉全部赌注。

如果庄家和你的总点数相同,为平局(你不输也不赢)。

赌场中这个游戏的刺激之处在于,庄家开始的两张牌一张明、一张暗,所以你不知道庄家牌地总点数,必须根据那张明牌赌一把。

在这个项目模拟中你不用考虑这种情况,你需要做的是:

用两幅牌做12次游戏,你可以有无限的赌资(不希望吗?

),每次下赌2元。

两副牌玩过一次后,用两幅新牌(104张)继续玩。

这时记录你的得分(加或者减X元),然后下一幅牌从0开始。

输出是12次游戏的12个结果,可以用平均数或总数决定你的总成绩。

你的策略是什么?

完全由你决定!

可是这里有一招——假定庄家的牌你都看不到(于是你没有庄家牌这一点信息)。

选择一种游戏策略并在整个模拟中运行。

给出模拟算法的说明书、计算机程序以及12次游戏的输出结果。

游戏策略:

玩家的点数大于18或大于庄家明牌的两倍时我停止取牌

二、问题分析

在21点游戏的赌桌前,往往一套牌(由四到六副组成)在用掉一半左右之后,才会换一副洗过的新牌。

这一规则使得21点游戏中有了“算牌”的机会,玩家可以记住前面几局中哪些牌已经打出,哪些牌还留在剩下的牌里。

因此在21点游戏中,玩家并不只是听天由命,可以主动做出很多决定。

比如,手里有一张10,一张5,是否继续要牌呢?

最后获胜的概率各是多少呢?

这要受很多变数影响。

除了刚刚提到的算牌(正在使用的这一套扑克牌打出哪些牌,还剩哪些牌)以外,还要考虑到目前其他玩家手里都有什么牌,做出这个选择后其他玩家怎样回应……这个概率的计算很复杂,不像骰子、轮盘那样直接容易。

我们可以在电脑上使用一种名为“蒙特卡洛模拟”的方法来帮助我们。

蒙特卡洛模拟方法的名称就是来源于蒙特卡洛赌场,不过这种方法可不只是为了赌场而发明,物理、工程、金融、军事上都有应用。

进行蒙特卡洛模拟就是,首先要编写一个21点扑克牌的电脑程序(就像电脑游戏一样),然后让几个电脑玩家不停地互相玩。

在玩了几万局、几十万局甚至更多局数的时候,就可以统计出某一个特定牌局(例如手里有一张10,一张5)的所有可能情况,便能算出要牌和不要牌赢的可能性哪个大。

三、模型的建立与求解

21点的蒙特卡罗算法

输出玩家的得分SCORE

第1步初始化:

COUNTER=0.

第2步得到[1,13]内的随机数

.计算

的和SUM1(玩家总点数

),

的和SUM2(庄家总点数

);同时庄家现出自己的第一张牌

.

第3步判断

的值,若>10,则将其值改为10,并重新计算SUM1.

第4步判断

的值,若>10,则将其值改为10,并重新计算SUM1.

第5步判断

的值,若>10,则将其值改为10,并重新计算SUM2.

第6步判断

的值,若>10,则将其值改为10,并重新计算SUM2.

第7步判断

的值是否为1,若,等于1将其值改为11,重新计算SUM1,并判断SUM1是否大于21,若大于21则将

改为1,并重新计算SUM1,若没有大于21则继续第9步;若

不为1,直接进行第9步.

第8步判断

的值是否为1,若,等于1将其值改为11,重新计算SUM1,并判断SUM1是否大于21,若大于21则将

改为1,并重新计算SUM1,若没有大于21则继续第10步;若

不为1,直接进行第10步.

第9步判断

的值是否为1,若,等于1将其值改为11,重新计算SUM2,并判断SUM2是否大于21,若大于21则将

改为1,并重新计算SUM2,若没有大于21则继续第11步;若

不为1,直接进行第11步.

第10步判断

的值是否为1,若,等于1将其值改为11,重新计算SUM2,并判断SUM2是否大于21,若大于21则将

改为1,并重新计算SUM2,若没有大于21则继续第12步;若

不为1,直接进行第12步.

第11步玩家判断SUM1是否大于等于18或大于庄家第一张牌

的两倍,若是则玩家停止取牌,跳到第14步;若没有则继续取牌,得到[1,13]内的随机数

,进行第13步.

第12步同第4步和第8步,判断

的值,若>10,则将其值改为10,并将其值加到SUM1;接着判断

的值是否为1,若,等于1将其值改为11,重新计算SUM1,并判断SUM1是否大于21,若大于21则将

改为1,并重新计算SUM1,若没有大于21则回到第12步;若

不为1,直接进行第12步.

第13步庄家判断SUM2是否大于16,若是则庄家不取牌,则跳到第16步;否则庄家取牌,得到[1,13]内的随机数

,进行第15步.

第14步同第6步和第10步,判断

的值,若>10,则将其值改为10,并将其值加到SUM2;接着判断

的值是否为1,若,等于1将其值改为11,重新计算SUM1,并判断SUM2是否大于21,若大于21则将

改为1,并重新计算SUM2,若没有大于21则回到第14步;若

不为1,直接回到第14步.

第15步比较SUM1和SUM2的大小,

If(SUM1>21&&SUM2>21)or(SUM1=21&&SUM2=21),则为平局,得分SCORE=0;

IfSUM1=21&&UM2≠21,则玩家赢,得分SCORE=3;

If(SUM2=21&&SUM2≠21)or(21>SUM2>SUM1),则庄家赢,得分SCORE=-2;

If21>SUM1>SUM2则玩家赢,得分SCORE=2;

If21>SUM1=SUM2则为平局,SCORE=0.

第16步输出得分SCORE.

停止.

可以使用matlab实现上述蒙特卡罗算法,Matlab程序段如下:

functiony=dian21()

a=ones(8,13);%产生8*13的矩阵

numz=0;

numw=0;

pz=[];

pw=[];

totz=0;%庄家总点数

totw=0;%玩家总点数

[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);

while1

if(totw>18)|(totw>(2*pz

(1)))

break;

else

[numw,pw,a]=choose(numw,pw,a);

totw=totw+pw(numw);

end

end

while1

if(totz>=17)&(totz<=21)

break;

end

iftotz<17

[numz,pz,a]=choose(numz,pz,a);

totz=totz+pz(numz);

else

b=0;

fori=1:

numz

ifpz(i)==11

pz(i)=1;

totz=totz-10;

b=1;

break;

end

end

ifb==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;

elseif(totw==21&&totz~=21)

SCORE=3;

elseif(totz==21&&totw~=21)||(21>totz&&totz>totw)

SCORE=-2;

elseif21>totw&&totw>totz

SCORE=2;

elseif21>totw&&totw==totz

SCORE=0;

end

end

end

end

end

fprintf('玩家得分SCORE=%d\n',SCORE);

function[num,p,a]=choose(num,p,a)

while1

m=fix(rand

(1)*8)+1;

n=fix(rand

(1)*13)+1;

ifa(m,n)==1

a(m,n)=0;

num=num+1;

ifn==1

ifnum<21

n=11;

end

end

ifn>10

n=10;

end

p=[pn];

break;

end

end

运行结果总结表1:

玩家最终点数

庄家最终点数

玩家得分

14

24

2

21

17

3

26

20

-2

21

17

3

22

22

0

13

21

-2

22

17

-2

25

20

-2

19

17

2

17

20

-2

20

20

0

19

17

2

玩家平均得分

0.167

四、模型的评价

当比赛局数增加,上述游戏策略的玩家平均得分如下表。

局数

玩家平均得分

1000

9.2000E-02

2000

5.0000E-03

5000

-1.0200E-02

10000

-2.7900E-02

20000

-1.9600E-02

50000

-4.3540E-02

100000

-1.2880E-02

可见这种方法并不是很好,玩到最后,玩家的的平均得分不在为正,二是负值。

下面对上述游戏策略进行该进。

新的游戏策略:

玩家的总点数大于16就停止取牌

具体玩家应在手中的牌的总数为多少时停牌,可以用下面的程序段进行测试,其中flag变量就是我们向知道的决策数,运行程序,在命令窗口键入局数n(比如100000)和决策数(比如16),程序会输出在这个决策数下n局比赛玩家的平均得分。

functiony=dian21()

n=input('请输入局数:

');

SUM=0;

flag=input('请输入决策数:

');%这是一个决策数,我们可以改变其值,测试哪一个值最优

fori=1:

n

a=ones(8,13);%产生8*13的矩阵

numz=0;

numw=0;

pz=[];

pw=[];

totz=0;%庄家总点数

totw=0;%玩家总点数

[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);

while1

if(totw>flag)%|(totw>(2*pz

(1)))

break;

else

[numw,pw,a]=choose(numw,pw,a);

totw=totw+pw(numw);

end

end

while1

if(totz>=17)&(totz<=21)

break;

end

iftotz<17

[numz,pz,a]=choose(numz,pz,a);

totz=totz+pz(numz);

else

b=0;

fori=1:

numz

ifpz(i)==11

pz(i)=1;

totz=totz-10;

b=1;

break;

end

end

ifb==0

break;

end

end

end

%fprintf('玩家总点数=%d,',totw);

%fprintf('庄家总点数=%d\n',totz);

SCORE=0;

if(totw>21&&totz>21)||(totz==21&&totw==21)

SCORE=0;

elseif(totw==21&&totz~=21)

SCORE=3;

elseif(totz==21&&totw~=21)||(21>totz&&totz>totw)||(totw>21&&totz<21)

SCORE=-2;

elseif(21>totw&&totw>totz)||(totz>21&&totw<21)

SCORE=2;

elseif21>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);

 

function[num,p,a]=choose(num,p,a)

while1

m=fix(rand

(1)*8)+1;

n=fix(rand

(1)*13)+1;

ifa(m,n)==1

a(m,n)=0;

num=num+1;

ifn==1

ifnum<21

n=11;

end

end

ifn>10

n=10;

end

p=[pn];

break;

end

end

运行结果总结表2:

flag=15

flag=16

flag=17

局数

玩家平均得分

局数

玩家平均得分

局数

玩家平均得分

100000

3.7690E-02

100000

7.8620E-02

100000

2.5100E-02

100000

4.8770E-02

100000

6.6580E-02

100000

2.3450E-02

100000

4.1190E-02

100000

6.6530E-02

100000

2.0810E-02

可见,在flag=16时玩家的平均得分最高。

所以最终决策是:

玩家的总点数大于16就停止取牌

五、参考文献

[1]叶其孝姜启源译,数学建模(第3版),机械工业出版社,2005年1月。

[2]XX贴吧,赌场是如何利用概率赢利的,

[3]XX百科,21点,

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 工程科技 > 纺织轻工业

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1