سؤال

أنا أصنع لعبة بطاقة في روبي.

لدي فئة اللعبة ، التي لديها مجموعة من كائنات اللاعب.

 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

كل لاعب لديه أيضًا إمكانية الوصول إلى اللعبة ، حتى يتمكنوا من الوصول إلى الأجزاء المهمة من اللعبة مثل ذلك

self.game.last_card_dealt

يحتوي كل لاعب أيضًا على بطاقات (Player.Cards) ، وأريد التأكد من أنه لا يمكن للاعبين الوصول إلى بطاقات بعضهم البعض. ومع ذلك ، فإن اللعبة تحتاج إلى الوصول إلى البطاقات ، لذلك لا أعتقد استخدام private مناسب ، ويحتاج اللاعبون إلى الوصول إلى بعض معلومات بعضهم البعض ، لذلك لا أعتقد أنني أريد أن يكون ذلك private أيضاً...

في الأساس ، أريد أن تعمل هذه.

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

وهذا للفشل:

self.hand.players[0].cards  #=> Nice try sucker! Cheating is for losers.

كيف يتم التعامل مع أذونات أكثر تعقيدًا مثل هذا؟ شكرًا.

هل كانت مفيدة؟

المحلول 4

شكرا لجميع ردودك.

في النهاية ، اعتقدت أنه يمكنني إعطاء الكائن المعتمد مفتاحًا يستخدم للسماح له بالوصول إلى لحم الطريقة.

يحتوي كائن اللعبة على Auth_Object ويقوم بتعيينه على كائن اللاعب الذي يعتزم الوصول إلى الأساليب السرية لـ ، ويتحقق الطريقة السرية للاعب إذا كان Hand.Auth_Object self, ، وإلا فإنه لا يفعل شيئًا. ثم يتم تعيين Auth_Object إلى NIL. هناك attr_reader ولكن لا يوجد كاتب لـ Auth_Object.

انه يعمل انها تعمل.

نصائح أخرى

هذا أكثر عملية من إجابتي الأخرى ، ويستخدم كائن اللعبة كمندوب لجميع المعلومات في اللعبة نفسها (اللاعبين ، والبطاقات ، وما إلى ذلك). لاحظ أنه لا يزال يتعين عليك الوثوق بالمتصل لتمرير نفسه ، ولكن على محمل الجد أين ترسم الخط؟

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

الإخراج:

    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>

يحفظ Game.player خاص لعدم السماح للاعبين من الوصول إلى لاعبين آخرين من خلال الصفيف.

على سبيل المثال ، متى self هو لاعب ، self.game.players[0].name هو نوع من سخيفة.

ربما تريد الجمهور Game.player_names الطريقة التي تُرجع مجموعة من أسماء اللاعبين؟

علاوة على ذلك ، يمكنك أن تصنع الجمهور Players.opponents طريقة.

أمثلة

game.player_names

class Game
  # ...
  def player_names
    self.players.collect { |p| p.name }
  end

  private
  # private game methods
end

player.opponents

class Player
  # ...
  def opponents(i=nil)
    return i.nil? ? self.game.player_names : self.game.player_names[i]
  end
end

كان هذا ممتعا للعب مع. لست متأكدًا مما إذا كانت هذه هي أفضل إجابة ممكنة ، لكنها تعمل. المفتاح هو تمرير كائن الاتصال إلى Player.cards (OBJ) ، والتحقق مما إذا كان إما اللاعب نفسه ، أو من نوع اللعبة ، وكلاهما لديه وصول قانوني.

class Player
  attr_accessor :name, :game
  attr_writer :cards

  def initialize(name)
    @name = name
    @game = nil
    @cards = nil
  end

  def cards(caller)
    puts "%s cards called by %s." % [self, caller]
    if caller.kind_of?(Game) or caller == self
      puts "Here's your cards %s." % @cards
    else
      puts "Nice try sucker!  Cheating is for losers."
    end
  end
end

class Cards
  def initialize
    @cards = [1, 2, 3]
  end
end

class Game
  attr_reader :players

  def initialize(players)
    @players = players.each do |p|
      puts "Added %s to game." % p.name
      p.game = self
      p.cards = Cards.new
    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|
    p.cards(gp)
  end
end

puts "\nCalling each Player's cards as Game:\n\n"
g.players.each do |p|
  p.cards(g)
end

والإخراج:

    Added Bob to game.
    Added Ben to game.

    Calling each Player's cards as each Player:

    #<Player:0x100122b30> cards called by #<Player:0x100122b30>.
    Here's your cards #<Cards:0x1001229c8>.
    #<Player:0x100122ae0> cards called by #<Player:0x100122b30>.
    Nice try sucker!  Cheating is for losers.
    #<Player:0x100122b30> cards called by #<Player:0x100122ae0>.
    Nice try sucker!  Cheating is for losers.
    #<Player:0x100122ae0> cards called by #<Player:0x100122ae0>.
    Here's your cards #<Cards:0x100122928>.

    Calling each Player's cards as Game:

    #<Player:0x100122b30> cards called by #<Game:0x100122ab8>.
    Here's your cards #<Cards:0x1001229c8>.
    #<Player:0x100122ae0> cards called by #<Game:0x100122ab8>.
    Here's your cards #<Cards:0x100122928>.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top