zoukankan      html  css  js  c++  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个函数,其他的函数,如初始化,事件注册等,在源码已有注释,写的不好勿喷。

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

  • 相关阅读:
    Swift
    Swift
    Swift
    Swift
    iOS 判断某一日期是否在一日期区间
    iOS 本地推送通知
    iOS json解析中包含“ ”等解析出错
    iOS UILabel两侧加阴影
    IOS 设置ios中DatePicker的日期为中文格式
    [分享] 关于App Store下载到一半发生错误的问题 [复制链接]
  • 原文地址:https://www.cnblogs.com/csbt/p/ddz.html
Copyright © 2011-2022 走看看