Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2020
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.88 KB | None | 0 0
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4.  
  5.  
  6. public class batallanaval {
  7.  
  8. private static final int VALOR_AGUA = 5;
  9. private static final int NUM_BARCOS = 5;
  10.  
  11. /********************************************************************************************************
  12. * Método principal:
  13. * - es el primer método al que llama la máquina virtual para ejecutar nuestro programa
  14. * - programamos en el el funcionamiento general del programa. Intentamos en la medida de lo posible
  15. * aislar todas las funciones que podamos identificar como principales
  16. * @param args
  17. *******************************************************************************************************/
  18.  
  19. public static void main(String[] args) {
  20. /*
  21. * Estructura de los datos:
  22. * Por cada jugador mantengo una matriz donde almaceno tanto sus barcos como los disparos que el otro
  23. * le ha realizado. La declaro como matriz de enteros porque necesito considerar varios valores
  24. * distintos, por lo que no me puede servir un dato boolean.
  25. *
  26. * La tabla de barcos de cada jugador contiene un contador por cada uno de los barcos. Cuando un tiro
  27. * da sobre un barco en particular, decremento su valor. Cuando el valor está a 0, entonces asumo que
  28. * el barco ha sido hundido.
  29. */
  30.  
  31. int[][] matrizUsuario = inicializaMatrizDisparos();
  32. int[] barcosUsuario = inicializaTablaBarcos();
  33.  
  34. int[][] matrizMaquina = inicializaMatrizDisparos();
  35. int[] barcosMaquina = inicializaTablaBarcos();
  36.  
  37.  
  38. /*
  39. * Variables auxiliares que me sirven para llevar adelante la ejecución del método
  40. */
  41. // Variable que utilizo para llevar el control del programa. Cuando se ponga a cierto tendré que terminar
  42. boolean haFinalizado = false;
  43. // Variable que utilizo para comprobar si un tiro de algún jugador ha sido correcto antes de actualizar
  44. // la información
  45. boolean tiroCorrecto = false;
  46. // Variable donde recojo el disparo de cada jugador. Es una tabla de dos posiciones
  47. int[] tiro = new int[2];
  48.  
  49. /*
  50. ************************************************************
  51. * Inicialización del juego: Poner barcos (usuario y máquina)
  52. ************************************************************
  53. */
  54. inicializacion(matrizUsuario, matrizMaquina, barcosMaquina);
  55.  
  56. /*
  57. ************************************************************
  58. * Bucle principal del programa: se repite el juego hasta que
  59. * un jugador gana. La variable haFinalizado recoge un valor
  60. * lógico que me indica cuándo ha llegado ese punto.
  61. ************************************************************
  62. */
  63. while(!haFinalizado){
  64.  
  65. /*
  66. ************************************************************
  67. * Al principio de cada turno, tengo que mostrarle al usuario
  68. * cómo se encuentra el juego: Dibujo los paneles
  69. ************************************************************
  70. */
  71. dibujarPaneles(matrizUsuario, barcosUsuario, matrizMaquina, barcosMaquina);
  72. /*
  73. * Mientras que no de me un disparo correcto,
  74. * le solicito un disparo correcto.
  75. */
  76. tiroCorrecto = false;
  77. while(!tiroCorrecto)
  78. {
  79. /*
  80. * Solicito al usuario el disparo.
  81. */
  82. tiro = pedirCasilla("Dispare:");
  83.  
  84. /*
  85. * Evaluar Tiro usuario.
  86. */
  87. tiroCorrecto = evaluarTiro(tiro, matrizUsuario);
  88. }
  89.  
  90. /*
  91. * Actualizo los datos del disparo. Si llego aquí ya se
  92. * que ha sido un disparo correcto
  93. */
  94. actualizaMatriz(matrizUsuario, barcosUsuario, tiro);
  95. /*
  96. * Compruebo si ha terminado el juego el usuario
  97. */
  98. haFinalizado = compruebaFin(barcosUsuario);
  99.  
  100. /*
  101. * Si el usuario ha ganado,
  102. * entonces directamente terminamos.
  103. */
  104. if(!haFinalizado){
  105. /*
  106. * Mientras que no de me un disparo correcto,
  107. * le solicito un disparo correcto.
  108. */
  109. tiroCorrecto = false;
  110. while(!tiroCorrecto)
  111. {
  112. tiro = generaDisparoAleatorio();
  113.  
  114. /*
  115. * Evaluar tiro de la máquina
  116. */
  117. tiroCorrecto = evaluarTiro(tiro, matrizMaquina);
  118. }
  119. actualizaMatriz(matrizMaquina,barcosMaquina,tiro);
  120.  
  121. haFinalizado = compruebaFin(barcosMaquina);
  122. }
  123. }
  124. System.out.println("Fin del juego!!!!!!");
  125. }
  126.  
  127. /**********************************************************************************************
  128. * Funciones principales llamadas desde el cuerpo del programa
  129. **********************************************************************************************/
  130.  
  131. /**
  132. * Función destinada a dibujar los paneles del usuario.
  133. */
  134. private static void dibujarPaneles(int[][] matrizUsuario,
  135. int[] barcosUsuario, int[][] matrizMaquina, int[] barcosMaquina) {
  136. //TODO hay que crearlo.
  137. }
  138.  
  139. /**
  140. * Función que una vez hemos comprobado que el tiro ha sido correcto, actualiza la información en la matriz
  141. */
  142. private static void actualizaMatriz(
  143. int[][] matriz,
  144. int[] barcos,
  145. int[] tiro)
  146. {
  147. int valorCasilla = matriz[tiro[0]][tiro[1]];
  148.  
  149. if(valorCasilla<VALOR_AGUA)
  150. {
  151. barcos[valorCasilla]--;
  152. }
  153. matriz[tiro[0]][tiro[1]] = matriz[tiro[0]][tiro[1]] + NUM_BARCOS + 1;
  154. }
  155.  
  156. /**
  157. * Función que realiza la inicialización del juego.
  158. * Su función es colocar los barcos del usuario y de la máquina
  159. */
  160.  
  161. private static void inicializacion(int[][] matrizUsuario,
  162. int[][] matrizMaquina,
  163. int[] barcos) {
  164.  
  165. ponerBarcosUsuario(matrizUsuario, barcos);
  166. ponerBarcosMaquina(matrizMaquina, barcos);
  167.  
  168. }
  169.  
  170. /**
  171. * Función que se encarga de situar los barcos de la máquina
  172. */
  173.  
  174. private static void ponerBarcosMaquina(int[][] matrizMaquina, int[] barcos) {
  175. boolean esBarcoValido = false;
  176. int[] valoresUsuario = new int[3];
  177. for(int i=0;i<=4;i++) // contar 5 barcos
  178. {
  179. while(!esBarcoValido)
  180. {
  181. valoresUsuario = generaBarcoAleatorio();
  182. esBarcoValido = comprobarBarco(valoresUsuario[0],
  183. valoresUsuario[1],
  184. valoresUsuario[2]==1,
  185. barcos[i], // Tamaño del barco
  186. matrizMaquina); // Matriz de los barcos de la máquina
  187. if(esBarcoValido)
  188. {
  189. almacenaEnTabla(matrizMaquina,
  190. valoresUsuario[0],
  191. valoresUsuario[1],
  192. valoresUsuario[2]==1,
  193. barcos[i], // Tamaño del barco
  194. i); // Valor que le pongo en sus casillas
  195. }
  196. }
  197. esBarcoValido = false;
  198. }
  199.  
  200. }
  201.  
  202. /**
  203. * Función que se encarga de situar los barcos del usuario
  204. */
  205.  
  206. private static void ponerBarcosUsuario(int[][] matrizUsuario, int[] barcos) {
  207. boolean esBarcoValido = false;
  208. int[] valoresUsuario = new int[3];
  209. for(int i=0;i<=4;i++) // contar 5 barcos
  210. {
  211. while(!esBarcoValido)
  212. {
  213. valoresUsuario = pedirBarcoUsuario(String.valueOf(barcos[i]) + " (barco " + (i+1) + "º)");
  214. esBarcoValido = comprobarBarco(valoresUsuario[0],
  215. valoresUsuario[1],
  216. valoresUsuario[2]==1,
  217. barcos[i],
  218. matrizUsuario);
  219. if(esBarcoValido)
  220. {
  221. almacenaEnTabla(matrizUsuario,
  222. valoresUsuario[0],
  223. valoresUsuario[1],
  224. valoresUsuario[2]==1,
  225. barcos[i], // tamaño del barco
  226. i); //valor que le pongo en sus casillas
  227. }
  228. else
  229. System.out.println("Posición errónea");
  230. }
  231. esBarcoValido = false;
  232.  
  233. }
  234.  
  235. }
  236.  
  237. /**
  238. * Función que se encarga de pedir un barco al usuario.
  239. */
  240.  
  241. private static int[] pedirBarcoUsuario(String tamanhoBarco) {
  242. int[] valoresBarco = new int[3];
  243. int[] casilla = new int[2];
  244. char[] posicion = new char[1];
  245.  
  246. casilla = pedirCasilla("Introduzca la primera casilla del barco de tamaño " + tamanhoBarco + " (Ej: A4):");
  247. valoresBarco[0] = casilla[0];
  248. valoresBarco[1] = casilla[1];
  249.  
  250. posicion[0] = 'a';
  251. while(Character.toUpperCase(posicion[0])!='V' && Character.toUpperCase(posicion[0])!='H')
  252. {
  253. // pedir posicion
  254. System.out.println("¿En qué posición quiere poner su barco? (V/H):");
  255. posicion = leeCaracteresTeclado(1);
  256.  
  257. if(Character.toUpperCase(posicion[0]) == 'H')
  258. {
  259. valoresBarco[2] = 1;
  260. }
  261. else
  262. {
  263. if(Character.toUpperCase(posicion[0]) == 'V')
  264. valoresBarco[2] = 0;
  265. }
  266. }
  267.  
  268. return valoresBarco;
  269. }
  270.  
  271. /**
  272. * Función que se encarga de pedir una casilla al usuario.
  273. * Se utiliza bien para pedir un disparo o bien para pedir la primera posición del barco.
  274. */
  275.  
  276. private static int[] pedirCasilla(String cadenaMensaje){
  277. int[] valores = new int[2];
  278. boolean encontrada = false;
  279. char[] casilla = new char [2];
  280. char[] letras = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};
  281.  
  282. System.out.println(cadenaMensaje);
  283. casilla = leeCaracteresTeclado(2);
  284.  
  285. //transformar la fila
  286. for(int i=0;i<8 && !encontrada;i++)
  287. {
  288. if(Character.toUpperCase(casilla[0])==letras[i]){
  289. encontrada = true;
  290. valores[0] = i;
  291. }
  292. }
  293. if(!encontrada)
  294. valores[0]=-1;
  295. /***************************************************************
  296. * La transformación anterior se puede hacer de esta otra manera
  297. * utilizando el caracter como valor numérico.
  298. *
  299. * valores[0] = Character.toUpperCase(casilla[0]) - 'A';
  300. ***************************************************************/
  301. // Columna transformada
  302. valores[1] = Character.getNumericValue(casilla[1]);
  303.  
  304. return valores;
  305. }
  306.  
  307. /**
  308. * Función que se encarga de actualizar la matriz una vez
  309. * que el tiro ha sido evaluado como válido
  310. */
  311.  
  312. private static void almacenaEnTabla(int[][] matriz,
  313. int fila,
  314. int columna,
  315. boolean posicion,
  316. int tamanho,
  317. int valorBarco)
  318. {
  319. if(posicion) // si el barco está en horizontal
  320. {
  321. for(int i=columna;i<=columna+tamanho-1;i++)
  322. {
  323. matriz[fila][i] = valorBarco;
  324. }
  325. }
  326. else // (si no) ==> si el barco está en vertical
  327. {
  328. for(int i=fila;i<=fila+tamanho-1;i++)
  329. {
  330. matriz[i][columna] = valorBarco;
  331.  
  332. }
  333. }
  334. }
  335.  
  336. /********************************************************************************************************
  337. * Funciones para que la máquina genere valores aleatorios
  338. ********************************************************************************************************/
  339. /**
  340. * Función que genera un disparo aleatorio. Devuelve un array de dos posiciones de entero.
  341. * La primera casilla es la fila.
  342. * La segunda casilla es la columna.
  343. */
  344. private static int[] generaDisparoAleatorio(){
  345. int[] valores = new int[2];
  346.  
  347. valores[0] = (int)Math.round(7*Math.random());
  348. valores[1] = (int)Math.round(7*Math.random());
  349.  
  350. return valores;
  351. }
  352. /**
  353. * Función que genera un barco aleatorio. Devuelve un array de tres posiciones de entero.
  354. * La primera casilla es la fila.
  355. * La segunda casilla es la columna.
  356. * La tercera casilla es una valor 0 ó 1 que indica (vertical/horizontal).
  357. */
  358. private static int[] generaBarcoAleatorio() {
  359. int[] valores = new int[3];
  360.  
  361. valores[0] = (int)Math.round(7*Math.random());
  362. valores[1] = (int)Math.round(7*Math.random());
  363. valores[2] = (int)Math.round(Math.random());
  364.  
  365. return valores;
  366. }
  367.  
  368. /********************************************************************************************************
  369. * Funciones que comprueban restricciones
  370. ********************************************************************************************************/
  371.  
  372. /**
  373. * Función que comprueba si hemos finalizado el juego
  374. * Se reduce a una búsqueda en un array. Busco el primer valor distinto de 0
  375. */
  376. private static boolean compruebaFin(int[] barcos)
  377. {
  378. for(int i=0;i<NUM_BARCOS;i++)
  379. {
  380. if(barcos[i]!=0)
  381. return false;
  382. }
  383. return true;
  384. }
  385.  
  386. /**
  387. * Función que comprueba si una casilla, dadas por su fila y su columna, está dentro del tablero.
  388. */
  389.  
  390. private static boolean compruebaCasillaErronea(int fila, int columna){
  391. return ((fila < 0 || fila > 7 || columna < 0 || columna > 7));
  392.  
  393. }
  394.  
  395. /**
  396. * Función que comprueba si un barco que un jugador desea situar en algún punto del tablero es correcto.
  397. */
  398.  
  399. private static boolean comprobarBarco(int fila,
  400. int columna,
  401. boolean posicion, // True-H; False-V
  402. int tamanho,
  403. int[][] matriz)
  404. {
  405. // Se comprueba si la casilla inicial está dentro del tablero
  406. if(compruebaCasillaErronea(fila, columna))
  407. {
  408. return false;
  409. }
  410. // Si el barco está en horizontal, compruebo que no se sale por la derecha del tablero
  411. if(posicion && (columna+tamanho-1)>7)
  412. {
  413. return false;
  414. }
  415. // Si el barco está en vertical, compruebo que no se sale por debajo del tablero
  416. if(!posicion && (fila+tamanho-1)>7)
  417. {
  418. return false;
  419. }
  420.  
  421. // Si llego a este punto, es que el barco cabe dentro del tablero
  422. // Me queda por comprobar que el barco no se pisa con otros que ya estén puestos
  423.  
  424. if(posicion) // si el barco está en horizontal
  425. {
  426. for(int i=columna;i<=columna+tamanho-1;i++)
  427. {
  428. if(matriz[fila][i]!=VALOR_AGUA)
  429. {
  430. return false;
  431. }
  432. }
  433. }
  434. else // (si no) ==> si el barco está en vertical
  435. {
  436. for(int i=fila;i<=fila+tamanho-1;i++)
  437. {
  438. if(matriz[i][columna]!=VALOR_AGUA)
  439. {
  440. return false;
  441. }
  442. }
  443. }
  444. // Si llego a este punto es que todas las comprobaciones se han cumplido. Devuelvo cierto (true)
  445. return true;
  446. }
  447.  
  448. /**
  449. * Función que evalua si un tiro de algún jugador es correcto, es decir, es una casilla dentro del tablero
  450. * y no ha sido disparada previamente por ese mismo jugador
  451. */
  452.  
  453. private static boolean evaluarTiro(int[] valores, int[][] matriz) {
  454. // Casilla dentro del tablero
  455.  
  456. // Casilla repetida??
  457. return (
  458. (!compruebaCasillaErronea(valores[0], valores[1]))
  459. &&
  460. (matriz[valores[0]][valores[1]]<=VALOR_AGUA)
  461. );
  462. }
  463.  
  464. /*********************************************************************************************************
  465. * Funciones inicialización
  466. *********************************************************************************************************/
  467. /**
  468. * Función que sirve para crear un panel vacío. Inicialmente, rellena todas las casillas con el valor
  469. * de "agua no disparada" (VALOR_AGUA)
  470. */
  471. private static int[][] inicializaMatrizDisparos(){
  472. int[][] matriz = new int[8][8];
  473. for(int i=0;i<=7;i++)
  474. {
  475. for(int j=0;j<=7;j++)
  476. {
  477. matriz[i][j] = VALOR_AGUA;
  478. }
  479. }
  480. return matriz;
  481. }
  482.  
  483. /**
  484. * Función que sirve para crear la tabla de barcos de cada jugador. Inicializa la tabla con tantas posiciones
  485. * como barcos hay, y en cada una de ellas escribe el tamaño del barco correspondiente.
  486. */
  487. private static int[] inicializaTablaBarcos(){
  488. int[] tablaBarcos = {5,4,3,3,2};
  489. return tablaBarcos;
  490. }
  491.  
  492. /*********************************************************************************************************
  493. * Funciones auxiliares
  494. *********************************************************************************************************/
  495. /**
  496. * Lee un número de caracteres escritos desde el teclado
  497. * El parámetro numCaracteres es el número de caracteres que queremos leer
  498. * El resultado se devuelve en un array de ese mismo número de posiciones
  499. */
  500. public static char[] leeCaracteresTeclado(int numCaracteres){
  501. InputStreamReader isr = new InputStreamReader(System.in);
  502. BufferedReader br = new BufferedReader (isr);
  503. String cadena="";
  504. char[] resultado = new char[numCaracteres];
  505. try {
  506. while(cadena.length()<numCaracteres){
  507. cadena = br.readLine();
  508. if(cadena.length()<numCaracteres)
  509. System.out.println("Se espera un texto de " +
  510. numCaracteres);
  511. for(int i=0;i<numCaracteres
  512. && cadena.length()>=numCaracteres;i++)
  513. resultado[i]=cadena.charAt(i);
  514. }
  515. } catch (IOException e) {
  516. System.out.println("Error en la lectura del teclado.");
  517. }
  518.  
  519. return resultado;
  520. }
  521. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement