本文系 Creating JVM language 翻译的第 20 篇。
原文中的代码和原文有不一致的地方均在新的代码仓库中更正过,建议参考新的代码仓库。

源码

Github

扑克牌洗牌模拟器

在之前的 19 篇博客中,我把实现编程语言的每一步都详细的记录下来了。如果不拿这门语言,练练手,做个东西玩,那就没什么意思了,对不?

我准备实现一个扑克牌的洗牌模拟器。思路是提供一定数量的玩家,指定每个玩家的扑克牌的数量。作为输出,每个玩家都能获得一定数量的随机扑克牌。

Card 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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 类。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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 和分享整个过程我花费了大量的精力。写代码是一回事,能够表达和分享是另一回事(能够让读者通俗易懂本身就是一个很大的挑战)。

在这个过程中我学习到了很多,也希望屏幕前面的你也能有所收获。

很不幸的是,这是系列中的最后一篇了,这个项目将继续下去,所以,保持关注吧!