I am trying to figure out how to pass variables between classes in Ruby. The example I am working on now is a game, where the players health, equipment, etc keeps changing and is passed from scene to scene until the game is over. Here is what I have so far:
class Player
def enter()
end
end
class MyPlayer < Player
def initialize()
dog_biscuits = false
end
end
class Scene
def enter()
end
end
class Entrance < Scene
def enter(player)
puts "You are in the entrance"
if player.dog_biscuits == false
puts "You don't have any biscuits."
end
end
end
player = MyPlayer.new
entrance = Entrance.new
entrance.enter(player)
Whenever I run this, I get the following error message:
entrance.rb:20:in `enter': undefined method `dog_biscuits' for #<MyPlayer:0x007fbfe2167f20> (NoMethodError)
I am running ruby 2.2.3p173 on OSX El Capitan.
Do this:
class MyPlayer < Player
attr_accessor :dog_biscuits
def initialize()
#dog_biscuits = false
end
end
Using attr_accessor will allow you to set and get instance variables. Remember also that you have to prefix instance variables with #.
class MyPlayer < Player
def initialize()
#dog_biscuits = false
end
def has_no_dog_biscuits?
#dog_biscuits == false
end
end
It is better to create method has_no_dog_biscuits? then to have attr_reader and to expose attribute to outer world, this way, you can always check if player has not dog_biscuits.
Related
so ive made 2 classes the grass inherits from the Tile class, anytime the Tile class is called it should go to the grass class and create a tile containing itself. the problem is i get "uninitialized constant Tile::Grass (name error)" and im not sure why, if anyone has any insight please help me out!
require_relative './Assets.rb'
require_relative './Tile.rb'
class Grass < Tile
def initialize id
Tile.new Assets.grass, id
end
def isSolid
return false
end
end
require './Grass.rb'
class Tile
class << self
def tiles(id)
return ##Tiles[id]
end
end
##Tiles = []
##GrassTile = Grass.new(0)
def initialize asset, id
##Tiles[id] = self;
end
def update
end
def draw
end
end
class Player
attr_accessor :card_pile
def initialize
#bust = false
#card_pile = []
end
def bust?
return #cards.inject(:+) > 21
end
end
I have this Player class and have initazlied card_pile variable
class Game
def initialize
#players = []
end
def playing_game
puts "How many players are playing? "
players_amount = gets.chomp.to_i
(0...players_amount).each do
puts ("What is the players name? ")
name = gets.chomp
#players.push(name)
end
puts #players
player = Player.new
player.initialize
while #card_pile.length < 2 do
new_card = Card.new
#card_pile.push(new_card.value)
end
end
I wish to use this variable in the while loop below. Why cannot this be accessed in the way I am hoping it will be?
The error message is: ``playing_game': private method initialize' called for #<Player:0x007fda53073f48 #bust=false, #card_pile=[]> (NoMethodError)
initialize is called automatically when you make a new instance of a class using Player.new. You don't currently have any arguments being passed in to your initialize method, but you have set the instance variable card_pile with attr_accessor, so you can do this:
player = Player.new
while player.card_pile.length < 2 do
new_card = Card.new
player.card_pile.push(new_card.value)
end
I am building a Tic-Tac-Toe game to be played on the command line.
module TicTacToe
class Player
attr_accessor :symbol
def initialize(symbol)
#symbol = symbol
end
end
class Board
attr_reader :spaces
def initialize
#spaces = Array.new(9)
end
def to_s
output = ""
0.upto(8) do |position|
output << "#{#spaces[position] || position}"
case position % 3
when 0, 1 then output << " | "
when 2 then output << "\n-----------\n" unless position == 8
end
end
output
end
def space_available(cell, sym)
if spaces[cell].nil?
spaces[cell] = sym
else
puts "Space unavailable"
end
end
end
class Game < Board
attr_reader :player1, :player2
def initialize
play_game
end
def play_game
#player1 = Player.new("X")
#player2 = Player.new("O")
puts Board.new
#current_turn = 1
turn
end
def move(player)
while victory != true
puts "Where would you like to move?"
choice = gets.chomp.to_i
space_available(choice, player.symbol)
puts Board
#current_turn += 1
turn
end
end
def turn
#current_turn.even? ? move(#player2) : move(#player1)
end
def victory
#still working on this
end
end
end
puts TicTacToe::Game.new
The method that is to take a user's cell choice (space_available) and alter the array with their piece ('X' or 'O') is giving me an error. I can't find why my code is throwing this particular error.
The problem is that you don't call the parent constructor in your Game class, therefore #spaces is not initialized.
Your hierarchy decision is questionable, but to make it work, you can simply change the Game constructor to:
def initialize
super
play_game
end
You are calling spaces[cell]. The error is telling you that you are calling [] on nil, which means that spaces must be nil.
Perhaps you mean #spaces? Otherwise - you need to tell the program how spaces is defined and how it is initialized. A simple spaces = {} unless spaces would work
Another way of initialising your spaces variable would be to call super when you initialize the Game:
class Game < Board
attr_reader :player1, :player2
def initialize
super
play_game
end
...
Hi I try to make my first game in ruby :)
I have two files:
#"game.rb" with code:
class Game
attr_accessor :imie, :klasa, :honor
def initialize(start_scena)
#start = start_scena
end
def name()
puts "Some text"
exit(0)
end
end
and second file
#"game_engine.rb"
require_relative 'game.rb'
class Start
def initialize
#game = Game.new(:name)
end
def play()
next_scena = #start
while true
puts "\n---------"
scena = method(next_scena)
next_scena = scena.call()
end
end
end
go = Start.new()
go.play()
The question is, how can I call class Game.name method from Start.play() class. The game goes deeper, and insted of 'exit(0)' it returns :symbol of another method from "Game" class that should work.
Make start readable for the Game class. DO NOT call exit(0) in your code unless it's really necessary. Instead, use some conditions to make sure the program runs to the end of script.
#"game.rb" with code:
class Game
attr_accessor :imie, :klasa, :honor
attr_reader :start
def initialize(start_scena)
#start = start_scena
end
def name()
puts "Some text"
:round2
end
def round2
puts "round2"
nil
end
end
Use instance#method(...) to get a bounded method to that instance.
#"game_engine.rb"
require_relative 'game.rb'
class Start
def initialize
#game = Game.new(:name)
end
def play()
next_scene = #game.start
while next_scene
puts "\n---------"
scene = #game.method(next_scene)
next_scene = scene.call()
end
end
end
go = Start.new()
go.play()
So, I know there is a simple error, but I just can't seem to spot it. I'm using Modules/Mixins for the first time and any help would be much appreciated. I keep getting this error:
undefined method `this_is' for Value:Module (NoMethodError)
But it looks like the method is there...Here are is my module and classes...
module Value
def this_is
puts "#{self.players_hand} is the players hand"
end
end
require './value.rb'
class Player
include Value
attr_accessor :players_hand
def initialize
#players_hand = 0
end
def value_is
Value.this_is
end
end
require './player.rb'
class Game
def initialize
#player = Player.new
end
def start
puts #player.players_hand
puts #player.value_is
end
end
game = Game.new
game.start
When you include Value inside of the Player class, you are making the Value module's methods a part of the Player class, so the this_is method is not namespaced. Knowing that, we need to change this method:
def value_is
Value.this_is
end
To:
def value_is
this_is
end