Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Hashes? (+ arrays? pg. 2)

Can anyone please tell me how hashes in scripts work exactly, and when's the best time to use them? Could anyone provide a few examples of hashes? I saw one before where someone showed me a hash vs. long case statements, but I wanna know more.
 

OS

Sponsor

A hash is like an Array, except with Keys instead of indexes. Like this:

@hash = {key => value, key => value}

Keys can be anything, numbers, strings, etc.
So can Values. Check the Help File for some of it's more useful methods.
 
lol that was me :p

Ok, A Hash is a container object just like arrays are. Think of it as like a doorway. You need a key to open the door. that is how a hash basically works.

The hash literal is {} and you add key/value pairs to the Hash
the syntax of a hash is {key => value, key => value}

so for example
Code:
hash = {1 => 'Hi', 2 => 'Yo', 7 => 'Heya'}
Now to access values in the hash you use the [] method so
Code:
hash[1] #=> 'Hi'
hash[2] #=> 'Yo'
hash[3] #=> ?
ok next topic what if the key does not exist in the hash?
Well by default if the key is not in the hash it will return nil unless you have a default set for the hash you can do this one of two ways

1) By declaring it when using Hash.new(default = nil)
2) By calling the method <Hash>.default=

so back to our example If I did and then
Code:
hash.default = "HELLO"

hash[3] #=> "HELLO"

this behavior is pretty useful since you don't have to define each value of the hash as "HELLO"

there are other useful methods such as key?/has_key?/member?/include?, values, keys, each, each_key, each_value, but I'll let you look those up :)


for me though Hashes are used as setup objects rather than the long case statement the two have the exact same function but you don't have to keep typing

Code:
case somevalue
when blahblah
  something something something
when blahblah
  something something something
when blahblah
  something something something
else
  the default
end
 
@Trickster:

Of course I knew it was you, I just don't tend to name names is all. :P

Okay, lemme see if I got this right. First, lemme double check, the syntax of hash is something like this:

Code:
class Whatever

the_hash = {key_value => hash_value, key_value2 => hash_value, key_value3 => hash_value}
the_hash.default = whatever number I want the_hash to be by default

  def some_method_in_class_Whatever
    return the_hash[key_value]
  end
end

And the return will, uh, return the value of hash, and that value of hash depends on what the key_value ended up being, right?

Now say I want to give the characters additional Attack Power depending on their Exp. Level. It would start off like this:

Code:
Extra_ATK = {character's level => extra_atk_value, blah blah}


So to create a hash that adds ATK power depending on level, I'd go:

Code:
class Game_Actor < Game_Battler

alias level_extra_atk base_atk

extra_atk = level_extra_atk
extra_atk = {1 => 5, 5 => 10, 10 => 15, 15 => 20, 20 => 25} # and so on
extra_atk.default = 0

  def base_atk
    return extra_atk[@level]
  end
end

If the character's level is 1, they'll get +5 Atk, if their level is 5 they'll get +10 Atk, etc.

Did I do it right?


EDIT: My post was messed up.
 
Prexus;257819 said:
Yes, but at level 2-4, they will have 0 ATK.

... Dang, you're right. They'll only get extra ATK on levels 1, 5, 10, 15, and 20. Any other level and they won't get ATK bonuses. I was trying to give them extra attack power every 5 levels.

Now you see why I asked if I've done it right. :P
 
Code:
class Game_Actor < Game_Battler

  alias level_extra_atk base_atk

  extra_atk = {
    [0, 1, 2, 3, 4] => 5,
    [5, 6, 7, 8, 9] => 10,
    [10, 11, 12, 13, 14] => 15, 
    [15, 16, 17, 18, 19] => 20, 
    [20, 21, 22, 23, 24] => 25
  } # and so on
  extra_atk.default = 0

  def base_atk
    n = level_extra_atk
    for key in extra_atk.keys
      next unless key
      return n + extra_atk[@level] if key.include?(@level)
    end
  end
end

Something like this might work. I think you could also setup the level numbers as a range instead of each individual number. So something like
{[0..4] => 5, [5..9] => 10, etc.}

but I'm not sure.
 
Prexus;257881 said:
Code:
class Game_Actor < Game_Battler

  alias level_extra_atk base_atk

  extra_atk = {
    [0, 1, 2, 3, 4] => 5,
    [5, 6, 7, 8, 9] => 10,
    [10, 11, 12, 13, 14] => 15, 
    [15, 16, 17, 18, 19] => 20, 
    [20, 21, 22, 23, 24] => 25
  } # and so on

I didn't know you can set up hashes that way, too (the brackets part). Cool, that looks handy.

Prexus;257881 said:
Something like this might work. I think you could also setup the level numbers as a range instead of each individual number. So something like
{[0..4] => 5, [5..9] => 10, etc.}

but I'm not sure.

I was wondering if there was a way to say if this_value through that_value, instead of each individual number like you said. I haven't tested these out yet but I think I've seen it done somewhere before.

By the way what does "next unless key" mean exactly? I can take a guess that "return n + extra_atk[@level] if key.include?(@level)" means return the value of n (extra_atk) if the character's level is somewhere in the brackets.
 

OS

Sponsor

'next' means skip the current run through the for loop and start the next one.
'unless key' means use the next command unless key has a value. If key is nil, next will activate, starting the next iteration through the loop. Let me know if that was too confusing.

Also, you don't need to put a range inside of []. Just use
hash = {range => value},

like this:

extra_exp = {0...4 => 5}

Remember that using two periods in a range means the second number won't be used, so 0..4 is just 0, 1, 2, and 3, while 0...4 is 0, 1, 2, 3, and 4. At least, I'm pretty sure that's how it works. Peace.
 
hmm let me take a go at this as I am having a bit of trouble understanding prexus's code

Code:
  def base_atk
    # Get Base Attack
    n = level_extra_atk
    # For Each Key
    for key in extra_atk.keys
      # Skip unless key is false or nil? (Confusing :-/)
      next unless key
      # Return value + extra if key includes the level
      return n + extra_atk[@level] if key.include?(@level)
    end
  end
I don't even think that will work since the keys are arrays and you are sending just the level into it It should be extra_atk[key] to get the value the next unless key line should be removed as it (by what I am thinking now) make the loop useless there also needs to be a return value for if the level is not defined

something like this should work

Code:
  def base_atk
    # Get Base Attack
    n = level_extra_atk
    # For Each Key
    extra_atk.each_key do |key|
      # Return value + extra if key includes the level
      return n + extra_atk[key] if key.include?(@level)
    end
    # Just in Case
    return n
  end

Well maybe if somewhere was really smart they would either

  1. Create a new class inheriting from Hash to allow multiple keys to refer to a value ex 1..4 links to 4, so that you won't have to set each value up individually like this {1 => 4, 2 => 4, 3 => 4, 4 => 4}
  2. Add a new method to the hash class to allow for reading in an array like I have shown above
  3. (Might be a bit silly) Turn the arrays as keys in the hash to individual keys
but well I am smart :p I'll edit this post with the method later (being as I like 2 the best) I may do one later but then you won't be about to use the hash literal to do create an object of this class

@OS you have it backwards .. means include endpoint ... means exclude enpoint
 
I'm learning so much, thank you guys! ^^

'kay, double-posting again, but I decided to ask this here rather than create another thread.

So now I know how hashes work. Now, can anyone please explain how do arrays work exactly? Things like ".push" and "some array = []" and stuff, too.
 
An array is more basic than a hash:
Code:
array = []  # new empty array
array.push(5)  # 5 added to array
array  # [5]
array << 6  # same as .push
array  # [5, 6]
array[1]   # 6
array[1] = 7
array  # [5, 7]

You may want to be more specific on your question :)
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top