Question

So I am not asking anyone to solve this for me, but I do need some help. I am pretty new to Object-Oriented Programming, but it's starting to make sense for me. Below is the code I have so far for the War card game. I am not concerned with the Suits at the moment, though I do know how to add them in if need be. Basically, my next step is to figure out how to deal 26 cards to each player.

What this code does now is shuffles the deck using the Fisher-Yates algorithm, and outputs a string containing the now shuffled deck. I thought this would return an array since I was using the "to_a" method, but I don't think that's the case.

How do I then deal this deck to each player? Do I need a Class for the Table or players? Any help in the right direction would be awesome. Again, please do not solve it for me. I want to figure this out for myself as much as possible. EDIT: Using 1.9.3, if that's useful.

class Card
    VALUE = %w(2 3 4 5 6 7 8 9 10 J Q K A)

    attr_accessor :rank

    def initialize(id)
        self.rank = VALUE[id % 13]
    end
end

class Deck 
    attr_accessor :cards
    def initialize
        self.cards = (0..51).to_a.shuffle.collect { |id| Card.new(id) }
    end
end

class Array
    def shuffle!
        each_index do |i|
            r = rand(length-i) + i
            self[r], self[i] = self[i], self[r]
        end
    end

    def shuffle
        dup.shuffle!
    end
end


d = Deck.new
d.cards.each do |card|
    print "#{card.rank} "
end
Was it helpful?

Solution

There are many ways to do this. I didn't solve it but started some basic classes you could add to structure game playing. I'd add a method in your Deck class that takes one card from the deck. Also a 'Player' class would be useful to represent each player. Each player object would have a hand attribute that holds the cards:

class Deck
  def remove_card
    self.cards.pop    # removes a card from end of array
  end

  def empty?
    self.cards.count == 0
  end
end

d = Deck.new
d.cards.count      #=> 52 cards
p = Player.new
p.hand << d.remove_card
d.cards.count      #=> 51 cards now that one has been removed

Your deck holds the cards in an array. Your output is a string because you have it print out the ranks, but the card attribute is indeed an array holding card objects. You can also have a Game class that handles game play:

class Game
  def initialize(player1, player2)
    @player1 = player1
    @player2 = player2
  end

  def play_poker
    @deck = Deck.new
    # give each player five cards
    1.upto(5) do |num|
      @player1.hand << @deck.remove_card
      @player2.hand << @deck.remove_card
    end

    # each player has a five card hand at this point
    # omitted code, have a method to score the two hands and determine the winner
  end

  def play_war
    # omitted code, have players issued cards
    # omitted, instructions, game play code
  end
end

So you could have the game play different games. Scoring and output are other methods you would need to add. I also omitted the Player class for you to do. But you could play games like so:

p1 = Player.new
p2 = Player.new
game = Game.new(p1, p2)
game.play_poker         #=> output could be text like: Player 1's hand: A, 4, 4, 2, Q, Player 2's hand:...... etc
                        #=> winner is Player 1!

Scoring could be done by a method in the game class. It would also output text like above printing the hand each player got and who won. If doing many games with the same game object, you'd have to make sure the players have their hands cleared, new decks are used (or make a reshuffle method) and so on.

If you actually want two people playing, you would have buttons control each step. H to hit or s to stay and so on. Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top