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; }