I am making a card game in ruby.
I have the Game class, which has an array of Player objects.
array_of_players = Array[
Player.new("Ben"),
Player.new("Adam"),
Player.new("Peter"),
Player.new("Fred"),
]
my_game = Game.new(array_of_players)
puts my_game.players[2].name #=> Peter
Each player also has access to the Game, so that they can access the important bits of the game like so
self.game.last_card_dealt
Each player also has cards (Player.cards), and I want to make sure that players can't access each other's cards. However, the Game does need access to the cards, so I don't think using private
is appropriate, and the players need access to some of each other's information, so I don't think I want that to be private
either...
Basically, I want these to work.
self.cards #where self is a Player object
self.players[0].cards #where self is the Game
self.game.players[0].name #where self is a Player object
And this to fail:
self.hand.players[0].cards #=> Nice try sucker! Cheating is for losers.
How are more complex permissions like this handled? Thanks.
This is more practical than my other answer, and uses the Game object as a delegate to all information in the game itself (Players, Cards, etc.). Note that you still have to trust the caller to pass themselves, but seriously where do you draw the line?
class Player
attr_reader :name
def initialize(name)
@name = name
end
end
class Cards
attr_accessor :cards
end
class Game
attr_reader :name, :players
def initialize(players)
@name = "Game Master"
@hands = []
@players = players.each do |p|
puts "Added %s to game." % p.name
@hands << {:player => p, :cards => Cards.new}
end
end
def view_hand(player, caller)
@hands.each do |hand|
if hand[:player] == player
if hand[:player] == caller or caller == self
puts "%s: You can access all these cards: %s" % [caller.name, hand[:cards]]
else
# Do something to only display limited cards depending on this caller's view capabilities
puts "%s: You can only access the cards I will let you see: %s" % [caller.name, hand[:cards]]
end
end
end
end
def my_cards(player)
@hands.each do |hand|
puts "%s's cards: %s" % [player.name, hand[:cards]] if hand[:player] == player
end
end
end
g = Game.new([Player.new('Bob'), Player.new('Ben')])
puts "\nCalling each Player's cards as each Player:\n\n"
g.players.each do |gp|
g.players.each do |p|
g.view_hand(gp, p)
end
end
puts "\nCalling each Player's cards as Game:\n\n"
g.players.each do |p|
g.view_hand(p, g)
end
puts "\nEach Player calls for their own cards:\n\n"
g.players.each do |p|
g.my_cards(p)
end
The output:
Added Bob to game.
Added Ben to game.
Calling each Player's cards as each Player:
Bob: You can access all these cards: #<Cards:0x100121c58>
Ben: You can only access the cards I will let you see: #<Cards:0x100121c58>
Bob: You can only access the cards I will let you see: #<Cards:0x100121bb8>
Ben: You can access all these cards: #<Cards:0x100121bb8>
Calling each Player's cards as Game:
Game Master: You can access all these cards: #<Cards:0x100121c58>
Game Master: You can access all these cards: #<Cards:0x100121bb8>
Each Player calls for their own cards:
Bob's cards: #<Cards:0x100121c58>
Ben's cards: #<Cards:0x100121bb8>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With