Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Temas importantes
----------------------------------------
Páginas con recursos RPG Maker
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
Afiliados
Estadísticas
Tenemos 4133 miembros registrados.
El último usuario registrado es Neysersitoh.

Nuestros miembros han publicado un total de 84769 mensajes en 12064 argumentos.

[XP/VX/Ace] [Herramienta de Scripter] TableArray

Ver el tema anterior Ver el tema siguiente Ir abajo

[XP/VX/Ace] [Herramienta de Scripter] TableArray

Mensaje por Wecoc el 2016-08-24, 03:07

Pues sí, ahora hacía tiempo que no hacía un script loco de éstos.

Éste script es una reescritura no sustitutiva de la clase Table, pero ésta vez partiendo de una Array, de ahí su nombre TableArray. Se me ocurrió la idea tras beber vodka.

La clase Table, aunque cuesta un poco de ver cómo va al principio, es de las más simples estructuralmente y está muy limitada.
Ésta soporta 1, 2 o 3 dimensiones, y hay que definirles su tamaño previamente. Aunque ciertamente puede soportar de modo eficiente muchos más datos que la Array, en RPG maker difícilmente se llega a manipular tal cantidad de datos, por lo que apenas se aprecia esa mejora.

TableArray tiene dimensiones ilimitadas, solo hay que definir cuantas se usan al iniciar el objeto. A parte de esa mejora, soporta cambios de clase tales como pasar a array, a hash o a string (aunque éste último es bastante caótico). Puedes obtener el tamaño máximo actual de cada dimensión, lo que en table era xsize, ysize, zsize, ahora se usa size(dimensión) directamente, y se integró un nuevo total_size que es la interacción entre los tamaños de todas las dimensiones.

Código:

Código:
#==============================================================================
# ** [XP/VX/Ace] TableArray
#------------------------------------------------------------------------------
#  Author: Wecoc (no credits required)
#==============================================================================

class TableArray
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(dimension=1, default=nil)
    s = "" ; d = dimension
    d.times{ s.concat("[") }
    d.times{ s.concat("]") }
    @store = eval(s)
    @dimension = dimension
    @default = default
  end
  #--------------------------------------------------------------------------
  # * Default value (when nil)
  #--------------------------------------------------------------------------
  def default
    return @default
  end
  #--------------------------------------------------------------------------
  # * Define default value
  #--------------------------------------------------------------------------
  def default=(default)
    @default = default
  end
  #--------------------------------------------------------------------------
  # * Get dimension
  #--------------------------------------------------------------------------
  def dimension
    return @dimension
  end
  #--------------------------------------------------------------------------
  # * Get value
  #--------------------------------------------------------------------------
  def [](*args)
    r = "@store"
    for i in 0...args.size
      r.concat("[#{args[i]}]")
      if eval(r) == nil
        s = ""
        d = (@dimension - args.size)
        d.times{ s.concat("[") }
        d.times{ s.concat("]") }
        r = eval(s)
        r = @default if r == nil
        return r
      end
    end
    return eval(r)
  end
  #--------------------------------------------------------------------------
  # * Set value
  #--------------------------------------------------------------------------
  def []=(*args)
    r = "@store"
    for i in 0...(args.size - 1)
      r.concat("[#{args[i]}]")
      if eval(r) == nil
        s = ""
        d = (args.size - i - 1)
        d.times{ s.concat("[") }
        d.times{ s.concat("]") }
        eval("#{r} = #{s}")
      end
    end
    eval("#{r} = args[args.size - 1]")
    r = "@store"
    for i in 0...(args.size - 1)
      r.concat("[#{args[i]}]")
      if eval("#{r}.is_a?(Array) && #{r}.empty?")
        eval("#{r} = nil")
      end
    end
    return args[args.size - 1]
  end
  #--------------------------------------------------------------------------
  # * Get size for a specific dimension (d)
  #--------------------------------------------------------------------------
  def size(d=0)
    return nil if d > (@dimension - 1)
    return 0 if @store.join == ""
    return @store.size if d == 0
    s = 0
    a = []
    b = d-1
    loop do |k|
      for i in 0...d
        a[i] = 0 if a[i] == nil
      end
      r = ""
      avoid_check = false
      for i in 0...d
        r.concat("[#{a[i]}]")
        if eval("@store#{r}") == nil
          avoid_check = true
          break i
        end
      end
      if avoid_check == false
        s = [eval("@store#{r}.size"), s].max
      end
      a[b] += 1
      loop do |l|
        break l if b == 0
        r = ""
        avoid_check = false
        for i in 0...b
          r.concat("[#{a[i]}]")
          if eval("@store#{r}") == nil
            avoid_check = true
            break i
          end
        end
        if avoid_check == false
          if a[b] == eval("@store#{r}.size")
            b -= 1
            a[b] += 1
            a[b+1] = 0
          else
            break l
          end
        end
      end
      break k if a[0] == @store.size
    end
    return s
  end
  #--------------------------------------------------------------------------
  # * Get size of the TableArray
  #--------------------------------------------------------------------------
  def total_size
    s = 1
    for i in 0...@dimension
      s *= size(i)
    end
    return s
  end
  #--------------------------------------------------------------------------
  # * Get defined keys
  #--------------------------------------------------------------------------
  def keys
    k = []
    a = []
    d = @dimension
    b = d-1
    for i in 0...d
      a[i] = 0 if a[i] == nil
    end
    loop do |v|
      r = ""
      avoid_check = false
      for i in 0...d
        r.concat("[#{a[i]}]")
        if eval("@store#{r}") == nil
          avoid_check = true
          break i
        end
      end
      if avoid_check == false
        s = eval("@store#{r}")
        k.push(a.clone)
      end
      c = 0
      loop do |l|
        break l if b-c == 0
        if a[b-c] > self.size(b-c)
          for i in 0..c
            a[b-i] = 0
          end
          c += 1
          a[b-c] += 1
        else
          break l
        end
      end
      a[b] += 1
      break v if a[0] == self.size
    end
    return k
  end
  #--------------------------------------------------------------------------
  # * Get defined values
  #--------------------------------------------------------------------------
  def values
    v = []
    a = []
    d = @dimension
    b = d-1
    for i in 0...d
      a[i] = 0 if a[i] == nil
    end
    loop do |k|
      r = ""
      avoid_check = false
      for i in 0...d
        r.concat("[#{a[i]}]")
        if eval("@store#{r}") == nil
          avoid_check = true
          break i
        end
      end
      if avoid_check == false
        s = eval("@store#{r}")
        v.push(s)
      end
      c = 0
      loop do |l|
        break l if b-c == 0
        if a[b-c] > self.size(b-c)
          for i in 0..c
            a[b-i] = 0
          end
          c += 1
          a[b-c] += 1
        else
          break l
        end
      end
      a[b] += 1
      break k if a[0] == self.size
    end
    return v
  end
  #--------------------------------------------------------------------------
  # * Convert to array
  #--------------------------------------------------------------------------
  def to_a
    return @store
  end
  #--------------------------------------------------------------------------
  # * Convert to string
  #--------------------------------------------------------------------------
  def inspect
    return self.to_a.inspect
  end
  alias_method(:to_s, :inspect)
  #--------------------------------------------------------------------------
  # * Convert to hash
  #--------------------------------------------------------------------------
  def to_hash
    k = self.keys
    v = self.values
    h = {}
    for i in 0...k.size
      a = k[i]
      b = v[i]
      h[a] = b
    end
    return h
  end
end

Métodos:

Para iniciar una TableArray debes definir sus dimensiones, por defecto 3 como la Table normal:
Para los ejemplos crearé una de 5 dimensiones.

table = TableArray.new(5)

Tras hacer esto podemos definir un valor default, que por defecto vale nil. Es el valor cuando intentas obtener un valor en una ranura que no has definido.

p table.default # nil
table.default = 0
p table.default # 0


Podemos obtener la dimensión asignada.

p table.dimension # 5


Ahora vamos a lo más importante, definir y obtener valores. Se hace como con las Table.

table[0,0,0,0,0] = 5
table[0,0,0,0,1] = 10
table[0,0,0,2,2] = 15
table[0,0,1,0,3] = 20
table[0,1,0,0,4] = 25
table[0,1,0,0,5] = 30

p table[0,0,0,0,0] # 5


Luego podemos obtener el tamaño de una dimensión concreta y el total. Pongo en rojo el por qué de los valores que salen.

p table.size(0) # 1 *[0]
p table.size(1) # 2 *[0,1]
p table.size(2) # 2 *[0,1]
p table.size(3) # 3 *[0,1,2] pese a estar el 1 vacío
p table.size(4) # 6 *[0,1,2,3,4,5]

p table.size # 1 Equivale a size(0)
p table.total_size # 72 1 * 2 * 2 * 3 * 6 = 72


Podemos obtener las ranuras que hemos llenado con keys, y sus valores con values, tal como funcionan los Hash.

p table.keys # [[0,0,0,0,0],[0,0,0,0,1],[0,0,0,2,2],[0,0,1,0,3],[0,1,0,0,4],[0,1,0,0,5]]
p table.values # [5,10,15,20,25,30]


Convertir en array (to_a) y en string (to_s) no tiene demasiado interés puesto que simplemente devuelve la array interna de la clase, y la versión en String de lo mismo.
Algo más intuitivo es convertirlo a Hash, que junta las keys y values.

p table.to_hash # {[0,0,0,0,0]=>5,[0,0,0,0,1]=>10,[0,0,0,2,2]=>15,[0,0,1,0,3]=>20,[0,1,0,0,4]=>25,[0,1,0,0,5]=>30}
avatar
Wecoc
Administrador
Administrador



Créditos 9217

Gracias : 493

Volver arriba Ir abajo

Re: [XP/VX/Ace] [Herramienta de Scripter] TableArray

Mensaje por newold el 2016-08-24, 21:39

por qué usas texto para convertirlo en array después, no es más eficiente hacerlo todo en arrays?

@store = Array.new(Dimensiones) { Array.new }

y te ahorras los evals y conversiones entre texto y arrays
avatar
newold
Principiante
Principiante

0/3

Créditos 1096

Gracias : 71

Volver arriba Ir abajo

Re: [XP/VX/Ace] [Herramienta de Scripter] TableArray

Mensaje por Wecoc el 2016-08-24, 21:56

@store = Array.new(5) { Array.new } crea ésto [[],[],[],[],[]]

No es el mismo tipo de "dimensiones" de array multidimensional al que me refiero yo, dimensión 5 es [[[[[]]]]]. Al fin y al cabo son números sepultados en claudátors, con una soledad nunca vivida hasta ahora por un número (?) Por eso creí que lo más compatible para trabajar con eso era con strings "[" (x 5), "]" (x 5) y luego releer esa string con eval.

Está hecho así para que la info sea básicamente los números sí modificados, los entremedios no modificados siguen sin construirse si no es necesario (así se ahorra mucho proceso), éstos valen nil y se leen con el valor default directamente. El inconveniente es que si intentas leer la array en sí es muy liado/caótico, por eso creé la posibilidad de leer los keys y values, que es mucho más intuitivo.

Aquí la table del ejemplo:



No digo que los evals sea la única forma, pero a mí me pareció justificado usarla así xD

PD.- También quise añadir un default_proc similar al de Hash pero consideré que en éste caso hubiera sido un lío horrible así que deseché la idea y dejé el default como un valor único.
avatar
Wecoc
Administrador
Administrador



Créditos 9217

Gracias : 493

Volver arriba Ir abajo

Re: [XP/VX/Ace] [Herramienta de Scripter] TableArray

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.