撲克牌 ---JavaScript enumeration

這個是JavaScript權威指南里example 9-7 的例子,在這裏與大家交流一下

/**

 * 此方法將返回一個新對象(繼承於傳來的參數)
 * @param {} p
 * @return {}
 */
function inherit(p) {
         if(p == null)    //其實這裏可以寫成if(p);if可以檢測出undefined,null,false,"",0,NaN
                   throwTypeError();
         if(Object.create) {  //這裏檢查當前ECMAScript 版本,如果有create方法了則直接返回新對象,否則就用下來的方法來創建新對象
                   returnObject.create(p);
         }
         vart = typeof p;   //typeof  可以檢查出 右邊 參數的對象類型
         if(t !== "object" && t !== "function")
                   throwTypeError();
         functionf() {
         }
         f.prototype= p;  //這個句話是繼承的關鍵,表名 f 繼承於 p  
         returnnew f();
}


function enumeration(namesToValues) {
         /**
          *這function書上是這樣解釋的
          *This is the dummy constructor function that will be the return value.
          *至於你懂不懂,反正我不懂,懂的你希望能留言一下,解釋一下,謝謝
          */
         varenumeration = function() {
                   throw"Can't Instantiate Enumeration";
         };
/**
 * 這是對enumeration的擴展,我目前是這麼理解的,擴展了:增加了一個構造function和幾個方法
 * 這裏的proto 是一個引用,指向enumeration
 * @type 
 */
         varproto = enumeration.prototype = {
                   constructor: enumeration,  //這裏的enumeration是不是指的是上面enumeration的引用呢?有什麼作用?
                   toString: function() {
                            returnthis.name;
                   },
                   valueOf: function() {
                            returnthis.value;
                   },
                   toJson: function() {
                            returnthis.name;
                   }
         };


         enumeration.values= [];  //擴展,增加了一個values的數據對象
/**
 * 這是一個遍歷方法,比如這裏namesToValues爲{Club : 1,Diamond : 2},那麼name的值分別爲“Club”與”Diamond“
 */
         for(name in namesToValues) {
                   vare = inherit(proto);  //產生新對象 ,都繼承於proto
                   e.name= name;
                   e.value= namesToValues[name]; // 根據name來取得namesToValues裏的name的值,如Map
                   enumeration[name]= e; // 在enumeration增加一個name的屬性(這就是動態語言的特點吧)
                   enumeration.values.push(e);//加到values裏去,保存起來
         }


         enumeration.foreach= function(f, c) {
                   for(var i = 0; i < this.values.length; i++) {
                            f.call(c,this.values[i]); // 每次調用c對象裏的f方法,並傳入enumeration.values裏的值
                   }
         };
         returnenumeration;


}
/**
 * 這是一個撲克牌的例子
 * @param {} suit   爲方塊、紅星之類的
 * @param {} rank  就是指2、3、4....K、A
 */
function Card(suit, rank) {
         this.suit= suit;
         this.rank= rank;
}


//這裏算是執行程序的入口吧
Card.Suit = enumeration({
                            Club: 1,
                            Diamond: 2,
                            Heart: 3,
                            Spades: 4

                   });

//執行後應該是這樣;親,你能看懂嗎?

 

Card.Rank = enumeration({
                            Two: 2,
                            Three: 3,
                            Four: 4,
                            Five: 5,
                            Six: 6,
                            Seven: 7,
                            Eight: 8,
                            Nine: 9,
                            Ten: 10,
                            Jack: 11,
                            Queen: 12,
                            King: 13,
                            Ace: 14
                   });
Card.prototype.toString = function(){
         returnthis.rank.toString() + "   of    " +this.suit.toString();
};


Card.prototype.compareTo = function(that){
         if(this.rank< this.rank) return -1;
         if(this.rand> this.rank) return 1;
         return0;
};


Card.orderByRank = function(a, b){
         returna.compareTo(b);
};


//排序法則,優先對比紅心、黑桃....
Card.orderBySuit = function(a, b){
         if(a.suit< b.suit) return -1;
         if(a.suit> b.suit) return 1;
         if(a.rank< b.rank) return -1;
         if(a.rank> b.rank) return 1;
         return0;
};
/**
 * 這是一個遍歷的方法
 * cards裏就放着4 * 13 個對象
 * 意思就是得到全部撲克牌,比如new Deck();就可以得到4 * 13個牌了
 * 這應該就是Deck的構造函數吧
 * 這裏的foreach是上面定義的,有兩個參數,可這裏都只傳一個參數,第二個參數則爲null,傳null會有什麼影響呢?求指導...
 */
function Deck(){
         varcards = this.cards = [];
         Card.Suit.foreach(function(s){//外層爲紅心、黑桃等4種牌
                   Card.Rank.foreach(function(r){//內層爲2、3、4、5....K、A
                            cards.push(newCard(s,r));
                   });
         });     
}
/**
 * 這方法是用來打亂牌的(洗牌)
 * 這裏的Math.random() * (i +1) 寫得不錯,0 < Math.random() < 1 那裏整個值的範圍爲  0 到 i 了,不懂的請在紙上寫寫看,你就容易明白了
 * @return {} 
 */
Deck.prototype.shuffle = function(){
         vardeck = this.cards, len = deck.length;
         for(vari = len -1; i > 0; i --){
                   varr = Math.floor(Math.random() * (i +1)),temp;  //Math.floor()是去一法的,比如0.9則取0,5.5則取5;這與Math.ceil()相反
                   temp= deck[i],
                   deck[i]= deck[r],
                   deck[r]= temp;
         }
         returnthis;  //return this 是爲了方法鏈,如deck.deal(13).sort(Card.orderBySuit),執行順序爲從左到右
};
/**
 * 在這裏的意思是刪除第n個後的撲克牌
 * @param {} n
 * @return {}
 */
Deck.prototype.deal = function(n){
         if(this.cards.length< n){
                   throw"Out of cards";
         }
         returnthis.cards.splice(this.cards.length - n, n);  //splice(m,n)是從數組裏刪除數據,從第m個開始(包括m),刪除n個數據;
};


var deck = (new Deck()).shuffle(); //得到全部撲克牌後,洗牌
var iii = deck.deal(13);
var hand = deck.deal(13).sort(Card.orderBySuit); 
for(var i = 0; i < hand.length; i ++){
         console.log(hand[i].toString());
}
/**
 * 刪除每13張後全部的撲克牌,意思只要13張牌,然後排序,這裏的Card.orderBySuit,我一開始我不懂, 後來我懂了,不懂的同鞋可以去看看js 裏的sort的用法
 * arrayObject.sort(sortby)         sortby可選。規定排序順序。必須是函數
 *     若 a 小於 b,在排序後的數組中 a 應該出現在 b 之前,則返回一個小於 0 的值。
 *          若 a 等於 b,則返回 0。
 *          若 a 大於 b,則返回一個大於 0 的值。
 *
 * 後面的for是我自己加上去了,可以打印出手上是哪13張牌

發佈了23 篇原創文章 · 獲贊 0 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章