Ruby class refresh/rollback deleted array elements - arrays

I am trying to create a ruby class for a game called times up. Essentially, i want the following functionality to start with:
each instance of the class is a game.
Each game has an array of words which are input by the players.
the class should enable getting a random element out of the array of words and subsequently removing that elemennt from play.
When all the words are out of the "hat", the game should be able to refresh the array to its original content, simulating putting the words back into the hat for the next round.
It is this last point that I am having trouble with.. I tried to create a dummy array or a base array that is not modified and then just set the emptied array to the base array at the end of a round but this only results in me removing elements from the base array in the second round and being left with two empty arrays at the end of the second round :( how do i create a copy which will not be modified??
Here is my code:
class TimesUp
def initialize
#hat = []
#basehat = []
end
def NewWord(word)
#hat.push(word)
#basehat.push(word)
end
def grab
if #hat.empty?
puts "End of round!"
else
l = #hat.length
word = rand(l)
puts #hat[word]
#hat.delete_at(word)
end
end
def printout
puts #hat
end
# here is where i try to set the game array to the 'base' array.
def refresh
#hat = #basehat
#basehat = #basehat
end
end

Use Object#dup, and clone might also be an option.
def refresh
#hat = #basehat.dup
#basehat = #basehat.dup
end

Related

Develop a class a one-dimensional array and two instances of this class

My task:
 Create 2 class objects. Delete all elements in the first object that are contained in the second.
My implementation:
class Vector
def initialize
#vector = Array.new
end
end
vector1 = Vector.new(1,2,3,4,5,6,7)
vector2 = Vector.new(3,6,7)
But this does not work as needed. What should I fix?
I think it is some sort of question from institute, and requirements are different than what you coded, I am just trying to correct your coding and rectify so you get some result, than you can further proceed to full-fill your requirements.
Your first mistake is you are asking for one parameter but providing
commas is giving multiple parameters, so I have changed it to get
array.
As changed array so now you can't add another array in first, as it
is just one array so I am removing << and adding = in initialize
method
Your initialize method is not taking any parameter, but you are
providing, but you have to define a method set_vector so you have
to use that method instead of class, as per your requirement that is
what you want.
You should define - method but than you have to play with class
variables too, as you are playing with two object and with in your
class you have to define - function, but I am here just using your
get_vector method to compare arrays and return your response.
changing put to print so you can have variables instead of all items.
Hope this will give you some helpful insight to coding.
class Vector
def initialize
#vector = Array.new
end
def set_vector=(vector)
#vector = vector
end
def get_vector
#vector
end
end
def confront(first_vector, second_vector)
first_vector.get_vector - second_vector.get_vector
end
first_vector = Vector.new
first_vector.set_vector=[1,2,3,4,5,6,7]
second_vector = Vector.new
second_vector.set_vector=[3,6,7]
final_vector = confront(first_vector, second_vector)
begin
puts "First:"
print first_vector.get_vector
puts "\nSecond:"
print second_vector.get_vector
puts "\nFinal Vector:"
print final_vector
end

Pushing objects into an array is returning an empty array

Problem
I have a method called queue, belonging to the Board Class that returns an empty array. I am having trouble pushing modified objects to this array. Currently it returns an empty array.
def queue
queue = []
end
Functionality Explained
I have a rules method, that belongs to the Board Class that conditionally calls queue_for_birth or queue_for_death
def rules(cell)
if something
cell.queue_for_birth
else something_else
cell.queue_for_death
end
end
This method is being called multiple times in an each block contained in the game_logic method also belonging to the Board Class.
Each time rules is called, and it queues_for_birth or queues_for_death, it should add that instance of cell to an array called queue
def game_logic(cells)
cells.each_with_index do |cell,index|
if index == 0
rules(cell) #push to the queue
end
if index == 1
rules(cell) #push to the queue
end
...
Here is where the logic that adds cells to a queue lives, it belongs to the Cell Class, which inherits from Board
def queue_for_birth(queue)
#will_survive = true
queue << self
end
However, whenever I call board.queue, an empty array is returned.
=> []
Adding an instance variable queue to the board class solved this
class Board
def initialize(live_cell_count, queue)
#live_cell_count = live_cell_count
#queue = queue
end
def queue
#queue
end
Inserting queue.push(cell) in the conditional successfully appends each cell to the queue array.
def rules(cell)
if something
cell.queue_for_birth
#queue.push(cell)
else something_else
cell.queue_for_death
#queue.push(cell)
end
end

Ruby program returns error "implicit conversion of String into Integer (TypeError)"

I'm trying to create a replica of Go Fish to help me learn more about arrays and hashes, and just how to go about structuring data. I'm on day two and have what looks to be much closer to the end goal. Keep in mind, I'm new to this. Anyway, here's the problem I'm running into:
=> gofish.rb:21:in `player_turn': no implicit conversion of String into Integer (TypeError)
I understand why I'm getting the error, but I can't figure out how to use the .shift method without giving an index number. I would like to select which object to shift based on the value instead. So, if I correctly guess do you have an 'ace of spades', the card is removed from the cpu_hand array and is added to the my_hand array. With that said, I would just like to know the best way to go about this.
Here's my script:
card_values = ['ace', 'two', 'three', 'four', 'five', 'six', 'seven',
'eight', 'nine', 'ten', 'jack', 'queen', 'king']
suits = ['spades', 'diamonds', 'hearts', 'clubs']
# creates array objects with every value and suit possible (full deck)
card_deck = card_values.product(suits).collect{|card, suit| "#{card} of #{suit}"}
def print_hand
puts "Your hand: #{#my_hand.join(', ')}."
end
def player_turn
puts "You go first!"
puts "Do you have a..."
puts #cpu_hand.join(', ')
print "> "
#card = $stdin.gets.chomp.downcase
# if cpu has the card requested give it to the player and add to their array
if #cpu_hand.include?(#card)
puts "Ahhh...you got me. Here you go!"
#my_hand.shift(#cpu_hand[#card]) # ****Here's the error(line:21)
print_hand
else
puts "Go fish!"
#my_hand.shift(#card_deck[1])
print_hand
end
end
puts "There are #{card_deck.length} cards in this deck."
puts "Welcome to Go-Fish."
print "Your name please: "
player_name = $stdin.gets.chomp.capitalize
puts "Ok #{player_name}, lets get this deck shuffled..."
#sleep(1)
# shuffles card_deck using .shuffle method
card_deck = card_deck.shuffle
puts "Cards are perfectly shuffled!"
#sleep(1)
puts "Dealing cards..."
#sleep(1)
# assigns first 7 cards to user, removes from card_deck
#my_hand = Array.new
#my_hand = card_deck.shift(7)
# assigns next 7 cards to CPU, removes from card_deck
#cpu_hand = Array.new
#cpu_hand = card_deck.shift(7)
print_hand
until card_deck.length < 1 || #cpu_hand.length < 1 || #my_hand.length < 1
player_turn
end
puts "GAME OVER!"
In your error line,
#my_hand.shift(#cpu_hand[#card])
your crash is caused by attempting to index into the #cpu_hand array with a string (#card). The second issue is trying to call shift using a string as a parameter. Both of these need to be integers. shift removes the first element (or first n elements if an integer parameter is specified); this seems appropriate for taking an item from card_deck, but you'd want push, unshift, or << to add an element to #my_hand. You'll also need a method to remove the specified card from #cpu_hand, delete:
if #cpu_hand.include?(#card)
puts "Ahhh...you got me. Here you go!"
#my_hand << #cpu_hand.delete(#card) # transfer a card from CPU to my hand
print_hand
else
puts "Go fish!"
#my_hand << card_deck.shift # take the first card from the deck (could also be pop?)
print_hand
end
However, card_deck is not a global like your other variables, so you'll need to pass it into the function and change the function header to def player_turn card_deck, or make it global. But making everything global is generally considered poor design because data can be mutated from anywhere, leading to difficult-to-find bugs. Consider writing classes such as Hand and GoFish (for example) that encapsulate all of the logic necessary to represent reusable pieces of your game.
I recommend taking a read through the array docs. You'll surely find some cool methods and learn a few tidbits.

How to store a specific element from a csv into a variable?

I have a csv file called Energy.csv and it's very simple:
Building A,150
Building B,160
I would like to import the csv into Ruby and print the second row, second column element (160). This is what I have so far but I don't know how to improve this code.
require 'csv'
class CSVImport
energyusageA = Array.new
energyusageB = Array.new
CSV.foreach('CSV/Energy.csv') do |row|
energyusageA = row[1]
energyusageB = row[2]
end
puts energyusageB[1]
end
To read this in quickly if it's a small file and memory isn't a constraint:
CSV.open('CSV/energy.csv').read[1][1]
Where that pulls the second row's second value as everything's zero-indexed in Ruby.
In your code you have it wrapped inside of a class definition but that doesn't really make sense unless you're defining methods. Yes you can run executable code there in that context but that's reserved for other situations like meta-progamming.
A Ruby-style design looks like this:
class CSVReader
def initialize(path)
#path = path
end
def value(row: 1, col: 1)
CSV.open(#path).read[row][col]
end
end
Where you can call it like:
CSVReader.new('CSV/energy.csv').value
CSVReader.new('CSV/energy.csv').value(row: 4, col: 2)
And so on.
I think you were quite close.
To get second row you can do it the following way:
require 'CSV'
second_row = Array.new
CSV.foreach('energy.csv') do | row |
second_row << row[1]
end
To get the second element you just need to access second column element (since ruby is 0-based it is 1):
second_row[1] will print you =>"160".
Edit I think I need to explain one more thing. The difference between = (assignment) and << (appending).
The = assigns the variable the right side.
The << appends the right side to the end of an Array.
You can try it out on the following test:
test = Array.new
test = 'Yo' => this assigns string to the test (*"Yo\n"* will be stored in the *test8 variable)
OR
test << 'Yo' => this appends to the empty array the string 'Yo' so the *Array* will look like this *["Yo"]*.

Checking if an element belongs to an array in Ruby

I'm trying to figure out how to check if an element belongs to an array using ruby. I'm reading from a file (say demo.txt) which has comma separated pairs in each line. I'm concatenating these two pairs and pushing it into an array. Later I need to check if a specific value belongs to the array. I can see the array is populated successfully but the second check is unsuccessful, i.e. it can't find the element in the array. 'My demo.txt' is as follows
a, b
c, d
The ruby code goes as follows
array = Array.new
File.readlines('demo.txt').each do |line|
line.slice! ", "
array.push line
end
array.each do|d|
puts d
end
if array.include? 'ab'
puts "correct" #this is not printed
end
How do I check if the array contains the element 'ab'?
There is ab\n in your array.
Instead of
array.each do|d|
puts d
end
use inspect to check the values,
p array
#=> ["ab\n", "cd"]
To fix the issue, use chomp on line
File.readlines('b.txt').each do |line|
line = line.chomp
...
end
Replacing this
if array.include? 'ab'
puts "correct"
end
with this one
if array.find 'ab'
puts "correct"
end
resolves the issue.

Resources