El hundir la flota en C y con la librería gráfica allegro.
Hay que instalar Allegro con la versión 4 (versión probada allegro4-4.4.2-2), la cinco no consigo compilar. Se compila con gcc -o hundirLaFlota hundirlaflota.c `allegro-config –libs`
Hundir la flota: Pulsa para ver/ocultar el código
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <allegro.h>
//#define TRUE 1
//#define FALSE 0
//#define FILA 10
//#define COLUMNA 10
#define NUMBARCOS 5
#define VERTICAL 1
#define HORIZONTAL 2
//valores que puede tomar la matriz y que significa, a partir del cuatro, son los barcos en tamaño incremental (4-5-6-7-8) restando 3
#define NADA 0
#define AGUA 1
#define TIROAGUA 2
#define TOCADO 3
#define ALTOVENTANA 480
#define ANCHOVENTANA 640
#define BORDELATERAL 35
#define BORDESUPERIOR 40
#define MARGENINFERIOR 100
#define MARGENLATERALTEXTO 30
#define INTERESPACIADO 15
#define WHITE makecol(255,255,255)
#define BLACK makecol(0,0,0)
int numBarcos[]={0,0,1,0,0};
int FILA=10;
int COLUMNA=10;
BITMAP* BUFFER;
void colocarBarcosManualmente(int *matriz);
void colocarBarcosAutomaticamente(int *matriz);
void inicializarTablero(int *matriz);
void imprimirTablero(int *matriz);
int comprobacionEspacioParaBarco(int fila, int columna, int orientacion, int tamano, int *matriz);
int compruebaGanador(int *matriz);
int compruebaDisparo(int *matriz, int fila, int columna, int enemigo);
void juegoManual(int *matriz);
void juegoAutomatico(int *matriz);
void imprimirMenu(int numOpciones, char *opciones[]);
int compruebaOpcion(int min, int max, int opcion);
void ordenador();
void jugador();
int compruebaRangoCasilla(int fila, int columna);
void colocarBarco(int fila, int columna, int orientacion, int tamano, int *matriz);
int aleatorio(int min, int max);
void rellenarAguaAlrededor(int columna, int fila, int orientacion, int tamano, int *matriz);
void rellenarAgua(int *matriz);
void bucleJuego(int *jugador, int *enemigo);
void imprimirTableroJuego(int *enemigo, int *jugador, int barcos);
void limpiarMargenInferior();
int leerNumero();
void ponerTituloCasillas(int numTablas);
void opciones();
int main(int argc, char* argv[]){
allegro_init();
install_keyboard();
set_gfx_mode(GFX_AUTODETECT_WINDOWED, ANCHOVENTANA, ALTOVENTANA, 0, 0);
BUFFER = create_bitmap(SCREEN_W,SCREEN_H);
int numOpciones=4;
int opcion;
char *op[]={
"Jugar (ordenador vs jugador)",
"Jugar (ordenador vs ordenador)",
"Opciones",
"Salir"
};
srand(time(NULL));
while(TRUE){
do{
//muestro menú y pido opcion
imprimirMenu(numOpciones, op);
opcion=(readkey() & 0xff)-48;
//scanf("%d", &opcion);
}while(!compruebaOpcion(1,numOpciones, opcion));
//según la opción....
switch(opcion){
case 1:
jugador(); //jugador contra ordenador
break;
case 2:
ordenador(); //ordenador contra ordenador
break;
case 3:
opciones();
break;
case 4:
return 0; //cierro el programa
}
}
return 0;
}
END_OF_MAIN()
//modificar opciones
void opciones(){
int numero, i, opcion, salto;
int numOpciones=3;
char *op[]={
"Cambiar tamaño del tablero",
"Cambiar número de barcos",
"Salir"
};
while(TRUE){
do{
//muestro menú y pido opcion
imprimirMenu(numOpciones, op);
opcion=(readkey() & 0xff)-48;
//scanf("%d", &opcion);
}while(!compruebaOpcion(1,numOpciones, opcion));
rectfill(screen, 0, 0, ANCHOVENTANA, ALTOVENTANA, makecol(255, 255, 255)); //ventana en blanco
switch(opcion){
case 1:
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*2, makecol(0, 0, 0), -1,
"Columnas: %d. Escriba el nuevo valor", COLUMNA);
COLUMNA=leerNumero();
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*3, makecol(0, 0, 0), -1,
"Establecido en %d", COLUMNA);
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*5, makecol(0, 0, 0), -1,
"Filas: %d. Escriba el nuevo valor", FILA);
FILA=leerNumero();
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*6, makecol(0, 0, 0), -1,
"Establecido en %d", FILA);
readkey();
break;
case 2:
for(i=0, salto=0; i<NUMBARCOS; i++){
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*(salto+1), makecol(0, 0, 0), -1,
"%d barcos de tamaño %d", numBarcos[i], i+1);
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*(salto+2), makecol(0, 0, 0), -1,
"Especifique cuantos serán");
numBarcos[i]=leerNumero();
textprintf_ex(screen, font, MARGENLATERALTEXTO, INTERESPACIADO*(salto+3), makecol(0, 0, 0), -1,
"Establecido en %d", numBarcos[i]);
salto=salto+4;
}
readkey();
break;
case 3:
return;
}
}
}
//Jugador contra ordenador
void jugador(){
//allegro_init();
int numMenu=3, opcion;
int *jugador, *enemigo;
char *menu2[]={
"Colocar los barcos de forma automática.",
"Colocar los barcos de forma manual",
"Volver"
};
do{
//muestro menú y pido opcion
imprimirMenu(numMenu, menu2);
opcion=(readkey() & 0xff)-48;
//scanf("%d", &opcion);
}while(!compruebaOpcion(1,numMenu, opcion));
//voy inicializando
jugador=(int*)malloc(sizeof(int)*FILA*COLUMNA); //inicializo matriz del jugador
enemigo=(int*)malloc(sizeof(int)*FILA*COLUMNA); //inicializo matriz del ordenador
//inicializo los tableros
inicializarTablero(jugador);
inicializarTablero(enemigo);
//según la opcion...
switch(opcion){
case 2:
//coloco barcos
colocarBarcosManualmente(jugador);
colocarBarcosAutomaticamente(enemigo);
break;
case 1:
//coloco barcos
colocarBarcosAutomaticamente(jugador);
colocarBarcosAutomaticamente(enemigo);
break;
case 3:
//por si no los vuelvo a usar, los libero
free(jugador);
free(enemigo);
return; //salgo de aquí y regreso al menú principal
}
//comienzo a jugar!!
bucleJuego(jugador, enemigo);
free(jugador);
free(enemigo);
}
//ordenador contra ordenador
void ordenador(){
int ganador=FALSE;
int fila, columna, colocacion, respuesta;
int *jugador, *enemigo;
jugador=(int*)malloc(sizeof(int)*FILA*COLUMNA); //inicializo matriz del jugador
enemigo=(int*)malloc(sizeof(int)*FILA*COLUMNA); //inicializo matriz del ordenador
//inicializo los tableros
inicializarTablero(jugador);
inicializarTablero(enemigo);
//coloco barcos
colocarBarcosAutomaticamente(jugador);
colocarBarcosAutomaticamente(enemigo);
imprimirTableroJuego(enemigo, jugador, TRUE);
while(TRUE){
//JUGADOR 1
while(TRUE){
//genero una tirada
fila=aleatorio(1, FILA);
columna=aleatorio(1, COLUMNA);
respuesta=compruebaDisparo(jugador, fila, columna, FALSE);
if(respuesta!=-1){break;}
}
if(respuesta==0){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"%c%d -> Jugador 1 dió en agua", columna+64, fila);
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"%c%d -> ¡Jugador 1 ha dado tocado!", columna+64, fila);
if(compruebaGanador(jugador)){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"¡¡Jugador 1 ha ganado!!");
ganador=TRUE;
}
}
readkey();
if(ganador){break;}
limpiarMargenInferior();
//JUGADOR 2
while(TRUE){
//genero una tirada
fila=aleatorio(1, FILA);
columna=aleatorio(1, COLUMNA);
respuesta=compruebaDisparo(enemigo, fila, columna, TRUE);
if(respuesta!=-1){break;}
}
if(respuesta==0){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"%c%d -> Jugador 2 dió en agua", columna+64, fila);
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"%c%d -> ¡Jugador 2 ha dado tocado!", columna+64, fila);
if(compruebaGanador(enemigo)){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"¡¡Jugador 2 ha ganado!!");
ganador=TRUE;
}
}
readkey();
if(ganador){break;}
limpiarMargenInferior();
}
free(jugador);
free(enemigo);
}
//bucle del juego en el que se van visualizando matrices, disparando hasta que uno de los dos gane
void bucleJuego(int *jugador, int *enemigo){
int ganador=FALSE, salida=TRUE;
int fila, columna, colocacion, respuesta;
imprimirTableroJuego(enemigo, jugador, FALSE);
while(TRUE){
while(salida){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, -1,
"¿A dónde quieres disparar?");
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"Introduce la letra");
columna=(readkey() & 0xff);
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"Introduce el número");
fila=leerNumero();
limpiarMargenInferior();
if(!compruebaRangoCasilla(fila, columna)){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"Se pasó en la fila o columna, vuelva a seleccionar una casilla.");
readkey();
limpiarMargenInferior();
}else{
//formateo la casilla y compruebo si hay barco, si es así, marco tocado y devuelvo tamaño del barco
respuesta=compruebaDisparo(enemigo, fila, columna, TRUE);
if(respuesta!=-1){
salida=FALSE;
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"La casilla ya estaba seleccionada, vuelva a seleccionar una casilla.");
readkey();
limpiarMargenInferior();
}
}
}
salida=TRUE;
columna=toupper(columna);
if(respuesta==0){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"%c%d -> Diste en agua :(", columna, fila);
}else{
//printf("¡Tocado! es un barco de tamaño %d\n", respuesta-3);
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"%c%d -> ¡Tocado! es un barco de tamaño %d", columna, fila, respuesta-3);
if(compruebaGanador(enemigo)){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*3, BLACK, WHITE,
"¡¡¡¡Ha ganadooo!!!!");
ganador=TRUE;
}
}
readkey();
if(ganador){break;}
limpiarMargenInferior();
while(TRUE){
//genero una tirada del enemigo
fila=aleatorio(1, FILA);
columna=aleatorio(1, COLUMNA);
respuesta=compruebaDisparo(jugador, fila, columna, FALSE);
if(respuesta!=-1){break;}
}
if(respuesta==0){
//printf("Te dió en agua.\n");
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"%c%d -> Te dió en agua", columna+64, fila);
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"%c%d -> ¡Tocado! :(", columna+64, fila);
if(compruebaGanador(jugador)){
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*3, BLACK, WHITE,
"Ha perdido... :(");
ganador=TRUE;
}
}
readkey();
if(ganador){break;}
limpiarMargenInferior();
}
}
//comprueba que la opción esté dentro del rango
int compruebaOpcion(int min, int max, int opcion){
if((opcion>=min && opcion<=max)){
return TRUE;
}else{
return FALSE;
}
}
//imprime el menú que se pasa por parámetros
void imprimirMenu(int numOpciones, char *opciones[]){
int i, comienzoX=MARGENLATERALTEXTO*2, comienzoY=INTERESPACIADO*3, distancia=INTERESPACIADO;
clear_bitmap(BUFFER);
rectfill(BUFFER, 0, 0, ANCHOVENTANA, ALTOVENTANA, makecol(255, 255, 255)); //ventana en blanco
for(i=0; i<numOpciones; i++){
textprintf_ex(BUFFER, font, comienzoX, (comienzoY+(distancia*i)), makecol(0, 0, 0), -1, "%d. %s", i+1, *(opciones+i));
}
textprintf_ex(BUFFER, font, comienzoX-distancia, (comienzoY+(distancia*i+(distancia*2))), makecol(0, 0, 0), -1, "Seleccione su opción");
/***********************AAAAAAAAAAAAAARRRRRRRRRRGGGGGGGGGGGHHHHHHHHHHHHH!!!!!!!!!***********************
BITMAP *punto;
PALETTE paleta;
punto=create_bitmap(500,500);
punto = load_bitmap ("/home/dorian/barco.bmp", NULL);
readkey ();
draw_sprite (screen, punto, 0, 10);
readkey ();
destroy_bitmap (punto);*/
blit(BUFFER, screen, 0,0,0,0,SCREEN_W, SCREEN_H);
}
//limpia el margen inferior usado para escribir
void limpiarMargenInferior(){
rectfill(screen, 0, ALTOVENTANA-MARGENINFERIOR+10, ANCHOVENTANA, ALTOVENTANA, WHITE); //pintar el recuadro
}
//va pidiendo los datos de los barcos para ir colocándolos en la matriz
void colocarBarcosManualmente(int *matriz){
int i, letra, numero, colocacion, pregunta=0, numDelBarco;
char l;
imprimirTablero(matriz);
for(i=0; i<NUMBARCOS; i++){
numDelBarco=numBarcos[i];
while(numDelBarco>0){
//printf("\n\n");
switch(pregunta){
case 0:
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, -1,
"Estás colocando un barco de tamaño %d, te quedan %d barcos de ese tamaño.",
i+1, numDelBarco);
//printf("\nEstás colocando un barco de tamaño %d, te quedan %d barcos de ese tamaño para colocar.\n", i+1, numDelBarco);
//printf("Introduzca número y letra de la casilla donde quiere colocarlo (separado por una coma): ");
//scanf("%d, %c", &numero, &l);
//letra=l;
//while(getchar()!='\n');
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"Introduce la letra");
letra=(readkey() & 0xff);
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"Introduce el número");
numero=leerNumero();
limpiarMargenInferior();
if(compruebaRangoCasilla(numero, letra)){
pregunta++;
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"Se pasó en la fila o columna, vuelva a seleccionar una casilla.");
readkey();
limpiarMargenInferior();
//printf("Se pasó en la fila o columna, vuelva a seleccionar una casilla.\n");
}
break;
case 1:
//printf("¿Como quiere colocarlo?\n 1. Vertical\n 2. Horizontal\n(introduzca número): ");
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO, BLACK, WHITE,
"¿Cómo quiere colocarlo?");
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"1. Vertical");
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*3, BLACK, WHITE,
"2. Horizontal");
//scanf("%d", &colocacion);
colocacion=(readkey() & 0xff)-48;
//while(getchar()!='\n');
limpiarMargenInferior();
if(colocacion==1 || colocacion==2){
pregunta++;
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"Opción incorrecta, vuelva a introducirlo.");
//printf("Opción incorrecta, vuelva a introducirlo.\n");
readkey();
limpiarMargenInferior();
}
break;
case 2:
pregunta=0;
if(comprobacionEspacioParaBarco(numero, letra, colocacion, i+1, matriz)){
numDelBarco--;
}else{
textprintf_ex(screen, font, MARGENLATERALTEXTO, ALTOVENTANA-MARGENINFERIOR+INTERESPACIADO*2, BLACK, WHITE,
"El barco está en mal sitio, vuelva a colocarlo.");
//printf("El barco está en mal sitio (fuera de tablero o con otro barco por el medio), vuelva a colocarlo\n");
readkey();
limpiarMargenInferior();
}
readkey();
}
}
}
rellenarAgua(matriz);
}
//comprueba que la casilla esté dentro del rango (lo formatea)
int compruebaRangoCasilla(int fila, int columna){
fila--;
if(fila<0 || fila>=FILA){
return FALSE;
}
if(isalpha(columna)){
if(isupper(columna)){
columna=columna+32;
}
columna=columna-97;
}else{
columna--;
}
if(columna<0 || columna>=COLUMNA){
return FALSE;
}
return TRUE;
}
//una vez comprobado que los datos son correctos (y está formateado la fila y columna), procedo a escribirlo en la matriz y dibujarlo
void colocarBarco(int fila, int columna, int orientacion, int tamano, int *matriz){
int columnaFinal, filaFinal, posicion;
int anchoCasilla, altoCasilla, color=makecol(0,200,0); //verde-barco;
anchoCasilla=(ANCHOVENTANA-BORDELATERAL*2)/COLUMNA;
altoCasilla=(ALTOVENTANA-MARGENINFERIOR-BORDESUPERIOR)/FILA;
//selecciono la opcion que ha de incrementarse
switch(orientacion){
case HORIZONTAL:
columnaFinal=columna+tamano-1; //hallo la columna final
while(columna<=columnaFinal){
posicion=COLUMNA*fila+columna; //posicion actual
*(matriz+posicion)=tamano+3;
rectfill(screen, BORDELATERAL+(columna*anchoCasilla), BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla), BORDESUPERIOR+((fila+1)*altoCasilla), color); //pintar la casilla correspondiente
rect(screen, BORDELATERAL+(columna*anchoCasilla), BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla), BORDESUPERIOR+((fila+1)*altoCasilla), BLACK); //repintar el BORDELATERAL
columna++;
}
break;
case VERTICAL:
filaFinal=fila+tamano-1; //hallo la fila final
while(fila<=filaFinal){
posicion=COLUMNA*fila+columna; //posicion actual
*(matriz+posicion)=tamano+3;
rectfill(screen, BORDELATERAL+(columna*anchoCasilla), BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla), BORDESUPERIOR+((fila+1)*altoCasilla), color); //pintar la casilla correspondiente
rect(screen, BORDELATERAL+(columna*anchoCasilla), BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla), BORDESUPERIOR+((fila+1)*altoCasilla), BLACK); //repintar el BORDELATERAL
fila++;
}
break;
}
}
//comprueba que según la casilla, orientación y tamaño, ese barco pueda colocarse en la matriz dada y lo escribe si es correcto
int comprobacionEspacioParaBarco(int fila, int columna, int orientacion, int tamano, int *matriz){
int filaFinal, columnaFinal, posicion;
//char letra[]={columna};
//compruebo si la columna necesita ser formateada
if(isalpha(columna)){
if(isupper(columna)){
columna=columna+32;
}
columna=columna-97;
}else{
columna--;
}
//resto uno para ajustar indices
fila--;
//sumo a la fila o columna (según orientación) para hallar la casilla final y voy comprobando por el camino que no haya otros barcos
switch(orientacion){
case HORIZONTAL:
columnaFinal=columna+tamano-1; //hallo la columna final
if(columnaFinal>=COLUMNA){
return FALSE;
}
while(columna<=columnaFinal){
posicion=COLUMNA*fila+columna; //posicion actual
if(*(matriz+posicion)!=0){
return FALSE; //incorrecto, aborto operación
}else{
columna++; //correcto, avanzo una posicion
}
}
columna--; //restauro el contador de las columnas
//llegado aquí, no hay problemas por el camino y puedo escribirlo
colocarBarco(fila, columna-tamano+1, orientacion, tamano, matriz);
break;
case VERTICAL:
filaFinal=fila+tamano-1; //hallo la fila final
if(filaFinal>=FILA){
return FALSE;
}
while(fila<=filaFinal){
posicion=COLUMNA*fila+columna;//posicion actual
if(*(matriz+posicion)!=0){
return FALSE; //incorrecto, aborto operación
}else{
fila++;//correcto, avanzo una posicion
}
}
fila--; //restauro el contador de las filas
//llegado aquí, no hay problemas por el camino y puedo escribirlo
colocarBarco(fila-tamano+1, columna, orientacion, tamano, matriz);
break;
}
return TRUE;
}
//relleno alrededor del barco dado con agua
void rellenarAguaAlrededor(int columna, int fila, int orientacion, int tamano, int *matriz){
int posicion, filaFinal, columnaFinal, filaInicial, columnaInicial;
switch(orientacion){
case VERTICAL:
printf("La fila y columna iniciales son: %d %d\n", fila, columna);
filaFinal=fila+tamano-1; //hallo la fila final
filaInicial=fila;
//por encima del barco pongo un agua
if(fila>0){//compruebo que pueda hacerlo
fila--;
posicion=COLUMNA*fila+columna;
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
}
//me pongo a la izquierda del barco y voy rellenando (si puedo hacerlo)
if(columna>0){
columna--;
while(fila<=filaFinal){
posicion=COLUMNA*fila+columna;
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
fila++;
}
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
//bajo uno más
if(fila<FILA){//compruebo que pueda hacerlo
fila++;
posicion=COLUMNA*fila+columna;
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
}
columna++; //recupero la posicion y añado justo debajo del barco
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
}
//me pongo a la derecha del barco y voy rellenando (si puedo hacerlo)
if(columna<COLUMNA){
columna++;
while(fila>=filaInicial){
posicion=COLUMNA*fila+columna;
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
fila--;
}
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
if(fila>0){//subo uno más si puedo
fila--;
posicion=COLUMNA*fila+columna;
if(*(matriz+posicion)==NADA){
*(matriz+posicion)=8;
}
}
}
break;
case HORIZONTAL:
/*columnaFinal=columna+tamano-1; //hallo la columna final
columnaInicial=columna;
//al lado del barco pongo un agua
if(columna>0){//compruebo que pueda hacerlo
columna--;
posicion=COLUMNA*fila+columna;
*(matriz+posicion)=AGUA;
}
//me pongo arriba del barco y voy rellenando (si puedo hacerlo)
if(fila>0){
fila--;
while(columna<columnaFinal){
posicion=COLUMNA*fila+columna;
*(matriz+posicion)=AGUA;
columna++;
}
//voy a la derecha uno más
if(columna<COLUMNA){//compruebo que pueda hacerlo
columna++;
posicion=COLUMNA*fila+columna;
*(matriz+posicion)=AGUA;
}
fila--; //recupero la posicion
}
//me pongo abajo del barco y voy rellenando (si puedo hacerlo)
if(fila<FILA){
fila++;
while(columna>=columnaInicial){
posicion=COLUMNA*fila+columna;
*(matriz+posicion)=AGUA;
fila--;
}
if(columna>0){//voy más a la izquierda si puedo
columna--;
posicion=COLUMNA*fila+columna;
*(matriz+posicion)=AGUA;
}
}*/
break;
}
}
//termino de rellenar el tablero con agua
void rellenarAgua(int *matriz){
int i;
for(i=0; i<FILA*COLUMNA; i++){
if(*(matriz+i)==NADA){
*(matriz+i)=AGUA;
}
}
}
//coloco los barcos aleatoriamente cuidando de no ponerlos juntos
void colocarBarcosAutomaticamente(int *matriz){
int fila, columna, orientacion, i, numDelBarco;
for(i=0; i<NUMBARCOS; i++){
numDelBarco=numBarcos[i];
while(numDelBarco>0){
//selecciono una casilla al azar (los valores como si me los pasara el usuario porque después se ajustan indices)
fila=aleatorio(1, FILA+1);
columna=aleatorio(1, COLUMNA+1);
//selecciono una orientación
//orientacion=aleatorio(1,2);
orientacion=1;
//compruebo que sea correcto y lo escriba dado el caso
if(comprobacionEspacioParaBarco(fila, columna, orientacion, i+1, matriz)){
numDelBarco--;
//siendo correcto, añado alrededor del barco agua para que no se ponga otro barco ahí
//rellenarAguaAlrededor(columna-1, fila-1, orientacion, i+1, matriz);
}
}
}
rellenarAgua(matriz);
}
//inicializo la matriz a ceros
void inicializarTablero(int *matriz){
int i;
for(i=0; i<FILA*COLUMNA; i++){
*(matriz+i)=NADA; //inicializo a 0 (NADA según la enumeración)
}
}
//comprueba que uno de los dos haya ganado
int compruebaGanador(int *matriz){
int i;
for(i=0; i<FILA*COLUMNA; i++){
if(*(matriz+i)>3){
return FALSE;
}
}
return TRUE;
}
//formateo la casilla y compruebo si hay barco, si es así, marco tocado y devuelvo tamaño del barco
//-1 si ya está usada
//0 si agua
//>=1 tamaño del barco tocado
int compruebaDisparo(int *matriz, int fila, int columna, int enemigo){
int color, devuelta, anchoCasilla, altoCasilla;
int ancho=ANCHOVENTANA-(BORDELATERAL*3), anadido=(ancho/2)+BORDELATERAL;
anchoCasilla=(ancho/2)/COLUMNA;
altoCasilla=(ALTOVENTANA-MARGENINFERIOR-BORDESUPERIOR)/FILA;
fila--;
if(isalpha(columna)){
if(isupper(columna)){
columna=columna+32;
}
columna=columna-97;
}else{
columna--;
}
int posicion=COLUMNA*fila+columna, barco;
switch(*(matriz+posicion)){
case 2://casilla utilizada
case 3:
devuelta=-1;
break;
case 1: //agua
*(matriz+posicion)=TIROAGUA;
color=makecol(50, 50, 150);
devuelta=0;
break;
default: //barcos
barco=*(matriz+posicion);
*(matriz+posicion)=TOCADO;
color=makecol(255, 0, 0); //rojo
devuelta=barco;
break;
}
//codigo para marcar la casilla
if(devuelta!=-1){
if(enemigo){
rectfill(screen, BORDELATERAL+(columna*anchoCasilla), BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla), BORDESUPERIOR+((fila+1)*altoCasilla), color); //pintar la casilla correspondiente
rect(screen, BORDELATERAL+(columna*anchoCasilla), BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla), BORDESUPERIOR+((fila+1)*altoCasilla), BLACK); //pintar el recuadro
}else{
rectfill(screen, BORDELATERAL+(columna*anchoCasilla)+anadido, BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla)+anadido, BORDESUPERIOR+((fila+1)*altoCasilla), color); //pintar la casilla correspondiente
rect(screen, BORDELATERAL+(columna*anchoCasilla)+anadido, BORDESUPERIOR+(fila*altoCasilla),
BORDELATERAL+((columna+1)*anchoCasilla)+anadido, BORDESUPERIOR+((fila+1)*altoCasilla), BLACK); //pintar el recuadro
}
}
return devuelta;
}
//imprimo ambos tableros al mismo tiempo
void imprimirTableroJuego(int *enemigo, int *jugador, int barcos){
int i,j, posicion, colorear=FALSE, contador=0, anadido;
int anchoCasilla, altoCasilla, color, *matriz;
int ancho=ANCHOVENTANA-(BORDELATERAL*3), alto=ALTOVENTANA-MARGENINFERIOR-BORDESUPERIOR;
anchoCasilla=(ancho/2)/COLUMNA;
altoCasilla=alto/FILA;
clear_bitmap(BUFFER);
rectfill(BUFFER, 0, 0, ANCHOVENTANA, ALTOVENTANA, makecol(255, 255, 255)); //fondo blanco
rectfill(BUFFER, BORDELATERAL, BORDESUPERIOR, (anchoCasilla*COLUMNA)+BORDELATERAL,
(altoCasilla*FILA)+BORDESUPERIOR, makecol(0, 0, 200)); //fondo de la matriz
rectfill(BUFFER, (ancho/2)+BORDELATERAL*2, BORDESUPERIOR, (ancho/2)+(anchoCasilla*COLUMNA)+BORDELATERAL*2,
(altoCasilla*FILA)+BORDESUPERIOR, makecol(0, 0, 200)); //el otro fondo de la matriz
matriz=enemigo;
anadido=0;
//barcos=TRUE;
while(contador<2){
contador++;
for(i=0; i<FILA; i++){
for(j=0; j<COLUMNA; j++){
posicion=COLUMNA*i+j;
switch(*(matriz+posicion)){
case 4:
case 5:
case 6:
case 7:
case 8:
if(barcos){
colorear=TRUE;
}else{
colorear=FALSE;
}
//caracter=*(matriz+posicion)-3+48;
color=makecol(0,200,0); //verde-barco
break;
case 2: //tiro agua
//caracter=174;
color=makecol(50, 50, 150); //ni idea
colorear=TRUE;
break;
case 3: //tocado
color=makecol(255, 0, 0); //rojo
colorear=TRUE;
break;
default: //agua, sin tiros
//caracter=32;
colorear=FALSE;
break;
}
if(colorear){
rectfill(BUFFER, BORDELATERAL+(j*anchoCasilla)+anadido, BORDESUPERIOR+(i*altoCasilla),
BORDELATERAL+((j+1)*anchoCasilla)+anadido, BORDESUPERIOR+((i+1)*altoCasilla), color); //pintar la casilla correspondiente
}
}
}
matriz=jugador;
barcos=TRUE;
anadido=(ancho/2)+BORDELATERAL;
}
rect(BUFFER, BORDELATERAL, BORDESUPERIOR, (anchoCasilla*COLUMNA)+BORDELATERAL, (altoCasilla*FILA)+BORDESUPERIOR, BLACK);
rect(BUFFER, (ancho/2)+BORDELATERAL*2, BORDESUPERIOR, (ancho/2)+(anchoCasilla*COLUMNA)+BORDELATERAL*2, (altoCasilla*FILA)+BORDESUPERIOR, BLACK);
for(i=1; i<COLUMNA; i++){
vline(BUFFER, (anchoCasilla*i)+BORDELATERAL, BORDESUPERIOR, (altoCasilla*FILA)+BORDESUPERIOR, BLACK);
vline(BUFFER, (anchoCasilla*i)+BORDELATERAL*2+(ancho/2), BORDESUPERIOR, (altoCasilla*FILA)+BORDESUPERIOR, BLACK);
}
for(i=1; i<FILA; i++){
hline(BUFFER, BORDELATERAL, (altoCasilla*i)+BORDESUPERIOR, (anchoCasilla*COLUMNA)+BORDELATERAL, BLACK);
hline(BUFFER, BORDELATERAL*2+(ancho/2), (altoCasilla*i)+BORDESUPERIOR, (ancho/2)+(anchoCasilla*COLUMNA)+BORDELATERAL*2, BLACK);
}
ponerTituloCasillas(TRUE);
blit(BUFFER, screen, 0,0,0,0,SCREEN_W, SCREEN_H);
}
//imprimo un tablero
void imprimirTablero(int *matriz){
int i,j, posicion, colorear=FALSE;
int anchoCasilla, altoCasilla, color;
int ancho=ANCHOVENTANA-BORDELATERAL*2, alto=ALTOVENTANA-MARGENINFERIOR-BORDESUPERIOR;
anchoCasilla=ancho/COLUMNA;
altoCasilla=alto/FILA;
clear_bitmap(BUFFER);
rectfill(BUFFER, 0, 0, ANCHOVENTANA, ALTOVENTANA, makecol(255, 255, 255)); //fondo blanco
rectfill(BUFFER, BORDELATERAL, BORDESUPERIOR, (anchoCasilla*COLUMNA)+BORDELATERAL,
(altoCasilla*FILA)+BORDESUPERIOR, makecol(0, 0, 200)); //fondo de la matriz
//char caracter;
for(i=0; i<FILA; i++){
for(j=0; j<COLUMNA; j++){
posicion=COLUMNA*i+j;
switch(*(matriz+posicion)){
case 4:
case 5:
case 6:
case 7:
case 8:
//caracter=*(matriz+posicion)-3+48;
color=makecol(0,200,0); //verde-barco
colorear=TRUE;
break;
case 2: //tiro agua
//caracter=174;
color=makecol(50, 50, 150); //ni idea
colorear=TRUE;
break;
case 3: //tocado
color=makecol(255, 0, 0); //rojo
colorear=TRUE;
break;
default: //agua, sin tiros
//caracter=32;
colorear=FALSE;
break;
}
if(colorear){
rectfill(BUFFER, BORDELATERAL+(j*anchoCasilla), BORDESUPERIOR+(i*altoCasilla),
BORDELATERAL+((j+1)*anchoCasilla), BORDESUPERIOR+((i+1)*altoCasilla), color); //pintar la casilla correspondiente
}
}
}
rect(BUFFER, BORDELATERAL, BORDESUPERIOR, (anchoCasilla*COLUMNA)+BORDELATERAL, (altoCasilla*FILA)+BORDESUPERIOR, BLACK);
for(i=1; i<COLUMNA; i++){
vline(BUFFER, (anchoCasilla*i)+BORDELATERAL, BORDESUPERIOR, (altoCasilla*FILA)+BORDESUPERIOR, BLACK);
}
for(i=1; i<FILA; i++){
hline(BUFFER, BORDELATERAL, (altoCasilla*i)+BORDESUPERIOR, (anchoCasilla*COLUMNA)+BORDELATERAL, BLACK);
}
ponerTituloCasillas(FALSE);
blit(BUFFER, screen, 0,0,0,0,SCREEN_W, SCREEN_H);
}
//coloca las letras y números alrededor de la tabla
void ponerTituloCasillas(int dosTablas){
int letra='A', i;
int anchoCasilla, altoCasilla, ancho, alto;
if(dosTablas){
ancho=ANCHOVENTANA-(BORDELATERAL*3);
alto=ALTOVENTANA-MARGENINFERIOR-BORDESUPERIOR;
anchoCasilla=(ancho/2)/COLUMNA;
altoCasilla=alto/FILA;
for(i=0; i<COLUMNA; i++){
textprintf_ex(BUFFER, font, BORDELATERAL+(i*anchoCasilla)+(anchoCasilla/2), BORDESUPERIOR/2, BLACK, -1,
"%c", letra+i);
textprintf_ex(BUFFER, font, BORDELATERAL*2+(ancho/2)+(i*anchoCasilla)+(anchoCasilla/2), BORDESUPERIOR/2, BLACK, -1,
"%c", letra+i);
}
for(i=0; i<FILA; i++){
textprintf_ex(BUFFER, font, BORDELATERAL/2, BORDESUPERIOR+(i*altoCasilla)+(altoCasilla/2) , BLACK, -1,
"%d", i+1);
textprintf_ex(BUFFER, font, (BORDELATERAL/2)+(ancho/2)+BORDELATERAL, BORDESUPERIOR+(i*altoCasilla)+(altoCasilla/2) , BLACK, -1,
"%d", i+1);
textprintf_ex(BUFFER, font, (BORDELATERAL/2)+(ancho)+BORDELATERAL*2, BORDESUPERIOR+(i*altoCasilla)+(altoCasilla/2) , BLACK, -1,
"%d", i+1);
}
}else{
ancho=ANCHOVENTANA-BORDELATERAL*2;
alto=ALTOVENTANA-MARGENINFERIOR-BORDESUPERIOR;
anchoCasilla=ancho/COLUMNA;
altoCasilla=alto/FILA;
for(i=0; i<COLUMNA; i++){
textprintf_ex(BUFFER, font, BORDELATERAL+(i*anchoCasilla)+(anchoCasilla/2), BORDESUPERIOR/2, BLACK, -1,
"%c", letra+i);
}
for(i=0; i<FILA; i++){
textprintf_ex(BUFFER, font, BORDELATERAL/2, BORDESUPERIOR+(i*altoCasilla)+(altoCasilla/2) , BLACK, -1,
"%d", i+1);
textprintf_ex(BUFFER, font, (BORDELATERAL/2)+(ancho)+BORDELATERAL, BORDESUPERIOR+(i*altoCasilla)+(altoCasilla/2) , BLACK, -1,
"%d", i+1);
}
}
}
//genero un número aleatorio, min y max incluidos
int aleatorio(int min, int max){
int aleatorio;
aleatorio=rand()%(max-min+1);
aleatorio=aleatorio+min;
return aleatorio;
}
//leo un número
int leerNumero(){
int lectura, resultado=0;
do{
lectura=(readkey() & 0xff)-48;
if(lectura>=0 && lectura<=9){
resultado=resultado*10+lectura;
}else{
break;
}
}while(TRUE);
return resultado;
}
