Sunday, October 11, 2009

Programación y ajedrez

El verano del 2008 comencé a programar un motor de ajedrez en C, que probablemente será un chimpacé al lado de cualquier otro motor. Aún no lo termino, pues le dedico tiempo solo los veranos y unos escazos días.
En los primeros programas de ajedrez el tablero se representaba usando un arreglo, luego se comenzó a usar una técnica que revolucionó el mundo del ajedrez, los bitboards.
Un bitboard es una representación del tablero usando un entero de 8 bytes, dado que cada byte tiene 8 bits se pueden representar los 64 casilleros del tablero con un bitboard.
La ventaja de esta representación es que los cálculos son mucho menos costosos en memoria y CPU porque un bitboard pesa mucho menos que un arreglo de 64 carácteres y se usan operaciones a nivel de bit como el AND,OR,XOR y shift para muchos de los cálculos.

Verificar si un casillero del tablero se encuentra ocupado por una pieza usando bitboards:

typedef uint64_t bitboard;
...
/* square number 0-63 (a1-h8) */
int isOccuped(bitboard board, int square) {

if( board & (1<< square) ) {
return 1;
}
return 0;
}

Para revisar si una casilla del tablero esta ocupada usando un arreglo tendriamos que recorrer el arreglo e ir revisando casilla por casilla, lo cual resulta más costoso y menos elegante.

Wednesday, October 7, 2009

Aritmética de punteros

Estaba indeciso acerca de que escribir en mi descuidado blog y decidí que a partir de hoy comenzaré a postear algunos fragmentos de código.
Sé que es muy fácil encontrar buenos ejemplos acerca del tema de hoy, pero más de alguno lo habrá olvidado y lo recordará por casualidad al llegar aquí.
C permite sumar o restar números enteros a un puntero, desplazando la dirección a la que este apunta la cantidad de bytes que ocupa el tipo de dato del puntero multiplicada por el número entero que se le ha sumado o restado.


#include <stdio.h>
#include <stdlib.h>

int main() {

int* intArray;
/* (int *) indica al compilador que en la memoria reservada
se almacenaran enteros
malloc (memory allocate) reserva (sizeof(int)*3) bytes de memoria
sizeof(int) retorna la cantidad de bytes que ocupa un int
(en mi caso 4 bytes)
inicialmente intArray apunta al primer byte de memoria reservada
*/
intArray = (int *) malloc(sizeof(int)*3);
*intArray = 1; //equivalente a intArray[0] = 1
//desplazar direccion apuntada por intArray sizeof(int) bytes
intArray = intArray + 1;
*intArray = 2;
intArray = intArray +1;
*intArray = 3;
printf("%i %i %i\n",*(intArray - 2),*(intArray - 1),*intArray);
/* si llamamos inmediatamente a free(intArray) obtendremos un error
en tiempo de ejecucion pues intArray ya no apunta al primer byte
de memoria reservada*/

//intArray debe apuntar al 1er byte de la memoria reservada
intArray = intArray - 2;
free(intArray);

}


Muestra en pantalla:
1 2 3