TETRIS/TETRIS.CPP
2021-09-12 20:34:18 +02:00

1163 lines
36 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/********
Bases simples para recrear el juego TETRIS en modo texto y monoProceso
********/
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <time.h>
// Ya que el lenguaje carece de BOOLEANOS definimos unas macros
#define bool int
#define true 1
#define false 0
// N£mero de piezas con las que jugamos
#define NUMERO_DE_PIEZAS 7
#define ANCHO_TABLERO 15
#define ALTO_TABLERO 23
typedef enum tipoPieza { PIEZA_CUADRADA=1, PIEZA_LINEA, PIEZA_Rizq, PIEZA_Rder, PIEZA_Lder, PIEZA_Lizq,PIEZA_T };
// Definimos que es para nosotros una pieza
typedef struct {
tipoPieza tipo; // Tipo de pieza que estamos definiendo
int rotacion, proxRot; // Estado ¢ rotaci¢n actual de la pieza
int posX, posY, proxX; // Coordenadas de la pieza
} pieza;
// Definimos una partida
typedef struct {
// Necesitamos un tablero para jugar
char tablero[ALTO_TABLERO][ANCHO_TABLERO];
pieza piezaActual; // e informaci¢n de la pieza en juego
int lineas; // Estad¡sticas del n£mero de lineas conseguidas
int piezas; // Estad¡sticas del n£mero de piezas jugadas
int puntuacion; // Puntuaci¢n actual para esta partida
} partida;
pieza obtenerPieza(void);
void AnimaticaTimeSlice(void);
void dibujaPieza( pieza P, int color );
pieza obtenerPieza(void);
void procesaTecla( bool *salir, bool *pausa, bool *tocaMover );
void dibujaPieza( pieza P, int color );
void dibujaPiezaSOLIDA( pieza P, int color );
void dibujaPiezaHUECA( pieza P, int color );
int anchoPieza( pieza P );
int altoPieza( pieza P );
void muestraTablero(void);
bool piezaColisiona( char tablero[ALTO_TABLERO][ANCHO_TABLERO], pieza P );
bool actualizaFicha(bool bajarFicha);
int colorPieza(pieza P);
void procesaColision();
void fijaPieza();
/*******************************************************************/
partida partidaActual;
bool pSolida=true;
void eliminaLineaTablero( int Y )
{
int i,j;
for (i=0;i<ANCHO_TABLERO;i++)
for (j=Y;j>0;j--)
partidaActual.tablero[j][i] = partidaActual.tablero[j-1][i];
for (i=0;i<ANCHO_TABLERO;i++)
partidaActual.tablero[0][i] = 0;
};
void RedibujaTablero(void)
{
for (int i=0; i<ANCHO_TABLERO; i++)
for (int j=0; j<ALTO_TABLERO; j++)
{
gotoxy(i*2+2,j+1); textcolor( partidaActual.tablero[j][i] );
cprintf("ÛÛ");
}
};
void inicializaJuego(void)
{
randomize(); // Inicializamos el generador de numeros
partidaActual.lineas = 0; // Inicializamos las estadisticas
partidaActual.piezas = 0;
partidaActual.puntuacion = 0;
for(int i=0;i<ANCHO_TABLERO;i++) // Vaciamos el tablero
for(int j=0;j<ALTO_TABLERO;j++)
partidaActual.tablero[j][i] = 0;
partidaActual.piezaActual = obtenerPieza();
}
// Genera de forma aleatoria una pieza y un estado (rotacion)
pieza obtenerPieza(void)
{
pieza p;
p.tipo = random(NUMERO_DE_PIEZAS)+1;
p.rotacion = random(4);
p.proxRot = p.rotacion;
p.posX = 3;
p.proxX = 3;
p.posY = 0;//altoPieza(p)-1;
return p;
}
// Procesamos las posible teclas
void procesaTecla( bool *salir, bool *pausa, bool *tocaMover )
{
switch( getch() )
{
case 'B':
case 'b':
pSolida = true;
break;
case 'h':
case 'H':
pSolida = false;
break;
case 't':
partidaActual.piezaActual.tipo = (partidaActual.piezaActual.tipo+1)%7;
break;
case 's':
case 'S':
*salir = true;
break;
case 'p':
case 'P':
*pausa = (*pausa==false) ? true : false;
break;
case 'N':
case 'n':
muestraTablero();
inicializaJuego();
break;
// Teclas especiales
case 0:
switch( getch() )
{
// Flecha izquierda
case 75:
// Solo si no estamos en el borde del tablero
if ( partidaActual.piezaActual.posX > 0 )
partidaActual.piezaActual.proxX = partidaActual.piezaActual.posX-1;
break;
// Flecha derecha
case 77:
if ((partidaActual.piezaActual.posX+anchoPieza(partidaActual.piezaActual)) < ANCHO_TABLERO)
partidaActual.piezaActual.proxX = partidaActual.piezaActual.posX+1;
break;
// Flecha arriba
case 72:
partidaActual.piezaActual.proxRot = (partidaActual.piezaActual.rotacion+1)%4;
break;
// Flecha Abajo
case 80:
*tocaMover = true;
break;
}
}
}
// Nuestras posibles piezas
void dibujaPieza( pieza P, int color )
{
if ( pSolida ) dibujaPiezaSOLIDA(P,color);
else dibujaPiezaHUECA(P,color);
}
void dibujaPiezaSOLIDA( pieza P, int color )
{
int X, Y;
X = P.posX*2+2; // Coordenas iniciales para dibujar
Y = P.posY+1; // mas una correcci¢n visual (hay que encajar
// el tablero en la pantalla)
textcolor(color); // Establecemos el color de la pieza
switch( P.tipo )
{
/*******************
ROTACION 0 ROTACION 1 ROTACION 2 ROTACION 3
*********************/
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
case PIEZA_CUADRADA:
switch( P.rotacion )
{
case 0:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
break;
case 1:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
break;
case 2:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
break;
case 3:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
break;
}
break;
// ÛÛ
// ÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ
// ÛÛ
case PIEZA_LINEA:
switch( P.rotacion )
{
case 0:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛ");
break;
case 1:
gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ");
break;
case 2:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛ");
break;
case 3:
gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ");
break;
}
break;
// ÛÛ ÛÛ
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ
case PIEZA_Rizq:
switch( P.rotacion )
{
case 0:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X+2,Y+1); cprintf("ÛÛÛÛ");
break;
case 1:
gotoxy(X+2,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛ");
break;
case 2:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X+2,Y+1); cprintf("ÛÛÛÛ");
break;
case 3:
gotoxy(X+2,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛ");
break;
}
break;
// ÛÛ ÛÛ
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ
case PIEZA_Rder:
switch( P.rotacion )
{
case 0:
gotoxy(X+2,Y) ; cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
break;
case 1:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
gotoxy(X+2,Y+2); cprintf("ÛÛ");
break;
case 2:
gotoxy(X+2,Y); cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
break;
case 3:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
gotoxy(X+2,Y+2); cprintf("ÛÛ");
break;
}
break;
// ÛÛ ÛÛÛÛ
// ÛÛ ÛÛÛÛÛÛ ÛÛ ÛÛ
// ÛÛÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ
case PIEZA_Lizq:
switch( P.rotacion )
{
case 0:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛÛÛ");
break;
case 1:
gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛ");
break;
case 2:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X+2,Y+1); cprintf("ÛÛ");
gotoxy(X+2,Y+2); cprintf("ÛÛ");
break;
case 3:
gotoxy(X+4,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛÛÛ");
break;
}
break;
// ÛÛ ÛÛÛÛ
// ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ
// ÛÛÛÛ ÛÛÛÛÛÛ ÛÛ ÛÛ
case PIEZA_Lder:
switch( P.rotacion )
{
case 0:
gotoxy(X+2,Y); cprintf("ÛÛ");
gotoxy(X+2,Y+1); cprintf("ÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛÛÛ");
break;
case 1:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛÛÛ");
break;
case 2:
gotoxy(X,Y); cprintf("ÛÛÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛ");
break;
case 3:
gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ");
gotoxy(X+4,Y+1); cprintf("ÛÛ");
break;
}
break;
// ÛÛ ÛÛ
// ÛÛ ÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛÛÛ ÛÛ ÛÛ ÛÛ
case PIEZA_T:
switch( P.rotacion )
{
case 0:
gotoxy(X+2,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛÛÛ");
break;
case 1:
gotoxy(X,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
gotoxy(X,Y+2); cprintf("ÛÛ");
break;
case 2:
gotoxy(X,Y); cprintf("ÛÛÛÛÛÛ");
gotoxy(X+2,Y+1); cprintf("ÛÛ");
break;
case 3:
gotoxy(X+2,Y); cprintf("ÛÛ");
gotoxy(X,Y+1); cprintf("ÛÛÛÛ");
gotoxy(X+2,Y+2); cprintf("ÛÛ");
break;
}
break;
}
}
/* Devuelve la anchura de una pieza segun su tipo y rotacion actual
*/
int anchoPieza( pieza P )
{
int anchuraPiezas[8][4]={ {0,0,0,0},{2,2,2,2}, {1,3,1,3}, {3,2,3,2},
{3,2,3,2}, {2,3,2,3}, {2,3,2,3},
{3,2,3,2} };
return anchuraPiezas[P.tipo][P.rotacion];
}
/* Devuelve la altura de una pieza segun su tipo y rotacion actual
*/
int altoPieza( pieza P )
{
int alturaPiezas[8][4]={ {0,0,0,0}, {2,2,2,2}, {3,1,3,1}, {2,3,2,3},
{2,3,2,3}, {3,2,3,2}, {3,2,3,2},
{2,3,2,3} };
return alturaPiezas[P.tipo][P.rotacion];
}
void muestraTablero(void)
{
int i;
clrscr();
/* MARCO DEL TABLERO */
textcolor( LIGHTGREEN );
//123456789-123456789-123456789-
gotoxy(1,1); cprintf( "¿ ÃÄÄÄÄÄ>");
textcolor( GREEN );
cprintf(" T E T R I S ");
textcolor( LIGHTGREEN );
cprintf("<ÄÄÄ--- - ú");
for(i=0;i<ALTO_TABLERO; i++)
{
gotoxy(1,i+2); cprintf("³ ³");
}
gotoxy(1,24); cprintf("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ");
/// Informacion de las teclas
gotoxy(35,18); textcolor(RED); cprintf("N"); textcolor(BLUE); cprintf("ueva Partida");
gotoxy(35,19); textcolor(RED); cprintf("P"); textcolor(BLUE); cprintf("ausa");
gotoxy(35,23); textcolor(RED); cprintf("B"); textcolor(BLUE); cprintf("loques Solidos");
gotoxy(35,24); textcolor(RED); cprintf("H"); textcolor(BLUE); cprintf("uecos");
}
// Punto de entrada a la aplicacion
void main(void)
{
clock_t start;
bool salir, pausa, colision; // L¢gicos de control
bool tocaMover = true;
inicializaJuego(); // Inicializamos el juego Actual
muestraTablero(); // Mostramos el Tablero
salir = false;
pausa = false;
// Entramos en un bucle cuyo £nico fin
// ser  para acabar el programa
while( !salir )
{
/****** BLOQUE DE CONTROL DE COMANDOS
Se encarga (sin detener la ejecuci¢n del programa de procesar
las teclas pulsadas por el usuario).
*******/
if ( kbhit() ) // Solo si hay alguna tecla en el buffer
procesaTecla(&salir,&pausa,&tocaMover);// procesamos dicha tecla
// vaciar buffer
while( kbhit() ) getch();
/****** BLOQUE DE RETARDO
Se encarga de indicar si ha de actualizarse los movimientos de
las fichas o no (sin detener la ejecuci¢n del programa).
NOTA: temporalmente se ha colocado un "delay" hasta terminar el
bloque.
*******/
if ( tocaMover == false )
tocaMover = ( ( clock() - start ) / CLK_TCK > 0.5 ) ? true : false ;
/****** BLOQUE DE ACTUALIZACION DE FICHA
Actualiza la posici¢n actual de la FICHA en el tablero e informa
de posibles colisiones (choque con otras piezas).
*******/
if ( !pausa )
{
// Si no estamos en pausa y la pieza ha cambiado
if ( tocaMover==true || (partidaActual.piezaActual.proxX!=partidaActual.piezaActual.posX || partidaActual.piezaActual.rotacion != partidaActual.piezaActual.proxRot ) )
colision = actualizaFicha(tocaMover);
/**** SEGUNDA MITAD DEL CONTROL DE TIEMPO */
if ( tocaMover == true )
{
start = clock();
tocaMover = false;
}
/****** CONTROL DE COLISIONES
Fija la ficha en el tablero en caso de colision y procesa
posibles eliminaciones de linea/piezas.
*******/
if ( colision )
{
fijaPieza(); // Fijamos la pieza en el tablero
procesaColision(); // Procesamos la colision
partidaActual.piezaActual = obtenerPieza();
colision = false;
tocaMover = true;
}
// Demostracion de que nada se detiene
AnimaticaTimeSlice();
}
}
}
// Hacemos la ficha permanente en el tablero
void fijaPieza()
{
int X,Y, rotacion; // posicion base
X = partidaActual.piezaActual.posX;
Y = partidaActual.piezaActual.posY;
rotacion = partidaActual.piezaActual.rotacion;
switch ( partidaActual.piezaActual.tipo )
{
case PIEZA_CUADRADA:
partidaActual.tablero[Y][X] =PIEZA_CUADRADA;
partidaActual.tablero[Y+1][X] =PIEZA_CUADRADA;
partidaActual.tablero[Y][X+1] =PIEZA_CUADRADA;
partidaActual.tablero[Y+1][X+1] =PIEZA_CUADRADA;
break;
case PIEZA_LINEA:
if ( rotacion == 0 || rotacion == 2 )
{
partidaActual.tablero[Y][X] =PIEZA_LINEA;
partidaActual.tablero[Y+1][X]=PIEZA_LINEA;
partidaActual.tablero[Y+2][X]=PIEZA_LINEA;
} else {
partidaActual.tablero[Y][X] =PIEZA_LINEA;
partidaActual.tablero[Y][X+1]=PIEZA_LINEA;
partidaActual.tablero[Y][X+2]=PIEZA_LINEA;
}
break;
case PIEZA_Lizq:
switch( rotacion )
{
case 0: // |_
partidaActual.tablero[Y][X] = PIEZA_Lizq;
partidaActual.tablero[Y+1][X] = PIEZA_Lizq;
partidaActual.tablero[Y+2][X] = PIEZA_Lizq;
partidaActual.tablero[Y+2][X+1] = PIEZA_Lizq;
break;
case 1: // |ùùù
partidaActual.tablero[Y][X] = PIEZA_Lizq;
partidaActual.tablero[Y+1][X] = PIEZA_Lizq;
partidaActual.tablero[Y][X+1] = PIEZA_Lizq;
partidaActual.tablero[Y][X+2] = PIEZA_Lizq;
break;
case 2: // ù|
partidaActual.tablero[Y][X] = PIEZA_Lizq;
partidaActual.tablero[Y][X+1] = PIEZA_Lizq;
partidaActual.tablero[Y+1][X+1] = PIEZA_Lizq;
partidaActual.tablero[Y+2][X+1] = PIEZA_Lizq;
break;
case 3: // ___|
partidaActual.tablero[Y][X+2] = PIEZA_Lizq;
partidaActual.tablero[Y+1][X] = PIEZA_Lizq;
partidaActual.tablero[Y+1][X+1] = PIEZA_Lizq;
partidaActual.tablero[Y+1][X+2] = PIEZA_Lizq;
break;
}
break;
case PIEZA_Lder:
switch( rotacion )
{
case 0: // Ü
// ÜÛ
partidaActual.tablero[Y][X+1] = PIEZA_Lder;
partidaActual.tablero[Y+1][X+1] = PIEZA_Lder;
partidaActual.tablero[Y+2][X] = PIEZA_Lder;
partidaActual.tablero[Y+2][X+1] = PIEZA_Lder;
break;
case 1: // ÛÜÜÜ
partidaActual.tablero[Y][X] = PIEZA_Lder;
partidaActual.tablero[Y+1][X] = PIEZA_Lder;
partidaActual.tablero[Y+1][X+1] = PIEZA_Lder;
partidaActual.tablero[Y+1][X+2] = PIEZA_Lder;
break;
case 2: // Ûß
// Û
partidaActual.tablero[Y][X] = PIEZA_Lder;
partidaActual.tablero[Y][X+1] = PIEZA_Lder;
partidaActual.tablero[Y+1][X] = PIEZA_Lder;
partidaActual.tablero[Y+2][X] = PIEZA_Lder;
break;
case 3: // ßßßÛ
partidaActual.tablero[Y][X] = PIEZA_Lder;
partidaActual.tablero[Y][X+1] = PIEZA_Lder;
partidaActual.tablero[Y][X+2] = PIEZA_Lder;
partidaActual.tablero[Y+1][X+2] = PIEZA_Lder;
break;
}
break;
case PIEZA_Rizq:
switch( rotacion )
{
case 0: // ßÛÜ
case 2:
partidaActual.tablero[Y][X] = PIEZA_Rizq;
partidaActual.tablero[Y][X+1] = PIEZA_Rizq;
partidaActual.tablero[Y+1][X+1] = PIEZA_Rizq;
partidaActual.tablero[Y+1][X+2] = PIEZA_Rizq;
break;
case 1: // ÜÛ
case 3: // ß
partidaActual.tablero[Y][X+1] = PIEZA_Rizq;
partidaActual.tablero[Y+1][X+1] = PIEZA_Rizq;
partidaActual.tablero[Y+1][X] = PIEZA_Rizq;
partidaActual.tablero[Y+2][X] = PIEZA_Rizq;
break;
}
break;
case PIEZA_Rder:
switch( rotacion )
{
case 0: // ÜÛß
case 2:
partidaActual.tablero[Y][X+1] = PIEZA_Rder;
partidaActual.tablero[Y][X+2] = PIEZA_Rder;
partidaActual.tablero[Y+1][X] = PIEZA_Rder;
partidaActual.tablero[Y+1][X+1] = PIEZA_Rder;
break;
case 1: // ÛÜ
case 3: // ß
partidaActual.tablero[Y][X] = PIEZA_Rder;
partidaActual.tablero[Y+1][X] = PIEZA_Rder;
partidaActual.tablero[Y+1][X+1] = PIEZA_Rder;
partidaActual.tablero[Y+2][X+1] = PIEZA_Rder;
break;
}
break;
case PIEZA_T:
switch( rotacion )
{
case 0: // ÜÛÜ
partidaActual.tablero[Y][X+1] = PIEZA_T;
partidaActual.tablero[Y+1][X] = PIEZA_T;
partidaActual.tablero[Y+1][X+1] = PIEZA_T;
partidaActual.tablero[Y+1][X+2] = PIEZA_T;
break;
case 1: // ÛÜ
// ß
partidaActual.tablero[Y][X] = PIEZA_T;
partidaActual.tablero[Y+1][X] = PIEZA_T;
partidaActual.tablero[Y+1][X+1] = PIEZA_T;
partidaActual.tablero[Y+2][X] = PIEZA_T;
break;
case 2: //ÜÜÜ
// ß
partidaActual.tablero[Y][X] = PIEZA_T;
partidaActual.tablero[Y][X+1] = PIEZA_T;
partidaActual.tablero[Y][X+2] = PIEZA_T;
partidaActual.tablero[Y+1][X+1] = PIEZA_T;
break;
case 3: // ÜÛ
// ß
partidaActual.tablero[Y][X+1] = PIEZA_T;
partidaActual.tablero[Y+1][X] = PIEZA_T;
partidaActual.tablero[Y+1][X+1] = PIEZA_T;
partidaActual.tablero[Y+2][X+1] = PIEZA_T;
break;
}
break;
}
}
void procesaColision()
{
int X,Y,A, i,j;
bool noHayLINEA[3]={true,true,true}; // 3 es el alto MAXIMO de una PIEZA
// Miramos la pieza actual y vemos si consiguio una linea...
A = altoPieza( partidaActual.piezaActual );
X = partidaActual.piezaActual.posX;
Y = partidaActual.piezaActual.posY;
// Vemos si DE LAS POSIBLES LINEAS (alto de la ficha) DONDE ENCAJO
// alguna ha podido hacer linea.
for( i=0; i<A && i<3; i++ )
{
noHayLINEA[i] = false; // Inicialmente HAY linea
// En el momento que exista un HUECO en la HORIZONTAL, la cagaste
for ( j=0; j<ANCHO_TABLERO && noHayLINEA[i]==false; j++ )
noHayLINEA[i] = (partidaActual.tablero[Y+i][j] == 0) ? true : false;
}
// Ademas hace rato que me canse de "describir" y "comentar" el programa
if ( noHayLINEA[0]==false || noHayLINEA[1]==false || noHayLINEA[2]==false )
{
// Actualizamos el tablero
if ( noHayLINEA[0]==false )
eliminaLineaTablero( Y );
if ( noHayLINEA[1]==false )
eliminaLineaTablero( Y+1 );
if ( noHayLINEA[2]==false )
eliminaLineaTablero( Y+2 );
// ESTO DETENDRA LA EJECUCION DEL PROGRAMA
// PERO WUUUEEENO, ESTO SOLO ES UN EJEMPLO QUE MAS QUEREIS
for(i=0;i<10;i++)
if ( noHayLINEA[j]==false )
{
for( j=0;j<A;j++) {
gotoxy( 2,Y+1+j ); textcolor(GREEN); cprintf("±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±");
}
delay(50);
for( j=0;j<A;j++) {
gotoxy( 2,Y+1+j ); textcolor(LIGHTGREEN); cprintf("²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²");
}
delay(100);
for( j=0;j<A;j++) {
gotoxy( 2,Y+1+j ); textcolor(WHITE); cprintf("ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ");
}
delay(50);
}
RedibujaTablero();
}
}
/*
La colision de una pieza en el tablero, depende del tipo, rotacion
y posiciones dentro de este.
*/
bool piezaColisiona( char tablero[ALTO_TABLERO][ANCHO_TABLERO], pieza P )
{
bool colision;
colision = false;
/*
// Solo si no estamos en el borde del tablero
colision = ( P.posX < 0 );
*/
/*
// COLISION por la derecha FRUTO DE UNA ROTACION
colision = ( ((P.posX+anchoPieza(P)) > ANCHO_TABLERO) );
*/
// Comprobamos una posible colision con la base del tablero
if ( colision == false )
colision = ((P.posY+altoPieza(P)) > ALTO_TABLERO );
// Comprobamos colisiones DENTRO DEL TABLERO
/***********/
if ( colision == false && P.tipo==PIEZA_CUADRADA)
colision = tablero[P.posY+1][P.posX]!=0 || tablero[P.posY+1][P.posX+1]!=0 ||
tablero[P.posY][P.posX]!=0 || tablero[P.posY][P.posX+1]!=0;
if ( colision == false && P.tipo==PIEZA_LINEA )
{
if ( P.rotacion == 0 || P.rotacion == 2 )
colision = tablero[P.posY+0][P.posX]!=0 ||
tablero[P.posY+1][P.posX]!=0 ||
tablero[P.posY+2][P.posX]!=0
;
else
colision = (tablero[P.posY][P.posX]!=0 ||
tablero[P.posY][P.posX+1]!=0 ||
tablero[P.posY][P.posX+2]!=0 );
}
if ( colision == false && P.tipo==PIEZA_Lizq )
{
switch( P.rotacion )
{
case 0: // |_
colision = tablero[P.posY+2][P.posX] != 0 ||
tablero[P.posY+2][P.posX+1] != 0 ||
tablero[P.posY+0][P.posX]!=0 ||
tablero[P.posY+1][P.posX]!=0;
break;
case 1: // |ùùù
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY][P.posX+1] != 0 ||
tablero[P.posY][P.posX+2] != 0 ||
tablero[P.posY][P.posX]!=0;
break;
case 2: // ù|
colision = tablero[P.posY][P.posX] != 0 ||
tablero[P.posY+2][P.posX+1] != 0||
tablero[P.posY+0][P.posX+1]!=0 ||
tablero[P.posY+1][P.posX+1]!=0;
break;
case 3: // |___
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX+2] != 0 ||
tablero[P.posY][P.posX]!=0;
break;
}
}
if ( colision == false && P.tipo==PIEZA_Lder )
{
switch( P.rotacion )
{
case 0: // Ü
// ÜÛ
colision = tablero[P.posY+2][P.posX] != 0 ||
tablero[P.posY+2][P.posX+1] != 0 ||
tablero[P.posY+0][P.posX+1]!=0 ||
tablero[P.posY+1][P.posX+1]!=0;
break;
case 1: // ÛÜÜÜ
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX+2] != 0 ||
tablero[P.posY][P.posX]!=0;
break;
case 2: // Ûß
// Û
colision = tablero[P.posY][P.posX+1] != 0 ||
tablero[P.posY+2][P.posX] != 0 ||
tablero[P.posY][P.posX]!=0 ||
tablero[P.posY+1][P.posX]!=0;
break;
case 3: // ßßßÛ
colision = tablero[P.posY][P.posX] != 0 ||
tablero[P.posY][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX+2] != 0 ||
tablero[P.posY][P.posX+2]!=0;
break;
}
}
if ( colision == false && P.tipo==PIEZA_Rizq )
{
switch( P.rotacion )
{
case 0: // ßÛÜ
case 2:
colision = tablero[P.posY][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX+2] != 0 ||
tablero[P.posY][P.posX+1]!=0;
break;
case 1: // ÜÛ
case 3: // ß
colision = tablero[P.posY+2][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX]!=0 ||
tablero[P.posY+1][P.posX+1]!=0;
break;
}
}
if ( colision == false && P.tipo==PIEZA_Rder )
{
switch( P.rotacion )
{
case 0: // ÜÛß
case 2:
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY][P.posX+2] != 0 ||
tablero[P.posY+0][P.posX+1]!=0;
break;
case 1: // ÛÜ
case 3: // ß
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY+2][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX]!=0 ||
tablero[P.posY+1][P.posX+1]!=0;
break;
}
}
if ( colision == false && P.tipo==PIEZA_T )
{
switch( P.rotacion )
{
case 0: // ÜÛÜ
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY+1][P.posX+2] != 0 ||
tablero[P.posY+0][P.posX+1]!=0;
break;
case 1: // ÛÜ
// ß
colision = tablero[P.posY+2][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY+0][P.posX]!=0 ||
tablero[P.posY+1][P.posX]!=0;
break;
case 2: //ÜÜÜ
// ß
colision = tablero[P.posY][P.posX] != 0 ||
tablero[P.posY+1][P.posX+1] != 0 ||
tablero[P.posY][P.posX+2] != 0 ||
tablero[P.posY][P.posX+1]!=0;
break;
case 3: // ÜÛ
// ß
colision = tablero[P.posY+1][P.posX] != 0 ||
tablero[P.posY+2][P.posX+1] != 0 ||
tablero[P.posY][P.posX+1]!=0 ||
tablero[P.posY+1][P.posX+1]!=0;
break;
}
}
/************/
return colision;
}
/**********
Este proceso se encarga de actualizar la pieza en la pantalla, e informar
en caso de colision con otra pieza del tablero.
***********/
bool actualizaFicha(bool bajarFicha)
{
bool colision;
int alturaPieza, rot, x;
pieza nuevaPosicionPieza;
// Primero borramos la pieza anterior sobre el tablero
// (esto se hace dibujandola del color de fondo).
dibujaPieza( partidaActual.piezaActual, 0 );
// Esta sera la nueva posicion de la pieza (en caso de no colision)
nuevaPosicionPieza = partidaActual.piezaActual;
// COLISION por la derecha FRUTO DE UNA ROTACION
rot = nuevaPosicionPieza.rotacion;
nuevaPosicionPieza.rotacion = nuevaPosicionPieza.proxRot;
colision = ( ((nuevaPosicionPieza.posX+anchoPieza(nuevaPosicionPieza)) > ANCHO_TABLERO) );
if ( colision == true )
{
nuevaPosicionPieza.proxRot = rot;
nuevaPosicionPieza.rotacion = rot;
}
if ( bajarFicha == true )
nuevaPosicionPieza.posY++;
// Parece que intenta mover la pieza HORIZONTALMENTE
if ( nuevaPosicionPieza.posX != nuevaPosicionPieza.proxX )
{
x = nuevaPosicionPieza.posX;
nuevaPosicionPieza.posX = nuevaPosicionPieza.proxX;
// Si el desplazamiento horizontal hace colisionar la pieza, se aborta este
if ( piezaColisiona( partidaActual.tablero, nuevaPosicionPieza) )
nuevaPosicionPieza.posX = x;
}
// Miramos si podemos bajar la pieza un punto hacia abajo.
colision = piezaColisiona( partidaActual.tablero, nuevaPosicionPieza );
// Si no hay colisi¢n, entonces actualizamos la posicion de la pieza
if ( colision==false )
partidaActual.piezaActual = nuevaPosicionPieza;
// Finalmente dibujamos la pieza
dibujaPieza( partidaActual.piezaActual, colorPieza(partidaActual.piezaActual) );
return colision;
}
// Elegimos un color para cada tipo de pieza
int colorPieza(pieza P)
{
return P.tipo+1;
}
// Esta funcion dibuja una figura al azar en el rectangulo definido
void AnimaticaTimeSlice(void)
{
static bool reiniciarTIMER = false;
static clock_t s;
static pieza p = obtenerPieza();
if ( reiniciarTIMER == true )
{
reiniciarTIMER = false;
s=clock();
}
if ( (clock()-s)/CLK_TCK > 0.1 )
{
dibujaPieza( p, 0 );
p = obtenerPieza();
p.posX = 16 + random(12);
p.posY = 2 + random(5);
dibujaPieza( p, random(15) );
reiniciarTIMER = true;
}
/* REPRESENTO EL ESTADO ACTUAL DEL TABLERO
/// HAY QUE SABER QUE HAY PARA VER SI TODO VA BIEN ////
123456789012345
60
Üß Û
*/
for (int i=0;i<ANCHO_TABLERO;i++)
for (int j=0; j<ALTO_TABLERO;j++)
{ gotoxy( 60+i,2+j);
textcolor(partidaActual.tablero[j][i]);
cprintf("þ",partidaActual.tablero[j][i]);
}
}
/////////////////////////////////////////////////////////////////////////
//////// ESTO SON SOLO CHORRADITAS DECORATIVAS PARA PERDER EL TIEMPO ////
/////////////////////////////////////////////////////////////////////////
void dibujaPiezaHUECA( pieza P, int color )
{
int X, Y;
X = P.posX*2+2; // Coordenas iniciales para dibujar
Y = P.posY+1; // mas una correcci¢n visual (hay que encajar
// el tablero en la pantalla)
textcolor(color); // Establecemos el color de la pieza
switch( P.tipo )
{
/*******************
ROTACION 0 ROTACION 1 ROTACION 2 ROTACION 3
*********************/
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
case PIEZA_CUADRADA:
switch( P.rotacion )
{
case 0:
case 1:
case 2:
case 3:
gotoxy(X,Y); cprintf("ÚÄÄ¿");
gotoxy(X,Y+1); cprintf("ÀÄÄÙ");
break;
}
break;
// ÛÛ
// ÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ
// ÛÛ
case PIEZA_LINEA:
switch( P.rotacion )
{
case 0:
case 2:
gotoxy(X,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("³³");
gotoxy(X,Y+2); cprintf("ÀÙ");
break;
case 1:
case 3:
gotoxy(X,Y); cprintf("ÍÍÍÍÍÍ");
break;
}
break;
// ÛÛ ÛÛ
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ
case PIEZA_Rizq:
switch( P.rotacion )
{
case 0:
case 2:
gotoxy(X,Y); cprintf("ÍÍ¿¿");
gotoxy(X+2,Y+1); cprintf("ÀÀÍÍ");
break;
case 1:
case 3:
gotoxy(X+2,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("ÚÍÍÙ");
gotoxy(X,Y+2); cprintf("ÀÙ");
break;
}
break;
// ÛÛ ÛÛ
// ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛ ÛÛ ÛÛÛÛ ÛÛ
case PIEZA_Rder:
switch( P.rotacion )
{
case 0:
case 2:
gotoxy(X+2,Y) ; cprintf("ÚÚÍÍ");
gotoxy(X,Y+1); cprintf("ÍÍÙÙ");
break;
case 1:
case 3:
gotoxy(X,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("ÀÍÍ¿");
gotoxy(X+2,Y+2); cprintf("ÀÙ");
break;
}
break;
// ÛÛ ÛÛÛÛ
// ÛÛ ÛÛÛÛÛÛ ÛÛ ÛÛ
// ÛÛÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ
case PIEZA_Lizq:
switch( P.rotacion )
{
case 0:
gotoxy(X,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("³³");
gotoxy(X,Y+2); cprintf("ÀÄÍÙ");
break;
case 1:
gotoxy(X,Y); cprintf("ÚÍÍÍÍÍ");
gotoxy(X,Y+1); cprintf("ÀÙ");
break;
case 2:
gotoxy(X,Y); cprintf("ÚÍÍ¿");
gotoxy(X+2,Y+1); cprintf("³³");
gotoxy(X+2,Y+2); cprintf("ÀÙ");
break;
case 3:
gotoxy(X+4,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("ÍÍÍÍÍÙ");
break;
}
break;
// ÛÛ ÛÛÛÛ
// ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ
// ÛÛÛÛ ÛÛÛÛÛÛ ÛÛ ÛÛ
case PIEZA_Lder:
switch( P.rotacion )
{
case 0:
gotoxy(X+2,Y); cprintf("Ú¿");
gotoxy(X+2,Y+1); cprintf("³³");
gotoxy(X,Y+2); cprintf("ÀÍÍÙ");
break;
case 1:
gotoxy(X,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("ÀÍÍÍÍÍ");
break;
case 2:
gotoxy(X,Y); cprintf("ÚÍÍÍ");
gotoxy(X,Y+1); cprintf("³³");
gotoxy(X,Y+2); cprintf("ÀÙ");
break;
case 3:
gotoxy(X,Y); cprintf("ÍÍÍÍÍ¿");
gotoxy(X+4,Y+1); cprintf("ÀÙ");
break;
}
break;
// ÛÛ ÛÛ
// ÛÛ ÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛ
// ÛÛÛÛÛÛ ÛÛ ÛÛ ÛÛ
case PIEZA_T:
switch( P.rotacion )
{
case 0:
gotoxy(X+2,Y); cprintf("É»");
gotoxy(X,Y+1); cprintf("ÍÍÊÊÍÍ");
break;
case 1:
gotoxy(X,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("³ÌÍÍ");
gotoxy(X,Y+2); cprintf("ÀÙ");
break;
case 2:
gotoxy(X,Y); cprintf("ÍÍËËÍÍ");
gotoxy(X+2,Y+1); cprintf("ȼ");
break;
case 3:
gotoxy(X+2,Y); cprintf("Ú¿");
gotoxy(X,Y+1); cprintf("Í͹³");
gotoxy(X+2,Y+2); cprintf("ÀÙ");
break;
}
break;
}
}