Código fuente de la clase Cgridcellcheck
#Contiene "stdio.h"
#Contiene "bios.h"
#Contiene "dos.h"
#Include "graphics.h"
#Include " string.h "
#Include " stdlib.h "
#Definición verdadera 1
#define false 0
#define ancho del tablero 12
#define alto del tablero 23
# define _INNER_HELPER /* Método auxiliar interno*/
/*Definición de código de escaneo*/
Códigos de clave de enumeración
{
K_ESC = 0x011b, p>
K_UP =0x4800, /*flecha arriba*/
K_LEFT =0x4b00,
K_DOWN =0x5000,
K_RIGHT = 0x4d00, p>
K_SPACE =0x3920,
K_P =0x1970
};
/*Bloquear estructura de datos*/
typedef bloque de etiquetas de estructura
{
char c[4][4]; /*matriz de información de llenado de celdas, 0 vacía, 1 llena*/
int x; /*Posición del módulo cx [0, BoardWidht -1] */
int y /*Posición del bloque cy [-4, Altura del tablero-1] */
Color del carácter; /*Color del bloque*/
Tamaño del carácter; /*Ancho o alto máximo del bloque*/
Nombre del personaje /*Nombre del bloque (forma del bloque)*/
}bloque;
/*Información global del juego*/
int frame time = 1300;
int CellSize = 18; p>
int BoardLeft = 30
int BoardTop = 30
/*Siguiente bloque grid*/
int NBBoardLeft = 300
int NBBoardTop = 30
int NBCellSize = 10;
/*Posición del marcador*/
int ScoreBoardLeft = 300
int parte superior del marcador = 100;
int ancho del marcador = 200;
int ScoreBoardHeight = 35
int ScoreColor = LIGHTCYAN
/*Información posición del texto*/
int InfoLeft = 300
int InfoTop = 200
int InfoColor = amarillo;
int BorderColor = DARKGRAY
int BkGndColor = BLACK
int GameRunning = true
int TopLine = altura del tablero-1 ;/*Línea en blanco en la parte superior*/
int puntuación total = 100;
char info _ puntuación[20];
char info _ ayuda[255] ;
char info_common[255];
/*Nuestro tablero, Tablero[x][y][0]-relleno, Tablero[x][y] [1]-color de relleno */
Tablero de caracteres sin firmar [Ancho del tablero
][Altura del tablero][2];
unidad de búfer de caracteres[4][4];/*Se utiliza para determinar si el bloque se puede girar*/
Bloqueo de bordillos;/ * Bloque en movimiento actual*/
Bloque siguienteBloque/*El siguiente bloque en aparecer*/
/*Lista de funciones*/
int obtener código clave() ;
int CanMove(int dx, int dy);
int puede rotar();
int rotar Bloque(Bloque * Bloque);
int MoveBlock(Bloque *bloque, int dx, int dy);
void DrawBlock(Bloque *bloque, int, int, int);
void EraseBlock(Bloque *bloque, int, int, int);
void DisplayScore().
anular información de visualización (char * texto);
anular generar bloque (Bloque * Bloque);
anular siguiente bloque();
void init game();
int PauseGame();
void quit game();
/*Obtener código clave*/ p >
int _INNER_HELPER GetKeyCode()
{
int clave = 0;
if(bioskey(1))
{
tecla = tecla BIOS(0);
}
tecla Enter;
}
/ *¡Mostrar texto! */
void _ INNER _ HELPER mostrar información(char * text)
{
establecer color(BkGndColor);
outtextxy (InfoLeft, InfoTop, info_common);
strcpy(info_common, texto
establecer color(info color);
outtextxy(InfoLeft, InfoTop, info_common); );
}
/*Crea un nuevo bloque por número de clave,
*El bloque está anclado en la parte superior izquierda del Angular de 4*4 celdas.
*/
void _ INNER _ AYUDANTE generar Bloque(Bloque * Bloque)
{
int key =(random( 13 )* random(17)+random(1000)+random(3000))% 7;
bloque->; tamaño = 3 /* porque la mayoría de los bloques tienen tamaño = 3 */ p>
memset(bloque->c,0,16);
interruptor(clave)
{
Caso 0:
p>bloque->; nombre = ' T
bloque->; color = rojo;
bloque->; >
bloque->;c[1][1]=1, bloque->;c[2][1]= 1;
bloque->;c[1][ 2] = 1;
Rotura;
Caso 1:
bloque->; nombre = ' L
bloque->; amarillo;
bloque->;c[1][0]= 1;
bloque->;c[1][1]= 1;
bloque->;c[1][2]=1, bloque->;c[2][2]= 1;
Romper;
Caso 2: p>
bloque->; nombre = ' J
bloque->; color = gris claro
bloque->;
bloque->c[1][1]= 1;
bloque->c[1][2]=1, bloque->c[ 0][2] = 1;
Rotura;
Caso 3:
bloque->; nombre = ' z
bloque ->Color=cian ;
bloque->c[0][0]=1, bloque->c[1][0]= 1;
bloque->c[1][ 1]
=1, bloque->; c[2][1]= 1;
Romper;
Caso 4:
nombre del bloque = ' 5
bloque->; color = azul claro;
bloque->; c[1][0]=1, bloque->;c[2][0] = 1;
bloque->; c[0][1]=1, bloque->; c[1][1]= 1;
Caso 5:
bloque->; nombre = ' o
bloque->; color = azul
tamaño de bloque = 2
bloque->; c[0][0]=1, bloque-> c[1][0]=
bloque->; ][1]=1, bloque->; c[1][1]= 1;
Romper
Caso 6:
bloque-> nombre = ' I
bloque-> color = verde
bloque-> tamaño = 4
bloque->c [1][0]= 1;
bloque->; c[1][1]= 1;
bloque->; c[1][2]= 1 ;
bloque ->;c[1][3]= 1;
Descanso;
}
}
/*Obtener el siguiente ¡bloquear! */
void NextBlock()
{
/*Copia el siguiente bloque en curBlock */
curb lock =. tamaño del siguiente bloque;
color del bloqueo del bordillo = color del siguiente bloque;
bloqueo del bordillo x =(ancho del tablero-4)/2;
bloqueo de acera. y =-bloqueo de acera.
memcpy(curBlock.c, nextBlock.c, 16);
/*Generar siguienteBlock*/ p >
borrar bloque(& nextBlock, NBBoardLeft, NBBoardTop, NBCellSize);
generar bloque(& siguiente bloque);
nextBlock.x=1, siguiente bloque y =. 0;
Stretcher(& ampnextBlock, NBBoardLeft, NBBoardTop, NBCellSize
}
/*Rotar bloque, actualizar datos de estructura del bloque*/
int _ INNER _ HELPER RotateCells(char c[4][4], char blockSize)
{
Temperatura de carga, I, j;
Cambiar (tamaño de bloque)
{
Caso 3:
temp = c[0][0];
c [0][0]=c[2][0], c[2][0]=c[2][2], c[2][2]=c[0] [2], c[0 ][2]=temp;
temp = c[0][1];
c[0][1]=c[1] [0], c[1 ][0]=c[2][1], c[2][1]=c[1][2], c[1][2]= temp;
Descanso; p>
Caso 4: /*¡Aquí sólo está el bloque "I"! */
c[1][0]= 1-c[
1][0], c[1][2]= 1-c[1][2], c[1][3]= 1-c[1][3];
c [0][1]= 1-c[0][1], c[2][1]= 1-c[2][1], c[3][1]= 1-c[3][ 1];
Romper;
}
}
/*Determinar si el bloque puede moverse en la dirección*/ p>
int CanMove(int dx, int dy)
{
int i, j, tempX, tempY
for(I = 0; i & ltcurBlock.sizei++)
{
for(j = 0; j & ltcurBlock.sizej++)
{
if( curBlock. c[i][j])
{
/*No se puede mover hacia la izquierda o hacia la derecha*/
tempX = bloqueo de acera. ;
if(tempX & lt;0 | | tempX & gt(BoardWidth-1)) devuelve false/*¡Asegúrate de que x sea válido! */
/*No se puede bajar*/
tempY = bloqueo de acera .
if(tempY & gt;(BoardHeight - 1)) Devolver false/* y es solo verificar el límite inferior, ¡que puede ser negativo! ! ! ! */
/*La celda ya está llena, ¡debemos verificar el límite superior de Y antes de verificar la celda! */
if(tempY & gt; = 0 & amp& ampBoard[tempX][tempY][0]) devuelve falso
}
} p>
}
Devuelve verdadero
}
/*Determina si el bloque de construcción se puede rotar*/
int CanRotate()
{
int i, j, tempX, tempY
/*Actualizar buffer*/
memcpy(BufferCells, curBlock. c, 16);
RotateCells(BufferCells, bloqueo de acera . tamaño); /p>
for(j = 0;j & ltcurBlock.sizej++)
{
if(BufferCells[i][j])
{
tempX = bloqueo de acera . x+I;
tempY = bloqueo de acera .
if(tempX & lt; 0 | | tempX & gt(Ancho del tablero-1))
Devuelve falso
if(tempY & gt; (Alto del tablero-1))
Devuelve falso
if(tempY>= 0&& tablero[temporal][temporal][0])
devuelve falso
}
}
}
Devuelve verdadero
}
/*Dibujar el cuadro*/
void _ INNER _ HELPER dibujar Bloquear( Bloque * Bloque, int bdLeft, int bdTop, int cellSize)
{
int i, j;
setfillstyle(SOLID_FILL, block ->color) ;
for(i = 0;i<block->tamaño;i++)
{
for(j = 0;j<block->; tamaño; j++)
{
if(bloque->c[I][j]& & amp(bloque->y+j)>=0)
{
Relleno de inundación(
BD izquierda+tamaño de celda *(I+bloque->x)+tamaño de celda/2,
BD superior+tamaño de celda *(j +bloque-& gt;y)+tamaño de celda/2,
color del borde);
}
}
}
}
/*Gira el bloque, si tiene éxito, devuelve verdadero */
int RotateBlock(Bloquear * bloque)
{
Temperatura de carga, I, j;
int b _ Success
if(block->; size = =2)
Regresar verdadero
if(( b_success=CanRotate()))
{
EraseBlock(bloque, BoardLeft, BoardTop, CellSize);
memcpy(curBlock.c, BufferCells, 16);
DrawBlock(bloque, BoardLeft, BoardTop, tamaño de celda);
}
Devuelve b_success;
}
/* Borrar un bloque y llenar solo las celdas llenas con el color de fondo*/
void _ INNER _ HELPER borrar Bloque(Bloque * Bloque, int bdLeft, int bdTop, int cellSize)
{
int i, j;
setfillstyle(SOLID_FILL,BkGndColor);
for(i = 0;i<block->tamaño;i++)
{
for(j = 0 ;j<block->tamañoj++)
{
if(block->c[I][j]& &(block->y +j>=0))
{
Relleno de inundación( p>
BD izquierda+tamaño de celda *(I+bloque->x)+ tamaño de celda/2,
BD arriba+tamaño de celda *(j+bloque->y)+tamaño de celda/ 2,
color del borde);
}
}
}
}
/*Si puedes, muévete en la dirección, si no, no lo hagas
*Valor de retorno: verdadero - exitoso, falso - no puedes moverte en esta dirección
*/
int MoveBlock(Bloque *bloque, int dx, int dy)
{
int b_canmove=CanMove(dx,dy);
if(b_canmove)
{
EraseBlock(bloque, BoardLeft, BoardTop, CellSize
bloqueo de acera
p>bloqueo de acera. y+= dy;
DrawBlock(bloque).
k, BoardLeft, BoardTop, tamaño de celda);
}
Regresar b _ canmove
}
/*Soltar el bloque a el departamento de abajo! */
int DropBlock(Bloquear *bloque)
{
EraseBlock(bloque, BoardLeft, BoardTop, CellSize
mientras); (CanMove(0, 1))
{
bloqueo de acera. y++;
}
DrawBlock(bloque, BoardLeft, BoardTop). , tamaño de celda);
Return 0; /*El valor de retorno se asigna al activo del bloque */
}
/*Inicializa los gráficos. mode y dibuja el tablero de ajedrez Grid*/
void InitGame()
{
int i,j,gdriver=DETECT,gmode
Estructurar sistema de tiempo;
/*Celda de la mesa de trabajo*/
memset(Tablero, 0, Ancho del tablero * Alto del tablero * 2);
memset(nextBlock .c, 0, 16);
strcpy(info_help, "P: Pausa el juego.
- por gangster 1980");
init graph(&g driver &gmode, "";
establecer color(color del borde);
for(I = 0 ;i<=ancho del tablero;i++)
{
line(BoardLeft+i*CellSize, BoardTop, BoardLeft+i*CellSize, tablero superior+ altura del tablero * CellSize);
}
for(I = 0;i<= BoardHeighti++)
{
línea( BoardLeft, BoardTop+i*CellSize, BoardLeft+BoardWidth *CellSize, tablero superior+I * CellSize);
}
/*Rectángulo del borde exterior de la mesa de trabajo*/
Rectángulo (BoardLeft-CellSize/4, BoardTop -CellSize/4,
tablero izquierdo+ancho del tablero * CellSize+CellSize/4,
tablero superior+alto del tablero * CellSize+ CellSize/4);
/*Dibuja la cuadrícula del siguiente bloque*/
for(I = 0;i<=4;i++)
{
line(NBBoardLeft+i*NBCellSize , NBBoardTop, NBBoardLeft+i*NBCellSize, nbboard top+4 * NBCellSize);
línea(NBBoardLeft, NBBoardTop+i*NBCellSize, NBBoardLeft +4*NBCellSize, nbboard top+I * NBCellSize); p>
}
/*Dibujar rectángulo de puntuación*/
Rectángulo (ScoreBoardLeft, ScoreBoardTop, ScoreBoardLeft+ ScoreBoardWidth, parte superior del tablero de puntuación+altura del tablero de puntuación);
display score();
/*Establecer una nueva semilla */
gettime(& amp; sysTime);
srand(systime . ti _ hora * 360systime . ti _ min * 6systime . el primer bloque*/
setcolor(gris oscuro);
outtextxy(InfoLeft, InfoTop+20, "Rotar espacio arriba-abajo"); (InfoLeft, InfoTop+35, "Izquierda-Izquierda-Derecha-Derecha");
outtextxy(InfoLeft, InfoTop+50, " Esc-exit "); info_help);
}
/*Establecer datos isFilled y color de relleno en cartón*/
void _INNER_HELPER FillBoardData()
{
int i, j;
para(I = 0; i<
curBlock.sizei++)
{
for(j = 0; j & ltcurBlock.sizej++)
{
if(bloqueo de acera c[I][j]& &(bloqueo de acera . y+j)& gt;=0)
{
tablero[bloqueo de acera x+I ][acera. bloquear . y+j][0]= 1;
tablero[bloqueo de acera x+I][bloqueo de acera . p>tablero[bloqueo de acera . p>
}
}
}
}
/*Dibuja una línea en el tablero*/
void _INNER_HELPER PaintBoard()
{
int i, j, fillcolor
for(j=max( (TopLine-4), 0 );j<board height;j++)
{
for(I = 0;i<board width;i++)
{ p >
fillcolor=Tablero[i][j][0]? tablero[I][j][1]:BkGndColor;
setfillstyle(SOLID_FILL, FILL color);
relleno de inundación (tablero izquierdo+I * CellSize+CellSize/2, BoardTop +j*CellSize+CellSize/2, color del borde);
}
}
}
/*Compruebe si una fila ¡Se completa en su totalidad y aumenta tu puntuación total! */
void _INNER_HELPER CheckBoard()
{
int i, j, k, puntuación=10, suma=0, topy, líneas = 0;
/*¡Encontramos la línea vacía en la parte superior! */
j = topy = altura del tablero-1;
Hacer
{
suma = 0;
for(I = 0;i<board width;i++)
{
suma+= Tablero[I][topy][0];
}
topy-;
} while(sum & gt;0 & amp& amptopy & gt0);
/*Eliminar filas completadas (Número máximo de filas eliminadas = 4) */
Hacer
{
suma = 0;
for(I = 0; i<BoardWidth;i++) p>
sum+= Board[I][j][0];
Si (sum==BoardWidth)/* encontramos que esta línea está llena Si está llena, ¡bórrala! */
{
/*Mover los datos de la celda una fila hacia abajo*/
for(k = j; k & gttopyk -)
{
for(I = 0;i & ltancho del tablero;i++)
{
Tablero[I][k][0] =Tablero [I][k-1][0];
Tablero[I][k][1]=Tablero[I][k-1][1];
}
}
/*¡Deja vacía la fila superior! */
for(I = 0;i<board width;i++)
{
tablero[I][topy][0]= 0 ; p>
tablero[I][topy][1]= 0
;
}
topy++;/*¡Mueve la línea superior una línea hacia abajo! */
líneas++; /* líneas <=4 */
puntuación total+=puntuación;
Puntuación* = 2 /*Agregar: 10 , 30, 70, 150 */
}
Otros
j-;
} while(suma & gt; 0 & amp& ampj & gttopy & amp& amp line& lt4);
/*Acelera el juego cuando la puntuación es alta, el mínimo es 400 */
frame time = max(1200 -100 *( Puntuación total/200), 400);
TopLine = topy/*Actualizar línea superior*/
/*Si no se elimina ninguna línea, solo agregue 1: * / p>
if(lines==0)
puntuación total++;
}
/*Mostrar puntuación*/
void _INNER_HELPER DisplayScore()
{
establecer color(BkGndColor);
outtextxy(ScoreBoardLeft+5, ScoreBoardTop+5, info_score);
p>
establecer color(color de puntuación);
sprintf(info_score, " Puntuación: %d ", puntuación total
outtextxy(ScoreBoardLeft); +5, ScoreBoardTop+5 , info_score);
}
/*Cuando un bloque está inactivo, llamamos a esta función. */
anular tablero de actualización()
{
FillBoardData();
verificar tablero();
Pintar tablero();
mostrar puntuación();
}
/*¡Pausa el juego y el cronómetro dejará de moverse hacia abajo! */
int PauseGame()
{
int key = 0;
DisplayInfo("¡Presiona P para comenzar o continuar! " );
Y(key!= K_P & amp& ampkey!=K_ESC)
{
Y(!(key = getkey code() ){ }
}
Mostrar información (info _ ayuda);
Tecla Intro
}
/ *Sal del juego y haz el trabajo de limpieza */
void exit game()
{
closegraph();
}
/*Función de punto de entrada.
*/
void main()
{
int i, flag=1, j, key=0, tick = 0;
init game();
if(PauseGame()==K_ESC)
Ir a GameOver
/*Esperar hasta que se presione el botón*/ p>
Y (key!=K_ESC)
{
/*Esperar hasta que se presione la tecla*/
Y (!( key=GetKeyCode( )))
{
tick++;
if (comprobar>=tiempo de fotograma)
{
/*¡Nuestro barrio está muerto! (no se puede bajar), obtenemos el siguiente bloque*/
if (! mover bloque(& bloqueo de acera, 0, 1))
{
UpdateBoard();
siguiente bloque();
If (!CanMove(0, 1))
Ir a GameOver
}
tick = 0;
}
Retraso (100);
}
Interruptor ( clave)
{
Caso K_LEFT:
mover bloque (y bordillo, -1, 0);
Romper;
Caso K _right:
mover bloque(& bordillo, 1, 0);
Romper;
Caso K_DOWN: p>
mover bloque(& acera, 0, 1);
Romper;
Caso K_UP:
rotar bloque(& acera)
romper;
Caso K_Space:
soltar bloque(& amp; bloqueo de acera);
Romper;
Caso K_P:
PausaJuego();
Pausa;
}
}
Juego over:
DisplayInfo("¡Se acabó el juego! ¡Presiona cualquier tecla para salir!");
getch() /* Espera a que el usuario presione cualquier tecla. */
salir del juego();
}