/*
Slider Puzzle 1.0
Copyright (C) 2000 John David Ratliff
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// C Source File
// Created 12/20/00; 4:01:49 PM
// Updated 8/22/2002; 11:29:55 PM
#include <tigcclib.h> // Incluye Todos los Archivos de Cabecera
// define la altura de los sprites de las piezas del rompecabezas
#define ALTURA_PIEZA 16
// define los sprites de las piezas
static unsigned short int pieza1[] =
{0xFFFF,0xC003,0x8001,0x8181,0x8781,0x8181,0x8181,0x8181,
0x8181,0x8181,0x8181,0x8181,0x8181,0x8001,0xC003,0xFFFF};
static unsigned short int pieza2[] =
{0xFFFF,0xC003,0x8001,0x83C1,0x8661,0x8661,0x8061,0x80C1,
0x8181,0x8301,0x8601,0x8601,0x87E1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza3[] =
{0xFFFF,0xC003,0x8001,0x83C1,0x8661,0x8061,0x8061,0x81C1,
0x8061,0x8061,0x8061,0x8661,0x83C1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza4[] =
{0xFFFF,0xC003,0x8001,0x80C1,0x81C1,0x83C1,0x83C1,0x86C1,
0x86C1,0x8CC1,0x8FF1,0x80C1,0x80C1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza5[] =
{0xFFFF,0xC003,0x8001,0x87E1,0x8601,0x8601,0x8601,0x87C1,
0x8661,0x8061,0x8061,0x8661,0x83C1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza6[] =
{0xFFFF,0xC003,0x8001,0x83C1,0x8661,0x8601,0x8601,0x87C1,
0x8661,0x8661,0x8661,0x8661,0x83C1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza7[] =
{0xFFFF,0xC003,0x8001,0x87E1,0x8061,0x80C1,0x80C1,0x8181,
0x8181,0x8181,0x8301,0x8301,0x8301,0x8001,0xC003,0xFFFF};
static unsigned short int pieza8[] =
{0xFFFF,0xC003,0x8001,0x83C1,0x8661,0x8661,0x8661,0x83C1,
0x8661,0x8661,0x8661,0x8661,0x83C1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza9[] =
{0xFFFF,0xC003,0x8001,0x83C1,0x8661,0x8661,0x8661,0x8661,
0x83E1,0x8061,0x8061,0x8661,0x83C1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza10[] =
{0xFFFF,0xC003,0x8001,0x8C79,0xBCCD,0x8CCD,0x8CCD,0x8CCD,
0x8CCD,0x8CCD,0x8CCD,0x8CCD,0x8C79,0x8001,0xC003,0xFFFF};
static unsigned short int pieza11[] =
{0xFFFF,0xC003,0x8001,0x8C31,0xBCF1,0x8C31,0x8C31,0x8C31,
0x8C31,0x8C31,0x8C31,0x8C31,0x8C31,0x8001,0xC003,0xFFFF};
static unsigned short int pieza12[] =
{0xFFFF,0xC003,0x8001,0x8C79,0xBCCD,0x8CCD,0x8C0D,0x8C19,
0x8C31,0x8C61,0x8CC1,0x8CC1,0x8CFD,0x8001,0xC003,0xFFFF};
static unsigned short int pieza13[] =
{0xFFFF,0xC003,0x8001,0x8CF1,0xBD99,0x8C19,0x8C19,0x8C71,
0x8C19,0x8C19,0x8C19,0x8D99,0x8CF1,0x8001,0xC003,0xFFFF};
static unsigned short int pieza14[] =
{0xFFFF,0xC003,0x8001,0x8C0D,0xBC1D,0x8C3D,0x8C3D,0x8C6D,
0x8C6D,0x8CCD,0x8CFD,0x8C0D,0x8C0D,0x8001,0xC003,0xFFFF};
static unsigned short int pieza15[] =
{0xFFFF,0xC003,0x8001,0x8CFD,0xBCC1,0x8CC1,0x8CC1,0x8CF9,
0x8CCD,0x8C0D,0x8C0D,0x8CCD,0x8C79,0x8001,0xC003,0xFFFF};
// un puntero a las piezas del rompecabezas para acceder a
// ellas por medio de un arreglo
static unsigned short int *piezas[] =
{pieza1, pieza2, pieza3, pieza4, pieza5,
pieza6, pieza7, pieza8, pieza9, pieza10,
pieza11, pieza12, pieza13, pieza14, pieza15};
// Main Function
void _main(void)
{
int xLoop, yLoop, pieza = 0;
int loop, temp, randNum;
int tablero[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,-1};
int x1 = 0, x2 = 0, x3 = 0, x4 = 0, x5 = 0, x6 =0, x7 = 0, x8 = 0;
int x9 = 0, x10 = 0, x11 = 0, x12 = 0, x13 = 0, x14 = 0, x15 = 0;
int y1 = 0, y2 = 0, y3 = 0, y4 = 0, y5 = 0, y6 =0, y7 = 0, y8 = 0;
int y9 = 0, y10 = 0, y11 = 0, y12 = 0, y13 = 0, y14 = 0, y15=0;
int *x[] = {&x1,&x2,&x3,&x4,&x5,&x6,&x7,&x8,&x9,&x10,&x11,&x12,&x13,&x14,&x15};
int *y[] = {&y1,&y2,&y3,&y4,&y5,&y6,&y7,&y8,&y9,&y10,&y11,&y12,&y13,&y14,&y15};
int posicion, piezaActual = 0, completado = 0, tecla = 0, on = 1, movida = 0;
int ganador = 0;
// borra la pantalla
ClrScr();
// muestra las líneas de instrucciones del juego
DrawStr(0, 70, "Mueve con las Flechas", A_NORMAL);
DrawStr(0, 80, "ENTER para deslizar pieza", A_NORMAL);
DrawStr(0, 90, "Presione ESC para Salir", A_NORMAL);
// muestra la línea de información del juego
DrawStr(67, 0, "Slider 1.0", A_NORMAL);
FontSetSys(F_4x6);
DrawStr(80, 10, "Copyright (C) 2000", A_NORMAL);
DrawStr(80, 18, "John David Ratliff", A_NORMAL);
DrawStr(67, 26, "Traduc: Camilo Rodríguez", A_NORMAL);
DrawStr(67, 34, "Creado por Techno-Plaza", A_NORMAL);
DrawStr(67, 42, "para Lección de Repaso 1", A_NORMAL);
// DrawStr(67, 50, "Learn more at our website", A_NORMAL);
DrawStr(70, 54, "www.technoplaza.net", A_NORMAL);
// siembra el generador de números aleatorios
randomize();
// aleatoriza las piezas del rompecabezas
for (loop = 0; loop < 16; loop++) {
// selecciona una pieza cualquiera
randNum = random(16);
// reemplaza la pieza anterior con la nueva
temp = tablero[loop];
tablero[loop] = tablero[randNum];
tablero[randNum] = temp;
}
// muestra las piezas del rompecabezas
for (yLoop = 0; yLoop < (16 * 4); yLoop += 16) {
for (xLoop = 0; xLoop < (16 * 4); xLoop += 16) {
// sólo intenta desplegar piezas válidas
if (tablero[pieza] != -1) {
Sprite16(xLoop, yLoop, ALTURA_PIEZA,
piezas[tablero[pieza]], LCD_MEM, SPRT_XOR);
// marca la posición de la pieza
*x[tablero[pieza]] = xLoop;
*y[tablero[pieza]] = yLoop;
}
pieza++;
}
}
// configura la primera pieza como pieza 0
posicion = 0;
piezaActual = tablero[posicion];
// entra en un ciclo hasta que el rompecabezas se haya completado
// o hasta que el usuario presione ESC
while (!completado) {
// fija el intérvalo de tiempo en 1/2 segundo
OSFreeTimer(USER_TIMER);
OSRegisterTimer(USER_TIMER, 10);
// espera que el temporizdor expire, o que el usuario presione una tecla
while (!OSTimerExpired(USER_TIMER) && !kbhit());
if (kbhit()) {
// si el usuario presiona una tecla, grábela
tecla = ngetchx();
} else {
// de otra forma, borre las pulsaciones anteriores
tecla = 0;
}
// maneja las pulsaciones de teclado
if (tecla == KEY_ESC) {
// ESC significa salir
completado = 1;
} else if (tecla == KEY_ENTER) {
// si se intenta mover una pieza
movida = 0;
// intente mover la pieza a la derecha
if (posicion+1 <= 16) {
// si la posición derecha está vacía
if (tablero[posicion+1] == -1 && *x[piezaActual] != (16*4-16)) {
// asegúrese que la pieza antigua todavía está en pantalla
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// borra la pieza
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// mueve la pieza a la derecha 1 posición (16 pixeles)
*x[piezaActual]+=16;
// reinicia los contenedores de la posición de la pieza
tablero[posicion+1] = tablero[posicion];
tablero[posicion] = -1;
posicion++;
piezaActual = tablero[posicion];
// dibuja la pieza en la nueva posición
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// no intente mover la pieza en ninguna otra dirección
movida = 1;
}
}
// intenta mover la pieza a la izquierda
if (posicion-1 >= 0) {
// si la posición izquierda está vacía, y no nos hemos movido ya
if (tablero[posicion-1] == -1 && *x[piezaActual] != 0 && !movida) {
// asegúrese que la pieza esté en pantalla, de modo que pueda ser borrada correctamente
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// borra la pieza
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// mueve la pieza 1 posición a la izquierda (16 pixeles)
*x[piezaActual]-=16;
// reinicia los contenedores de la posición de la pieza
tablero[posicion-1] = tablero[posicion];
tablero[posicion] = -1;
posicion--;
piezaActual = tablero[posicion];
// dibuja la pieza en su nueva posición
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// no intente mover la pieza en ninguna otra dirección
movida = 1;
}
}
// intenta mover la pieza hacia arriba
if (posicion-4 >= 0) {
// si la posición superior está vacía, y no nos hemos movido aún
if (tablero[posicion-4] == -1 && *y[piezaActual] != 0 && !movida) {
// se asegura que la pieza está dibujada, de forma que se pueda borrar
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// borra la pieza
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// mueve la pieza 1 posición hacia arriba (16 pixeles)
*y[piezaActual]-=16;
// reinicia los contenedores de posición
tablero[posicion-4] = tablero[posicion];
tablero[posicion] = -1;
posicion-=4;
piezaActual = tablero[posicion];
// redibuja la pieza en la nueva ubicación
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// no intente mover esta pieza en ninguna otra dirección
movida = 1;
}
}
// intente mover la pieza hacia abajo
if (posicion+4 <= 15) {
// si la posición inferior está vacía, y no nos hemos movido aún
if (tablero[posicion+4] == -1 && *y[piezaActual] != (16*4-16) && !movida) {
// se asegura que la pieza está dibujada, para poder borrarla
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// borra la pieza
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// mueve la pieza una posición hacia abajo (16 pixeles)
*y[piezaActual]+=16;
// reinicia los contenedores de posición
tablero[posicion+4] = tablero[posicion];
tablero[posicion] = -1;
posicion+=4;
piezaActual = tablero[posicion];
// redibuja la pieza en la nueva ubicación
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// no intente mover en ninguna otra dirección
movida = 1;
}
}
} else if (tecla == KEY_LEFT) {
// se asegura que la pieza todavía está dibujada, de forma que permanezca ahí cuando nos movamos
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// si hay una posición a la izquierda hacia donde moverse
if (posicion > 0) {
// mover a la izquierda
posicion--;
// si estamos en el espacio vacío, mover a la izquierda de nuevo
if (tablero[posicion] == -1 && posicion > 0) {
posicion--;
// si no nos podemos mover más a la izquierda, comenzar al final
} else if (tablero[posicion] == -1 && posicion == 0) {
posicion = 15;
}
} else {
// coloca la posición al final
posicion = 15;
// si encontramos el espacio vacío, mover uno a la izquierda
if (tablero[posicion] == -1) {
posicion--;
}
}
// reiniciar los contenedores de posición
piezaActual = tablero[posicion];
} else if (tecla == KEY_RIGHT) {
// se asegura que la pieza está dibujada, de modo que nos podamos mover a otra con seguridad
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// si hay una posición a la derecha a dónde moverse
if (posicion < 15) {
// moverse una posición a la derecha
posicion++;
// si llegamos a la casilla vacía, moverse a la derecha de nuevo
if (tablero[posicion] == -1 && posicion < 15) {
posicion++;
// si llegamos a la casilla vacía y a un borde, comenzar de nuevo
} else if (tablero[posicion] == -1 && posicion == 15) {
posicion = 0;
}
// si no necesitamos comenzar de nuevo al inicio
} else {
// mover al inicio
posicion = 0;
// si llegamos a la casilla vacía, moverse a la derecha de nuevo
if (tablero[posicion] == -1) {
posicion++;
}
}
// reiniciar los contenedores de posición
piezaActual = tablero[posicion];
} else if (tecla == KEY_UP) {
// se asegura que la pieza está dibujada, de modo que nos podamos mover a otra con seguridad
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// si hay una posición arriba a dónde moverse
if ((posicion - 4) >= 0) {
// mover una posición arriba
posicion-=4;
// si llegamos a la casilla vacía
if (tablero[posicion] == -1) {
// si hay otra posición arriba, ir allí
if ((posicion - 4) >= 0) {
posicion-=4;
// de lo contrario, ir a la fila inferior
} else {
posicion = 16 - (4 - posicion);
}
}
// si no, moverse a la fila inferior
} else {
// colocar la posición en la fila inferior
posicion = 16 - (4 - posicion);
// si llegamos a la casilla vacía, moverse arriba de nuevo
if (tablero[posicion] == -1) {
posicion-=4;
}
}
// reiniciar los contenedores de posición
piezaActual = tablero[posicion];
} else if (tecla == KEY_DOWN) {
// se asegura que la pieza está dibujada, de modo que nos podamos mover a otra con seguridad
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// si hay una posición debajo donde moverse
if ((posicion + 4) <= 15) {
// mover una posición hacia abajo
posicion+=4;
// si llegamos a la casilla vacía
if (tablero[posicion] == -1) {
// si hay otra posición debajo
if ((posicion + 4) <= 15) {
// moverse a la siguiente posición hacia abajo
posicion+=4;
// de lo contrario, ir a la fila superior
} else {
posicion%=4;
}
}
// si no, moverse a la fila superior
} else {
// moverse a la fila superior
posicion%=4;
// si llegamos a la casilla vacía
if (tablero[posicion] == -1) {
// moverse hacia abajo una vez más
posicion+=4;
}
}
// reiniciar los contenedores de posición
piezaActual = tablero[posicion];
}
// hace titilar la pieza actual de modo que sepamos cuál es
on = !on;
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
// coloca la variable 'ganador' en uno, luego trata de descalificarla con
// el bucle for. Es más fácil llegar a una conclusión falsa que a una
// verdadera, así que comenzamos en verdadero, y nos vamos hacia el falso
ganador = 1;
// verifica si se ganó el juego
// Pasa por todas las piezas del juego, y verifica si sus posiciones
// coinciden con sus números de pieza. Si es así, entonces el jugador ganó
// si encontramos una pieza que no está en el lugar correcto, no tenemos ganador
// y detenemos el bucle for
for (loop = 0; loop < 15; loop++) {
if (*y[loop] != ((loop / 4) * 16) || *x[loop] != ((loop % 4) * 16)) {
ganador = 0;
break;
}
}
// si tenemos un ganador, nos aseguramos que la pieza está dibujada y
// colocamos la variable 'completado' en verdadero
if (ganador) {
// si ganamos, hemos completado el juego, obviamente
completado = 1;
// nos aseguramos que la pieza este dibujado de manera que se vea bien
if (!on) {
Sprite16(*x[piezaActual], *y[piezaActual], ALTURA_PIEZA,
piezas[piezaActual], LCD_MEM, SPRT_XOR);
on = 1;
}
// se le dice al jugador que ganó
DlgMessage("Ganador", "¡Haz completado el rompecabezas!", BT_OK, BT_NONE);
}
}
}