Cristalab

Almacenar matrices binarias en ActionScript

Por: HernanRivas + 29.06.2008

Recientemente, tuve que hacer un editor de AIR que generara XMLs para un videojuego. El problema que tuve es que el tamanio de los archivos generados era bastante grande. Esto se debe a que el juego necesita decenas de matrices de un arbitrariamente grandes donde las casillas pueden estar ocupadas o no (de ahora en adelante voy a llamar a esta estructura mapa booleano).

La solución que se me ocurrió fue guardar la información empleando los códigos de las letras.

Básicamente, si tengo un mapa como este:

0010100
0010100
0011100
0010100
0010100

Podría almacenarlo de la siguiente manera:

00101000010100001110000101000010100

Pero eso es poco practico. Así que opte por aprovechar la forma en la que las computadoras almacenan los caracteres.

Supongamos la @, cuyo código es el 64. En binario, 01000000, lo que es idéntico a un mapa booleano de 8 casilleros.

Para este momento, ya tenemos la idea principal. Podemos guardar uno de estos mapas booleanos usando 8 veces menos caracteres (esto, en el mejor de los casos, si la cantidad de casillas no es múltiplo de 8 nos sobran algunos bits, pero no es nada grave).

Volviendo al ejemplo anterior, el mapa booleano que contiene esa información, se puede almacenar como: )QâC? Lo que es un considerable ahorro de espacio.


Manos a la obra entonces, los algoritmos que emplee son los siguientes. Aunque lógicamente hay lugar para la optimización, hacen su trabajo correctamente. En este caso no me preocupe demasiado por la velocidad, simplemente no es necesario. Quizá en alguna aplicación donde hagamos esto en tiempo real lo sea, pero no se me ocurre ninguna.

Código :


public static function toString (map:Array):String
{
   var tempArray:Array = new Array ();
   var finalString:String = "";
   
   var l:int = map.length;
   for (var i:int = 0; i < l; i++)
   {
      tempArray.push (int (map[i]));
      if (tempArray.length >= 8)
      {
         finalString += String.fromCharCode (binaryArrayToDecimal (tempArray) + 1);
         tempArray = new Array ();
      }
   }
   while (tempArray.length < 8)
      tempArray.push (0);
   
   finalString += String.fromCharCode (binaryArrayToDecimal (tempArray));
   return finalString;
}

private static const zeroes:String = "00000000";
public static function toArray (string:String):Array
{
   var map:Array = new Array ();
   var tempString:String;
   
   var l:int = string.length;
   for (var i:int = 0; i < l; i++)
   {
      tempString = (string.charCodeAt (i) - 1).toString (2);
      tempString = zeroes.substr (0, 8 - tempString.length) + tempString;
      
      for (var j:int = 0; j < 8; j++)
         map.push (tempString.charAt (j));
   }
   
   for (i = 0; i < l; i++)
      map[i] = int (String (map[i]));
   
   return map;
}

private static function binaryArrayToDecimal (arr:Array):int
{
   var finalNumber:int = 0;
   var l:int = arr.length;
   for (var i:int = 0; i < l; i++)
      finalNumber = finalNumber * 2 + arr[i];
   
   return finalNumber;
}

Etiquetas actionscript

Comentarios | Enviar un comentario
Buen Tip Hernan, muy útil Guiño
Por: Zguillez
Muy bueno hernán, otra opción, es convertirlos en hexadecimal. Guardarias numeros hexadecimales, y también se reduciría el tamaño. Aunque en tamaño, tu forma es mas óptima, ya que ocupa un caracter, en hexadecimal, se ocuparían dos caracteres para un bloque de 8.
Por: Dano
Muy util che.

cuando le ponen las variasbles y clases en inglés me confundo con las palabras del lenguaje Riendo
Por: danyrik-blog
brillante sin palabras
Por: j3g-blog
quero aprender de las matematicas y luego conpetir con otros colegios
Por: fernando-blog
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.