2

I am writing a 'card-shuffling program' to play with Ruby. Consider it personal homework that I assign myself to learn more :)

The output that I would like is here:

----Triple Cut Deck on 3rd and 5th cards---------
  -- reset
Number: 1,  Position: 3, Suit: Clubs, Card: 3
Number: 2,  Position: 4, Suit: Clubs, Card: 4
Number: 3,  Position: 1, Suit: Clubs, Card: 5
Number: 4,  Position: 2, Suit: Clubs, Card: 6
Number: 5,  Position: 5, Suit: Clubs, Card: Ace
Number: 6,  Position: 6, Suit: Clubs, Card: 2

but I am getting:

----Triple Cut Deck on 3rd and 5th cards---------
  -- reset
Number: 1,  Position: 3, Suit: Clubs, Card: 3
Number: 2,  Position: 4, Suit: Clubs, Card: 4
Number: 3,  Position: 5, Suit: Clubs, Card: 5
Number: 4,  Position: 5, Suit: Clubs, Card: 5
Number: 5,  Position: 6, Suit: Clubs, Card: 6
Number: 6,  Position: 6, Suit: Clubs, Card: 6

Basically what I am trying to get is re-ordered cards so that 'Ace, 2, 3, 4, 5, 6" have their card order changed from "1,2,3,4,5" to "5, 6, 3, 4, 1, 2". In other words the top two cards at the bottom (order-wise), the bottom two at the top and the middle stay the same. It's a version of a 3-way cut.

I am having a tough time getting this array 're-ordering' to work correctly. Right now card 'rank' and card_position are getting messed up as shown above, with duplicates, etc.

class Card
  RANKS = %w(Ace 2 3 4 5 6 7 8 9 10 J Q K )
  SUITS = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
  SCORES = [1..54]
  attr_accessor :rank, :suit, :card_position

  def initialize(id, rank='', suit='', card_position=0)
    self.card_position =  id
    self.rank = RANKS[(id % 14)-1]
    self.suit = SUITS[(id / 14)]
  end
end

class Deck
  DECK_SIZE = 6
  attr_accessor :cards
  def initialize
    self.cards = (1..DECK_SIZE).to_a.collect { |id| Card.new(id) }
    @deck = cards
  end

  def process_cards

    puts "\n----Triple Cut Deck on 3rd and 5th cards---------"
    self.triple_cut_deck(3, 5, true)
    self.show_deck

  end

  def show_deck
    @deck.sort_by!(&:card_position).each_with_index do |card, index|
      puts 'Number: ' + (index+1).to_s + ",  Position: #{card.card_position.to_s}, Suit: #{card.suit.to_s}, Card: #{card.rank.to_s}"
    end
  end

  def triple_cut_deck(top_cut, bottom_cut, reset_deck=false)
    reset_the_deck(reset_deck)

    top_cut-= 1
    bottom_cut-= 1
    deck_array_size = DECK_SIZE-1

    @new_deck = []
    @new_deck[0..1] = @deck[4..5]
    @new_deck[2..3] = @deck[2..3]
    @new_deck[4..5] = @deck[0..1]

    DECK_SIZE.times do |card|
      @deck[card].card_position= @new_deck[card].card_position
      @deck[card].card_position= @new_deck[card].card_position
      @deck[card].card_position= @new_deck[card].card_position
    end
  end


  def reset_the_deck(reset_deck)
    puts reset_deck == true ? "  -- reset" : 'no-reset'
    initialize if (true && reset_deck)
  end

end
Michael Durrant
  • 93,410
  • 97
  • 333
  • 497

3 Answers3

1

Unlikely to be the fastest solution, but you can zip the two arrays together (array with sort keys first) and sort the result, like this:

a = [ 8, 4, 2, 7, 5 ]
b = [ 5, 7, 0, 3, 3 ]

a.zip(b).sort.transpose.last
# => [0, 7, 3, 3, 5]
Denis Defreyne
  • 2,213
  • 15
  • 18
  • useful to know about zip. More about zip - map - reduce at http://stackoverflow.com/questions/3281/mapping-values-from-two-array-in-ruby – Michael Durrant Feb 07 '12 at 21:21
1

Is this what you want?

a = [1,2,3,4,5,6]

n = 2
b = a[-n, n] + a[n..-(n+1)] + a[0,n]

p a # => [1,2,3,4,5,6]
p b # => [5,6,3,4,1,2]
SimonMayer
  • 4,719
  • 4
  • 33
  • 45
0

You are trying to keep the position as a method and as an actual position in an array. That is a lot of bookkeeping. Also cutting and triple or fourfold cutting are basically the same thing.

Ranks = %w(Ace 2 3 4 5 6 7 8 9 10 J Q K )
Suits = ['Clubs', 'Diamonds', 'Hearts', 'Spades']
Card = Struct.new(:rank, :suit)
deck = Suits.product(Ranks).map{|suit, rank| Card.new(rank, suit) }
hand = deck[0, 6]
def cut(hand, *at) #returns a new hand, multi-cutted 
  indices = (at.map{|i| i-1}+[0, hand.size]).sort
  res = indices.each_cons(2).map{|i1,i2| hand[i1..i2-1] }
  res.reverse.flatten
end
p cut(hand, 3, 5)

output:

 [#<struct Card rank="Ace", suit="Clubs">, #<struct Card rank="2", suit="Clubs">,
    #<struct Card rank="3", suit="Clubs">, #<struct Card rank="4", suit="Clubs">,
    #<struct Card rank="5", suit="Clubs">, #<struct Card rank="6", suit="Clubs">]

    [#<struct Card rank="5", suit="Clubs">, #<struct Card rank="6", suit="Clubs">,
    #<struct Card rank="3", suit="Clubs">, #<struct Card rank="4", suit="Clubs">,
    #<struct Card rank="Ace", suit="Clubs">, #<struct Card rank="2", suit="Clubs">]
steenslag
  • 79,051
  • 16
  • 138
  • 171