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.

MultiArray

MultiArray Version: 2.2
By: Neo-Bahamut

Introduction

I think most of you scripters know what a Table and an Array is, right?
Both have advantages and disadantages. Tables can only hold Integers and Arrays have only one dimension.
This script creates the MultiArray class which is like an Array but can have any number of dimensions.

Methods:
  • MultiArray.new(D1, D2, D3, D4...) (creates a new MultiArray)
  • [1, 2, 3, 4] (returns the value at that position)
  • [1, 2, 3, 4] = object (sets the value at that position to object)
  • .fill(object[, duplicate = true]) fills each position with object. If duplicate is true, the .dup method of object is called evertime
  • all methods of Enumerable

Script

Code:
#============================================================================

# ** MultiArray

#----------------------------------------------------------------------------

# Neo-Bahamut

# V 2.4

# 23.06.2009

#============================================================================

 

 

#=============================================================================

# ** MultiArray

#-----------------------------------------------------------------------------

#  Some kind of Table-Array-Fusion.

#=============================================================================

class MultiArray

  

  include Enumerable

  

  SizeError      = Exception.new("Too large amount of data.")

  CopyError      = Exception.new("Object can not be duplicated.")

  RangeError     = Exception.new("Index out of Range.")

  

  #--------------------------------------------------------------------------

  # * Initialization

  #--------------------------------------------------------------------------

  def initialize(*args)

    @sizes = args

    size = 1

    args.each {|n| size *= n}

    if size.is_a?(Bignum)

      raise SizeError

    end

    @array = Array.new(size)

  end

  

  #--------------------------------------------------------------------------

  # * Gets an element.

  #--------------------------------------------------------------------------

  def [](*args)

    raise RangeError if args.size > @sizes.size

    args.each_index {|n| if args[n] >= @sizes[n] then raise RangeError end}

    index = 0

    for n in 0...args.size

      i = args[n]

      for m in [email=0...@sizes.size]0...@sizes.size[/email]

        break if m >= n

        i *= @sizes[m]

      end

      index += i

    end

    return @array[index]

  end

  

  #--------------------------------------------------------------------------

  # * Changes an element.

  #--------------------------------------------------------------------------

  def []=(*args)

    object = args.pop

    raise RangeError if args.size > @sizes.size

    args.each_index {|n| if args[n] >= @sizes[n] then raise RangeError end}

    index = 0

    for n in 0...args.size

      i = args[n]

      for m in [email=0...@sizes.size]0...@sizes.size[/email]

        break if m >= n

        i *= @sizes[m]

      end

      index += i

    end

    @array[index] = object

  end

  

  #--------------------------------------------------------------------------

  # * Method description

  #     obj: The Object the Array will be filled with.

  #     dup: If true, obj is duplicated for each tile

  #--------------------------------------------------------------------------

  def fill(obj, dup = true)

    begin

      for n in [email=0...@array.size]0...@array.size[/email]

        i = dup ? obj.dup : obj

        @array[n] = i

      end

    rescue

      raise CopyError

    end

  end

  

  #--------------------------------------------------------------------------

  # * Iterates for each element.

  #--------------------------------------------------------------------------

  def each(&block)

    @array.each(&block)

  end

  

end

Instructions

Code:
marray = MultiArray.new(1, 2, 3)

marray[1, 2, 2] = 1

p marray[1, 2, 2] # => 1

MultiArrays have a fixed size as Tables. They also can't be too big (too big means each size multiplicated is a Bignum)

FAQ

Nothing asked

Compatibility

Should be compatibel with anything that doesn't make a MultiArray-class

Terms and Conditions

I think this will be only used for writing scripts and not just be put into a game ;D
So if you use this as a help for your script, please write me with you in the Credits (or at least to "Thanks")
If somebody uses a script which uses this one, please add me too to your credits.
 
Neo-Bahamut":3b1kpqq8 said:
MultiArray Version: 2.2
By: Neo-Bahamut

Introduction

I think most of you scripters know what a Table and an Array is, right?
Both have advantages and disadantages. Tables can only hold Integers and Arrays have only one dimension.
This script creates the MultiArray class which is like an Array but can have any number of dimensions.

Methods:
  • MultiArray.new(D1, D2, D3, D4...) (creates a new MultiArray)
  • [1, 2, 3, 4] (returns the value at that position)
  • [1, 2, 3, 4] = object (sets the value at that position to object)
  • .fill(object[, duplicate = true]) fills each position with object. If duplicate is true, the .dup method of object is called evertime
  • all methods of Enumerable

Script

Code:
#============================================================================

# ** MultiArray

#----------------------------------------------------------------------------

# Neo-Bahamut

# V 2.2

# 23.05.2009

#============================================================================

 

 

#=============================================================================

# ** MultiArray

#-----------------------------------------------------------------------------

#  Some kind of Table-Array-Fusion.

#=============================================================================

class MultiArray

  

  include Enumerable

  

  SizeError      = Exception.new("Too large amount of data.")

  CopyError      = Exception.new("Object can not be duplicated.")

  RangeError     = Exception.new("Index out of Range.")

  

  #--------------------------------------------------------------------------

  # * Initialization

  #--------------------------------------------------------------------------

  def initialize(*args)

    @sizes = args

    size = 1

    args.each {|n| size *= n}

    if size.is_a?(Bignum)

      raise SizeError

    end

    @array = Array.new(size)

  end

  

  #--------------------------------------------------------------------------

  # * Gets an element.

  #--------------------------------------------------------------------------

  def [](*args)

    args.each_index {|n| if args[n] >= @sizes[n] then raise RangeError end}

    index = 0

    for n in 0...args.size

      i = args[n]

      for m in [email=0...@sizes.size]0...@sizes.size[/email]

        break if m >= n

        i *= m

      end

      index += i

    end

    return @array[index]

  end

  

  #--------------------------------------------------------------------------

  # * Changes an element.

  #--------------------------------------------------------------------------

  def []=(*args)

    object = args.pop

    args.each_index {|n| if args[n] >= @sizes[n] then raise RangeError end}

    index = 0

    for n in 0...args.size

      i = args[n]

      for m in [email=0...@sizes.size]0...@sizes.size[/email]

        break if m >= n

        i *= @sizes[m]

      end

      index += i

    end

    @array[index] = object

  end

  

  #--------------------------------------------------------------------------

  # * Method description

  #     obj: The Object the Array will be filled with.

  #     dup: If true, obj is duplicated for each tile

  #--------------------------------------------------------------------------

  def fill(obj, dup = true)

    begin

      for n in [email=0...@array.size]0...@array.size[/email]

        i = dup ? obj.dup : obj

        @array[n] = i

      end

    rescue

      raise CopyError

    end

  end

  

  #--------------------------------------------------------------------------

  # * Iterates for each element.

  #--------------------------------------------------------------------------

  def each(&block)

    @array.each(&block)

  end

  

end

Instructions



FAQ

Nothing asked

Compatibility

Should be compatibel with anything that doesn't make a MultiArray-class

Terms and Conditions

I think this will be only used for writing scripts and not just be put into a game ;D
So if you use this as a help for your script, please write me with you in the Credits (or at least to "Thanks")
If somebody uses a script which uses this one, please add me too to your credits.

Ruby support multi-dimensional arrays..

array2d = [][]
array2d[1][2] = 3
print array2d[1][2]
Output: 3
 

Zeriab

Sponsor

If you want to put restrictions then encapsulating the multiarray in a class can be a good idea.
A perfect example of this is the Matrix class which is available for requiring in the standard ruby distribution. It's not available in XP/VX. The matrix is basically a 2-dimensional array with certain restrictions and loads of auxiliary methods.

The array[0,4,5] = 3 has the advantage of one being able to do array[*args] = 3.
Basically if you have a code which can deal with an arbitrary number of dimensions there can be an advantage.

I get an illegal argument error when trying to run the code nowayskill shows:
[ruby]array2d = [][]
[/ruby]
It may work in another version, but not in version 1.8.1, i.e. the version of Ruby used in RMXP. (I believe also VX uses 1.8.1)
I doubt it since [] creates an array and [][] complains about lack of arguments for the look-up method call. I.e. [][0] #=> nil. [][] #=> Argument error
So it appears that Ruby does not have support for multi-dimensional arrays in terms of syntactic sugar.

@Neo-Bahamut:
The script at hand can be described as a function which maps a number of arguments for an n-dimensional table onto a single array. The size must be known when creating the array.
You should make a note telling that the array can only hold up to a Fixnum number of elements since its a restriction you enforce.
You definitely tell that the dimensions are fixed. I.e. you cannot change the size of a MultiArray after having created it. You have some nice error catching after all ^_^
I would suggest also checking for if args.size == @sizes.size

*hugs*
 
@nowayskill & rey meustrus: As Zeriab said, RGSS/Ruby 1.8.1 does not have this method.

The script at hand can be described as a function which maps a number of arguments for an n-dimensional table onto a single array. The size must be known when creating the array.
You should make a note telling that the array can only hold up to a Fixnum number of elements since its a restriction you enforce.
You definitely tell that the dimensions are fixed.
Sorry, I don't really understand you. Do you mean I should add a How-to-use in the beginning?
(my english is bad recently ^^")

I wanted to add the feature that you can change the sizes but then I noticed that I'd have to define @array new every time and calculate the new positions. And I was to lazy to think about an algorithm which workd :D

I would suggest also checking for if args.size == @sizes.size
Added. Well... I hope you meant this ^^"
 

Zeriab

Sponsor

No I didn't mean that you should add a How-to-use.
I am suggestion that you add something like:
Like a Table the size of a MultiArray is fixed.

You understood my args.size == @sizes.size suggestion correction ^_^
 
Actually, for a 2d array, just do:

array = [[],[]]
array[0][0] = 2
p array[0][0]

But yes, this is pretty cool. It's probably better than what i just said.
 
@ Near: And your method requires more memory.
I tested one Array (500*500*500) and an Array with 500 Arrays in it and each of that Arrays had a Array (500) in it too.
The single big one requires about 95 MB and the large number of Arrays 123 MB
 
marray = MultiArray.new(1, 2, 3)
marray[1, 2, 2] = 1
p marray[1, 2, 2] # => 1

I just copy the script and test this and get me an Range Exception error in line 60.
Library=RGSS102J.dll
 
Mmmm
I changued it to:

marray = MultiArray.new(4, 5, 6)
marray[1, 2, 2] = 1
print marray[1, 2, 2] # => 1

But i have a new problem, print tells me that 1,2,2 is nill. I'm missing something?
 
Oh, yeah...
There was a bug in the script ^^"
I will update the first post (also because the script seems to be destroyed through the forum change)
 

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