Creating sort visualiser in Ruby - ruby
I'm trying to make a sort visualiser using Ruby and Gosu. When the user left clicks it will sort the numbers out using a insertion sort. When the user right clicks it will sort the numbers out using a bubble sort. So far the only the insertion sort works but the bubble sort crashes after sorting out the first number. Does anyone know why? Thanks.
require 'gosu'
module ZOrder
BACKGROUND, MIDDLE, TOP = *0..2
end
SCREEN_WIDTH = 600 # needs to be COUNT * COLUMN_WIDTH
SCREEN_HEIGHT = 200 # Should be multiple of 100
MAX_VALUE = 100 # the range of the data 1 to 100
COUNT = 30 # Number of items
COL_WIDTH = 20 # suggested at least 10
class Column
# have a pointer to the neighbouring cells
attr_accessor :height, :value
def initialize(value)
#value = value
#height = (SCREEN_HEIGHT/MAX_VALUE) * value
end
end
class GameWindow < Gosu::Window
def initialize
super SCREEN_WIDTH, SCREEN_HEIGHT, false
self.caption = "Sort Visualiser"
#path = nil
#do_insert = false
#do_bubble = false
#columns = Array.new(COUNT)
column_index = 0
while (column_index < COUNT)
col = Column.new(rand(MAX_VALUE + 1))
#columns[column_index] = col
column_index += 1
end
#text_font = Gosu::Font.new(10)
end
def needs_cursor?
true
end
def insertion_sort(loop)
j = loop
done = false
while ((j > 0) and (!done))
if (#columns[j].value < #columns[j - 1].value)
temp = #columns[j - 1]
#columns[j - 1] = #columns[j]
#columns[j] = temp
else
done = true
end
j = j - 1
end
end
def bubble_sort(loop2)
j = loop2
i = loop2 + 1
done = false
while ((j > 0) and (!done))
if (#columns[j].value > #columns[i].value)
temp = #columns[j]
#columns[j] = #columns[i]
#columns[i] = temp
else
done = true
end
j = j - 1
end
end
def button_down(id)
case id
when Gosu::MsLeft
#do_insert = true
#loop = 0
#do_bubble = false
when Gosu::MsRight
#do_bubble = true
#loop2 = 0
#do_insert = false
end
end
def update
if (#do_insert)
puts "Doing insert #{#loop}"
if #loop < (COUNT)
insertion_sort(#loop)
#loop += 1
sleep(0.5)
else
#do_insert = false
end
end
if (#do_bubble)
puts "Doing bubble #{#loop2}"
if #loop2 < (COUNT)
bubble_sort(#loop2)
#loop2 += 1
sleep(0.5)
else
#do_bubble = false
end
end
end
def draw
column_index = 0
while (column_index < #columns.length)
color = Gosu::Color::GREEN
Gosu.draw_rect((column_index * COL_WIDTH), SCREEN_HEIGHT - #columns[column_index].height, COL_WIDTH, #columns[column_index].height, color, ZOrder::MIDDLE, mode=:default)
#text_font.draw("#{#columns[column_index].value}", (column_index * COL_WIDTH) + 5, SCREEN_HEIGHT - 10, ZOrder::TOP, 1.0, 1.0, Gosu::Color::RED)
column_index += 1
end
end
end
window = GameWindow.new
window.show
EDIT: Added in the rest of the code and removed some tags
Related
ruby packing variables and monkey patching
Okay so this is the code: class Board attr_reader :size def initialize n #grid = Array.new(n) {Array.new(n,:N)} #size = n * n end def [] position row, col = position #grid[row][col] end def []= position, val row, col = position #grid[row][col] = val end def num_ships #grid.flatten.count(:S) end def attack position if self[position] == :S self[position] = :H puts "you sunk my battleship" return true else self[position] = :X return false end end def place_random_ships max_ships = #size * 0.25 while self.num_ships < max_ships row = rand(0...#grid.length) col = rand(0...#grid.length) position = [row,col] self[position] = :S end end end But, def place_random_ships max_ships = #size * 0.25 while self.num_ships < max_ships row = rand(0...#grid.length) col = rand(0...#grid.length) position = [row,col] self[position] = :S end end this works, and does what it's suppose to, but when I avoid packing [row,col] and add it directly it does not work. def place_random_ships max_ships = #size * 0.25 while self.num_ships < max_ships row = rand(0...#grid.length) col = rand(0...#grid.length) self[row,col] = :S end end I'm still new to programming, so please try to explain the issue to where I can understand it, or tell me the problem, so I can google it to get a better understanding please.
The issue is that you defined []= to take 2 argument, and array and a value. def []= position, val row, col = position #grid[row][col] = val end With your current implementation you would need to call it like this foo[[row,col]] = :S What you might want to to is define []= like this: def []= row, col, val #grid[row][col] = val end then when you want to pass the array position you can use the array spread operator. With this implementation both of these calls will work. position = [1,2] foo[1,2] = :S foo[*position] = :S if you do that you probably would want to define [] the same way. def [] row,col #grid[row][col] end
How do I fix a problem to call a function in Ruby?
I'm trying to use some ruby code that I've found in Github. I've downloaded the code and did the necessary imports the "requires" and tried to run it as it is described in the readme file on github repository. The code is the following: In the file pcset_test.rb the code is the following: require './pcset.rb' require 'test/unit' # # When possible, test cases are adapted from # Introduction to Post-Tonal Theory by Joseph N. Straus, # unless obvious or otherwise noted. # class PCSetTest < Test::Unit::TestCase def test_init #assert_raise(ArgumentError) {PCSet.new []} assert_raise(ArgumentError) {PCSet.new [1, 2, 3, 'string']} assert_raise(ArgumentError) {PCSet.new "string"} assert_raise(ArgumentError) {PCSet.new [1, 2, 3.6, 4]} assert_equal([0, 1, 2, 9], PCSet.new([0, 1, 2, 33, 13]).pitches) assert_equal([3, 2, 1, 11, 10, 0], PCSet.new_from_string('321bac').pitches) assert_equal([0,2,4,5,7,11,9], PCSet.new([12,2,4,5,7,11,9]).pitches) assert_nothing_raised() {PCSet.new []} end def test_inversion end def test_transposition end def test_multiplication end # # set normal prime forte # # 0,2,4,7,8,11 7,8,11,0,2,4 0,1,4,5,7,9 6-31 # 0,1,2,4,5,7,11 11,0,1,2,4,5,7 0,1,2,3,5,6,8 7-Z36 # 0,1,3,5,6,7,9,10,11 5,6,7,9,10,11,0,1,3 0,1,2,3,4,6,7,8,10 9-8 # def test_normal_form testPC = PCSet.new [0,4,8,9,11] assert_kind_of(PCSet, testPC.normal_form) assert_equal([8,9,11,0,4], testPC.normal_form.pitches) assert_equal([10,1,4,6], PCSet.new([1,6,4,10]).normal_form.pitches) assert_equal([2,4,8,10], PCSet.new([10,8,4,2]).normal_form.pitches) assert_equal([7,8,11,0,2,4], PCSet.new([0,2,4,7,8,11]).normal_form.pitches) assert_equal([11,0,1,2,4,5,7], PCSet.new([0,1,2,4,5,7,11]).normal_form.pitches) assert_equal([5,6,7,9,10,11,0,1,3], PCSet.new([0,1,3,5,6,7,9,10,11]).normal_form.pitches) end def test_prime_form assert_equal([0,1,2,6], PCSet.new([5,6,1,7]).prime.pitches) assert_equal([0,1,4], PCSet.new([2,5,6]).prime.pitches) assert_equal([0,1,4,5,7,9], PCSet.new([0,2,4,7,8,11]).prime.pitches) assert_equal([0,1,2,3,5,6,8], PCSet.new([0,1,2,4,5,7,11]).prime.pitches) assert_equal([0,1,2,3,4,6,7,8,10], PCSet.new([0,1,3,5,6,7,9,10,11]).prime.pitches) end def test_set_class testPcs = PCSet.new([2,5,6]) testPrime = testPcs.prime assert_equal([ [2,5,6], [3,6,7], [4,7,8], [5,8,9], [6,9,10], [7,10,11], [8,11,0],[9,0,1], [10,1,2],[11,2,3],[0,3,4], [1,4,5], [6,7,10],[7,8,11],[8,9,0], [9,10,1],[10,11,2],[11,0,3], [0,1,4], [1,2,5], [2,3,6], [3,4,7], [4,5,8], [5,6,9] ].sort, PCSet.new([2,5,6]).set_class.map{|x| x.pitches}) assert_equal(testPcs.set_class.map{|x| x.pitches}, testPrime.set_class.map{|x| x.pitches}) end def test_interval_vector assert_equal([2,1,2,1,0,0], PCSet.new([0,1,3,4]).interval_vector) assert_equal([2,5,4,3,6,1], PCSet.new([0,1,3,5,6,8,10]).interval_vector) assert_equal([0,6,0,6,0,3], PCSet.new([0,2,4,6,8,10]).interval_vector) end def test_complement assert_equal([6,7,8,9,10,11], PCSet.new([0,1,2,3,4,5]).complement.pitches) assert_equal([3,4,5], PCSet.new([0,1,2], 6).complement.pitches) end # # Test values from (Morris 1991), pages 105-111 # Citation: # Morris. Class Notes for Atonal Music Theory # Lebanon, NH. Frog Peak Music, 1991. # def test_invariance_vector assert_equal([1,0,0,0,5,6,5,5],PCSet.new([0,2,5]).invariance_vector) assert_equal([2,2,2,2,6,6,6,6],PCSet.new([0,1,6,7]).invariance_vector) assert_equal([6,6,6,6,6,6,6,6],PCSet.new([0,2,4,6,8,10]).invariance_vector) assert_equal([1,0,0,0,0,0,0,0],PCSet.new([0,1,2,3,4,5,8]).invariance_vector) assert_equal([1,0,0,1,0,0,0,0],PCSet.new([0,1,2,3,5,6,8]).invariance_vector) assert_equal([12,12,12,12,0,0,0,0],PCSet.new([0,1,2,3,4,5,6,7,8,9,10,11]).invariance_vector) end # # Test values from (Huron 1994). Huron rounds, thus the 0.01 margin of error. # Citation: # Huron. Interval-Class Content in Equally Tempered Pitch-Class Sets: # Common Scales Exhibit Optimum Tonal Consonance. # Music Perception (1994) vol. 11 (3) pp. 289-305 # def test_huron h1 = PCSet.new([0,1,2,3,4,5,6,7,8,9,10,11]).huron assert_in_delta(-0.2, h1[0], 0.01) assert_in_delta(0.21, h1[1], 0.01) h2 = PCSet.new([0,2,4,5,7,9,11]).huron assert_in_delta(4.76, h2[0], 0.01) assert_in_delta(0.62, h2[1], 0.01) end def test_coherence end end And in the file pcset.rb the folloing code: # # => PCSet Class for Ruby # => Beau Sievers # => Hanover, Fall 2008. # # # TODO: Make this a module to avoid namespace collisions. # Lilypond and MusicXML output # include Math def choose(n, k) return [[]] if n.nil? || n.empty? && k == 0 return [] if n.nil? || n.empty? && k > 0 return [[]] if n.size > 0 && k == 0 c2 = n.clone c2.pop new_element = n.clone.pop choose(c2, k) + append_all(choose(c2, k-1), new_element) end def append_all(lists, element) lists.map { |l| l << element } end def array_to_binary(array) array.inject(0) {|sum, n| sum + 2**n} end # the following method is horrifically inelegant # but avoids monkey-patching. # TODO: do this right, incl. error checking def pearsons(x, y) if !x.is_a?(Array) || !y.is_a?(Array) then raise StandardError, "x and y must be arrays", caller end if x.size != y.size then raise StandardError, "x and y must be same size", caller end sum_x = x.inject(0) {|sum, n| sum + n} sum_y = y.inject(0) {|sum, n| sum + n} sum_square_x = x.inject(0) {|sum, n| sum + n * n} sum_square_y = y.inject(0) {|sum, n| sum + n * n} xy = [] x.zip(y) {|a, b| xy.push(a * b)} sum_xy = xy.inject(0) {|sum, n| sum + n} num = sum_xy - ((sum_x * sum_y)/x.size) den = Math.sqrt((sum_square_x - ((sum_x*sum_x)/x.size)) * (sum_square_y - ((sum_y*sum_y)/x.size))) (num/den) end class PCSet include Comparable attr_reader :pitches, :base, :input def initialize(pcarray, base = 12) if pcarray.instance_of?(Array) && pcarray.all?{|pc| pc.instance_of?(Fixnum)} #base, #input = base, pcarray #pitches = pcarray.map{ |x| x % #base }.uniq else raise ArgumentError, "Improperly formatted PC array", caller end end def PCSet.new_from_string(pcstring, base = 12) if base > 36 then raise StandardError, "Use PCSet.new to create pcsets with a base larger than 36", caller end pcarray = [] pcstring.downcase.split(//).each do |c| if c <= 'z' and c >= '0' then pcarray.push(c.to_i(36)) end end PCSet.new pcarray, base end def <=>(pcs) #pitches <=> pcs.pitches end def [](index) #pitches[index] end # Intersection def &(other) PCSet.new #pitches & other.pitches end # Union def |(other) PCSet.new #pitches | other.pitches end def inspect #pitches.inspect end def length #pitches.length end def invert(axis = 0) PCSet.new #pitches.map {|x| (axis-x) % #base} end def invert!(axis = 0) #pitches.map! {|x| (axis-x) % #base} end def transpose(interval) PCSet.new #pitches.map {|x| (x + interval) % #base} end def transpose!(interval) #pitches.map! {|x| (x + interval) % #base} end def multiply(m = 5) PCSet.new #pitches.map {|x| (x * m) % #base} end def multiply!(m = 5) #pitches.map! {|x| (x * m) % #base} end def zero transpose(-1 * #pitches[0]) end def zero! transpose!(-1 * #pitches[0]) end def transpositions (0..(#base-1)).to_a.map{|x| #pitches.map {|y| (y + x) % #base}}.sort.map {|x| PCSet.new x} end def transpositions_and_inversions(axis = 0) transpositions + invert(axis).transpositions end # # Normal form after Straus. Morris and AthenaCL do this differently. # def normal_form tempar = #pitches.sort arar = [] # [[1,4,7,8,10],[4,7,8,10,1], etc.] get each cyclic variation tempar.each {arar.push PCSet.new(tempar.unshift(tempar.pop))} most_left_compact(arar) end def normal_form! #pitches = normal_form.pitches end def is_normal_form? self.pitches == self.normal_form.pitches end def set_class transpositions_and_inversions.map{|pcs| pcs.normal_form}.sort end def prime most_left_compact([normal_form.zero, invert.normal_form.zero]) end def prime! self.pitches = self.prime.pitches end def is_prime? self.pitches == self.prime.pitches end def complement new_pitches = [] #base.times do |p| if !#pitches.include? p then new_pitches.push p end end PCSet.new new_pitches end def full_interval_vector pairs = choose(#pitches, 2) # choose every pc pair intervals = pairs.map {|x| (x[1] - x[0]) % #base} # calculate every interval i_vector = Array.new(#base-1).fill(0) intervals.each {|x| i_vector[x-1] += 1} # count the intervals i_vector end def interval_vector i_vector = full_interval_vector (0..((#base-1)/2)-1).each {|x| i_vector[x] += i_vector.pop} i_vector end # # Morris's invariance vector # def invariance_vector(m = 5) t = transpositions.map!{|pcs| self & pcs} ti = invert.transpositions.map!{|pcs| self & pcs} tm = multiply(m).transpositions.map!{|pcs| self & pcs} tmi = invert.multiply(m).transpositions.map!{|pcs| self & pcs} tc = complement.transpositions.map!{|pcs| self & pcs} tic = complement.invert.transpositions.map!{|pcs| self & pcs} tmc = complement.multiply(m).transpositions.map!{|pcs| self & pcs} tmic = complement.invert.multiply(m).transpositions.map!{|pcs| self & pcs} [t, ti, tm, tmi, tc, tic, tmc, tmic].map{|x| x.reject{|pcs| pcs.pitches != #pitches}.length} end # Huron's aggregate dyadic consonance measure. # Huron. Interval-Class Content in Equally Tempered Pitch-Class Sets: # Common Scales Exhibit Optimum Tonal Consonance. # Music Perception (1994) vol. 11 (3) pp. 289-305 def huron if #base != 12 then raise StandardError, "PCSet.huron only makes sense for mod 12 pcsets", caller end # m2/M7 M2/m7 m3/M6 M3/m6 P4/P5 A4/d5 huron_table = [-1.428, -0.582, 0.594, 0.386, 1.240, -0.453] interval_consonance = [] interval_vector.zip(huron_table) {|x, y| interval_consonance.push(x * y) } aggregate_dyadic_consonance = interval_consonance.inject {|sum, n| sum + n} [aggregate_dyadic_consonance, pearsons(interval_vector, huron_table)] end # # Balzano's vector of relations. Citation for all Balzano methods: # # Balzano. "The Pitch Set as a Level of Description for Studying Musical # Pitch Perception" in Music, Mind, and Brain ed. Clynes. Plenum Press. 1982. # def vector_of_relations (0..length-1).to_a.map do |i| (0..length-1).to_a.map do |j| (#pitches[(i + j) % length] - #pitches[i]) % #base end end end # # Checks if the set satisfies Balzano's uniqueness. # def is_unique? vector_of_relations.uniq.size == vector_of_relations.size end # # Checks if the set satisfies Balzano's scalestep-semitone coherence. # For all s[i] and s[i1]: # j < k => v[i][j] < v[i1][k] # Where j and k are scalestep-counting indices. # And unless v[i][j] == 6 (a tritone), in which case the strict inequality is relaxed. # def is_coherent? v = vector_of_relations truth_array = [] all_pair_indices = choose((0..length-1).to_a, 2) all_pair_indices.each do |i, i1| all_pair_indices.each do |j, k| if v[i][j] == 6 truth_array.push(v[i][j] <= v[i1][k]) else truth_array.push(v[i][j] < v[i1][k]) end if v[i1][j] == 6 truth_array.push(v[i1][j] <= v[i][k]) else truth_array.push(v[i1][j] < v[i][k]) end end end !truth_array.include?(false) end # # Strict Balzano coherence, no inequality relaxation for tritones. # def is_strictly_coherent? v = vector_of_relations truth_array = [] all_pair_indices = choose((0..length-1).to_a, 2) all_pair_indices.each do |i, i1| all_pair_indices.each do |j, k| truth_array.push(v[i][j] < v[i1][k]) truth_array.push(v[i1][j] < v[i][k]) end end !truth_array.include?(false) end def notes(middle_c = 0) noteArray = ['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'] if #base != 12 then raise StandardError, "PCSet.notes only makes sense for mod 12 pcsets", caller end out_string = String.new transpose(-middle_c).pitches.each do |p| out_string += noteArray[p] + ", " end out_string.chop.chop end def info print "modulo: #{#base}\n" print "raw input: #{#input.inspect}\n" print "pitch set: #{#pitches.inspect}\n" print "notes: #{notes}\n" print "normal: #{normal_form.inspect}\n" print "prime: #{prime.inspect}\n" print "interval vector: #{interval_vector.inspect}\n" print "invariance vector: #{invariance_vector.inspect}\n" print "huron ADC: #{huron[0]} pearsons: #{huron[1]}\n" print "balzano coherence: " if is_strictly_coherent? print "strictly coherent\n" elsif is_coherent? print "coherent\n" else print "false\n" end end # def lilypond # # end # # def musicXML # # end ############################################################################### private # # Convert every pitch array to a binary representation, e.g.: # [0,2,4,8,10] -> 010100010101 # 2^n: BA9876543210 # The smallest binary number is the most left-compact. # def most_left_compact(pcset_array) if !pcset_array.all? {|pcs| pcs.length == pcset_array[0].length} raise ArgumentError, "PCSet.most_left_compact: All PCSets must be of same cardinality", caller end zeroed_pitch_arrays = pcset_array.map {|pcs| pcs.zero.pitches} binaries = zeroed_pitch_arrays.map {|array| array_to_binary(array)} winners = [] binaries.each_with_index do |num, i| if num == binaries.min then winners.push(pcset_array[i]) end end winners.sort[0] end end I'm calling them as follows: > my_pcset = PCSet.new([0,2,4,6,8,10]) > my_pcset2 = PCSet.new([1,5,9]) It shoud return: > my_pcset = PCSet.new([0,2,4,6,8,10]) => [0, 2, 4, 6, 8, 10] > my_pcset2 = PCSet.new([1,5,9]) => [1, 5, 9] But is returning nothing. The code is available on github Thanks
Try this in terminal: irb -r ./path_to_directory/pcset.rb and then initialize the objects.
I think the documentation for the repo is bad as it does not explain how you should be running this. The result of my_pcset = PCSet.new([0,2,4,6,8,10]) should set my_pcset to an instance of a PCSet not an array, so these lines from the README file are confusing at best. 3. How to use it Make new PCSets: my_pcset = PCSet.new([0,2,4,6,8,10]) => [0, 2, 4, 6, 8, 10] my_pcset2 = PCSet.new([1,5,9]) => [1, 5, 9] Looking at the code, I see inspect has been delegated to #pitches def inspect #pitches.inspect end I think if you inspect my_pcset you will get the expected result. my_pcset = PCSet.new([0,2,4,6,8,10]) p my_pcset # will print [0, 2, 4, 6, 8, 10] or `my_pcset.inspect` will return what you are expecting.
Ruby NoMethodError - Undefined method
The following is my code. I tried to only include the code where I think the problem may be. Class Ship contains getStatus: class Ship def initialize(name, size, status, shipNumber, firedUpon) #name = name #size = size #status = status #shipNumber = shipNumber #firedUpon = firedUpon end def setSize(nSize) #size = nSize end def getSize return #size end def setName(nName) #name = nName end def getName() return #name end def setStatus(nStatus) #status = nStatus end def getStatus return #status end def setFiredUpon(nFired) #firedUpon = nFired end def getFiredUpon return #firedUpon end def setShipNumber(nNum) #shipNumber = nNum end def getShipNumber return #shipNumber end def ==(rhs) if (#name !=rhs.getName() || #size != rhs.getSize() || #status != rhs.getStatus() || #shipNumber != rhs.getShipNumber() || #firedUpon != rhs.getFiredUpon()) return false end return true end end Class Board Calls upon getStatus and contains rangeIsOccupied: load 'ship.rb' class Board def initialize() #gameBoard = Array.new(100) #Ships = Array.new(5) #initialize all ships on board r = 0 while(r < 100) #gameBoard[r] = Ship.new('', -1, false, -1, false) r = r + 1 end #Ships[0] = Ship.new('Carrier', 5, true,0, false) #Ships[1] = Ship.new('BattleShip', 4, true,1, false) #Ships[2] = Ship.new('Cruiser', 3, true,2, false) #Ships[3] = Ship.new('Submarine', 3, true,3, false) #Ships[4] = Ship.new('Destroyer', 2, true,4, false) end def printBoard() board_size = 10 alphabet = 'abcdefghijklmnopqrstuvwxyz' puts 'x = hit ship' "\n" 'o = ship on board' "\n" 'm = empty space' "\n" puts '---------------------------------------------------------' "\n" puts ' |A| |B| |C| |D| |E| |F| |G| |H| |I| |J|' s = 0 rownum = 0 printrow = true while(s < 100) if printrow print rownum print ' - ' print ' ' printrow = false end if #gameBoard[s].getShipNumber() != -1 && #gameBoard[s].getFiredUpon() print 'x' elsif(!#gameBoard[s].getStatus) print 'm' else print 'o' end if s % 10 == 9 print "\n" printrow = true rownum = rownum + 1 else print ' ' end s = s + 1 end end def isValidDirection(x1, y1, x2, y2) if x1 == x2 || y1 == y2 return true end return false end def rangeIsOccupied(x1, y1, x2, y2) #if horizontal if(y1 == y2) while(x1 != x2) if #gameBoard[(y1*10)+x1]. return true end if x1 > x2 x1 = x1 - 1 else x1 = x1 + 1 end end if #gameBoard[(y1*10)+x1].getStatus return true end else while y1 != y2 if #gameBoard[(y1*10)+x1].getStatus return true end if y1 > y2 y1 = y1 - 1 else y1 = y1 + 1 end end if #gameBoard[(y1*10)+x1].getStatus return true end end return false end Class Game calls getBoard() and randomizeFleet, the start of the problem: load 'player.rb' class Game def initialize() #p1 = Player.new('', 1, true) #p2 = Player.new('cpu', 2, false) gamemode = 0 puts '---------------------------------------------------------' print "Gamemodes:\n1. Player vs. CPU\n2. CPU vs. CPU\n" puts '---------------------------------------------------------' print "Please select a gamemode (1/2):\n: " gamemode = gets.chomp #p2.getBoard().randomizeFleet() When I try to run my codeI get the error: board:89:in rangeIsOccupied': undefined methodgetStatus' for nil:NilClass (NoMethodError) I would like to overcome this issue.
if you are not sure that #gameBoard[(y1*10)+x1] will return a ship instance, then you can add another clause to your conditionals, like: if #gameBoard[(y1*10)+x1] && #gameBoard[(y1*10)+x1].getStatus
How to improve time complexity of this code piece?
I am having a hard time trying to down down the time. If this can be done in O(n^2) thatd be awesome. def printDistance(file) line = file.gets if line == nil then return end sz, sx, sy, ex, ey = line.split(/\s/) #counter = 0 while line = file.gets do if line[0...4] == "path" else x, y, ds, w = line.split(/\s/,4) x = x.to_i y = y.to_i matrix= Array.new later = Array.new tmp = Array.new processing = Array.new if matrix[y].class != Array matrix[y] = Array.new end if ds == "" #this cell has NO way to get to matrix[y][x] = nil else matrix[y][x] = ds end end end for y in 0...matrix.length processing[y] = Array.new tmp[y] = Array.new later[y] = Array.new end printing = Array.new counter = 0 sy = sy.to_i sx = sx.to_i processing[sy][sx] = matrix[sy][sx] matrix[sy][sx] = nil puts "#{counter},(#{sx},#{sy})" #first one counter += 1 loop do print "#{counter}," counter += 1 for y in 0...processing.length for x in 0...processing[y].length if processing[y][x].class != nil tmp[y][x] = processing[y][x] dirArr = tmp[y][x].to_s.split(//) dirArr.each { |c| if c == "u" newY = y - 1 newX = x elsif c == "d" newY = y + 1 newX = x elsif c == "l" newY = y newX = x - 1 else #c == r newY = y newX = x + 1 end if matrix[newY][newX] != nil tmpStr = "(#{newX},#{newY})" printing.unshift(tmpStr) later[newY][newX] = matrix[newY][newX] matrix[newY][newX] = nil end } end end end printing.sort! for i in 0...printing.length print printing[i] if i < printing.length - 1 print "," end end printing = [] #resetting puts for i in 0...later.length for j in 0...later[i].length if later[i][j] != nil processing[i][j] = later[i][j] end end end break if NotEmpty(matrix) == false end end def NotEmpty (a) for i in 0...a.length for j in 0...a[i].length if a[i][j] != nil return true end end end return false end Basically this code reads in a file and places it in a 2-d array representing a maze, then based on maze's starting point it will perform a BFS to put all cells in order from closest to the start to the farthest, then print everything out This code is now O(n^3) but I am trying to shrink it to O(n^2), is there anyway I can traverse a 2-d array and keeping track of the x and y values without using two forloops? Any help is appreciated!! Thanks!
ruby code stopping at run time, seemingly an infinite loop
if i run the code, it will stop and not do anything and i am unable to type. seems to be an infinite loop. the problem seems to be the end until loop, however if i take that out, my condition will not be met. can anyone find a solution? i have tried all the loops that i can think of. /. 2d array board ./ board = Array.new(10) { Array.new(10, 0) } /. printing board ./ if board.count(5) != 5 && board.count(4) != 4 && board.count(3) != 3 for i in 0..9 for j in 0..9 board[i][j] = 0 end end aircraftcoord1 = (rand*10).floor aircraftcoord2 = (rand 6).floor aircraftalign = rand if aircraftalign < 0.5 for i in 0..4 board[aircraftcoord2+i][aircraftcoord1] = 5 end else for i in 0..4 board[aircraftcoord1][aircraftcoord2+i] = 5 end end cruisercoord1 = (rand*10).floor cruisercoord2 = (rand 7).floor cruiseralign = rand if cruiseralign < 0.5 for i in 0..3 board[cruisercoord2+i][cruisercoord1] = 4 end else for i in 0..3 board[cruisercoord1][cruisercoord2+i] = 4 end end destroyercoord1 = (rand*10).floor destroyercoord2 = (rand 8).floor destroyeralign = rand if destroyeralign < 0.5 for i in 0..2 board[destroyercoord2+i][destroyercoord1] = 3 end else for i in 0..2 board[destroyercoord1][destroyercoord2+i] = 3 end end end until board.count(5) == 5 && board.count(4) == 4 && board.count(3) == 3 print " " for i in 0..9 print i end puts for i in 0..9 print i for j in 0..9 print board[i][j] end puts end
The line board.count(5) == 5 ... will never be true because board is a two-dimensional array. I can't tell what the condition should be, but it could look something like: board[5].count(5) == 5