¿Cómo escribir un programa de Tetris en lenguaje C?
Código fuente de Tetris C
#include?lt;stdio.hgt;
#include?lt;windows.hgt;
#include?lt;conio.hgt;
#include?lt;time.hgt;
#define?ZL?4 //Incremento de coordenadas,?No hacer ventana de juego Hacer a un lado
#define?WID?36 ? //El ancho de la ventana del juego
#define?HEI?20 ? //El alto de la ventana del juego
int?i, j, Ta, Tb, Tc; //Ta, Tb, Tc se utilizan para recordar y convertir los valores de las variables de bloque
int?a[60][ 60]={0}; ? //Marca los puntos de coordenadas de la pantalla del juego: 0, 1 y 2 están vacíos, cuadrados y con borde respectivamente
int?b[4]; Marque los 4 cuadrados de "boca": 1 es, 0 Ninguno, similar a un interruptor
int?x, y, ?nivel, puntuación, velocidad ? //x, y coordenadas del centro; bloque, nivel de juego, puntuación y velocidad del juego
int?flag, next ? //El número de serie del tipo de bloque que se va a operar actualmente, el número de serie del siguiente tipo de bloque
<; p>void?gtxy(int?m,?int?n); ? //Se deben utilizar las siguientes declaraciones La función autoescritavoid?gflag(?);? siguiente número de bloque
void?csh(?);? //Interfaz de inicialización
void?start(?);? //Parte inicial
void? prfk?(?);? //Imprimir bloque
void?clfk(?);? //Borrar el bloque
void?mkfk(?);? block
void?keyD(?);? //Operación clave
int ?ifmov(?);? //Determinar si el bloque se puede mover o transformar
void clHA(?);? //Borrar la fila completa de bloques
void?clNEXT(? );? //Borrar el SIGUIENTE cuadrado fuera del borde
int ?main(?)
{?csh(?); ?
? while(1 )
{start(?);?//parte inicial
? while(1)
? {?prfk(?);?
Dormir(velocidad);? > ? clfk(?);
? Tb=x; Tc=flag; ?//Guardar temporalmente las coordenadas y números de serie en preparación para deshacer operaciones keyD(? ?); ?
? y;?//Mover el bloque hacia abajo
if?(ifmov (?)==0)?{?y--;?prfk(? );?dlHA(?);?break;}?// Soltar inamovible, eliminar línea, salir del bucle
}
for(i=y-2) ;ilt;y 2;i){?if?(i==ZL)?{?j=0;?}?}? //cuadrado Toca la parte superior del cuadro
if?(j ==0)?{?system("cls");gtxy(10,10);printf("¡Se acabó el juego! ");?getch();?romper;?}?
>
clNEXT(?); ? //Borrar el cuadro SIGUIENTE fuera del cuadro
}
? >
void?gtxy(int?m,?int?n)?//Controlar el movimiento del cursor
{COORD?pos;?//Definir variable pos.X?=?m;?/ / Abscisa pos.Y?=?n; //Coordenada vertical SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),?pos);?
}
void?csh(?)//Inicialización Interfaz
{gtxy(ZL WID/2-5, ZL-2);?printf("Tetris");?//Imprime el nombre del juego gtxy(ZL WID 3, ZL 7);?printf ("************?NEXT:");?//Imprimir información del menú gtxy(ZL WID 3, ZL 13);?printf("************ "); gtxy( ZL WID 3, ZL 15);?printf("Esc?: Salir del juego");
gtxy(ZL WID 3, ZL 17);?printf(" ↑ Clave: Variante "); gtxy (ZL WID 3, ZL 19);?printf("Espacio: Pausar juego"); gtxy(ZL, ZL);?printf("╔");?gtxy(ZL WID-2, ZL); ?printf(" ╗");?//Imprimir esquina del marco gtxy(ZL, ZL HEI);?printf("╚");?gtxy(ZL WID-2, ZL HEI);?printf("╝");
a[ZL][ZL HEI]=2;?a[ZL WID-2][ZL HEI]=2;?//Recuerda que hay un patrón para(i=2;ilt;WID -2;i = 2)?{gtxy(ZL i, ZL);?printf("═");?}?//Imprime el cuadro horizontal superior para(i=2; ilt; WID-2; i =2 )?{gtxy(ZL i, ZL HEI);?printf("═");?a[ZL i][ZL HEI]=2;?}?//Cuadro inferior para(i=1;ilt;HEI; i)?{?gtxy (ZL, ZL i);?printf("║");?a[ZL][ZL i]=2;?}?//Recuerde que hay un patrón en el marco vertical izquierdo para (i=1;ilt;HEI;i )?{gtxy(ZL WID-2, ZL i);?printf("║");?a[ZL WID-2][ZL i]=2;?}? //Cuadro derecho CONSOLE_CURSOR_INFO?cursor_info={1, 0}; //Las siguientes son las configuraciones para ocultar el cursor SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), amp; cursor_info=1;?score=0;?speed=400); ; gflag(?);?flag=next;?/ /Obtener un número de serie del bloque actual
}
void?gflag(?) //Obtener el número de serie del siguiente bloque
{?srand((unsigned) time(NULL));?next?=?rand()19 1 }
void?start(?)?//Iniciar parte
{?gflag(?); ?Ta=bandera;
?flag=next;?//Guarde el número de bloque actual y opere temporalmente el siguiente número de bloque como x=ZL WID 6;?y=ZL 10;?prfk(?);?//Asignar valores a xey fuera del cuadro Imprima el siguiente bloque flag=Ta;?x=ZL WID/2;?y=ZL-1;?//Obtenga el número de bloque actual y asigne valores a xey
}
void?prfk?(?)?//Imprimir Tetris
{?for(i=0;ilt;4;i)?{b[i]=1 ;?}? //El valor de cada elemento de la matriz b[4] es 1 mkfk?(?);?//Hacer Tetris for(?i=?x-2;?ilt;=x 4;?i = 2?) ?//Imprimir cuadrado {?for(j=y-2;jlt;=?y 1;j)?{?if(?a[i][j]==1?amp;amp;?jgt ;ZL? ){?gtxy(i,j);?printf("□");?}?}?} gtxy(ZL WID 3, ZL 1); ?/ /La siguiente información del menú de impresión gtxy(ZL WID 3, ZL 3);? printf("speed?: ?d", velocidad);
}
void?clfk(?)?//Borrar Tetris
{?for(i=0;ilt; 4;i )?{?b[i]=0;?}?//El valor de cada elemento de la matriz b[4] es 0 mkfk?(?);?//Haciendo Tetris para(?i=x- 2; ?ilt;=x 4;?i =2?)?//Limpiar el cuadrado{?for(j=y-2;jlt;=y 1;j){?if(?a[i][j] ]== 0?amp;amp;?jgt;ZL?){?gtxy(i,j);?printf("?");?}?}?}
}
void?mkfk(?)?//Haciendo Tetris
{?a[x][?y]=b[0];?//El estado de la posición central del bloque: ?1-Sí, 0- Sin cambio(bandera)//***6 categorías principales, 19 tipos pequeños{?case?1:?{?a[x][y-1]=b[1];?a [x 2][y -1]=b[2];?a[x 2][y]=b[3];?break;?}?// Caso del cuadrado de la palabra Tian?2:?{?a[ x-2][y ]=b[1];?a[x 2][y]=b[2];?a[x 4][y]=b[3];?break;?}?/ /Bloque de línea recta: -- -- case?3:?{?a[x][y-1]=b[1];?a[x][y-2]=b[2];?a[ x][y 1]= b[3];?break;?}?//Bloque de línea recta:?| case?4:?{?a[x-2][y]=b[1];?a [x 2][y]= b[2];?a[x][y 1]=b[3];?break;?}?//Caja cuadrada en forma de T?5:?{?a[x ][y-1]=b[ 1];?a[x][y 1]=b[2];?a[x-2][y]=b[3];?romper;?}?/ /T girar 90 grados en el sentido de las agujas del reloj caso ?6:?{?a[x][y-1]=b[1];?a[x-2][y]=b[2];?a[x 2] [y]=b[3 ];?break;?}?//El carácter T se gira 180 grados hacia adelante case?7:?{?a[x][y-1]=b[1];?a[ incógnita]
[y 1]=b[2];?a[x 2][y]=b[3];?break;?}?//El carácter T se gira 270 grados hacia adelante case?8:?{?a[ x] [y 1]=b[1];?a[x-2][y]=b[2];?a[x 2][y 1]=b[3];?romper;?}? // Caso cuadrado en forma de Z?9:?{?a[x][y-1]=b[1];?a[x-2][y]=b[2];?a[x-2 ][y 1]=b[3];?break;?}?//Girar el carácter Z 90 grados hacia adelante case?10:?{?a[x][y-1]=b[1];?a [x-2 ][y-1]=b[2];?a[x 2][y]=b[3];?break;?}?//Carácter Z girado 180 grados hacia adelante case?11:? {?a[ x][y 1]=b[1];?a[x 2][y-1]=b[2];?a[x 2][?y]=b[3];? break;?} ?//Carácter Z girado 270 grados case?12:?{?a[x][y-1]=b[1];?a[x][y 1]=b[2];? a[x -2][y-1]=b[3];?break;?}?//Caso cuadrado de 7 palabras?13:?{a[x-2][y]=b[1]; ?a[x 2][y-1]=b[2];?a[x 2][y]=b[3];?break;?}?//7 palabras rotadas 90 grados hacia adelante mayúsculas y minúsculas?14: ?{?a [x][y-1]=b[1];?a[x][y 1]=b[2];?a[x 2][y 1]=b[3];? break;?} ?//7 caracteres girados 180 grados case?15:?{?a[x-2][y]=b[1];?a[x-2][y 1]=b[2] ;?a [x 2][y]=b[3];?break;?}?//7 caracteres girados 270 grados case?16:?{?a[x][y 1]=b[1]; ?a [x][y-1]=b[2];?a[x 2][y-1]=b[3];?break;?}?//Caso cuadrado invertido de 7 palabras?17: ?{? a[x-2][y]=b[1];?a[x 2][y 1]=b[2];?a[x 2][y]=b[3];? break;? }?//Invertir 7 caracteres y rotar 90 grados hacia adelante case?18:?{?a[x][y-1]=b[1];?a[x][y 1]=b[2 ];?a [x-2][y 1]=b[3];?break;?}?//invertir 7 caracteres y rotar 180 grados case?19:?{?a[x-2][y] =b[1 ];?a[x-2][y-1]=b[2];?a[x 2][y]=b[3];?break;?}?//invertir 7 caracteres y girar 270 grados hacia adelante }
}
void?keyD(?)?//Operación clave
{?if?(kbhit(?))
{?int?key;
key=getch(); si?(key==224)
{?key=getch(); p>
if?(key==75)?{?x-=2;?}?//Presione la tecla de dirección izquierda y la abscisa central disminuirá en 2 if?(key==77)?{? x =2;?}? //Presione la tecla de dirección derecha, la abscisa central aumenta en 2
if?(key==72)?//Presione la tecla de dirección hacia arriba, la variante de bloque {? si?(flaggt;=2? amp;amp;?flaglt;=3?)?{?flag;?flag=2;?flag=2;?}
si?(?flaggt;= 4?amp;amp;?flaglt ;=7?)?{?fl
ag;?flag=4;?flag =4;?}
if?(flaggt;=8?amp;amp;?flaglt;=11?)?{?flag;?flag=4; ?flag =8;?}
si?(flaggt;=12?amp;amp;?flaglt;=15?)?{?flag;?flag=4;?flag=12;?}
si?(?flaggt;=16?amp;amp;?flaglt;=19?)?{?flag;?flag=4;?flag=16;?}?}
}
? if?(key==32)?//Presiona la barra espaciadora para pausar
{?prfk(?);? while(1)?{ ? if?(getch(?)==32)?{?clfk(?);break;}?}?}? //Presiona la barra espaciadora nuevamente para continuar el juego
?( ifmov(? )==0)?{?x=Tb;?flag=Tc;?}? //Si es inamovible, deshace la operación anterior
?{?prfk(?);? Sleep(speed );?clfk(?);?Tb=x;Tc=flag;} ? //Si es móvil, realice la operación}
}
int?ifmov( ?)/ /Juzga si se puede mover
{?if?(a[x][y]!=0)?{?return?0;?}?//Si hay un patrón en el centro del bloque, devuelve 0 y no se puede mover else{?if?(?(flag==1?amp;?(?a[x][?y-1]==0?amp;amp ;?a[x 2][y-1]= =0?amp;amp;?a[x 2][y]==0?)?|| =2?amp;amp;?(?a[x -2][y]==0?amp;amp;?a[x 2][y]==0?amp;amp;?a[x 4] [y]==0?)?)?|| ?
(flag==3?amp;?(?a[x][y-1]==0?amp;amp;? a[x][y-2]== 0?amp;amp;?a[x][y 1]==0?)?)?||
(flag==4?amp ;amp;?(?a[x-2 ][y]==0?amp;amp;?a[x 2][y]==0?amp;amp;?a[x][y 1]= =0?)?)?|| p>
(flag==5?amp;?(?a[x][y-1]==0?amp;?a[x][y 1 ]==0?amp; amp;?a[x-2][y]==0?)??||
(flag==6?amp;amp;?(?a [x][?y- 1]==0?amp;amp;?a[x-2][y]==0?amp;amp;?a[x 2][y]==0?)? )?||
(flag==7?amp;?(?a[x][y-1]==0?amp;?a[x][y 1]==0? amp;amp ;?a[x 2][y]==0?)?||
(flag==8?amp;amp;?(?a[x][y 1 ]== 0?amp;amp;?a[x-2][y]==0?amp;amp;?a[x 2][y 1]==0?)?)?||
(bandera==9?amp;?(?a[x][y-1]==0?amp;?a[x-2][y]==0?amp;amp;?a [x-2 ][y 1]==0?)?)?||
(flag==10?amp;?(?a[x][y-1]== 0?amp;amp; ?a[x-2][y-1]==0?amp;amp;?a[x 2][y]==0?)?||
(flag== 11?amp;?(?a[x][y 1]==0?amp;?a[x 2][y-1]==0?amp;amp; ?a[x 2][y]= =0?)?)?||
(flag==12?amp; ?(?a[x][y-1]== 0?amp;amp;?a[x][ y 1]==0?amp;amp;?a[x-2][y-1]==0?)?)?||
( bandera==13 amp; ( a[ x-2][y]==0 amp; a[x 2][y-1]==0 amp; a[x 2] [y]==0 ) ) || ; ( a[x][y-1]==0 amp; a[x][y 1]==0 amp; ; a[x 2][y 1]==0 ) ) ||
? (bandera==15 amp; amp; ( a[x-2][y]==0 amp; amp ; a[x-2][y 1]==0 amp; amp; a[x 2][y]==0 ) ) ||
? (bandera==16 amp; amp; ( a[x][y 1]==0 amp; amp; a[x][ y-1]==0 amp; a[x 2][y-1]==0 ) ) ||
( bandera==17 amp; amp; ( a[x- 2][y]==0 amp; a[x 2][y 1]==0 amp; a [x 2][y]==0 ) ) || amperio ( a[x][y-1]==0 amperio; amperio; a[x][y 1]== 0 amperio; amperio; a[x-2][y 1]==0 ) ) | |
? (flag==19 amp; amp; ( a[x-2][y]= =0 amp;amp; a[x-2][y-1]==0
? amp;amp;?a[x 2][y]==0?)?)?) ?{?return?1;?}
} return?0; ? //Devuelve 0 en otros casos
}
void?clNEXT(?) ? //Borrar los bloques SIGUIENTE fuera del marco
{?flag? =?next;?x=ZL WID 6;?y=ZL 10;?clfk(?);?}
void clHA(?) ? //Borrar toda la fila de bloques
{?int?k, ?Hang=0; //k es el número de bloques en una fila, ?Hang es el número de fila del bloque eliminado for(j=ZL HEI-1;jgt;=ZL 1; j--)?//Cuando una fila tiene WID/2-2 bloques, es una fila completa{?k=0;?for(i =ZL 2;ilt;ZL WID-2;i =2) p>
{?si
?(a[i][j]==1)//La coordenada vertical es de abajo hacia arriba y la coordenada horizontal es de izquierda a derecha para determinar si la línea está llena {?k; eliminará la línea
? if?(k==WID/2-2)? { ? for(k=ZL 2;klt;ZL WID-2;k =2)?
?a[k ][j]=0;?gtxy(k,j);?printf("?");?Sleep(1);?}
? k=j-1;kgt;ZL ;k--)
? {?for(i=ZL 2;ilt;ZL WID-2;i =2)?//Hay cuadros encima del número de líneas eliminadas, bórrelas primero y luego muévalas todas hacia abajo Una línea
{?if(a[i][k]==1)?{?a[i][k]=0 ;?gtxy(i,k);?printf("?" ); a[i][k 1]=1;?
? ");?}?}
}
? j ;?// Después de que el bloque baje, vuelva a juzgar si la fila eliminada está llena
? Hang ;?//Registra el número de filas en el bloque eliminado
}
}
} } puntuación =100*Hang; Cada vez que se elimina una línea, se obtienen 100 puntos if?(?Hanggt;0?amp;amp;?( score500==0?||?score/500gt;?level-1?)?) ?//Score 500 acelerará el nivel
{?speed-=20;?level;?if (speedlt; 200)speed }?
}