El trastero de José Juan Valid XHTML 1.1 Valid CSS! Estilo de página alternativo
Artículo creado en 2009.
Valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración sobre 28 comentarios.

Guerras Tribales a MySql


¿Estás interesado en una herramienta que te ayude a jugar a Guerras Tribales?, dame tu opinión y veré si merece la pena. Opinar AQUI.


Los datos

En ocasiones disponemos de fuentes de información que nos gustaría poder procesar de acuerdo a nuestras propias necesidades. Puede tratarse de las cotizaciones de bolsa, de las coordenadas de las ciudades del mundo o, como en este caso, de información global de un juego de estrategia.

Las fuentes externas pueden estar disponibles en una amplia variedad de formas pero, exceptuando que el orígen disponga de algún tipo de servicio (por ejemplo OLAP o lógicamente SQL) no podremos realizar consultas eficientes de forma remota. Es por eso que se hace necesario descargar y guardar la información de forma adecuada.

Datos en Guerras Tribales

Sin entrar en detalle (ni porqué ni para qué) disponemos de la siguiente información:

Existen otros archivos disponibles, pero éstos forman un conjunto cerrado (no hay códigos cuyas tablas no estén definidas) y son un buen ejemplo.

Base de datos en MySql

Sin lugar a dudas, la mejor forma de poder procesar adecuadamente los datos es usar un buen motor de bases de datos. Siento decir (lo siento) que MySql no es (con mucho) mi base de datos preferida (ya lo he comentado en algún otro artículo) y sitiendolo mucho (sitiendolo por los detractores) mi preferido (motor de base de datos) es sin duda Microsoft SQL Server. Pero, aquí sólo dispongo de MySql, así que tendrá que bastar.

Bueno, además de recuperar la información, querremos un histórico del estado en el que se encuentra todo, con ésto podremos identificar los cambios producidos y su evolución en el tiempo (algo muy importante en la estrategia si queremos saber qué tan rápidos responden o evolucionan otros jugadores o tribus). Así, las tablas que haremos serán:


La única diferencia entre las tablas gt_[ALIAS] y las tablas gt_[ALIAS]_HIS es que las primeras almacenan el estado actual, mientras que las segundas guardan todas y cada una de las variaciones producidas. Podrías pensar (y con razón) que sólo hacen falta tres tablas (que con las _HIS podemos tener todos los datos) pero es mejor hacerlo así, ya que nos facilitará (en consultas y en rendimiento) el trabajo.

Creando la base de datos

Bueno, las tablas no tienen ningún misterio, casi son una traslación directa de lo ya escrito.

/* Tribus */
CREATE TABLE gt_ALLY (
	ally_pk		INT NOT NULL,
	ally_name	VARCHAR(50) NOT NULL,
	tag		VARCHAR(15) NOT NULL,
	PRIMARY KEY ( ally_pk )
);

/* Si pudiéramos asegurar que son únicas, crearíamos el índice UNIQUE: */
CREATE INDEX idx_gt_ALLY_ally_name ON gt_ALLY ( ally_name ASC );

/* Si pudiéramos asegurar que son únicas, crearíamos el índice UNIQUE: */
CREATE INDEX idx_gt_ALLY_tag ON gt_ALLY ( tag ASC );

/* Jugadores */
CREATE TABLE gt_PLAYER (
	player_pk	INT NOT NULL,
	player_name	VARCHAR(30) NOT NULL,
	ally_pk		INT NOT NULL,
	PRIMARY KEY ( player_pk ),
	FOREIGN KEY ( ally_pk ) REFERENCES gt_ALLY ( ally_pk )
);

/* Si pudiéramos asegurar que son únicas, crearíamos el índice UNIQUE: /*
CREATE INDEX idx_gt_PLAYER_player_name ON gt_PLAYER ( player_name ASC );

/* Nos vendrá bien para buscar los miembros de una tribu: */
CREATE INDEX idx_gt_PLAYER_ally_pk ON gt_PLAYER ( ally_pk ASC );

/* Ciudades */
CREATE TABLE gt_VILLAGE (
	village_pk	INT NOT NULL,
	village_name	VARCHAR(130) NOT NULL,
	player_pk	INT NOT NULL,
	x		INT NOT NULL,
	y		INT NOT NULL,
	points		INT NOT NULL,
	rank		INT NOT NULL,
	PRIMARY KEY ( village_pk ),
	FOREIGN KEY ( player_pk ) REFERENCES gt_PLAYER ( player_pk )
);

/* Si pudiéramos asegurar que son únicas, crearíamos el índice UNIQUE: */
CREATE INDEX idx_gt_VILLAGE_village_name ON gt_VILLAGE ( village_name ASC );

/* Nos vendrá bien para buscar las ciudades de un jugador: */
CREATE INDEX idx_gt_VILLAGE_ally_pk ON gt_VILLAGE ( player_pk ASC );




/* Tribus */
CREATE TABLE gt_ALLY_HIS (
	ally_pk		INT NOT NULL,
	rtime		DATETIME NOT NULL,
	ally_name	VARCHAR(50) NOT NULL,
	tag		VARCHAR(15) NOT NULL,
	PRIMARY KEY ( rtime, ally_pk )
);

CREATE INDEX idx_gt_ALLY_HIS_ally_name ON gt_ALLY_HIS ( ally_name ASC );

/* Si pudiéramos asegurar que son únicas, crearíamos el índice UNIQUE: */
CREATE INDEX idx_gt_ALLY_HIS_tag ON gt_ALLY_HIS ( tag ASC );

/* Jugadores */
CREATE TABLE gt_PLAYER_HIS (
	player_pk	INT NOT NULL,
	rtime		DATETIME NOT NULL,
	player_name	VARCHAR(30) NOT NULL,
	ally_pk		INT NOT NULL,
	PRIMARY KEY ( rtime, player_pk ),
	FOREIGN KEY ( ally_pk ) REFERENCES gt_ALLY_HIS ( ally_pk )
);

CREATE INDEX idx_gt_PLAYER_HIS_player_name ON gt_PLAYER_HIS ( player_name ASC );

/* Nos vendrá bien para buscar los miembros de una tribu: */
CREATE INDEX idx_gt_PLAYER_HIS_ally_pk ON gt_PLAYER_HIS ( ally_pk ASC );

/* Ciudades */
CREATE TABLE gt_VILLAGE_HIS (
	village_pk	INT NOT NULL,
	rtime		DATETIME NOT NULL,
	village_name	VARCHAR(130) NOT NULL,
	player_pk	INT NOT NULL,
	x		INT NOT NULL,
	y		INT NOT NULL,
	points		INT NOT NULL,
	rank		INT NOT NULL,
	PRIMARY KEY ( rtime, village_pk ),
	FOREIGN KEY ( player_pk ) REFERENCES gt_PLAYER_HIS ( player_pk )
);

CREATE INDEX idx_gt_VILLAGE_HIS_village_name ON gt_VILLAGE_HIS ( village_name ASC );

/* Nos vendrá bien para buscar las ciudades de un jugador: */
CREATE INDEX idx_gt_VILLAGE_HIS_ally_pk ON gt_VILLAGE_HIS ( player_pk ASC );

Procedimientos almacenados

Sin duda, el uso de procedmientos almacenados es vital en la gestión eficiente (en muchos sentidos) de bases de datos, e aquí uno de los 3 (los otros dos son casi idénticos) que nos permitirán cargar la información de forma cómoda y sencilla:

gtp_ally_update

DELIMITER //

CREATE PROCEDURE gtp_ally_update(
	_ally_pk	INT,
	_ally_name	VARCHAR(50),
	_tag		VARCHAR(15)
)
BEGIN
	DECLARE	_prev_ally_pk	INT;

	# ¿Existe uno exactamente con esos datos?
	SELECT	ally_pk
	FROM	gt_ALLY
	WHERE	ally_pk		= _ally_pk
	AND	ally_name	= _ally_name
	AND	tag		= _tag
	LIMIT	1
	INTO	_prev_ally_pk;

	# Sólo si no existe con esos datos debemos insertar o actualizar:
	IF _prev_ally_pk IS NULL THEN

		# Veamos si el registro existe:
		SELECT	ally_pk
		FROM	gt_ALLY
		WHERE	ally_pk		= _ally_pk
		LIMIT	1
		INTO	_prev_ally_pk;

		# ¿Insertar?
		IF _prev_ally_pk IS NULL THEN

			INSERT INTO gt_ALLY (
				ally_pk,
				ally_name,
				tag
			)
			SELECT	_ally_pk	as ally_pk,
				_ally_name	as ally_name,
				_tag		as tag;

		ELSE
		# ¿Actualizar?

			UPDATE	gt_ALLY
			SET	_ally_name	= ally_name,
				_tag		= tag
			WHERE	ally_pk		= _ally_pk;

		END IF;

		# En cualquier caso, guardamos en el histórico
		INSERT INTO gt_ALLY_HIS (
			ally_pk,
			rtime,
			ally_name,
			tag
		)
		SELECT	_ally_pk	as ally_pk,
			NOW()		as rtime,
			_ally_name	as ally_name,
			_tag		as tag;

	END IF;
END //

DELIMITER ;

Poblando con los archivos

Supuesto que tenemos los archivos localmente y descomprimidos (ver más adelante el script), una buena forma de importalos es mediante Perl, sí, se que podía usar el interprete de PHP de la misma forma que el de Perl pero es que Perl me gusta mucho más (por ahí explico porqué).

Bueno, el código es muy sencillo, me ahorraré explicaciones (y como antes, añadir la parte que lee de los otros dos archivos es idéntica a la mostrada).

GT_Up_DataFile.pl

#!/usr/bin/perl

use strict;

use DBI();

my $dbh = DBI->connect(
	'DBI:mysql:database=BASE_DE_DATOS;host=SERVIDOR_MYSQL',
	'USUARIO',
	'PASSWORD',
	{'RaiseError' => 1}
);

open ALLY, "ally.txt"
	or die("Imposible abrir el archivo 'ally.txt'.\n");

while( <ALLY> ) {
	if( /^([^,]*),([^,]*),([^,]*),/ ) {
		my $id = $1;
		my $nm = URLDecode($2);
		my $tg = URLDecode($3);

		$id =~ s/'\''/'\'\''/g;
		$nm =~ s/'\''/'\'\''/g;
		$tg =~ s/'\''/'\'\''/g;

		print "$id: \"$nm\", \"$tg\".\n";

		my $sth = $dbh->prepare("call gtp_ally_update( '$id', '$nm', '$tg' )");
		$sth->execute();
		$sth->finish();
	}
}

close ALLY;

$dbh->disconnect();

sub URLDecode {
	my $theURL = $_[0];
	$theURL =~ tr/+/ /;
	$theURL =~ s/%([a-fA-F0-9]{2,2})/chr(hex($1))/eg;
	$theURL =~ s/<!-(.|\n)*->//g;
	return $theURL;
}

Bajando los archivos

Bajar los archivos, descomprimirlos y lanzar el script en Perl que carga los datos en la base de datos de MySql es también muy sencillo. Dependiendo de si usas Windows o usas Linux (o Mac u otros) emplearás un intérprete de comandos u otro. La alternativa que yo he usado es la siguiente:

GT_Check_Changes.Bat

wget -O village_txt.gz http://es2.guerrastribales.es/map/village.txt.gz
wget -O player_txt.gz http://es2.guerrastribales.es/map/player.txt.gz
wget -O ally_txt.gz http://es2.guerrastribales.es/map/ally.txt.gz
winrar.exe x village_txt.gz
winrar.exe x player_txt.gz
winrar.exe x ally_txt.gz
GT_Up_DataFile.pl

Bastante sencillo ¿no?. Lanzando periodicamente este script tendremos actualizada nuestra base de datos.

Consultas interesantes

Con todos los datos normalizados y metidos en una base de datos son obvias las aplicaciones que dichos datos tienen. Quizás el más útil sea saber qué pueblos bárbaros y de bonificación (u otras granjas si somos agresivos) tenemos en un radio determinado con un nivel de puntos dentro de un rango (ni muy pequeños que no nos darán recursos, ni muy grandes que nos producirán bajas) y quizás con otros criterios más refinados como aquellos que, además, estén más alejados de otros posibles granjeadores, ir almacenando el resultado de nuestros ataques, etc... Pero hay muchas otras aplicaciones, como saber qué progresión tecnológica (indicada de forma aproximada por los puntos) poseen los contrincantes cercanos, conocer cuales están más o menos activos (para atacar o no), saber qué miembros de la tribu evolucionan con mayor rapidez, saber quienes conquistan a quienes, etc...

Los 30 pueblos abandonados más cercanos a la posición (222|333) con puntos entre 100 y 200 .

	SET @x = 222;
	SET @y = 333;
	SET @A = 100;
	SET @B = 200;

	SELECT	CONCAT( x , '|' , y ) as Posicion,
		SQRT( (x-@x) * (x-@x) + (y-@y) * (y-@y) ) as Distancia,
		g.*
	FROM	gt_VILLAGE g
	WHERE	player_pk	= 0
	AND	points		BETWEEN @A AND @B
	ORDER
	BY	SQRT( (x-@x) * (x-@x) + (y-@y) * (y-@y) )
	LIMIT	30;

Todos los jugadores con más de 4000 puntos con alguna ciudad a menos de 10 cuadros de alguna de las ciudades del jugador 666.


SET @x = 0;
SET @y = 0;

SELECT	x, y
FROM	gt_VILLAGE
WHERE	player_pk	= 149051
INTO	@x, @y;

SELECT	player_pk
FROM	gt_VILLAGE
WHERE	x	= @x
AND	y	= @y;




Opinado el 05/02/10 15:27, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Joder, que pena que no se hacerlo, pero aprenderee,.. buen trabajo el tullo gracias.
Opinado el 24/02/10 18:07, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    que pena haber encontrado esto ahora... muy buen trabajo
Opinado el 12/03/10 02:48, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 23/03/10 17:03, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    es legal??
Opinado el 14/04/10 21:38, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Hola, indico la respuesta del servicio tecnico del juego. Afirma que las tablas NO son p?cas. as?ue... de donde han salido? como se pueden conseguir para el mundo 4, son las mismas? steoz 2010-04-14 21:30:51 no son publicas es una forma que esta persona que accedia pero y on ote puedo dar acceso ni ningun link Saludos, steoz -Equipo de Soporte-
Opinado el 15/04/10 09:34, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Pues te han mentido descaradamente, TODOS los archivos están disponibles desde las direcciones "http://es6.guerrastribales.es/help2.php?article=map_data" (cámbiese es6 por: es1, es2, es3, ...).
Opinado el 27/04/10 23:00, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 07/05/10 08:14, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Gracias por la respuesta. Lo cierto es que al servicio tecnico no le hubiera costado nada decirme eso mismo...
Opinado el 03/06/10 11:31, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    no puedes hacer un yuyo?
Opinado el 26/06/10 16:17, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    como o donde ejecuto el script de perl
Opinado el 26/06/10 18:41, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    El Script de Perl debes ejecutarlo en el directorio donde tengas los archivos de datos (ya descomprimidos). Un ejemplo completo se muestra en el archivo "GT_Check_Changes.Bat".
Opinado el 14/07/10 00:47, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Me parece bien, pero no he entendido lo de los archivos
Opinado el 10/08/10 16:45, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    impresionante
Opinado el 18/09/10 06:12, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Y donde pego ese texto? No entiendo nada! Saludos!
Opinado el 01/11/10 11:53, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    ya entiendo como algunos crecen tan rapido muy bueno
Opinado el 10/11/10 20:48, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    lastima que no se hacerlo en linux
Opinado el 25/11/10 23:38, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    wow hace como 3 años yo habia bajado estas tablas también pero antes no sabia nada de sql ni php, ahora voy a ver si puedo programar alguna aplicacion usando estos datos y compartirla con los de mi tribu aunque ya hay muchas paginas que proporcionan datos del tribal
Opinado el 11/12/10 00:37, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Gracias
Opinado el 17/03/11 10:23, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Excelente
Opinado el 27/07/11 03:04, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    En esta p?na http://www.bot-tribalwars.com.ar retomaron el proyecto del bot de gt, y anda logue y construye solo., y por ahora se puede Bajar gratis
Opinado el 16/09/11 20:38, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Â¿Alguien me puede decir como hacerlo con PHP? No tengo Perl. Uso Apple. Lo que más me importa es saber como pasar los datos de .txt a un .php que pueda ejecutar para insertar los datos en una tabla sql. Mi email si teneis una respuesta: adrianlattes@yahoo.es
Opinado el 11/11/11 19:06, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    ahora ya entiendo como otros crecen tan rapidos
Opinado el 27/11/11 00:37, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    simplemente fantastico...
Opinado el 27/11/11 12:32, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    mario_21-10-91@hotmail.com, alguien puede ayudarme
Opinado el 21/01/12 21:40, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    acuariosalobre@hotmail,es perfecto,ayudame?
Opinado el 15/06/12 23:51, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    puedes ayudarme findelmundoangel@hotmail.es
Opinado el 08/06/13 02:40, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Molaa! Estoy estudiando procedimientos y trigger..
Opinado el 26/04/15 12:33, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    HDA autoclick 2.0
¿Te ha gustado? ¡aporta tu opinión!
Valoración:
 0    1    2    3    4    5    6    7    8    9    10

Comentario:
NOTA: si es una petición... ¡pon el e-mail al que responderte o no sabré a dónde escribir!

Código de verificación captcha