English 中文(简体)
Scala: 利用配对模式在5个卡普车手中检测出一个Salight
原标题:Scala: Detecting a Straight in a 5-card Poker hand using pattern matching
最佳回答

您可以将信息传递给一位精子,除<条码><>><>条/代码>说明外,你可以不使用从另一笔价值中退回的信息。

你们可以做的是,为检验这些事情创造自己的精炼者,但是,如果找不到任何再利用的话,你就会获得很多好处。

例如:

class SeqExtractor[A, B](f: A => B) {
  def unapplySeq(s: Seq[A]): Option[Seq[A]] =
    if (s map f sliding 2 forall { case Seq(a, b) => a == b  } ) Some(s)
    else None
}

val Straight = new SeqExtractor((_: Card).rank)

之后,你可以这样使用:

listOfCards match {
    case Straight(cards) => true
    case _ => false
}

But, of course, all that you really want is that if statement in SeqExtractor. So, don t get too much in love with a solution, as you may miss simpler ways of doing stuff.

问题回答

你可以做这样的事情:

val ids = ranks.map(_.id)
ids.max - ids.min == 4 && ids.distinct.length == 5

然而,正确处理特许权需要一定程度的工作。

这里的解决办法更好:

(ids zip ids.tail).forall{case (p,q) => q%13==(p+1)%13}

比较中的<代码>% 13处理的是第1级和第14级的应收款。

如何做这样的事情:

def isStraight(cards:List[Card]) = (cards zip card.tail) forall{ case (c1,c2) => c1.rank+1 = c2.rank}

valka = List(Card(1),Card(2),Card(3),Card(4)>。

scala> isStraight(cards)
res2: Boolean = true

This is a completely different approache, but it does use pattern matching. It produces warnings in the match clause which seem to indicate that it shouldn t work. But it actually produces the correct results:

Straight !!! 34567
Straight !!! 34567
Sorry no straight this time

我现在忽视了该《宪章》,我也忽视了根据2条提出诉讼的可能性。

abstract class Rank {
    def value : Int
}
case class Next[A <: Rank](a : A) extends Rank {
    def value = a.value + 1
}
case class Two() extends Rank {
    def value = 2
}

class Hand(a : Rank, b : Rank, c : Rank, d : Rank, e : Rank) {
    val cards = List(a, b, c, d, e).sortWith(_.value < _.value)
}

object Hand{
    def unapply(h : Hand) : Option[(Rank, Rank, Rank, Rank, Rank)] = Some((h.cards(0), h.cards(1), h.cards(2), h.cards(3), h.cards(4)))
}

object Poker {

    val two = Two()
    val three = Next(two)
    val four = Next(three)
    val five = Next(four)
    val six = Next(five)
    val seven = Next(six)
    val eight = Next(seven)
    val nine = Next(eight)
    val ten = Next(nine)
    val jack = Next(ten)
    val queen = Next(jack)
    val king = Next(queen)
    val ace = Next(king)

    def main(args : Array[String]) {
        val simpleStraight = new Hand(three, four, five, six, seven)
        val unsortedStraight = new Hand(four, seven, three, six, five)
        val notStraight = new Hand (two, two, five, five, ace)

        printIfStraight(simpleStraight)
        printIfStraight(unsortedStraight)
        printIfStraight(notStraight)
    }

    def printIfStraight[A](h : Hand) {

        h match  {
            case  Hand(a: A , b : Next[A], c : Next[Next[A]], d : Next[Next[Next[A]]], e : Next[Next[Next[Next[A]]]]) => println("Straight !!! " + a.value + b.value + c.value + d.value + e.value)
            case Hand(a,b,c,d,e)  => println("Sorry no straight this time")
        }
    }
}

如果你有兴趣像这个神学院的计数系统那样做更细微的工作,

How about something like this?

def isStraight = {
  cards.map(_.rank).toList match {
    case first :: second :: third :: fourth :: fifth :: Nil if 
      first.id == second.id - 1 &&
      second.id == third.id - 1 &&
      third.id == fourth.id - 1 &&
      fourth.id == fifth.id - 1 => true
    case _ => false
  }
}

您仍然坚持<代码>if(事实上该编码范围更大),但是没有再入侵或海关提取器(我认为你改用next,因此你第二次尝试没有工作)。

如果你重新撰写掩体方案,你已经检查了哪一种东西。 手是直截了当的,它没有实物(n > 1),最低名称和最高值之间的差别是四。

我在几天前就对“Euler项目54”做了类似的事情。 和你一样,我有排名和苏伊特。

我的卡片人喜欢:

  case class Card(rank: Rank.Value, suit: Suit.Value) extends Ordered[Card] {
    def compare(that: Card) = that.rank compare this.rank
  }

注一提供了<代码>Ordered trait,以便我们能够在晚些时候比较卡片。 此外,如果用<条码>或将其从高到低,这就使得评估价值更为容易。

这里是我的<条码>限值/代码>测试,填上<条码>。 备选案文价值取决于其是否直截了当。 实际收益价值(斜体清单)用于确定手头的强度,第一类是手头类型,从0(无奶)到9(斜体)不等,而其他则是任何其他计价卡的排名。 简单地说,我们只担心最高排名卡。

而且,我们注意到,你可以直截了Ace,“轮”或A2345。

  case class Hand(cards: Array[Card]) {
    ...
    def straight: Option[List[Int]] = {

      if( cards.sliding(2).forall { case Array(x, y) => (y compare x) == 1 } )
        Some(5 :: cards(0).rank.id :: 0 :: 0 :: 0 :: 0 :: Nil)

      else if ( cards.map(_.rank.id).toList == List(12, 3, 2, 1, 0) )
        Some(5 :: cards(1).rank.id :: 0 :: 0 :: 0 :: 0 :: Nil) 

      else None
    }
  }

这里是一门全方位的方位方位(直线5高):

case class Card(rank: Int, suit: Int) { override def toString = s"${"23456789TJQKA" rank}${"♣♠♦♥" suit}" }

object HandType extends Enumeration {
  val HighCard, OnePair, TwoPair, ThreeOfAKind, Straight, Flush, FullHouse, FourOfAKind, StraightFlush = Value
}

case class Hand(hand: Set[Card]) {
  val (handType, sorted) = {
    def rankMatches(card: Card) = hand count (_.rank == card.rank)
    val groups = hand groupBy rankMatches mapValues {_.toList.sorted}

    val isFlush = (hand groupBy {_.suit}).size == 1
    val isWheel = "A2345" forall {r => hand exists (_.rank == Card.ranks.indexOf(r))}   // A,2,3,4,5 straight
    val isStraight = groups.size == 1 && (hand.max.rank - hand.min.rank) == 4 || isWheel
    val (isThreeOfAKind, isOnePair) = (groups contains 3, groups contains 2)

    val handType = if (isStraight && isFlush)     HandType.StraightFlush
      else if (groups contains 4)                 HandType.FourOfAKind
      else if (isThreeOfAKind && isOnePair)       HandType.FullHouse
      else if (isFlush)                           HandType.Flush
      else if (isStraight)                        HandType.Straight
      else if (isThreeOfAKind)                    HandType.ThreeOfAKind
      else if (isOnePair && groups(2).size == 4)  HandType.TwoPair
      else if (isOnePair)                         HandType.OnePair
      else                                        HandType.HighCard

    val kickers = ((1 until 5) flatMap groups.get).flatten.reverse
    require(hand.size == 5 && kickers.size == 5)
    (handType, if (isWheel) (kickers takeRight 4) :+ kickers.head else kickers)
  }
}

object Hand {
  import scala.math.Ordering.Implicits._
  implicit val rankOrdering = Ordering by {hand: Hand => (hand.handType, hand.sorted)}
}




相关问题
How to flatten a List of different types in Scala?

I have 4 elements:List[List[Object]] (Objects are different in each element) that I want to zip so that I can have a List[List[obj1],List[obj2],List[obj3],List[obj4]] I tried to zip them and I ...

To use or not to use Scala for new Java projects? [closed]

I m impressed with Twitter and investigating to use Scala for a new large scale web project with Hibernate and Wicket. What do you think about Scala, and should I use it instead of Java? EDIT: And, ...

Why does Scala create a ~/tmp directory when I run a script?

When I execute a Scala script from the command line, a directory named "tmp" is created in my home directory. It is always empty, so I simply deleted it without any apparent problem. Of course, when I ...

Include jar file in Scala interpreter

Is it possible to include a jar file run running the Scala interpreter? My code is working when I compile from scalac: scalac script.scala -classpath *.jar But I would like to be able to include a ...

Scala and tail recursion

There are various answers on Stack Overflow which explain the conditions under which tail recursion is possible in Scala. I understand the limitations and how and where I can take advantage of tail ...

热门标签