Jump to content
New account registrations are disabed. This website is now an archive. Read more here.
Bigace360

Scripting Question: each/for loops

Recommended Posts

Well this question is also related to the other two engines, but since there's no main scripting forum, and I'm coding in RMXP I'll place it here.

 

So I was writing a loop, in my bestairy script, and I know that for is a call to each like:

 

 

@win = [@command_window, @playtime_window, @steps_window, @gold_window, @status_window]
for x in @win
x.dispose unless x.disposed?
end

 

is actually calling this

 

@win = [@command_window, @playtime_window, @steps_window, @gold_window, @status_window]
@win.each {|x| x.dispose unless x.disposed?}

 

However how come when you do this method of looping with something like this:

 

@test_enemy_id = id
for i in 1...$data_troops.size
for j in 0...$data_troops[i].members.size
if $data_troops[i].members[j].enemy_id == id
troop = $data_troops[i]
break
end
end
end
return troop.id

 

and then try to change it to a each loop:

 

@test_enemy_id = id
(1...$data_troops.size).each do |i|
(0...$data_troops[i].members.size).each do |j|
if $data_troops[i].members[j].enemy_id == id
troop = $data_troops[i]
break
end
end
end
return troop.id

 

you get and error where at the last line, return troop.id, it tells it doesn't know what troop is.

 

So my question is why does it give an error even though Ruby is going to call for each anyways when you use for x in y loop. I don't know maybe I'm missing something, but if Ruby is going to call each anyways, why don't I just right it save the computer from thinking it, but this error stops me from doing that. Hopefully that made sense.l

Share this post


Link to post
Share on other sites

I see no reason why this shouldn't work, except maybe for the break statement which seems out of place to me;

Share this post


Link to post
Share on other sites

Well I created the error and I got this:

 


Script ' Game_Album' line 65: NameError occured.

 

undefined local variable or method 'troop' for #<Game_Album:0x31e51c8>


For some reason it states troop as undefined, It could be the break, I'll see what happens if I remove it.

 

Edit: Moving the break does nothing.

Edited by bigace

Share this post


Link to post
Share on other sites


Script ' Game_Album' line 65: NameError occured.

 

undefined local variable or method 'troop' for #<Game_Album:0x31e51c8>


For some reason it states troop as undefined, It could be the break, I'll see what happens if I remove it.

This is one of your own custom classes, isn't it? We can't help you unless you post its code.

 

Edit: Moving the break does nothing.

I'm probably understanding your script's purpose wrong, but you didn't say a word about it either.

Share this post


Link to post
Share on other sites

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# ■ Game_Album
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
class Game_Album
include ACE::Bestiary
attr_reader   :seen, :killed, :rank, :percent, :test_enemy_id, :black_list	
attr_accessor :battle_test   
def initialize
 @seen, @killed = [], []
 (1...$data_enemies.size).each do |i|
  @killed.push(nil)
  @seen.push(nil)
 end
 @percent, @test_enemy_id, @battle_test, @rank = 0, 0, false, 'none'
end
def add_enemy_seen(enemy)
 index = enemy.id - 1
 @seen.insert(index, enemy)
 @seen.delete_at(enemy.id)
 determine_rank
end
def add_enemy_killed(enemy)
 index = enemy.id - 1
 @killed.insert(index, enemy)
 @killed.delete_at(enemy.id)
 determine_rank
end
def determine_rank
 return @rank = ZERO_RANK if @seen.nitems > @killed.nitems
 @percent = ((@killed.nitems * 100) / ($data_enemies.size - 1))
 case @percent
 when 1..25 then  @rank = RANK_NAMES[0]
 when 26..50 then @rank = RANK_NAMES[1]
 when 51..75 then @rank = RANK_NAMES[2]
 when 76..99 then @rank = RANK_NAMES[3]
 when 100 then    @rank = RANK_NAMES[4]
 end
end
def has_seen_enemy?(enemy);	   return @seen.include?(enemy); end
def has_killed_enemy?(enemy);	 return @killed.include?(enemy); end
def enemy_blacklisted?(enemy_id); return BLACK_LIST.include?(enemy_id); end
def soul_searcher(id)  
 if $atoa_script["SBS Tankentai"]
  $data_troops[0] = RPG::Troop.new
  $data_troops[0].name = "Album Battle"
  $data_troops[0].id = 0
  $data_troops[0].members = [RPG::Troop::Member.new]
  $data_troops[0].members[0].enemy_id = id
  $data_troops[0].members[0].x = 160
  $data_troops[0].members[0].y = 240
  $data_troops[0].members[0].immortal = false
  $data_troops[0].members[0].hidden = false
  return 0
 else
  @test_enemy_id = id
  for i in 1...$data_troops.size
   for j in 0...$data_troops[i].members.size
 if $data_troops[i].members[j].enemy_id == id
  troop = $data_troops[i]
  break
 end
   end
  end
  return troop.id
 end
end
def start_battle
 @battle_test = true
 $game_temp.map_bgm = $game_system.playing_bgm
 $game_system.bgm_stop
 $game_system.se_play($data_system.battle_start_se)
 $game_system.bgm_play($game_system.battle_bgm)
 $scene = Scene_Battle.new
end
end

 

Okay, here's the rest of the script, the part were looking at is the soul_searcher(id) method that calls up the enemy from the database your going to battle and poitions the enemy in the battle. Scene_Album calls up the method when you select case 4 which is battle. Hope that shed some light on it.

Share this post


Link to post
Share on other sites

Well there's only one explanation - the condition at line 59 is never met and thus the troop local variable is not defined.

Share this post


Link to post
Share on other sites

Cool, I got it to work now I just need to add troop = 0 at the top of the double loop., thx.

Share this post


Link to post
Share on other sites

A "for..end" loop is not the same as using "each", and your error is because of it. They are both very similar, and are interchangeable the majority of the time, but not always. A variable created inside of a for..end loop's scope is retained. Meaning it still exists after the loop.

 

Example.

 

for i in 0..34
 number = i
end

p number

 

As you can see if you run this, "number" has a value of 34, outside of the loop, even though is was created within it, and did not exist before it.

 

Now try the same with an "each" block.

 

(0..34).each {|i| number = i }
p number

 

Now the game crashes, telling you "undefined method or local variable for "number" ".

This because any local variable created in a block only has a scope of that block.

Edited by ForeverZer0

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...