手拉手教你實現一門程式語言 Enkel, 系列 20

KevinOfNeu發表於2018-09-06

本文系 Creating JVM language 翻譯的第 20 篇。 原文中的程式碼和原文有不一致的地方均在新的程式碼倉庫中更正過,建議參考新的程式碼倉庫。

原始碼

Github

撲克牌洗牌模擬器

在之前的 19 篇部落格中,我把實現程式語言的每一步都詳細的記錄下來了。如果不拿這門語言,練練手,做個東西玩,那就沒什麼意思了,對不?

我準備實現一個撲克牌的洗牌模擬器。思路是提供一定數量的玩家,指定每個玩家的撲克牌的數量。作為輸出,每個玩家都能獲得一定數量的隨機撲克牌。

Card 類

Card {

    string color
    string pattern

    Card(string cardColor,string cardPattern) {
        color = cardColor
        pattern = cardPattern
    }

    string getColor() {
        color
    }

    string getPattern() {
        pattern
    }

    string toString() {
        return "{" + color + "," + pattern + "}"
    }
}
複製程式碼

沒有黑科技,就是一個物件,並且是不可變的。

CardDrawer 類

CardDrawer {
    start {
        var cards = new List() //creates java.util.ArrayList 
        addNumberedCards(cards) //calling method with 3 arguments (last 2 are default)
        addCardWithAllColors("Ace",cards) 
        addCardWithAllColors("Queen",cards)
        addCardWithAllColors("King",cards)
        addCardWithAllColors("Jack",cards)
        //Calling with named arguments (and in differnet order)
        //The last parameter (cardsPerPlayer) is ommited (it's default value is 5)
        drawCardsForPlayers(playersAmount -> 5,cardsList -> cards) 
    }

    addNumberedCards(List cardsList,int first=2, int last=10) {
        for i from first to last {  //loop from first to last (inclusive)
            var numberString = new java.lang.Integer(i).toString()
            addCardWithAllColors(numberString,cardsList)
        }
    }

    addCardWithAllColors(string pattern,List cardsList) {
        cardsList.add(new Card("Clubs",pattern))
        cardsList.add(new Card("Diamonds",pattern))
        cardsList.add(new Card("Hearts",pattern))
        cardsList.add(new Card("Spades",pattern))
    }

    drawCardsForPlayers(List cardsList,int playersAmount = 3,int cardsPerPlayer = 5) {
        if(cardsList.size() < (playersAmount * cardsPerPlayer)) {
            print "ERROR - Not enough cards" //No exceptions yet :)
            return
        }
        var random = new java.util.Random()
        for i from 1 to playersAmount {
            var playernumberString = new java.lang.Integer(i).toString()
            print "player " + playernumberString  + " is drawing:"
            for j from 1 to cardsPerPlayer {
                var dawnCardIndex = random.nextInt(cardsList.size() - 1)
                var drawedCard = cardsList.remove(dawnCardIndex)
                print "    drawed:" + drawedCard
            }
        }
    }
} 
複製程式碼

執行

首先我們需要編譯 Card 類。然後編譯 CardDrawer 類。

java -classpath compiler/target/compiler-1.0-SNAPSHOT-jar-with-dependencies.jar: com.kubadziworski.compiler.Compiler EnkelExamples/RealApp/Card.enk
java -classpath compiler/target/compiler-1.0-SNAPSHOT-jar-with-dependencies.jar:. com.kubadziworski.compiler.Compiler EnkelExamples/RealApp/CardDrawer.enk

kuba@kuba-laptop:~/repos/Enkel-JVM-language$ java CardDrawer 
player 1 is drawing:
    drawed:{Diamonds,Queen}
    drawed:{Spades,7}
    drawed:{Hearts,Jack}
    drawed:{Spades,4}
    drawed:{Hearts,2}
player 2 is drawing:
    drawed:{Diamonds,4}
    drawed:{Hearts,Ace}
    drawed:{Diamonds,Jack}
    drawed:{Spades,Queen}
    drawed:{Spades,King}
player 3 is drawing:
    drawed:{Diamonds,Ace}
    drawed:{Clubs,2}
    drawed:{Clubs,3}
    drawed:{Spades,8}
    drawed:{Clubs,7}
player 4 is drawing:
    drawed:{Spades,Ace}
    drawed:{Diamonds,3}
    drawed:{Clubs,4}
    drawed:{Clubs,6}
    drawed:{Diamonds,2}
player 5 is drawing:
    drawed:{Hearts,4}
    drawed:{Hearts,Queen}
    drawed:{Hearts,10}
    drawed:{Clubs,Jack}
    drawed:{Diamonds,8}
複製程式碼

完美!

再見,Enkel

為了實現 Enkel 和分享整個過程我花費了大量的精力。寫程式碼是一回事,能夠表達和分享是另一回事(能夠讓讀者通俗易懂本身就是一個很大的挑戰)。

在這個過程中我學習到了很多,也希望螢幕前面的你也能有所收穫。

很不幸的是,這是系列中的最後一篇了,這個專案將繼續下去,所以,保持關注吧!

相關文章