Pioneras de la programación

«Deberíamos pensar en internet como una escuela a la que muchas chicas como nosotras nunca tuvieron la ocasión de asistir, utilizándola precisamente para superar el miedo de no ser lo bastante guapas, lo bastante cultas, lo bastante fuertes, lo bastantes bellas, lo bastante despiertas o lo que sea. puede que las mujeres no sean tan buenas en la batalla física, pero de lo que estoy segura es que son buenísimas tecleando como una ráfaga de metralleta.»

Esta frase es de Jude Milhon, autora fundamental en la cultura hacker y una de las madres del término y género cyberpunk.

En su día, con motivo de la muerte del genial Dennis Ritchie, incidía en que en la mitología creada alrededor de la informática el sistema prefiere resaltar a los empresarios por encima de a los perfiles más técnicos, a pesar de que estos últimos sean los verdaderos artífices de la innovación y la genialidad. Pero el capitalismo necesita mitos para sostenerse, y los millones de Gates, Jobs y Zuckerberg son más vendibles que las aportaciones técnicas de Torvals, Berners-Lee y Ritchie o que las de todas estas señoras de las que hablaremos a continuación. La verdad es que entre los billonarios tecnológicos no hay mucha presencia femenina, como si la hay entre las grandes mentes de este campo.

Ya en el siglo XIX, la matemática Augusta Ada Byron (hija de Lord Byron, poeta esencial en el romanticismo británico), condesa de Lovelace, nos avanzó múltiples conceptos de la computación y la informática en su trabajo sobre la máquina analítica de Charles Babbage. Originalmente se consideró qúe Ada sólo fue la traductora del trabajo del ingeniero italiano Luigi Menabrea, pero posteriormente se comprobó que la matemática inglesa había añadido las notas fundamentales a este trabajo para darle consistencia, definiendo conceptos como subrutina o análisis antes incluso de la existencia del ordenador y del concepto «software».

La contribución de Ada Lovelace puede parece muy «primitiva» por haberse dado en una etapa que podríamos describir como «prehistoria de la informática» , pero inspiraría años después a otra mujer fundamental en la historia de la informática, la estadounidense Grace Hopper. Durante la II Guerra Mundial ingresó en el ejército estadounidense, tras haberse doctorado en matemáticas en Yale. La marina la destinó a Harvard para que trabajase en el Mark I de IBM, y allí desarrolló FLOW-MATIC, el primer lenguaje de programación de alto nivel, creando posteriormente A-0 y B-0, los primeros compiladores. Fuera de su trabajo en el ejército (se mantuvo años en la reserva naval, volviendo puntualmente para trabajos con el ejército hasta su jubilación en 1986, con el rango de contraalmirante y siendo en ese momento la oficial de más edad de las fuerzas armadas estadounidenses) llevó los conceptos de FLOW-MATIC, un lenguaje de programación que utiliza palabras clave en inglés para facilitar su comprensión, a un lenguaje de uso empresarial: el popular COBOL. Posteriormente también fue parte del comité de estandarización del lenguage Fortran. Como curiosidad, bastante paradójica, ganó el premio a Hombre del Año en Ciencias de la Computación de la AITP.

Grace Hopper en 1952

Casi contemporáneamente a Hopper, en el desarrollo de ENIAC, el primer superordenador de propósito general, trabajaron como programadoras un grupo de mujeres, las cuales contaban con la dificultad de tener que trabajar sin manuales ni referencias, teniendo que desarrollar su propio método para programar. Para la historia siempre quedaron los nombres de John Mauchly y John Eckert, los ingenieros desarrolladores del hardware, mientras que Betty Snyder Holberton, Jean Jennings Bartik, Kathleen McNulty Mauchly Antonelli, Marlyn Wescoff Meltzer, Ruth Lichterman Teitelbaum y Frances Bilas Spence permanecieron en el anonimato, e incluso durante años hubo quien afirmó que se trataba de modelos que sólo posaban para la foto, despreciando su papel fundamental para el funcionamiento de la máquina.

Programadoras del ENIAC

La primera mujer en recibir un doctorado en Ciencias de la Computación, y realmente una de las primeras dos personas en recibirlo pues lo consiguieron a la vez, fue la hermana Mary Kenneth Keller. Sí, hermana en el sentido religioso, la Dra. Keller había tomado los votos con 19 años uniéndose a las Hermanas de la Caridad de la Beata Virgen María, dedicando posteriormente su vida a la ciencia y la ingeniería, licenciándose en matemáticas en 1943, obteniendo el master en matemáticas y física en 1953 y finalmente siendo nombrada doctora en Ciencias de la Computación en 1965. Antes de ese logro académico formó parte del grupo de investigación de la Universida de Dartmouth que trabajaría en el desarrolo del lenguaje BASIC, una de las familias de lenguajes de programación más extendidas e importantes.

Mary-Kenneth-Keller-780x583

Tampoco sería justo olvidar a Margaret Hamilton, que fue la creadora del término Ingeniería del Software cuando trabajaba en la NASA nada menos que en el proyecto del Apollo XI, así que si has visto el meme de cómo una nave con el hardware de una lavadora llegó a la luna fue esta señora quien dirigió la creación del software que ejecutaba. Aunque su aportación al proyecto Apollo sea lo más llamativo y famoso seguramente en el día a día su importancia sea mayor por sus aportaciones en los inicios de la programación asíncrona, el procesamiento multi-hilo o la técnica de control de fallos conocida como End-To-End Testing.

800px-Margaret_Hamilton_-_restoration

Como decía al principio, en la historia de la informática, en los últimos años, se ha resaltado más el papel de aquellos que triunfaron en el campo económico y se ha relegado al ostracismo a los perfiles más técnicos, dejando en muchos casos a estas pioneras olvidadas de forma intencional. ¿Puede ser esto la causa de que a día de hoy haya más hombres interesados en la programación que mujeres? Tal vez sea más necesario que nunca reivindicar a estas pioneras, en lugar de a hipsters que se hicieron millonarios a base de vender teléfonos fabricados por obreros explotados en Asia.

El patrón Observer y su implementación en PHP

Volvemos con el tema de los patrones de diseño y PHP, que estaba abandonado (y ahora tengo más tiempo para escribir con el parón temporal del podcast). Esta tarde vamos a hablar del patrón Observer, que en castellano es conocido como el patrón publicación-inscripción.

La idea de este patrón es que nos permita definir una dependencia uno-a-muchos entre varios objetos, provocando que cuando uno cambie de estado se lo notifique a sus objetos dependientes. El objetivo de este patrón es reducir el acoplamiento entre clases que requieren mantener una gran consistencia en sus relaciones, siendo clave para la implementación del patrón MVC. Dentro de esta relación denominamos Sujeto al objeto que emite la información sobre el cambio de estado, y Observador al que la recibe para realizar la acción que sea necesaria.

Os dejo esta imagen con un diagrama cargado desde la Wikipedia para ilustrar su funcionamiento:

Diagrama Estructura Patrón Observer
Un diagrama de estructura del patrón Observer (publicación-inscripción).

En PHP 5, a partir de la revisión 5.1 contamos con las interfaces SplSubject y SplObserver para implementar respectivamente el sujeto y el observador.

Vamos con un ejemplo clásico: una tienda on-line que notifica la compra y la venta de un artículo.

<?php
class Articulo implements \SplSubject /*Empezamos importando la interfaz del sujeto*/
{
    protected $storage;

    public function __construct(\SplObjectStorage $storage)
    {
        $this->storage = $storage;
    }

    public function compra()
    {
        // compra
        $this->notify('comprado');
    }

    public function vende()
    {
        // vende
        $this->notify('vendido');
    }

    public function attach(\SplObserver $observer)
    {
        $this->storage->attach($observer);
    }

    public function detach(\SplObserver $observer)
    {
        $this->storage->detach($observer);
    }

    public function notify($event = '')
    {
        foreach ($this->storage as $observer)
            $observer->update($this, $event);
    }
}

class Notify implements \SplObserver /*seguimos con lai implementacion del observer*/
{
    public function update(\SplSubject $subject, $event = '')
    {
        if ($event == 'comprado')
            echo 'El artículo se ha comprado' . PHP_EOL;
        else if ($event == 'vendido')
            echo 'El artículo se ha vendido' . PHP_EOL;
    }
}

/*¿Cómo luciría llevado a la práctica?*/

/*Creamos el objeto*/
$articulo = new Articulo(new \SplObjectStorage());
/*vinculamos el artículo al observer*/
$articulo->attach(new Notify()); 
/*imprimiría en pantalla que se ha comprado*/
$articulo->compra();
/*imprimiría que se ha vendido*/ 
$articulo->vende(); 
?>

Es una idea básica donde simplemente se imprime en pantalla el resultado de una acción, pero ya os hacéis una idea de las posibilidades de este patrón.

jPage: Plugin de jQuery para paginación

Tras las comida con el $Hyperboss me ha comentado que reunión a las 7… así que forzado a salir más tarde hoy voy a alargar la pausa de la comida para dedicaros una entradilla corta, hablando de un interesante plugin de jQuery llamado jPage, que permitirá paginar listas desdde el lado del cliente. Creado por Luís Almeida os lo podéis descargar desde su página en gitHub donde encontraréis también referencias a los útiles (y perfectamente complementarios) plugins Lazy Load, para aligerar la carga de imágenes, y animate.css con varias vistosas animaciones.

Os copio el código de ejemplo de como iría la cosa con la versión «default» del plugin:

El html sería:

<!-- navigation holder -->
<div class="holder">
</div>

<!-- item container -->
<ul id="itemContainer">
    <li><img src="img/img (1).jpg" alt="image"></li>
    <li><img src="img/img (2).jpg" alt="image"></li>
    <li><img src="img/img (3).jpg" alt="image"></li>
     ...<!--aquí metéis las imágenes que hagan falta-->
</ul>

<!-- navigation holder -->
<div class="holder">
</div>

El javascript es apena intrusivo y muy cortito:

/* when document is ready */
  $(function() {
    /* initiate plugin */
    $("div.holder").jPages({
        containerID: "itemContainer"
    });
});

Y para finalizas el CSS sería este:

 .holder {
    margin:15px 0;
}
.holder a {
    font-size:12px;
    cursor:pointer;
    margin:0 5px;
    color:#333;
}
.holder a:hover {
    background-color:#222;
    color:#fff;
}
.holder a.jp-previous {
    margin-right:15px;
}
.holder a.jp-next {
    margin-left:15px;
}
.holder a.jp-current,a.jp-current:hover {
    color:#FF4242;
    font-weight:bold;
}
.holder a.jp-disabled,a.jp-disabled:hover {
    color:#bbb;
}
.holder a.jp-current,a.jp-current:hover,.holder a.jp-disabled,a.jp-disabled:hover {
    cursor:default;
    background:none;
}
.holder span {
    margin: 0 5px;
}

Podéis ver el resultado, junto al código original en este enlace. Además, podréis ver muchas más interesantes opciones para personalizarlo e implementarlo en vuestra página.

A mi me ha ahorrado un rato largo de trabajo esta mañana. Disfrutadlo.

Piedra-papel-tijera en Ruby

Un pequeño ejercicio de Ruby que he tenido que hacer en el curso de SaaS de Berkeley (en EdX) es un método que «juegue» al tres en raya. Recibiendo un array bidimimensional (la variable game en el ejemplo) debe devolver el resultado de qué jugador sería el ganador. Si hay más de dos jugadores devuelve una excepción, y si alguno mete una letra que no sea R (rock), P (paper), S (scissors) lanza otra excepción (ambas vienen ya dadas en el código de ejemplo). Finalmente, si ambos sacan lo mismo da como ganador al jugador 1 (¿por qué? pues porque es lo que pide el enunciado a reclamarle al maese armero)

En fin, el código sería tal que así:

class WrongNumberOfPlayersError < StandardError ; end
class NoSuchStrategyError < StandardError ; end

def rps_game_winner(game)
  raise WrongNumberOfPlayersError unless game.length == 2
  game[0][1] = game[0][1].downcase
  game[1][1] = game[1][1].downcase
  raise NoSuchStrategyError if game[0][1] != 'r' and game[0][1] != 'p' and game[0][1] != 's'
  raise NoSuchStrategyError if game[1][1] != 'r' and game[1][1] != 'p' and game[1][1] != 's'
  ganador = 0
  if game[0][1] == 'r'
   if game[1][1] == 'r'
   elsif game [1][1] == 'p'
   ganador = 1
   else
   end
  elsif game[0][1] == 'p'
   if game[1][1] == 'r'
   elsif game [1][1] == 'p'
   else
   ganador = 1
   end
  else
   if game[1][1] == 'r'
   ganador = 1
   elsif game [1][1] == 'p'
   else
   end
  end
  return game[ganador]
end

La chicha viene con la segunda parte del ejercicio, el modo tournament. Este recibe un array de arrays bidimensionales con todos los enfrentamientos (hay que suponer que están bien formados y bien anidados, y debe permitir cualquier cantidad de jugadores, siempre que crezcan en progresión de potencias de 2: 4,8,16,32… piensa el cualquier Play off de cualquier deporte) y los recorre como una eliminatoria. Ponen como ejemplo que reciba algo tal que así:

[
    [
        [ ["Armando", "P"], ["Dave", "S"] ],
        [ ["Richard", "R"],  ["Michael", "S"] ],
    ],
    [
        [ ["Allen", "S"], ["Omer", "P"] ],
        [ ["David E.", "R"], ["Richard X.", "P"] ]
    ]
]

Ok, ¿qué hacer frente al anidamiento? Pues recursividad, tema que ya explicamos. En este caso, el método comprobará que cada array a su vez contenga un array y si es así vuelve a llamarse a si mismo hasta que llegue a un enfretamiento, donde entonces llamará al método de la primera parte para devolver al ganador.

def rps_tournament_winner(tournament)
  if tournament[0][0].kind_of?(Array)
       rps_game_winner([rps_tournament_winner(tournament[0]), rps_tournament_winner(tournament[1])])
  else
   rps_game_winner(tournament)
  end
end

Y con esto y un bizcocho, ejercicio realizado. Lo he enviado y ya está corregido, y me ha dado el 100%, así que espero que os aclare las dudas. (Como dice un colega mío «no me copiar, me cago en Satán»… en fin, o sí, que yo tampoco soy ni profesor ni vuestro padre). En todo caso veis que con la recursividad un simple if/else resuelve toda la carga de trabajo en cinco líneas (bueno, realmente dos)

Número aleatorios en C

No es tan extraño verse en la situacion de tener que generar números aleatorios en C. Mi primer programa en C no «académico» era un programilla de consola que generaba fichas de PNJ’s aletorios para Runequest. Elegías una criatura y un «nivel» (criatura flojilla, del montón, poderosa y fuckin’ master) y te mostraba sus características mediante números aleatorios. No es muy habitual que en un programa corporativo o una aplicación del sistema tengamos que usar números aleatorios, pero sí lo puede ser a la hora de programar un juego, una aplicación de sonido (lista de reproducción aleatoria, algún efecto se sonido psicodélico) o una para tratar imágenes (para un filtro artístico).

La función rand() nos devuelve un número entre 0 y el número más alto que pueda generar el sistema. Como lo habitual es que no queramos un rango tan alto, podemos reducirlo utilizando la operación de módulo. Por ejemplo, para obtener un número entre 0 y 10 haríamos x = rand() % 11, y para uno entre 0 y 100 x = rand() % 101.

Si te estás parando a leer esto supongo que tienes ciertas inquietudes al respecto de la programación, por lo que ya sabes que el ordenador no puede inventarse un número al azar. Hasta la actualidad (y por suerte, como sabemos todos los amantes del género cyberpunk) los ordenadores no pueden crear por si mismos. Para la generación de valores aleatorios se necesita pasarle un valor a la función rand() que funcione como semilla, un primer número que permita generar el resto a partir de él. Usando un valor constante el programa siempre generaría los mismos valores, así que la raíz tiene que ser algo cambiante. Una opción suele ser coger el número de proceso del sistema (tiene un fallo, porque si haces varias llamadas a la función principal sin cerrar el programa será como usar una constante), aunque lo mejor suele ser coger los datos del reloj del sistema, ya que al ir ajustado hasta la milésima de segundo es muy poco probable que se coja el mismo valor dos veces seguidas. Para definir la semilla utilizaremos la función srand(), pasándole como parámetro la función time().

Para usar las funciones rand() y srand() debes incluir la librería stdlib en la cabecera de tu proyecto, y para time() la librería time. En el siguiente ejemplo podréis ver cómo generar aleatoriamente un número entre 6 y 12.

#include stdio.h
#include stdlib.h
#include time.h

main(){
int numero; // el número a imprimir

srand(time(0));
numero = (rand() % 7)+6;

printf("El número a imprimir es %d\n",numero);

}

Punteros en C

Uno de los conceptos más complejos del lenguaje C, por lo abstracto de los mismos, es el de los punteros. Su principal utlidad está en que nos permiten hacer una asignación dinámica de memoria.

Un puntero realmente no es más que una dirección de memoria, que normalmente lleva asociado un tipo de datos. Por ejemplo un puntero a entero, que será una dirección de memoria donde podemos almacenar un entero. Para designar un puntero sólo tenemos que poner, en la declaración, un asterisco (*) entre el nombre de la variable y el tipo de datos, tal que así:

int *primero; //declaramos un puntero a entero
int* segundo; //el asterisco puede ir en cualquiera de los dos lados
float *tercero; //y podemos declarar flotantes, caracteres, ficheros...

Para reservar la memoria necesaria utilizaremos la función malloc, abreviatura de memory allocation, pasando como parámetros el tamaño que queremos reservar. La función sizeof() nos puede ayudar mucho, ya que por ejemplo sizeof(int) nos devolverá el tamaño de un entero. Ojea este ejemplo, donde decimos que en la dirección apuntada por el puntero primero vamos a guardar la cantidad de enteros definida en la variable cantidadX:

primero = (*int) malloc(cantidadX*sizeof(int));

Para usar malloc debemos incluir la librería stdlib.h al principio del código. Después de usar malloc se debe usar free para liberar la memoria asignada dinámicamente.

El siguiente es un ejemplo del manual de introducción a C de Nacho Cabanes que ilustra un poco todo esto:

/*---------------------------*/ 
/*  Ejemplo en C nº 73:      */ 
/*  c073.c                   */ 
/*                           */ 
/*  Manejo básico de         */ 
/*  punteros                 */ 
/*                           */ 
/*  Curso de C,              */ 
/*    Nacho Cabanes          */ 
/*---------------------------*/ 
 
#include <stdio.h> 
#include <stdlib.h> 
 
main() { 
  float n1;           /* Primer número, estático */ 
  float *n2, *suma;   /* Los otros dos números */       
   
  n1 = 5.0;           /* Damos un valor prefijado a n1 (real) */ 
  n2 = (float *) malloc (sizeof(float)); /* Reservamos espacio para n2 */ 
  *n2 = 6.7;          /* Valor prefijado para n2 (puntero a real) */ 
   
  suma = (float *) malloc (sizeof(float)); /* Reservamos espacio para suma */ 
  *suma = n1 + *n2;   /* Calculamos la suma */ 
   
  printf("El valor prefijado para la suma era %4.2f\n", 
    *suma); 

printf("Ahora es tu turno: Introduce el primer número "); 
  scanf("%f",&n1);   /* Leemos valor para n1 (real) */ 
   
  printf("Introduce el segundo número "); 
  scanf("%f",n2);    /* Valor para n2 (puntero a real) */   
 
  *suma = n1 + *n2;  /* Calculamos nuevamente la suma */ 
   
  printf("Ahora la suma es %4.2f\n", *suma); 
 
  free(n2);          /* Liberamos la memoria reservada */ 
  free(suma); 
} 

A la hora de meternos en la aritmética de punteros cabe destacar que, en estos casos, los operadores unarios de incremento y decremento no funcionan como una variable estática. Por ejemplo, si tenemos un puntero i y ejecutamos i++, el valor de i no se incrementará en uno, lo que ocurrirá es que la dirección a la que apunta el puntero se incrementará, apuntando hacia el siguiente elemento (Por ejemplo, si i es un entero y apunta a la posición 1000, i++ le hará apuntar a la posición 1004 en un sistema de 32bits, donde un entero ocupa 4bytes). Si queremos incrementar el valor almacenado en el puntero i debemos acceder a él, por lo que deberíamos haber usado (*i)++. Hay que tener cuidado con esto, porque si movemos accidentalmente la posición del puntero podríamos apuntar a una posición de memoria sin reservar que haga romper el programa.

En la página de Nacho Cabanes que os cité antes, y de la que saqué el ejemplo, tenéis un manual muy bueno y claro de introducción a C. No dudéis en descargarlo o en consultarlo on-line cuando lo necesitéis, porque es muy bueno.

Usando librerías .dll de .NET en SQL-Server2008

Aunque normalmente no se recomiende tener la lógica de negocio en el lado del servidor de la base de datos, en algunos casos puede resultar interesante el hacerlo. Microsoft, en su empeño (por otra parte loable) de lograr una integración total entre sus servicios, nos permite utilizar nuestras .dll creadas en .NET (sea en VB.NET o en C#.NET o en C++) dentro de nuestra base de datos SQL-Server como «código gestionado».

Iré construyendo poco a poco un ejemplo para que veáis, paso a paso como se realiza esto. Lo primero es activar clr para que nos permita la integración con .NET tal que así:

USE [basedatosdeejemplo]
go
sp_configure 'clr enabled', 1
go
reconfigure
go

Seleccionamos la base de datos a utilizar, configuramos clr como ‘enabled’ (armado, activado) con el parámetro 1 y ejecutamos reconfigure para que el cambio tenga efecto. Acuérdate de poner el parámetro (en este caso 1) y de ejecutar reconfigure.

El primer paso está realizado. Lo siguiente es crear el ensamblado para la librería, definiendo el esquema y el tipo de permisos.


CREATE ASSEMBLY [Utilidades]
AUTHORIZATION [dbo]
FROM 'C:\LibreriaEjemplo.dll'
WITH PERMISSION_SET = SAFE
GO

Creamos el ensamblado con el nombre «Utilidades» (podemos darle el que queramos mientras no sea una palabra reservada), con el esquema dbo (podríamos haber utilizado cualquiera de los disponibles), en FROM le especificamos la dirección del archivo en disco mediante una cadena de texto con la ruta y finalmente los permisos, en este caso SAFE.

SAFE es el permiso más restrictivo que hay, el más «seguro» para nuestro equipo pues limita mucho lo que pueda hacer la librería. En caso de que uses liberías de terceros es el permiso que te reportará más seguridad. Existe también el permiso EXTERNAL_ACCESS, que permite que el código acceda a ciertos recursos externos (registro, archivos, red) y el permiso UNSAFE, que da control sin restricciones a la librería sobre los recursos de la máquina. Si usas una librería propia puedes usar UNSAFE, pero si usas una de un tercero piensa que pueden entrañar riesgos de seguridad.

Con lo puesto ya tenemos la librería disponible en nuestra base datos. ¿Y ahora qué? Ahora simplemente puedes usar las clases y métodos de dicha librería en tu base. Puedes crear tus tipos de datos propios usando sus objetos, incluir sus métodos en procedimientos o triggers. En este ejemplo vamos a suponer que la librería importada tiene una clase Point que guarda las coordenadas de un eje X y un eje Y junto a un valor booleano, y tiene también una función GetCoordsAsText que muestra un mensaje largo con las coordendas. Vamos a crear un tipo de datos Point, usarlo en una tabla, acceder a los valores y usar el método GetCoordsAsText en una función. Pondré comentarios para ir explicando el proceso

--Creamos el tipo de datos Point como un objeto de la clase Point.
--Para acceder a la clase point tenemos que usar el método external name de SQL-Server
--accediendo a la clase mediante el nombre del assembly que creamos antes y el namespace de la clase (en 
--este caso point)
create type Point
external name Utilidades.Point 
go

--Creamos la tabla

create table dbo.Points
(
	id int identity primary key,
	valor Point
);
go

--Para acceder a los datos de la tabla debemos usar un método que nos devuelva
--los valores almacenados dentro del objeto en forma de texto (en este caso .X para el valor X, .Y para 
--el valor Y o .ToString() para sacar ambos en una columna como texto).

select id,
			valor.X as X,
			valor.Y as Y,
			valor.ToString() as Completo
from dbo.Points

--Si intentáramos acceder al objeto a pelo, como voy a poner debajo, nos devolvería el valor del objeto
--sin convertir (un churrazo con la dirección de memoria del puntero)

select valor from dbo.Points --así nos saldría un churo tipo 0x0000000100020000303000000

--También podríamos usar los métodos de la librería en una función, trigger, función de agregado,
--cursor... En este caso haremos una función que acceda a GetCoordsAsText (que está en la clase 
--UserFunctions)

create function dbo.CoordenadasComoTexto
returns nvarchar(50)
as
    external name Utilidades.UserFunctions.GetCoordsAsText

Y con esto tendríais la función que simplemente ejecuta el método definido en la dll y un tipo de datos igual al objeto. Las posibilidades de esto son muy grandes, así que podéis ir profundizando.

Cinco programas para la creación de aventuras gráficas.

Sin dejar el tema de la programación, pero acerándonos a un terreno más lúdico hoy hablaremos de programas para la creación de aventuras gráficas. Si como yo eras de los que flipaban con Monkey Island, Day of the Tentacle, Maniac Mansion, Full Throttle… y tienes alguna noción de programación podrás, con este software, dar forma a tu aventura gráfica deseada. Eso sí, necesitarás también a alguien con nociones de diseño gráfico para que te haga los fondos, personajes y demás diseños.

WinterMute Engine: Se trata de un motor muy potente para crear aventuras gráficas. Es un proyecto GNU que os permitirá crear tanto aventuras comerciales como gratuítas, que permite el uso de gráficos 3D, alta definición, gran cantidad de recursos multimedia y un scripting con una sintaxis similar a PHP, por lo que si tienes nociones de este lenguaje o de C++ no te costará mucho trabajar con él.

En su página oficial podrás descargar el programa y encontrar ejemplos, ayuda, hacer donaciones…

Open SLUDGE: Basado en SLUDGE, de HungrySoftware, se trata de una alternativa abierta muy simple e intuitivo. Existe para Windows, Linux y MacOS. Gráficamente no es tan potente como WinterMute, pero tiene una gran cantidad de características que implementar. En su página de sourceforge podéis encontrar todas sus características, juegos creados con este software y el programa en si.

Javascript Graphic Adventure Maker: Bueno, el nombre ya dice bastante. Se trata de un programa que nos permitirá crear aventuras gráficas en javascript. JSGAM se trata de un proyecto libre y proporciona la ventaja de que el juega pueda ser incrustado en una página y jugado desde un navegador. De nuevo en sourceforge podéis encontrar la página del proyecto con el programa para descargar. También podéis jugar a este juego de ejemplo

DAGE: Un editor de aventuras complejo y muy potente, orientado sobre todo a la realización de aventuras con gráficos en 3D. Existen versiones para Windows y Linux y soporta OpenGL, el motor de física open source Newton Game Dynamic y usa scripting Lua. En su portal podrás no sólo descargar el editor, sino también varias aventuras subidas por otros creadores.

ALPACA: Finalmente un editor para diseñadores en Flash. Dudé si incluirlo o no, ya que todos sabéis que no soy muy partidario de esta tecnología, pero la gran cantidad de desarrolladores flash que hay por el mundo supongo que hará de ALPACA una opción interesante para ellos. Su nombre es un acrónimo de ActionScript LDU Point-And-Click Adventure. Al igual que JSGAM nos permite hacer juegos ejecutables en un navegador. En la página del proyecto tenéis juegos de ejemplo, documentación y el propio editor.

Estos cinco ejemplos no son los únicos. Tenéis también Adventure Game Studio, potente, fácile de usar pero privativo. Y si sois fans de los juegos old school podéis encontrar SCIStudio, basado en el mítico motor de Sierra (Larry2, Kings Quest IV); o NAGI, basado en el motor AGI que usaban, por ejemplo, los tres primeros King’s Quest o Larry I, y además permite hacer juegos compatibles con el motor SCUMM o con Sarien (que pemite modo multijudaor on-line).

En fin, con todo este montón malo será que no encontréis una opción que os convenza. Ahora sólo necesitáis tener una buena idea y trabajarla bien…

Creando un menú con HTML5 y CSS3

Volviendo con los artículos sobre HTML5 hoy vamos a ver cómo hacer un menú horizontal básico utilizando html5 y CSS3 (sobre todo CSS3).

En fin, en el marcado poca chicha hay. Es decir, lista desordenada de toda la vida, y el único cambio es que usaremos la etiqueta nav:

<nav>
  <ul>
<ul>
	<li><a class="hiddenSpellError">title="Primero" href="#">First</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Segundo" href="#">Second</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Tercero" href="#">Third</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Cuarto" href="#">Fourth</a></li>
</ul>
<ul>
	<li><a class="hiddenSpellError">title="Quinto" href="#">Fifth</a></li>
</ul>
  </ul>
<!--<span class="hiddenSpellError" pre=""-->nav>

Con esto la parte HTML5 ya está liquidada. Ahora toca empezar a trastear con CSS3. Lo primero es el css de la sección NAV, donde pondremos bordes redondeados, degradado de blanco a gris y definiremos el tamaño. Luego a los elementos de lista les quitaremos el botón de lista y los flotaremos a la izquierda(como en cualquier menú horizontal tradicional). También añadiremos una transición a cada enlace. Como CSS3 todavía no está estandarizado hay que usar propiedades espcíficas para cada navegador. En el futuro debería funcionar en todos con la propiedad estandar.

nav{
    /*Borde redondeado*/
    -webkit-border-radius:9px;/*Chrome y Safari*/
    -moz-border-radius:9px;/*Firefox*/
    -o-border-radius:9px;/*Opera*/
    border-radius:9px;/*Estandar*/
    /*Color degradado*/
    background-image: -webkit-gradient(linear, left top, left bottom, from(#FFF), to(#BBB));/*Chrome y Safari*/
    background-image: -moz-linear-gradient(top center, #FFF, #BBB);/*Firefox*/
    background-image: -o-linear-gradient(top, #FFF, #BBB);/*Opera*/
    background-image: linear-gradient(top, #FFF, #BBB);/*Estandar*/
    overflow:hidden;
    padding:12px;
    width:890px;
}

nav ul{
    list-style:none;
    margin:0 10px 0 10px;
    padding:0;
}

nav ul li{
    /*Borde redondeado*/
    -webkit-border-radius:6px;/*Chrome y Safari*/
    -moz-border-radius:6px;/*Firefox*/
    -o-border-radius:6px;/*Opera*/
    border-radius:6px;/*Estandar*/
    float:left;
    font-size:16px;
    font-weight:bold;
    margin-right:11px;
    text-align:center;
    /*Sombras*/
    text-shadow: 0px 1px 0px #FFF;
}

nav ul li a{
    color:#AAA;
    display:block;
    padding:10px;
    text-decoration:none;
    /*Transiciones*/
    -webkit-transition: 0.3s linear all;
    -moz-transition: 0.3s linear all;
    -o-transition: 0.3s linear all;
    transition: 0.3s linear all;
}

Bueno, tenemos el color de fondo, tenemos los bordes, tenemos la lista en formato horizontal… ¿Qué nos falta? Pues nos falta definir qué ocurre cuando naveguemos sobre los enlaces, cuando pongamos el ratón encima. Para eso utilizamos la pseudo-clase :hover de toda la vida, pero en este caso con degradados y sombras. Además, el texto se oscurecerá.

nav ul li:hover{
    /*Color degradado*/
    background-image: -webkit-gradient(linear, left top, left bottom, from(#FFF), to( #E3E3E3));/*Chrome y Safari*/
    background-image: -moz-linear-gradient(top center, #FFF, #E3E3E3);/*Firefox*/
    background-image: -o-linear-gradient(top, #FFF, #E3E3E3);/*Opera*/
    background-image: linear-gradient(top, #FFF, #E3E3E3);/*Estandar*/
    /*Sombras*/
    -webkit-box-shadow:  1px -1px 0px #999;/*Chrome y Safari*/
    -moz-box-shadow:  1px -1px 0px #999;/*Firefox*/
    -o-box-shadow:  1px -1px 0px #999;/*Opera*/
    box-shadow:  1px -1px 0px #999;/*Estandar*/
    border:1px solid #E3E3E3;
}

nav ul li a:hover {
    color:#000;
}

Y ahí tenéis un menú con estilo css3 bien chulo, recordad si lo testeáis que en los navegadores antiguos no va a funcionar, así que si tenéis IE6 o 7… instalad un navegador actualizado, que son gratis, joder.