你的位置:首页 > Java教程

[Java教程]简陋的斗地主,js实现


最近闲了两天没事做,用js写了个斗地主,练习练习。代码和功能都很简陋,还有bug,咋只是聊聊自己的思路。

这里说说斗地主主要包含的功能:洗牌,发牌,玩家出牌、电脑出牌,出牌规则的验证,输赢啥的没有判断,只是实现了这几个主要功能,下面依次说说几个功能的实现:

  1.洗牌:

    

1 var pukes=this.manage.pukes;//存放扑克牌的数组2 //洗牌3 for(var i=0;i<pukes.length;i++){4     var tmp=pukes[i];5     var index=util.random(i,pukes.length);//随机交换两张牌6     pukes[i]=pukes[index];7     pukes[index]=tmp;8 }  

  2.发牌(简版默认是玩家自己为地主,电脑为农民),由于前面洗牌时已经将牌的顺序打乱,所以发牌只是简单的循环把pukes中的元素添加到每个玩家实例中的pukes字段中。

 1 //发牌 2   var start=0; 3   for(var i=0;i<this.manage.pukes.length-3;i++) { 4     if(start==this.manage.players.length){ 5       start=0; 6     } 7     this.manage.pukes[i].status=true; 8     this.manage.players[start].pukesLen++; 9     this.manage.players[start++].pukes.push(this.manage.pukes[i]);10   }11   for(var i=this.manage.pukes.length-3;i<this.manage.pukes.length;i++){12     //地主多三张13     this.manage.pukes[i].status=true;14     this.manage.players[this.manage.curPlayerIndex].pukesLen++;15     this.manage.players[this.manage.curPlayerIndex].pukes.push(this.manage.pukes[i]);16   }

  3.玩家出牌,玩家出牌分为电脑和玩家自己两个步骤,电脑出牌是非常傻瓜的出牌方式(有牌就出):

  

 1 //出牌 2   if(this.options.playerIndex==this.manage.curPlayerIndex) { 3     var spks = [],gz=false; 4  5     if (this.manage.curMaxPlayerIndex == this.options.playerIndex) { 6       this.manage.deskPukes = []; 7     } 8     if (this.isCompute) { 9       //电脑自动出牌10       var start = 0;11       var len=this.manage.deskPukes.length||1;12       while (start < this.pukes.length) {13         spks = [];14         for (var i = 0,j=start; i <len&&j<this.pukes.length; i++) {15           //随便选一张 可以出就行16           if(this.pukes[j].status) {17             spks.push(this.pukes[j++]);18           }19         }20         if(spks.length) {21           if (rules.valids(spks, this.manage.deskPukes)) {22             gz = true;23             break;24           }25         }26         start++;27       }28     }29     else {30       //玩家选择出牌31       for (var i = 0; i < this.pukes.length; i++) {32         if (this.pukes[i].selected && this.pukes[i].status) {33           spks.push(this.pukes[i]);34         }35       }36       if (rules.valids(spks, this.manage.deskPukes)) {37         gz=true;38       }39       else{40         alert("出牌不符合规则!");41       }42     }43     if(gz){44       this.manage.curMaxPlayerIndex=this.options.playerIndex;45       this.manage.deskPukes = [];46       for (var i = 0; i < spks.length; i++) {47         this.pukesLen--;48         this.manage.deskPukes.push(spks[i]);49         spks[i].status = false;50       }51     }52     this.manage.renderPukes();53     this.manage.renderCurDiscard();54     if(this.isCompute||gz) {55       this.manage.nextPlayer();56     }57   }58   else{59     alert("没轮到你出牌!");60   }

View Code

  4.出牌规则的验证,是很多函数组合起来,然后循环调用,如果遇到返回ture的即为出牌符合规则:

  

 1 //以下为出牌规则 2 var rules={ 3   _rules:[ 4     new danzRule(), 5     new duiRule(), 6     new sandRule(), 7     new zandRule(), 8     new shunzRule(), 9     new liandRule() 10   ], 11   valids:function(_pukes,_curPukes){ 12     for(var i=0;i<this._rules.length;i++){ 13       if(this._rules[i].valid(_pukes,_curPukes)){ 14         return true; 15       } 16     } 17     return false; 18   } 19 }; 20  21 function danzRule(){ 22   //单张规则 23 } 24 danzRule.prototype.valid=function(_pukes,_curPukes){ 25   //校验 26   var pukes=_pukes;//玩家的牌 27   var curPukes=_curPukes;//左面的牌 28   if(pukes&&pukes.length==1){ 29     //比较牌面值 30     if(!curPukes||!curPukes.length){ 31       return true; 32     } 33     if(curPukes[0].dians==2&&pukes[0].dians<15){ 34       //2特殊处理 35       return false; 36     } 37     if(pukes[0].dians==2&&curPukes[0].dians<15){ 38       //2特殊处理 39       return true; 40     } 41     return pukes[0].dians>curPukes[0].dians; 42   } 43   return false; 44 } 45  46 function duiRule(_pukes,_curPukes){ 47   //两张规则 48  49 } 50 duiRule.prototype.valid=function(_pukes,_curPukes){ 51   //校验 52   var pukes=_pukes;//玩家的牌 53   var curPukes=_curPukes;//左面的牌 54   if(pukes&&pukes.length==2){ 55     //比较牌面值 56     if(pukes[0].dians>14&&pukes[1].dians>14){ 57       return true; 58     } 59     if(pukes[0].dians!=pukes[1].dians){ 60       return false; 61     } 62     if(!curPukes||!curPukes.length){ 63       return true; 64     }else { 65       if(curPukes.length!=2){ 66         return false; 67       } 68       if (curPukes[0].dians > 14 && curPukes[1].dians > 14) { 69         return false; 70       } 71       if (curPukes[0].dians != curPukes[1].dians) { 72         return false; 73       } 74       if (curPukes[0].dians == 2) { 75         return false; 76       } 77     } 78     if(pukes[0].dians==2){ 79       return true; 80     } 81     return pukes[0].dians>curPukes[0].dians; 82   } 83   return false; 84 } 85  86 function sandRule(){ 87   //三带 88 } 89 sandRule.prototype.valid=function(_pukes,_curPukes){ 90   //校验 91  92  93   var pukes=_pukes;//玩家的牌 94   var curPukes=_curPukes;//左面的牌 95   if(pukes&&(pukes.length>=3)){ 96     //比较牌面值 97     var books=getBooks(pukes); 98     if(!valid(books))return false; 99     if(!curPukes||!curPukes.length)return true;100     if(curPukes.length!=books.length)return false;101     var books2=getBooks(curPukes);102     if(!valid(books2))return false;103     return getSum(books)>getSum(books2);104   }105   return false;106 107   function getSum(books){108     var sum=0;109     for(var i=0;i<books.length;i++) {110       if(books[i]==3){111         if(i==2)return 9999;112         sum+=i;113       }114     }115     return sum;116   }117   function valid(books){118     //验证三带是否有效119     var counts3= 0,countsd= 0,d2=true,start=false,startIndex=-1;120 121     for(var i=0;i<books.length;i++) {122       if(start&&books[i]==3&&startIndex!=(i-1)){123         return false;124       }else{125         startIndex=i;126       }127       if(books[i]==3){128         if(!start) {129           start = true;130           startIndex = i;131         }132         counts3++;133       }134       if(books[i]==1){135         d2=false;136       }137     }138 139     for(var i=0;i<books.length;i++) {140       if(d2&&books[i]==2){141         countsd++;142       }143       else if(!d2&&books[i]==1){144         countsd++;145       }146     }147     return counts3>0&&counts3==countsd;148   }149 150   function getBooks(pukes){151     //返回三带的每个点数的个数152     var books=[];153     for(var i=0;i<pukes.length;i++){154       if(!books[pukes[i].dians]){155         books[pukes[i].dians]=1;156       }else{157         books[pukes[i].dians]++;158       }159     }160     return books;161   }162 }163 164 165 function zandRule(){166   //炸弹167 }168 zandRule.prototype.valid=function(_pukes,_curPukes){169   var pukes=_pukes;//玩家的牌170   var curPukes=_curPukes;//左面的牌171   if(pukes&&pukes.length==4) {172     if(!allEqual(pukes)){173       return false;174     }175     if(!curPukes||(curPukes.length>0&&curPukes.length!=4)||!allEqual(curPukes)){176       return true;177     }178     else{179       if(pukes[0].dians==2){180         return true;181       }182       if(curPukes[0].dians==2){183         return false;184       }185       return pukes[0].dians>curPukes[0].dians;186     }187 188   }189   return false;190 191   function allEqual(pukes){192     if(!pukes||!pukes.length)return false;193     var base=pukes[0].dians;194     for(var i=1;i<pukes.length;i++){195       if(base!=pukes[i].dians){196         return false;197       }198     }199     return true;200   }201 202 }203 204 function liandRule(){205   //连对206 }207 liandRule.prototype.valid=function(_pukes,_curPukes) {208   var pukes=_pukes;//玩家的牌209   var curPukes=_curPukes;//左面的牌210   if(pukes&&pukes.length>=6) {211     if(!verificationCoherence(pukes)){212       return false;213     }214     if(!curPukes||curPukes.length<=0){215       return true;216     }217     if(!verificationCoherence(curPukes)){218       return false;219     }220     if(pukes.length!=curPukes.length){221       return false;222     }223     return getSumDians(pukes)>getSumDians(curPukes);224   }225   return false;226   function getSumDians(pukes){227     var sum=0;228     for(var i=0;i<pukes.length;i++) {229       sum+=pukes[i].dians;230     }231     return sum;232   }233 234   function verificationCoherence(pukes){235     //验证连贯性236     if(!pukes||!pukes.length)return false;237     var books=[];238     for(var i=0;i<pukes.length;i++){239       if(pukes[i].dians==2||pukes[i].dians>14){240         return false;241       }242       if(!books[pukes[i].dians]){243         books[pukes[i].dians]=1;244       }else{245         books[pukes[i].dians]++;246       }247       if(books[pukes[i].dians]>2){248         return false;249       }250     }251     var start=false;252 253     for(var i=0;i<books.length;i++) {254       if(books[i]&&books[i]!=2){255         return false;256       }257       if(books[i]==2&&!start){258         start=true;259       }260       if(start&&books[i]!=2){261         return false;262       }263     }264 265     return true;266   }267 }268 function shunzRule(){269   //顺子270 }271 shunzRule.prototype.valid=function(_pukes,_curPukes){272   var pukes=_pukes;//玩家的牌273   var curPukes=_curPukes;//左面的牌274   if(pukes&&pukes.length>=5) {275     if(!verificationCoherence(pukes)){276       return false;277     }278     if(!curPukes||curPukes.length<=0){279       return true;280     }281     if(!verificationCoherence(curPukes)){282       return false;283     }284     if(pukes.length!=curPukes.length){285       return false;286     }287     return getSumDians(pukes)>getSumDians(curPukes);288   }289   return false;290 291   function getSumDians(pukes){292     var sum=0;293     for(var i=0;i<pukes.length;i++) {294       sum+=pukes[i].dians;295     }296     return sum;297   }298 299   function verificationCoherence(pukes){300     //验证连贯性301     if(!pukes||!pukes.length)return false;302     var books=[];303     for(var i=0;i<pukes.length;i++){304       if(pukes[i].dians==2||pukes[i].dians>14){305         return false;306       }307       if(!books[pukes[i].dians]){308         books[pukes[i].dians]=1;309       }else{310         return false;311       }312     }313     var start=false;314     for(var i=0;i<books.length;i++) {315       if(books[i]==1&&!start){316         start=true;317       }318       if(start&&!books[i]){319         return false;320       }321     }322     return true;323   }324 325 }

View Code

  以上4步,是我认为的主要的4个函数,其他的函数,如初始化,事件注册等,在源码已有注释,写的不好勿喷。

    附上源码:http://files.cnblogs.com/files/csbt/DDZ.zip