Skip to content

Instantly share code, notes, and snippets.

@jakzal
Last active May 14, 2018 07:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jakzal/9e2cf64efa5cc90c2b1d1bc13c5132b3 to your computer and use it in GitHub Desktop.
Save jakzal/9e2cf64efa5cc90c2b1d1bc13c5132b3 to your computer and use it in GitHub Desktop.
War Card Game in Scala
sealed trait Suit
sealed case class Hearts() extends Suit {
override def toString = "♡"
}
sealed case class Diamonds() extends Suit {
override def toString = "♢"
}
sealed case class Clubs() extends Suit {
override def toString = "♧"
}
sealed case class Spades() extends Suit {
override def toString = "♤"
}
sealed class Rank(val value: Int) {
override def toString = s"${value}"
}
sealed case class Ace() extends Rank(14) {
override def toString = "A"
}
sealed case class King() extends Rank(13){
override def toString = "K"
}
sealed case class Queen() extends Rank(12){
override def toString = "Q"
}
sealed case class Jack() extends Rank(11){
override def toString = "J"
}
sealed case class Ten() extends Rank(10)
sealed case class Nine() extends Rank(9)
sealed case class Eight() extends Rank(8)
sealed case class Seven() extends Rank(7)
sealed case class Six() extends Rank(6)
sealed case class Five() extends Rank(5)
sealed case class Four() extends Rank(4)
sealed case class Three() extends Rank(3)
sealed case class Two() extends Rank(2)
case class Card(suit: Suit, rank: Rank) {
override def toString = rank.toString+suit.toString
}
type Deck = List[Card]
type Hand = List[Card]
def suits(): List[Suit] = List(Hearts(), Diamonds(), Clubs(), Spades())
def ranks(): List[Rank] = List(Ace(), King(), Queen(), Jack(), Ten(), Nine(), Eight(), Seven(), Six(), Five(), Four(), Three(), Two())
def deck(): Deck = for (
s <- suits();
r <- ranks()
) yield Card(s, r)
def shuffle(cards: Deck): Deck = util.Random.shuffle(cards)
def divide(cards: Deck): (Hand, Hand) = cards.splitAt(cards.length / 2)
sealed trait BattleResult
sealed case class Player1Wins(cards: List[Card]) extends BattleResult
sealed case class Player2Wins(cards: List[Card]) extends BattleResult
sealed case class War(cards: List[Card]) extends BattleResult
def score(player1Card: Card, player2Card: Card, previousTurnCards: List[Card] = List()): BattleResult = (player1Card.rank.value - player2Card.rank.value) match {
case s if (s == 0) => War(player1Card :: player2Card :: previousTurnCards)
case s if (s > 0) => Player1Wins(player1Card :: player2Card :: previousTurnCards)
case s if (s < 0) => Player2Wins(player2Card :: player1Card :: previousTurnCards)
}
def battle(player1Hand: Hand, player2Hand: Hand, previousTurnCards: List[Card] = List()): (Hand, Hand) = (player1Hand, player2Hand) match {
case (p1, List()) => (p1, List())
case (List(), p2) => (List(), p2)
case (nextCard1 :: remainingCards1, nextCard2 :: remainingCards2) => score(nextCard1, nextCard2, previousTurnCards) match {
case Player1Wins(cards) => (remainingCards1 ::: cards, remainingCards2)
case Player2Wins(cards) => (remainingCards1, remainingCards2 ::: cards)
case War(cards) => battle(remainingCards1, remainingCards2, cards)
}
}
def play(hands: (Hand, Hand)): (Hand, Hand) = hands match {
case (h, List()) => (h, List())
case (List(), h) => (List(), h)
case (player1: Hand, player2: Hand) => play(battle(player1, player2))
}
play(divide(shuffle(deck())))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment