# \[noob\] Problem with arrays

**URL:** <https://www.ruby-forum.com/t/noob-problem-with-arrays/226057>\
**Category:** Ruby\
**Created:** [February 12, 2010, 2:29pm UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057 "2010-02-12T14:29:45Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sobert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e19adc/32.png) [@sobert](https://www.ruby-forum.com/u/sobert)\
**Post date:** [February 12, 2010, 2:29pm UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057/1 "2010-02-12T14:29:45Z")

</div>

Hello,

I have a few issue using arrays.

I’m working with rubySDL to make a vertical shooting game. I have a  
ship, which had a collection of “fired\_missile”.  
The level have a collection of critters on screen.

My main loop is :

def main  
self.init\_lvl  
critest = Critters.new(@screen, SCREEN\_W,SCREEN\_H/2)  
@crit\<\<critest  
while(@finished == false)  
background = @screen.format.map\_rgb(0, 0, 0)  
@screen.fill\_rect(0,0,@screen.w,@screen.h,background)  
self.event\_poll  
@ship.move  
@ship.draw  
cur\_crit = @crit  
cur\_crit.each { |c|  
c.move  
c.draw  
self.check\_firing©  
}  
@screen.update\_rect(0,0,@screen.w,@screen.h)  
end  
end

If I understand my code well, for each critters in @crit collection (or  
cur\_crit to be more accurate), I move the crit, then draw it, and to  
finish I call “check\_firing” with the critters in parameter.

Here’s the check\_firing code :

def check\_firing©  
critemp = []  
if(@ship.firelist.length!=0)  
@ship.firelist.each { |f|  
if(f.collide\_with?©)  
else  
critemp\<\<c  
end  
@crit = critemp  
}  
end  
end

The amusing part is that all work well if I fire only one missile. When  
I fire more, it becomes unclear : the critters won’t disappear, and  
(surprisingly) it goes faster.

I used the cur\_crit temporary array in the main function because  
modifying the @crit array while looping on it was kind of hazardous.

If someone have an idea, it will be greatly appreciated 😉  
Thanks.

---

<div class="post-metadata">

**Author:** ![sobert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e19adc/32.png) [@sobert](https://www.ruby-forum.com/u/sobert)\
**Post date:** [February 12, 2010, 2:42pm UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057/2 "2010-02-12T14:42:57Z")

</div>

Ok, my mistake, I was lost in loops 😛

So, to explain that simply, I passed c as an argument so it became  
persistant outside the @crit.

Sylvain P. wrote:

> Hello,

---

<div class="post-metadata">

**Author:** ![sobert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e19adc/32.png) [@sobert](https://www.ruby-forum.com/u/sobert)\
**Post date:** [February 12, 2010, 6:10pm UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057/3 "2010-02-12T18:10:21Z")

</div>

Sylvain P. wrote:

> Hello,
> 
> I have a few issue using arrays.
> 
> I’m working with rubySDL to make a vertical shooting game. I have a  
> ship, which had a collection of “fired\_missile”.  
> The level have a collection of critters on screen.

I saw your later post that this is working, but I thought that since  
you’re a newcomer, I’d just point a few things about your programming  
style that aren’t so Rubyish…

> My main loop is :
> 
> def main  
> self.init\_lvl  
> critest = Critters.new(@screen, SCREEN\_W,SCREEN\_H/2)

If each instance of this class represents one critter, then it would  
usually best to call the class Critter (in the singular).

> ```
> @crit<<critest
> 
> ```

I think most Rubyists use spaces around operators, for what that’s  
worth…

> ```
> while(@finished == false)
> 
> ```

You don’t need the parentheses or the “== false”. You probably just  
want “while !@finished”.

Caveat: that will also return true if @finished is nil.

> ```
> background = @screen.format.map_rgb(0, 0, 0)
> @screen.fill_rect(0,0,@screen.w,@screen.h,background)
> self.event_poll
> @ship.move
> @ship.draw
> cur_crit = @crit
> cur_crit.each { |c|
> 
> ```

In general, “do…end” is used for multiline blocks. The {} syntax is  
usually reserved for blocks on a single line. It is _very_ rare to use  
{} as you’ve used it here.

> ```
> c.move
> c.draw
> self.check_firing(c)
> }
> @screen.update_rect(0,0,@screen.w,@screen.h)
> 
> ```

That’s a long loop! Why not put it in a method of its own? You might  
also want to put the cur\_crit.each block in a method of its own.

> ```
> end
> 
> ```
> 
> end
> 
> If I understand my code well, for each critters in @crit collection (or  
> cur\_crit to be more accurate), I move the crit, then draw it, and to  
> finish I call “check\_firing” with the critters in parameter.
> 
> Here’s the check\_firing code :
> 
> def check\_firing(c)  
> critemp = []  
> if(@ship.firelist.length!=0)

Unnecessary. If the length is 0, then the each in the next line will  
simply perform its block 0 times.

Now, if firelist could be nil, then you’ll need to check for that. “if  
@ship.firelist” would be sufficient.

> ```
> @ship.firelist.each { |f|
> if(f.collide_with?(c))
> else
> critemp<<c
> end
> 
> ```

Why do you have an empty if clause? You could make this much more  
readable by reversing the conditional (and removing some parentheses):

if !f.collide\_with?(c)  
critemp \<\< c  
end

> ```
> @crit = critemp
> }
> end
> 
> ```
> 
> end

Are you sure about your logic here? The only thing that will be written  
to @crit is an array containing multiple copies of c. No further  
information, just multiple copies of c.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![sobert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e19adc/32.png) [@sobert](https://www.ruby-forum.com/u/sobert)\
**Post date:** [February 12, 2010, 7:40pm UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057/4 "2010-02-12T19:40:04Z")

</div>

Luc H. wrote:

> On 12 fï¿½vr. 2010, at 18:10, Marnen Laibow-Koser wrote:
> 
> > You don’t need the parentheses or the “== false”. You probably just  
> > want “while !@finished”.
> 
> Even better: until @finished

Thanks! I forgot about until.

> > if !f.collide\_with?(c)
> 
> Same here: unless f.collide\_with?(c)

I don’t like unless. I find it less confusing, in most cases, to write  
if !. But it certainly is an option.

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![sobert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e19adc/32.png) [@sobert](https://www.ruby-forum.com/u/sobert)\
**Post date:** [February 13, 2010, 12:34am UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057/5 "2010-02-13T00:34:13Z")

</div>

On Fri, Feb 12, 2010 at 12:03 PM, Luc H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> –  
> Luc H. - removed\_email\_address@domain.invalid

I would also define getters for boolean variables

def finished?  
!!@finished  
end

…

until finished?  
…  
end

I try to restrict direct references to instance variables, and instead  
use  
them through methods, it seems like better encapsulation to me. For  
example,  
maybe later I realize I can tell if it is finished by checking something  
else rather than storing state in an instance variable, then there is  
only  
the setter and getter methods that need to be looked at, rather than  
every  
place I used the instance variable.

I guess I see the method as an interface to the functionality, and the  
instance variable as the implementation.

---

<div class="post-metadata">

**Author:** ![sobert](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/s/e19adc/32.png) [@sobert](https://www.ruby-forum.com/u/sobert)\
**Post date:** [February 12, 2010, 7:03pm UTC](https://www.ruby-forum.com/t/noob-problem-with-arrays/226057/6 "2010-02-12T19:03:32Z")

</div>

On 12 févr. 2010, at 18:10, Marnen Laibow-Koser wrote:

> You don’t need the parentheses or the “== false”. You probably just  
> want “while !@finished”.

Even better: until @finished

> if !f.collide\_with?©

Same here: unless f.collide\_with?©
