2015-12-20 4 views
2

Я написал программу tictactoe, и я пытаюсь организовать ее в классы.Разбиение программы на классы и доступ к переменным из одного класса в другой

class Board 
    attr_accessor :fields 

    def initialize 
    self.fields = { 
     '1' => ' ', '2' => ' ', '3' => ' ', 
     '4' => ' ', '5' => ' ', '6' => ' ', 
     '7' => ' ', '8' => ' ', '9' => ' ' 
    } 
    end 
    def set_stone_at(position, stone) 
    fields[position] = stone 
    end 
    def stone_at(position) 
    stone = fields[position] 
    puts stone 
    end 
    def show 
    puts fields 
    end 
end 

class Game 
    attr_accessor :board 

    def initialize 
    self.board = Board.new 
    end 
    def print_board 
    puts "\n #{fields['1']} | #{fields['2']} | #{fields['3']}" 
    puts " --*---*---" 
    puts " #{fields['4']} | #{fields['5']} | #{fields['6']}" 
    puts " --*---*---" 
    puts " #{fields['7']} | #{fields['8']} | #{fields['9']} \n" 
    end 
end 

board = Board.new 
board.show 
Game.new.board.show 
game = Game.new 
game.board.set_stone_at('1', 'X') 
game.board.set_stone_at('2', 'O') 
game.print_board 

У меня возникли проблемы с доступом к переменной fields из класса Board в классе Game. Я получаю сообщение об ошибке:

in `print_board': undefined local variable or method `fields' for #<Game:0x007ffc1a895710> (NameError) 

Я хотел бы получить любую помощь. Я благодарен за любую помощь и объяснения.

+0

Переместить метод 'print_board' в класс' Board', класс 'Game', похоже, не делает ничего –

+0

Привет, да, это так, но я думал логически, print_board должен быть в классе Game, или Я ошибаюсь? – ayda

+0

Я не скажу, что вы ошибаетесь, поскольку это вопрос мнения. Лично я бы предпочел, чтобы методы, которые нуждались в доступе к частным членам «Совета», были в «Совете», кажется неправильным раскрывать внутреннее состояние «Правления» внешнему миру. Вы правильно используете методы mutatator для 'fields' в' set_stone_at' и 'stone_at', поэтому кажется, что не нужно выставлять' fields' через 'attr_accessor' –

ответ

1

Извините, отвечая на мобильный телефон. От взгляда на это, похоже, вы хотите иметь self.board.fields в вашем методе print_board в игре. Поля являются аксессуарами класса Board. Вы хотите отправить его в экземпляр класса платы. В игре у вас есть accessor, board, у которого есть экземпляр доступной доски, если выполняется инициализация. Поэтому вам нужно убедиться, что вы создаете экземпляр игры, если хотите, чтобы она была доступна. Похоже, ты сделал это. Вы также можете попробовать @board.fields в своем методе печати. Я думаю, что это также будет работать с вашим аксессуаром.

- Добавить это после получения на реальный компьютер. Это должно многое сделать с «я» в Ruby. Вы, похоже, хорошо понимаете, как начать работу здесь, и хотя, как отметил @WandMaker, было бы проще сделать метод #print вне дома, я рад, что вы сделали это таким образом. «Я в рубине» найдет много достойных связанных должностей. Для более широкого контекста/лучшего опыта обучения я также рекомендую «The Well Grounded Rubyist». Я думаю, вы также получите отличное представление об этом и других очень полезных вещах, если вы изучите мета-программирование. Для этого «Meta-Programming Ruby» из PragProgs хорош, а также уроки метапрограммирования на Ruby Monk http://rubymonk.com/learning/books/.

«Практичный объектно-ориентированный рубин» Санди Меца может быть лучшим, но я еще не прочитал его. Хотите ...

Gotta go!

+0

Спасибо, это сработало !!! Я подумал об этом, но не был уверен – ayda

+0

@ayda что-нибудь еще вам нужно, чтобы понять это лучше? Вы приезжаете в Ruby с опытом работы на других языках? –

2

Напишите board.fields вместо fields.

Кстати, у вас нет переменной fields; у вас есть метод экземпляра fields по классу Board, который относится к переменной @fields.