/* Inclusion de librerias graficas */
#include "./X11/Xlib.h"
#include "./X11/keysymdef.h"
#include "./X11/keysym.h"
#include "./X11/Xutil.h"
#include "./X11/Xatom.h"
/* Inclusion de librerias para procesos UNIX */
#include <pthread.h>
#include <signal.h>
#include <assert.h>
#include <unistd.h>
/* otros includes */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/* Definicion de limites */
#define LIM_INFERIOR 300 // Esquina inferior grafica del tablero
#define LIM_SUPERIOR 0 // Esquina superior grafica del tablero
#define VENT_IZQ 100 // Posiciones iniciales de las ventanas
#define VENT_DER 500
#define VENT_SUP 0
#define VENT_INF 310
#define TAM_BLOQUE 20 // Dimension en pixels de un bloque
#define X_INICIAL 5 // Posicion X inicial de las fichas
#define Y_INICIAL 0 // Posicion Y inicial de las fichas
#define TOTAL_X 10 // Numero de columnas del tetris
#define TOTAL_Y 16 // Numero de filas del tetris
//Cadenas para opciones
#define X_CADENA 250 // Posicion de las cadenas de opciones en pantalla
#define INICIAR "a - Iniciar Partida:"
#define DEC_DIFICULTAD "b - Disminuir Dificultad"
#define INC_DIFICULTAD "c - Incrementar Dificultad"
#define PUNTOS "Puntos:"
#define FIN_PARTIDA "Fin de partida!!!"
//GLOBALES
/* Tipo que define la posicion de un bloque dentro del tablero del tetris,
* cada bloque lleva las coordenas x e y */
typedef struct strBloque
{
int x; //Posicion tablero
int y;
} Bloque;
/* La estructura Ficha, es una forma con cuatro bloques */
typedef struct strFicha
{
int tipo;
Bloque Bl[4]; //Cada ficha son 4 bloques
} Ficha;
/* Prototipos de funciones propias */
void AlmacenaFicha(Ficha * l);
void DibujaBloque(int x, int y);
void DibujaTablero();
void CompruebaLineas();
int Grafica(int z);
int MovPermitido(Bloque * l,int donde);
int MovFichaPermitido(Ficha * l, int donde);
void FichaAbajo(Ficha * l);
void FichaIzquierda(Ficha * l);
void FichaDerecha(Ficha * l);
void BorraFicha(Ficha * l);
void DibujaFicha(Ficha * l);
int MueveFicha(Ficha * l, int donde);
void GeneraFicha(Ficha * l);
int FinPartida();
void * lanzafichas(Ficha * l);
void Rotar(Ficha * l);
void Escribe(int x, int y, char * cad);
void CalculaPuntos(int n_lineas);
void IniciaPartida();
// Definiciones globales
Display *dpy; // Display X
Window w; // Ventana general
GC gc, gc_borrar, gc_fichas, gc_letras; // Contextos graficos
enum Movimientos { abajo,izquierda,derecha,rotacion}; // Varias constantes de movimiento
char Tablero[TOTAL_X][TOTAL_Y]; // Tablero de tetris
int dificultad=800000; // 0.8 segundos por movimiento hacia abajo
int Puntos; // Numero de puntos del usuario
int partida_jugando=0; // Se está jugando una partida?
Ficha l; // Ficha que cae
pthread_mutex_t tab; // Semaforo para memoria compartida (solo un proceso a la vez puede acceder al tablero)
// Funcion que calcula los puntos obtenidos por una o varias lineas
void CalculaPuntos(int n_lineas)
{
char cadena[20];
switch(n_lineas)
{
case 1:
Puntos+=10;
Escribe(X_CADENA, 250, "Simple: 10 puntos!!");
break;
case 2:
Puntos+=30;
Escribe(X_CADENA, 250, "Doble: 30 puntos!!");
break;
case 3:
Puntos+=70;
Escribe(X_CADENA, 250, "Triple: 70 puntos!!");
break;
case 4:
Puntos+=150;
Escribe(X_CADENA, 250, "Tetris: 150 puntos!!");
break;
}
printf("\a\n"); //Beep!
sprintf(cadena,"Puntos:%d",Puntos);
Escribe(X_CADENA,100, cadena);
}
// Funcion que escribe una cadena de caracteres en una posición de pantalla
void Escribe(int x, int y, char * cad)
{
XFillRectangle(dpy,w,gc_borrar,x-5,y-10,200,20);
XDrawString(dpy,w,gc_letras,x,y,cad,strlen(cad));
}
// Funcion que dibuja todos los bloques que hay en pantalla
void DibujaTablero()
{
int x,y;
XFillRectangle(dpy,w,gc_borrar,5,LIM_SUPERIOR+5,200,LIM_INFERIOR);
for(y=0;y<TOTAL_Y-1;y++) //Menos 1 por la barrera del final
for(x=0;x<TOTAL_X;x++)
if(Tablero[x][y]=='X')
DibujaBloque(x,y);
XFlush(dpy);
}
// Funcion que comprueba si hay lineas en el tablero de tetris
void CompruebaLineas()
{
int con_lineas=0; //Contador de lineas
pthread_mutex_lock(&tab); // Acceso a memoria compartida
/*[COLOR=red] Esta funcion se tiene que jecutar cuando la ficha a terminado de caer, hay que usar la funcion con_lineas (ya que se debe codificar la deteccion de lineas usando ese contador para eliminarlas del tablero)...pero no se me ocurre como hacerlo...ayudarme por favor....[/COLOR]
*/
if(con_lineas>0)
{
DibujaTablero();
CalculaPuntos(con_lineas);
}
pthread_mutex_unlock(&tab); // Liberamos acceso a memoria compartida
}
/* Funcion que retorna la posicion grafica de un bloque */
int Grafica(int z)
{
return z*TAM_BLOQUE+5;
}