2012-02-07 2 views
2

Я пишу «программу перетасовки карт», чтобы играть с Рубином. Рассмотрим его личные домашние задания, которые я задаю себе, чтобы узнать больше :)ruby ​​- как изменить порядок массива на основе другого массива?

Вывод, который я хотел бы здесь:

----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 

, но я получаю:

----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 

В основном то, что я пытаюсь для получения переупорядоченных карт, чтобы «Ace, 2, 3, 4, 5, 6» изменили порядок своих карт с «1,2,3,4,5» до «5, 6, 3, 4, 1 , 2 ". Иными словами, верхние две карты внизу (по порядку), нижние два в верхней и средней частях остаются одинаковыми. Это версия 3-полосного разреза.

Мне очень сложно заставить этот массив «переупорядочить» работать правильно. Прямо сейчас карта «ранг» и card_position становится перепутался, как показано выше, с дубликатами и т.д.

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 
+0

Рассматривали ли вы с помощью [Fisher-Yates перетасовать] (http://en.wikipedia.org/wiki/Knuth_shuffle) перетасовать колоду? – ddfreyne

+0

Да, однако предпочитают не использовать его, чтобы лучше изучить процесс, но спасибо! –

+0

Возможный дубликат [Как отсортировать массив в Ruby в определенном порядке?] (Http://stackoverflow.com/questions/4283295/how-to-sort-an-array-in-ruby-to-a-particular -order) –

ответ

1

Это то, что вы хотите?

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] 
+1

. синтаксис был неудобным. Благодарю. Удача в SO (переполнение стека). Разве это не здорово ?! –

1

Вряд ли быть самым быстрым решением, но вы можете zip два массива вместе (массив с ключами сортировки первым) и отсортировать результат следующим образом:

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

a.zip(b).sort.transpose.last 
# => [0, 7, 3, 3, 5] 
+0

полезно знать о zip. Подробнее о zip-карте - на странице http://stackoverflow.com/questions/3281/mapping-values-from-two-array-in-ruby –

0

Вы пытаетесь сохранить позицию как метод и как фактическое положение в массиве. Это много бухгалтерии. Кроме того, резка и тройная или четырехкратная резка - это в основном одно и то же.

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) 

выход:

[#<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">] 
Смежные вопросы