I'm trying to learn scala, and decided to create a poker app to get my head around some of the class objects. I've got decks working fine, but I've got to the point where I need to draw 5 cards. So far I have:
import util.Random
case class Card(value: Int, color: String)
class Deck {
private var deck = newDeck
def draw(amount: Int): List[Card] = {
val ret = deck.take(amount)
deck = deck.drop(amount)
ret
}
def newDeck: List[Card] = {
Random.shuffle((1 to 13).map(x =>
List(Card(x, "D"), Card(x, "C"), Card(x, "H"), Card(x, "S"))).toList.flatten)
}
override def toString: String = "Deck has " + deck.length + " cards left."
}
This draw function doesn't seem quite right having two steps - but I'm not sure how I else I can (or should) take the top however many cards, and leave the list in a state without those cards in?
(As an aside, if someone has a better function for the deck creation/shuffle I'm all ears, this seems a bit hacky too... but my main question is the list state)
In my opinion, you should rewrite the codes either:
(a) with totally immutable struct, i.e. NO var, NO mutable collection
OR
(b) replace var deck: List[Card]
by some mutable collection, like ListBuffer
.
Here is the (a) solution:
import util.Random
case class Card(value: Int, color: String)
class Deck(private val cards: Seq[Card]) {
def draw(amount: Int): (Deck, Seq[Card]) = {
val (ret, rem) = cards.splitAt(amount)
(new Deck(rem), ret)
}
override def toString: String = "Deck has " + cards.size + " cards left."
}
object Deck {
def apply(cards: Seq[Card] = Nil): Deck = cards match {
case Nil =>
val ncds = for(v <- 1 to 13; c <- Seq("D", "C", "H", "S")) yield Card(v, c)
new Deck(Random.shuffle(ncds))
case _ => new Deck(cards)
}
}
Use case:
scala> :paste
// Entering paste mode (ctrl-D to finish)
//paste code here
// Exiting paste mode, now interpreting.
import util.Random
defined class Card
defined class Deck
defined object Deck
scala> val d1 = Deck()
d1: Deck = Deck has 52 cards left.
scala> val (d2, cards) = d1.draw(4)
d2: Deck = Deck has 48 cards left.
cards: Seq[Card] = Vector(Card(3,H), Card(2,S), Card(11,H), Card(8,C))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With