
behaviors.evaluation.ThirtyOneHandEvaluation.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cards_2.13 Show documentation
Show all versions of cards_2.13 Show documentation
Scala library for card-playing functionality, including games Blackjack and Thirty-One
The newest version!
package cards.behaviors.evaluation
import cards.classes.Card
import cards.classes.Rank._
import cards.behaviors.Commons
import scala.annotation.tailrec
// Game play follows West Lansing Cut Throat rules
trait ThirtyOneHandEvaluation extends HandEvaluation {
type C <: Commons
val commons: C
override def eval(cards: Seq[Card]): Long = commons.suited(cards) match {
// 3-of-a-kind is 30.5 points, so to simulate we're making it instead be 31, and actual 31 will then be scored as 32 (behind the scenes)
case Nil => 0
case cs if (commons.countRank(cs).values.toSeq.contains(3)) => 31 // 3-of-a-kind, 30.5 points (see explanation above)
case cs => { // else not 3-of-a-kind, so determine highest score grouped by suit
val cardEval = (rank: Rank) => rank match {
case Jack => 10
case Queen => 10
case King => 10
case Ace => 11
case r => commons.getNumeric(r)
}
cs.groupBy(_.suit) // group by suit, sum up each grouping's card values, take the max
.map(kv => kv._1 -> kv._2.foldLeft(0)((acc, c1) => acc + cardEval(c1.rank)))
.values
.max match {
case 31 => 32 // since 3-of-a-kind's 30.5 is rounded up to 31, 31 now becomes 32
case x => x // else no special logic if it's not 31
}
}
}
// override preference so that if both hand evals tie, then hand with highest card by rank would break the tie (unless both highest ranks match)
override def preference(cs1: Seq[Card], cs2: Seq[Card], jokerReplacement: Boolean = true): Option[Seq[Card]] = super.preference(cs1, cs2) match {
case Some(results) => Some(results)
case None => (cs1, cs2) match {
case (Nil, Nil) => None
case (Nil, _) => Some(cs2)
case (_, Nil) => Some(cs1)
// determine highest single card in either hand and use it to break the tie if possible
case (_, _) => (commons.highest(cs1).head.rank.id.toInt, commons.highest(cs2).head.rank.id.toInt) match {
case (c1, c2) if (c1 == c2) => None
case (c1, c2) if (c1 > c2) => Some(cs1)
case (c1, c2) if (c1 < c2) => Some(cs2)
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy