Reputation: 11
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
Upvotes: 0
Views: 2174
Reputation: 1059
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.
Upvotes: 1