Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Ruby中检查数组的范围?_Ruby_Arrays - Fatal编程技术网

如何在Ruby中检查数组的范围?

如何在Ruby中检查数组的范围?,ruby,arrays,Ruby,Arrays,我正在写一个扑克程序,但我不知道如何处理直人 直接:一手5张牌中的所有牌都是连续值。 例2..6,3..7,4..8,5..9,6..T,7..J,8..Q,9..K,T..A cards = [2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K", "A"] 如何检查一只手(一个数组)的这些组合?最好我可以检查它,看看它是否是卡阵列中的一行5 第0步:让我们从一个空类开始 步骤1:将卡的值存储在散列中 允许快速引用卡的值 @@card_values = {

我正在写一个扑克程序,但我不知道如何处理直人

直接:一手5张牌中的所有牌都是连续值。 例2..6,3..7,4..8,5..9,6..T,7..J,8..Q,9..K,T..A

cards = [2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K", "A"]
如何检查一只手(一个数组)的这些组合?最好我可以检查它,看看它是否是卡阵列中的一行5

第0步:让我们从一个空类开始 步骤1:将卡的值存储在散列中 允许快速引用卡的值

@@card_values = {
    'A' => 1,   2  => 2,   3  => 3, 4 => 4,  5 => 5,
     6  => 6,   7  => 7,   8  => 8, 9 => 9, 'T' => 10,
    'J' => 11, 'Q' => 12, 'K' => 13
}
因此,您可以参考卡值,如下所示

@@card_values['A']
# => 1

@@card_values[8]
# => 8
步骤2:对手进行分类 参照卡片值将方法应用于手部

def self.sort(hand)
    hand.sort {|x,y| @@card_values[x] <=> @@card_values[y]}
end
#  => ["A", 2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K"] 
第4步:检查“直线” 这可以通过简单的迭代来完成

def self.has_straight(hand)
    hand = sort(hand)

    max_consecutive_count = 0
    consecutive_count = 0

    hand.each_with_index do |curr, i|
        prev = hand[i - 1]

        if is_consecutive(prev, curr) then
            consecutive_count += 1
        else
            consecutive_count = 0
        end

        if consecutive_count > max_consecutive_count then
            max_consecutive_count = consecutive_count
        end
    end

    max_consecutive_count >= 5
end
# hand = [2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K", "A"]
# CardUtils.has_straight(hand)
#  => true
最终结果
类CardUtils
@@卡_值={
‘A’=>1,2=>2,3=>3,4=>4,5=>5,
6=>6,7=>7,8=>8,9=>9,'T'=>10,
'J'=>11,'Q'=>12,'K'=>13
}
定义自身是连续的(x,y)
val_x=@@card_值[x]
val_y=@@card_值[y]
val_x==val_y-1 | val_x+13==val_y
结束
def自动分拣(手动)
hand.sort{| x,y |@@card_值[x]@@card_值[y]}
结束
def自举(手)
手=分类(手)
最大连续计数=0
连续计数=0
每个带有索引do | curr,i的|
上一个=手[i-1]
如果是连续的(上一个,当前),则
连续计数+=1
其他的
连续计数=0
结束
如果连续计数>最大连续计数,则
最大连续计数=连续计数
结束
结束
最大连续计数>=5
结束
结束

生成有效人手列表:

valid_hands = cards[0..8].each_with_index.map{|b,i| cards[i..i+4]}
#=> [[2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9], [6, 7, 8, 9, "T"], [7, 8, 9, "T", "J"], [8, 9, "T", "J", "Q"], [9, "T", "J", "Q", "K"], ["T", "J", "Q", "K", "A"]]
一旦您有了所有有效手的列表,您现在可以检查提供的手是否在其中(有效手):

更新

如果
2,3,4,5,“A”
2,3,4,“K”,“A”
2,3,“Q”,“K”,“A”
2,“J”,“Q”,“K”,“A”
,也被视为有效手,请按如下方式计算:

valid_hands = cards.each_with_index.map { |b,i| i < 9 ? cards[i..i+4] : cards[0..i-9] + cards[i..-1] }
# => [[2, 3, 4, 5, 6], [3, 4, 5, 6, 7], [4, 5, 6, 7, 8], [5, 6, 7, 8, 9], [6, 7, 8, 9, "T"], [7, 8, 9, "T", "J"], [8, 9, "T", "J", "Q"], [9, "T", "J", "Q", "K"], ["T", "J", "Q", "K", "A"], [2, "J", "Q", "K", "A"], [2, 3, "Q", "K", "A"], [2, 3, 4, "K", "A"], [2, 3, 4, 5, "A"]]
valid_hands=cards.each_with_index.map{b,i|i<9?cards[i..i+4]:cards[0..i-9]+cards[i..-1]}
#=>[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8],[5,6,7,8,9],[6,7,8,9,“T”],[7,8,9,“T”,“J”,“J”,“Q”,“Q”,“K”,“A”],[9,“T”,“J”,“K”,“A”],[2”,“J”,“Q”,“K”,“A”],[2,3”,“Q”,“K”,“A”],[2,3,4”,“K”,“A”,[3”,“A”]

如果我们将每张卡映射到一个值(9是9,“T”是10,“J”是11,等等),那么我们可以使用两个事实来解决我们的问题:

  • 所有直道都有五个独特的卡值
  • 最后一张卡和第一张卡的值之间的差值始终为4
  • 因此:

    CARD_VALUES = {
        2 =>  2,    3 =>  3,    4 =>  4,
        5 =>  5,    6 =>  6,    7 =>  7,
        8 =>  8,    9 =>  9,  "T" => 10,
      "J" => 11,  "Q" => 12,  "K" => 13,
      "A" => 14
    }
    
    def is_straight?(hand)
      hand_sorted = hand.map {|card| CARD_VALUES[card] }
        .sort.uniq
    
      hand_sorted.size == 5 &&
        (hand_sorted.last - hand_sorted.first) == 4
    end
    
    此方法(1)使用
    map
    将每张卡转换为其数值,然后(2)对它们进行
    排序,然后(3)使用
    uniq
    抛出重复的卡。用各种各样的手来说明:

    hand | 4 A T A 2 | 2 2 3 4 | 5 6 4 8 7 | 3 6 2 8 7
    ---------+--------------------+--------------------+--------------------+----------------
    1.地图| 4 14 10 14 2 | 2 3 4 | 5 6 4 8 7 | 3 6 2 8 7
    2.排序| 2 4 10 14 | 2 3 4 | 4 5 6 7 8 | 2 3 6 7 8
    3.uniq | 2 4 10 14 | 2 3 4 | 4 5 6 7 8 | 2 3 6 7 8
    
    或者。。。 我最初发布了以下解决方案,这并不坏,但肯定更复杂:

    如果手被分类,这很容易。您可以使用来检查每个可能的直线

    CARDS = [ 2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K", "A" ]
    hand = [ 4, 5, 6, 7, 8 ]
    
    def is_straight?(hand)
      CARDS.each_cons(5).any? do |straight|
        hand == straight
      end
    end
    
    if is_straight?(hand)
      puts "Straight!"
    else
      puts "Not straight!"
    end
    # => Straight!
    
    each_cons(5)
    返回每个连续的5个项目集,因此在上面的示例中,首先将
    hand
    [2,3,4,5,5,6,6]
    进行比较,然后
    [3,4,5,5,6,6,8]
    ,这是一个匹配项,因此
    返回
    true

    请注意,这并不是最有效的解决方案,但除非您需要每秒检查数千只手,否则这是非常有效的

    如果你的手还没有分类,你需要先分类。最简单的方法是创建一个散列,将卡片映射到一个数字值(如上所述),然后使用
    排序依据

    def sort_hand(hand)
      hand.sort_by {|card| CARD_VALUES[card] }
    end
    
    hand = [ 4, "A", 2, "A", "T" ]
    sort_hand(hand)
    # => [ 2, 4, "T", "A", "A" ]
    

    编辑2:这是我的最终解决方案:

    require 'set'
    STRAIGHTS = ['A',*2..9,'T','J','Q','K','A'].each_cons(5).map(&:to_set)
      #=> [#<Set: {"A", 2, 3, 4, 5}>, #<Set: {2, 3, 4, 5, 6}>,
      #   ...#<Set: {9, "T", "J", "Q", "K"}>, #<Set: {"T", "J", "Q", "K", "A"}>]
    
    def straight?(hand)
      STRAIGHTS.include?(hand.to_set)
    end
    
    STRAIGHTS.include?([6,3,4,5,2].to_set)
      # STRAIGHTS.include?(#<Set: {6, 3, 4, 5, 2}>)
      #=> true 
    
    straight?([6,5,4,3,2])            #=> true 
    straight?(["T","J","Q","K","A"])  #=> true 
    straight?(["A","K","Q","J","T"])  #=> true
    straight?([2,3,4,5,"A"])          #=> true 
    
    straight?([6,7,8,9,"J"])          #=> false 
    straight?(["J",7,8,9,"T"])        #=> false 
    

    我会这样写:

    hand  = [3,4,5,2,'A']
    
    
    def is_straight(hand)
    
      # No need to check further if we do not have 5 unique cards.
      return false unless hand.uniq.size == 5
    
      # Note the A at beginning AND end to count A as 1 or 14.
      list_of_straights = 'A23456789TJQKA'.chars.each_cons(5)
    
      sorted_hand = hand.map(&:to_s).sort
    
      list_of_straights.any? do |straight| 
        straight.sort==sorted_hand
      end
    
    end
    
    puts is_straight(hand) #=> true  
    
    或者,如果您不喜欢所有排序,您可以将最后一部分交换到:

      hand_as_stings = hand.map(&:to_s)
    
      list_of_straights.any? do |straight| 
        (straight-hand_as_stings).empty?
      end
    

    我不想参与,但我不能对周围所有这些过于复杂的解决方案保持沉默

    hand = [2, 5, 7, 'A', 'J'].map(&:to_s)
    
    '23456789TJQKA' =~ hand.sort_by{|hc| '23456789TJQKA'.index(hc)}.join ||
       'A23456789TJQK' =~ hand.sort_by{|hc| 'A23456789TJQK'.index(hc)}.join
    
    以非蹩脚的硬编码方式:

    suit = '23456789TJQKA'
    
    suit =~ hand.sort_by{|hc| suit.index(hc)}.join ||
       suit.rotate(-1) =~ hand.sort_by{|hc| suit.rotate(-1).index(hc)}.join
    

    我建议编写类来表示一张卡片(也可能是牌和手)。以这样的界面为目标:

    deck = Deck.new.shuffle!
    hand = Hand.new(deck.draw 5)
    hand.straight?
    #=>false
    puts hand
    8♣ 8♦ T♠ 2♦ 7♦
    
    功能的封装为您提供了可读性,并使其易于扩展(即使用套装)

    这里有一个更简单的版本,作为单个卡片类实现。不过我确实加了西装

    class Card
      include Enumerable #enables sorting
      attr_accessor :value, :suit
    
      @values = [2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K", "A"]
      @suits  = ["♣","♦","♥","♠"]
    
      def self.all
        @values.product(@suits).map{|c| Card.new c}
      end
    
      def self.straight?(cards)
        ["A", *@values].each_cons(5).include?(cards.map(&:value))
      end
    
      def self.flush?(cards)
        cards.map(&:suit).uniq.size == 1
      end
    
      def initialize(v)
        @value, @suit = *v
      end
    
      def <=>(other) #for sorting
        @values.index(value) <=> @values.index(other.value)
      end
    
      def to_s
        "#{value}#{suit}"
      end
    end
    

    请发布您目前掌握的代码。也不是因为您的问题中缺少
    1..5
    。在普通扑克中,Ace也被视为值1。显然,您从结果中删除了
    TJQKA
    街道。@mudasobwa谢谢,我添加了连续卡片检查的精确实现。我没有仔细检查,但是现在您可能在结果中包含
    QKA23
    。@mudasobwa第二个条件检查环绕:
    val_x+13==val_y
    Hmmm.
    hand=[3,4,5,“A”,“Q”];hand.sort#=>ArgumentError:将Fixnum与字符串进行比较失败
    。如果您将整数更改为字符串,则仍然存在一个问题:
    hand.map(&:to#s)。sort#=>[“3”、“4”、“5”、“a”、“Q”]
    @CarySwoveland fixed:)我喜欢您修改后的答案。到目前为止最好的答案,依我看,我是这么想的
      hand_as_stings = hand.map(&:to_s)
    
      list_of_straights.any? do |straight| 
        (straight-hand_as_stings).empty?
      end
    
    hand = [2, 5, 7, 'A', 'J'].map(&:to_s)
    
    '23456789TJQKA' =~ hand.sort_by{|hc| '23456789TJQKA'.index(hc)}.join ||
       'A23456789TJQK' =~ hand.sort_by{|hc| 'A23456789TJQK'.index(hc)}.join
    
    suit = '23456789TJQKA'
    
    suit =~ hand.sort_by{|hc| suit.index(hc)}.join ||
       suit.rotate(-1) =~ hand.sort_by{|hc| suit.rotate(-1).index(hc)}.join
    
    deck = Deck.new.shuffle!
    hand = Hand.new(deck.draw 5)
    hand.straight?
    #=>false
    puts hand
    8♣ 8♦ T♠ 2♦ 7♦
    
    class Card
      include Enumerable #enables sorting
      attr_accessor :value, :suit
    
      @values = [2, 3, 4, 5, 6, 7, 8, 9, "T", "J", "Q", "K", "A"]
      @suits  = ["♣","♦","♥","♠"]
    
      def self.all
        @values.product(@suits).map{|c| Card.new c}
      end
    
      def self.straight?(cards)
        ["A", *@values].each_cons(5).include?(cards.map(&:value))
      end
    
      def self.flush?(cards)
        cards.map(&:suit).uniq.size == 1
      end
    
      def initialize(v)
        @value, @suit = *v
      end
    
      def <=>(other) #for sorting
        @values.index(value) <=> @values.index(other.value)
      end
    
      def to_s
        "#{value}#{suit}"
      end
    end
    
    deck = Card.all
    puts deck
    #=> 2♣ 2♦ 2♥ 2♠ 3♣ 3♦ 3♥ 3♠ 4♣ 4♦ 4♥ 4♠ 5♣ 5♦ 5♥ 5♠ 6♣ 6♦ 6♥ 6♠ 7♣ 7♦ 7♥ 7♠ 8♣ 8♦ 8♥ 8♠ 9♣ 9♦ 9♥ 9♠ T♣ T♦ T♥ T♠ J♣ J♦ J♥ J♠ Q♣ Q♦ Q♥ Q♠ K♣ K♦ K♥ K♠ A♣ A♦ A♥ A♠
    hand = deck.sample 5
    puts hand
    #=> Q♥ 6♦ 2♣ T♠ Q♦
    Card.straight?(hand)
    #=>false