基于德州扑克的数据结构分析
游戏逻辑分析
本游戏实为“21点”扑克牌游戏,计算机作为庄家,1人作为普通玩家参与游戏。参与者设使自己的牌达到总分21而不超过这个数值。扑克牌的分值取他们的面值。A充当1分或11分(此时由玩家自己选择),“Jack”,“Queen”,”King”都当做10分。在一局开始时,包括庄家在内的参与者都有两张牌。玩家可以看到他们的所有牌以及总分,而庄家有一张牌暂时隐藏。接下来,只要愿意,玩家都有机会依次再拿一张牌。如果某个玩家的总分超过了21(称为“引爆”),则这个玩家就输了。在玩家都拿了额外的牌后,庄家将显示隐藏的牌。只要庄家的总分等于或小于16分,那么庄家必须再拿牌。如果庄家引爆了,而玩家没有引爆,玩家将获胜;如果玩家与庄家分数相同,则庄家与玩家达成平局,所投的筹码留为下一局使用。否则,庄家获胜。
玩家一共有¥1000,玩家可随意下注(不能超过剩余筹码),若玩家胜,则庄家需要拿出等额的筹码给玩家,若玩家输,则下注的筹码归庄家。
简单数据类型
本游戏用到的一些简单的数据类型如下:
undefined: 代表一切未知的事物,啥都没有,无法想象,代码也就更无法去处理了。
注意:typeof(undefined) 返回也是 undefined。
可以将undefined赋值给任何变量或属性,但并不意味了清除了该变量,反而会因此多了一个属性。
null: 有那么一个概念,但没有东西。无中似有,有中还无。虽难以想象,但已经可以用代码来处理了。
注意:typeof(null)返回object,但null并非object,具有null值的变量也并非object。
boolean: 是就是,非就非,没有疑义。对就对,错就错,绝对明确。既能被代码处理,也可以控制代码的流程。
number: 线性的事物,大小和次序分明,多而不乱。便于代码进行批量处理,也控制代码的迭代和循环等。
注意:typeof(NaN)和typeof(Infinity)都返回number 。
NaN参与任何数值计算的结构都是NaN,而且 NaN != NaN 。
Infinity / Infinity = NaN 。
string: 面向人类的理性事物,而不是机器信号。人机信息沟通,代码据此理解人的意图等等,都靠它了。
数据结构
数组,结构体(对象)
本游戏采用包含N个结构的数组,每个数据结构包括:牌的面值,牌的花色等。
var GAME={ //对象名
decks:5,
cash:0,
clearing:false,
dealing:false,
playing:false,
hitting:false,
turns:0,
maxturns:1}
JavaScript中{}用来定义一个对象,大部分情况下要有成对的属性和值,或是函数,所以访问时,应该用.(点)来层层访问。
此处定义一个对象GAME,包含多个成对的属性和值。
var SUITS=[] //牌的花色
SUITS[0]=‘Spades‘
SUITS[1]=‘Diamonds‘
SUITS[2]=‘Hearts‘
SUITS[3]=‘Spades‘
JavaScript中使用[]来定义一个数组,也可以理解为一个数组对象
此处定义一个SUITS数组存储四种不同的花色的数据。
var VALUES=[] //牌的面值
VALUES[0]=‘Ace‘
VALUES[1]=‘Two‘
VALUES[2]=‘Three‘
VALUES[3]=‘Four‘
VALUES[4]=‘Five‘
VALUES[5]=‘Six‘
VALUES[6]=‘Seven‘
VALUES[7]=‘Eight‘
VALUES[8]=‘Nine‘
VALUES[9]=‘Ten‘
VALUES[10]=‘Jack‘
VALUES[11]=‘Queen‘
VALUES[12]=‘King‘
此处定义一个VALUES数组存储从Ace到King的牌面值。
var newDeck=[] //用来存储牌
for(var d=0;d<GAME.decks;d++){
for(var s=0;s<SUITS.length;s++){
for(var v=0;v<VALUES.length;v++){
newDeck.push([SUITS[s],VALUES[v]])//用for循环将牌存入数组
n+=1}}}
JavaScript中push() 方法可把它的参数顺序添加到 arrayObject 的尾部。它直接修改 arrayObject,而不是创建一个新的数组。push() 方法和 pop() 方法使用数组提供的先进后出栈的功能。
此处定义一个数组newDeck,通过嵌套for循环,调用push()方法将牌面值和花色组合后存入该数组中。
function shuffle(){ //洗牌函数
var newDeck=DECK
var card1
var card2
var temp
for(var i=0;i<1000;i++){
card1=Math.floor(DECK.length*Math.random())
//随机选牌 Math.random取0.0-0.9
card2=Math.floor(DECK.length*Math.random())
//Math.floor求一个最接近它的整数,它的值小于或等于这个浮点数
temp=DECK[card2]
DECK[card2]=DECK[card1]//互换两张牌
DECK[card1]=temp}
DECK=newDeck}
此函数将牌的顺序打乱,同样保存在DECK数组中,相当于洗牌。
function checkscore(entity){
var hard=0
var soft=0
var h=HANDS[entity.attr(‘id‘)]
if(!h){
h=HANDS[entity.attr(‘id‘)]=[]}
for(var i=0;i<h.length;i++){
var c=$(‘#‘+HANDS[entity.attr(‘id‘)][i])
var b=c.find(‘.Back‘)
if(b.css(‘display‘)!=‘none‘){
if(b.hasClass(‘Ace‘)&&hard<=10){
hard+=11
soft+=1
}else if(b.hasClass(‘Ace‘)&&hard>10){
hard+=1
soft+=1}
else if(b.hasClass(‘Two‘)){
hard+=2
soft+=2}
else if(b.hasClass(‘Three‘)){
hard+=3
soft+=3}
else if(b.hasClass(‘Four‘)){
hard+=4
soft+=4}
else if(b.hasClass(‘Five‘)){
hard+=5
soft+=5}
else if(b.hasClass(‘Six‘)){
hard+=6
soft+=6}
else if(b.hasClass(‘Seven‘)){
hard+=7
soft+=7}
else if(b.hasClass(‘Eight‘)){
hard+=8
soft+=8}
else if(b.hasClass(‘Nine‘)){
hard+=9
soft+=9}
else if(b.hasClass(‘Ten‘)||
b.hasClass(‘Jack‘)||
b.hasClass(‘Queen‘)||
b.hasClass(‘King‘)){
hard+=10
soft+=10}}}
var ht=hard
if(hard>0){
if(soft&&hard !=soft){
if(hard !=21){
if(hard<=21){
ht=soft+‘/‘+hard
}else{
ht=soft}}}}
return ht}
此处同样用数组保存玩家和庄家的分数值,用于判断胜负。
总结
这个HTML游戏用到的数据结构相对简单,主要是对数组和对象的使用。