Hecho con un simulador MIPS en java que podéis descargar. Si alguien necesita ayuda para ejecutar el código, que deje un comentario.
El código es funcional, faltaría poner un poco de inteligencia artificial (modo difícil) y usar los nombres de los jugadores que se pueden personalizar.
Los barcos enemigos se muestran, lo dejé así para probar si funciona. Si quieres jugarlo de verdad, cambia el uno a cero en la sección del bucle de juego, en la línea 503:
li $a3, 1 #cero si no quiero que muestre los barcos enemigos
Hundir la flota: Pulsa para ver/ocultar el código
#====================================================================================== # HUNDIR LA FLOTA # by Dorian Hawkmoon # Open Source # Estilo Callee-saved # Iniciado en 17-6-2012 (pausado en 21-6-2012) continuado en 12-09-2012 # Finalizado en 14-09-2012 #====================================================================================== .data menu1: .asciiz "1. Jugar\n" menu2: .asciiz "2. Opciones\n" menu3: .asciiz "3. Salir\n" opcion1: .asciiz "1. Tamaño tablero\n" opcion2: .asciiz "2. Numero de barcos\n" opcion3: .asciiz "3. Dificultad\n" opcion4: .asciiz "4. Cambiar nombres jugadores\n" opcion5: .asciiz "5. Volver al menú\n" separacion: .asciiz "==============================================================\n" matrizJugador1:.space 520 matrizJugador2: .space 520 maximos: .byte 3, 26, 20 #máximo 3 barcos de cada tipo, 26 columnas y 20 filas de tablero datos: .byte 'A', 'a', '-', '_', '|', 171, '\n', ' ' letra: .space 2 #dos para que el cero que añade al final cuando pido no pise los siguientes datos tamañoMatriz: .byte 10, 10 #columnas-filas numeroBarcos: .byte 1, 1, 1, 1, 1 dificultad: .byte 0 #cero= fácil (al azar) 1=dificil (inteligencia) jugador1: .asciiz "Jugador1\n" jugador2: .asciiz "Jugador2\n" numeroCasillasFinal: .byte 0 casillasDadasPrimerJugador: .byte 0 casillasDadasSegundoJugador: .byte 0 seleccionOpcion: .asciiz "Seleccione una opción:\n" errorOpcion: .asciiz "Opción incorrecta, vuelva a seleccionar una opción.\n" mensajeErrorLetraTiro: .asciiz "Error, la letra está fuera de rango\n" mensajeErrorNumeroTiro: .asciiz "Error, el número está fuera de rango\n" tablaPropia: .asciiz "\nSus barcos y los disparos que le hicieron:\n" tablaDisparos: .asciiz "\nLos disparos que ha realizado:\n" seleccionarColumna: .asciiz "Seleccione la columna donde disparar (letra): " seleccionarFila: .asciiz "\nSeleccione la fila donde disparar (número): " colocarColumna: .asciiz "\nSeleccione la columna donde colocarlo (letra): " colocarFila:.asciiz "\nSeleccione la fila donde colocarlo (número): " mensajeTocadoIA:.asciiz "¡El enemigo te ha dado! " mensajeAguaIA: .asciiz "El enemigo dió en agua: " mensajeAgua: .asciiz "Agua: " yaSeleccionado: .asciiz "Casilla ya seleccionada: " mensajeTocado: .asciiz "Barco tocado: " mensajeTocadoHundido: .asciiz "Barco tocado y hundido: " ganar: .asciiz "¡¡Ha ganado la partida!!" perder: .asciiz "Ha perdido la partida... :(" ponerBarcos: .asciiz "Coloque los barcos de tamaño " ponerBarcos2: .asciiz ", le quedan " barcoMalColocado: .asciiz "Barco mal colocado, vuelva a intentarlo.\n" barcoEnMedio: .asciiz "Ya hay un barco en medio, colóquelo en otro sitio.\n" tamanoErroneo: .asciiz "El barco es más grande, especifique un sitio más grande\n" dificil: .asciiz "dificil\n" facil: .asciiz "fácil\n" cambioNumeroBarcos: .asciiz " El número de barcos de tamaño 1-2-3-4-5 está establecido en: " cambioNumeroBarcos2: .asciiz "Introduzca el número de barcos (máx. 3) de tamaño " cambioDificultadModo: .asciiz "El juego está establecido en modo " seleccionModo: .asciiz "Introduzca el número del modo deseado:" seleccionModoDificultad: .asciiz "\n0.Fácil\n1.Dificil\n" cambioNombres: .asciiz "El nombre del jugador 1 y 2 son:\n" cambioNombres2: .asciiz "Introduzca el nombre del primer jugador: " cambioNombres3: .asciiz "Introduzca el nombre del segundo jugador:" cambioTablero: .asciiz "El tamaño del tablero está establecido en: " opcionTableroColumnas: .asciiz "Introduzca el número de columnas (máx. 26): " opcionTableroFilas: .asciiz "Introduzca el número de filas (máx. 20): " .globl main .text main: mostrarMenu: lb $a0, datos+7 jal mostrarCaracter #salto de linea la $a0, separacion jal mostrarCadena la $a0, menu1 jal mostrarCadena la $a0, menu2 jal mostrarCadena la $a0, menu3 jal mostrarCadena la $a0, separacion jal mostrarCadena #pedir opción la $a0, seleccionOpcion jal mostrarCadena jal pedirNumero move $t0, $v0 #comienza el switch case beq $t0, 1, jugar beq $t0, 2, mostrarOpciones beq $t0, 3, salir #error opción, vuelvo a mostrar menú y pedir numero la $a0, errorOpcion jal mostrarCadena j mostrarMenu mostrarOpciones: la $a0, separacion jal mostrarCadena la $a0, opcion1 jal mostrarCadena la $a0, opcion2 jal mostrarCadena la $a0, opcion3 jal mostrarCadena la $a0, opcion4 jal mostrarCadena la $a0, opcion5 jal mostrarCadena la $a0, separacion jal mostrarCadena #pido opción la $a0, seleccionOpcion jal mostrarCadena jal pedirNumero move $t0, $v0 #comienza el switch case beq $t0, 1, tamaño beq $t0, 2, numero beq $t0, 3, dificultadJuego beq $t0, 4, cambioNombresJugadores beq $t0, 5, mostrarMenu #error opción, vuelvo a mostrar el menú y pedir número la $a0, errorOpcion jal mostrarCadena j mostrarOpciones #============================================================================================== # SECCIÓN APARTADOS DEL MAIN CORRESPONDIENTES A CADA OPCIÓN DEL MENÚ #============================================================================================== #cambio del tamaño del tablero tamaño: #muestro el tamaño establecido #El tamaño del tablero está establecido en: 10x10 la $a0, cambioTablero jal mostrarCadena #muestro mensaje (El tamaño del tablero está establecido en:) la $t0, tamañoMatriz lb $a0, ($t0) jal mostrarNumero #muestro el número de columnas lb $t1, datos+1 addi $t1, $t1, 23 move $a0, $t1 jal mostrarCaracter #muestro el x lb $a0, 1($t0) jal mostrarNumero #muestro el número de filas lb $a0, datos+6 jal mostrarCaracter #muestro un salto de linea #pregunto por el tamaño deseado lb $t0, maximos+1 #columnas máximas columnasTablero: la $a0, opcionTableroColumnas jal mostrarCadena jal pedirNumero bgt $v0, $t0, columnasTablero sb $v0, tamañoMatriz#guardo la opción #pregunto por el tamaño deseado lb $t0, maximos+2 #maximo de filas filasTablero: la $a0, opcionTableroFilas jal mostrarCadena jal pedirNumero bgt $v0, $t0, filasTablero sb $v0, tamañoMatriz+1#guardo la opción #vuelvo al menú j mostrarOpciones #cambio el número de barcos de cada tipo numero: #muestro el número de barcos establecido la $a0, cambioNumeroBarcos jal mostrarCadena lb $t0, datos+2 #recojo el guion (-) la $t1, numeroBarcos li $t2, 5 bucleNumBarcosMostrar: #por cada tamaño del barco muestro el número y lo separo con el guión lb $a0, ($t1) #recojo el número y lo muestro jal mostrarNumero #actualizo puntero y contador addi $t1, $t1, 1 addi $t2, $t2, -1 beqz $t2, finBucleNumBarcosMostrar #compruebo si acabé move $a0, $t0 #recojo el carácter y lo muestro (-) jal mostrarCaracter j bucleNumBarcosMostrar finBucleNumBarcosMostrar:#cuando acabo continuo lb $a0, datos+6 jal mostrarCaracter #muestro un salto de linea la $t0, cambioNumeroBarcos2 #frase la $t1, numeroBarcos #lugar donde guardo el número de barcos li $t2, 1 #contador lb $t4, datos+6 #salto de línea lb $t5, maximos #maximo de barcos por cada tamaño bucleCambiarNumBarcos: move $a0, $t0 jal mostrarCadena #muestro cadena de petición... move $a0, $t2 jal mostrarNumero #... del barco cuyo tamaño es el del contador move $a0, $t4 jal mostrarCaracter #salto de linea para mejor presentación jal pedirNumero #pido número bgt $v0, $t5, bucleCambiarNumBarcos #si paso el máximo vuelvo a pedir sb $v0, ($t1) #lo guardo #actualizo puntero y contador, condición de salida y vuelvo al bucle beq $t2, 5, finBucleCambiarNumBarcos #cuando ya cambió los cinco tipos de barcos addi $t1, $t1, 1 addi $t2, $t2, 1 j bucleCambiarNumBarcos #cuando termino vuelvo al menú finBucleCambiarNumBarcos: j mostrarOpciones #cambio el nombre de los jugadores cambioNombresJugadores: #muestro el nombre establecido a los jugadores: #El nombre del jugador 1 y 2 son: la $a0, cambioNombres jal mostrarCadena la $a0, jugador1 jal mostrarCadena #nombre jugador1 la $a0, jugador2 jal mostrarCadena#nombre jugador2 lb $a0, datos+7 jal mostrarCaracter #espacio de separación #pido ambos nombres la $a0, cambioNombres2 jal mostrarCadena la $a0, jugador1 la $a1, 8 jal pedirCadena la $a0, cambioNombres3 jal mostrarCadena la $a0, jugador2 la $a1, 8 jal pedirCadena j mostrarOpciones #cambio la dificultad al juego (contrincante ataca al azar, o si acierta un barco, atacará la zona hasta hundirlo) dificultadJuego: #muestro el modo establecido la $a0, cambioDificultadModo jal mostrarCadena #muestro el modo establecido lb $t0, dificultad la $a0, facil beq $t0, 0, mostrarDificultad la $a0, dificil mostrarDificultad: jal mostrarCadena #pido la dificultad escogida la $a0, seleccionModo jal mostrarCadena la $a0, seleccionModoDificultad jal mostrarCadena jal pedirNumero #cualquier error, vuelvo a mostrar el modo y pedir número blt $v0, 0, errorOpcionDificultad bgt $v0, 1, errorOpcionDificultad #guardo la opción sb $v0, dificultad j mostrarOpciones #cualquier error, vuelvo a mostrar el modo y pedir número errorOpcionDificultad: la $a0, errorOpcion jal mostrarCadena j dificultadJuego jugar: #inicializo unas variables que usaré mucho la $s0, letra la $s1, datos la $s2, tamañoMatriz #inicializo las matrices del juego move $a0, $s2 la $a1, matrizJugador1 jal inicializarMatricesCero move $a0, $s2 la $a1, matrizJugador2 jal inicializarMatricesCero #poner barcos #pongo los del enemigo la $a0, matrizJugador2 move $a1, $s2 la $a2, numeroBarcos move $a3, $s1 jal colocarBarcosEnemigo #pongo los del jugador #Muestro la matriz de barcos del jugador move $a0, $s1 move $a1, $s2 la $a2, matrizJugador1 li $a3, 1 #uno para que muestre los barcos jal dibujarTablero la $s3, numeroBarcos li $s5, 0 li $s6, 0 buclePonerBarcos: #bucle para poner todos los barcos beq $s5, 5, finBuclePonerBarcos addi $s5, $s5, 1 lb $s4, ($s3) #recojo el número de barcos de ese tamaño addi $s3, $s3, 1 bucleNumPonerBarco: #bucle para colocar todos los barcos de un determinado tamaño add $s6, $s6, $s5 lb $a0, datos+7 jal mostrarCaracter #salto de linea #muestro la frase para pedir donde colocar los barcos la $a0, ponerBarcos #"Coloque los barcos de tamaño " jal mostrarCadena move $a0, $s5 jal mostrarNumero # X la $a0, ponerBarcos2 jal mostrarCadena # ", le quedan " move $a0, $s4 jal mostrarNumero # X (barcos) lb $a0, 6($s1) jal mostrarCaracter # \n li $s7, 1 #dos iteracciones para pedir inicio y fin de barco bucleColocarBarco: #bucle para colocar un determinado barco #pido el barco: primera iteracción, principio del barco, segunda iteracción, final del barco la $a0, colocarColumna jal mostrarCadena move $a0, $s0 li $a1,2 jal pedirCadena la $a0, colocarFila jal mostrarCadena jal pedirNumero move $t3, $v0 lb $a0, ($s0) #letra move $a1, $t3 #numero move $a2, $s1 #datos move $a3, $s2 #tamaño matriz jal ajustesValoresCasilla beqz $v0, errorLetra beq $v0, 1, errorNumero beq $s7, 1, segundaIteraccion #queda guardado en pila letra-numero lb $t0, ($sp) addi $sp, $sp, 1 addi $sp, $sp, -4 sw $t0, ($sp) #letra addi $sp, $sp, -4 sw $v1, ($sp) #letra j continuarColocandoBarco segundaIteraccion: #queda finalmente guardado #letra-numero(final) y letra-numero(inicial) lb $t0, ($sp) addi $sp, $sp, 1 addi $sp, $sp, -4 sw $t0, ($sp) #letra addi $sp, $sp, -4 sw $v1, ($sp) #letra continuarColocandoBarco: beqz $s7, finBucleColocarBarco addi $s7, $s7, -1 j bucleColocarBarco errorLetra: la $a0, mensajeErrorLetraTiro jal mostrarCadena j bucleColocarBarco errorNumero: la $a0, mensajeErrorNumeroTiro jal mostrarCadena j bucleColocarBarco finBucleColocarBarco: #compruebo que el barco esté bien colocado lw $a2, ($sp) #letra final addi $sp, $sp, 4 lw $a3, ($sp) #numero final addi $sp, $sp, 4 lw $a0, ($sp) #letra inicial addi $sp, $sp, 4 lw $a1, ($sp) #numero inicial addi $sp, $sp, 4 addi $sp, $sp, -4 la $t3, matrizJugador1 sw $t3, ($sp) lb $t4, tamañoMatriz addi $sp, $sp, -1 sb $t4, ($sp) addi $sp, $sp, -1 sb $s5, ($sp) jal colocacionCorrecta #compruebo que se ha colocado correctamente y si es así, lo coloca en la matriz beq $v0, 1, errorColocacion beq $v0, 2, errorBarcoMedio beq $v0, 3, errorTamanoBarco #Muestro la matriz de barcos del jugador lb $a0, datos+7 jal mostrarCaracter #salto de linea move $a0, $s1 move $a1, $s2 la $a2, matrizJugador1 li $a3, 1 #uno para que muestre los barcos jal dibujarTablero addi $s4, $s4, -1 #quito un barco de ese tamaño beqz $s4, buclePonerBarcos #si ya terminé con ese tamaño, voy por el siguiente j bucleNumPonerBarco errorColocacion: la $a0, barcoMalColocado jal mostrarCadena j bucleNumPonerBarco errorBarcoMedio: la $a0, barcoEnMedio jal mostrarCadena j bucleNumPonerBarco errorTamanoBarco: la $a0, tamanoErroneo jal mostrarCadena j bucleNumPonerBarco finBuclePonerBarcos: #guardo las casillas de barco final para obtener la victoria sb $s6, numeroCasillasFinal #============================================================================================== # SECCIÓN BUCLE DEL JUEGO #============================================================================================== li $s2, 0 li $s3, 0 lb $s4, numeroCasillasFinal #inicio el bucle del juego bucleJuego: lb $a0, datos+7 jal mostrarCaracter #salto de linea la $a0, separacion jal mostrarCadena lb $a0, datos+7 jal mostrarCaracter #salto de linea #Comienzo con el jugador 1 la $a0, tablaDisparos jal mostrarCadena #Muestro la matriz de disparos del jugador la $a0, datos la $a1, tamañoMatriz la $a2, matrizJugador2 li $a3, 1 #cero si no quiero que muestre los barcos enemigos (esta a uno para debug) ############################################################# jal dibujarTablero la $a0, tablaPropia jal mostrarCadena #Muestro la matriz de barcos del jugador la $a0, datos la $a1, tamañoMatriz la $a2, matrizJugador1 li $a3, 1 #uno para que muestre los barcos jal dibujarTablero #pregunto por el tiro que quiere realizar preguntarTiro: la $a0, seleccionarColumna jal mostrarCadena la $a0, letra la $a1,2 jal pedirCadena la $a0, seleccionarFila jal mostrarCadena jal pedirNumero #tengo en registros los datos obtenidos move $s1, $v0#numero la $t0, letra lb $s0, ($t0) # compruebo la casilla y la marco move $a0, $s0 #paso letra move $a1, $s1 #paso numero la $a2, matrizJugador2 la $a3, datos addi $sp, $sp, -4 #actualizo el puntero la $t0, tamañoMatriz sw $t0, ($sp) #limites jal comprobarCasilla #comprueba que es correcto y lo marca #switch case beq $v0, 2, agua beq $v0, 3, tocado beq $v0, 4, seleccionado la $a0, mensajeErrorLetraTiro #presupongo error en la letra beqz $v0, errorTiro #si efectivamente es error de letra, salto al errorTIro la $a0, mensajeErrorNumeroTiro # si no lo es, pongo error de numero y salto al errorTiro j errorTiro tocado: #incremento contador de tocados addi $s2, $s2, 1 la $a0, mensajeTocado j coordenadasTirada agua: la $a0, mensajeAgua j coordenadasTirada seleccionado: la $a0, yaSeleccionado j coordenadasTirada coordenadasTirada: jal mostrarCadena move $a0, $s0 jal mostrarCaracter move $a0, $s1 jal mostrarNumero lb $a0, datos+6 jal mostrarCaracter beq $s2, $s4, partidaGanada tiroIA: lb $s0, tamañoMatriz #limite columna lb $s1, tamañoMatriz+1 #limite fila move $a0, $s0 jal generarNumero move $s0, $v0#escojo columna move $a0, $s1 jal generarNumero move $s1, $v0 #escojo fila # compruebo la casilla y la marco move $a0, $s0 #paso letra addi $a0,$a0, 97 move $a1, $s1 #paso numero addi $a1, $a1, 1 la $a2, matrizJugador1 la $a3, datos addi $sp, $sp, -4 #actualizo el puntero la $t0, tamañoMatriz sw $t0, ($sp) #limites jal comprobarCasilla #comprueba que es correcto y lo marca #switch case beq $v0, 2, aguaIA beq $v0, 3, tocadoIA j tiroIA tocadoIA: #incremento contador de tocados addi $s3, $s3, 1 la $a0, mensajeTocadoIA j tiradaIA aguaIA: la $a0, mensajeAguaIA j tiradaIA tiradaIA: jal mostrarCadena move $a0, $s0 addi $a0, $a0, 97 jal mostrarCaracter move $a0, $s1 addi $a0, $a0, 1 jal mostrarNumero lb $a0, datos+6 jal mostrarCaracter beq $s3, $s4, partidaPerdida j bucleJuego errorTiro: jal mostrarCadena j preguntarTiro partidaGanada: lb $a0, datos+7 jal mostrarCaracter #salto de linea la $a0, ganar jal mostrarCadena lb $a0, datos+7 jal mostrarCaracter #salto de linea j mostrarMenu partidaPerdida: lb $a0, datos+7 jal mostrarCaracter #salto de linea la $a0, perder jal mostrarCadena lb $a0, datos+7 jal mostrarCaracter #salto de linea j mostrarMenu salir: li $v0, 10 syscall #================================================================================================== # MÉTODOS #================================================================================================== # Muestra la cadena pasada por parámetro # parametros pasados: $a0 -> la cadena a mostrar mostrarCadena: li $v0, 4 syscall jr $ra # Pide un número y lo devuelve pedirNumero: li $v0, 5 syscall jr $ra # Muestra el número # $a0, el número mostrarNumero: li $v0, 1 syscall jr $ra #Muestra el caracter dado # $a0, el carácter mostrarCaracter: li $v0, 11 syscall jr $ra # Pide una cadena #$a0, cadena a mostrar # $a1, maximo caracteres pedirCadena: li $v0, 8 syscall jr $ra # Genera un número aleatorio # $a0 limite superior del rango de números (no incluido) # $v0 el número aleatorio generarNumero: li $v0, 42 move $a1, $a0 li $a0, 5 syscall move $v0, $a0 jr $ra # Coloca los barcos del enemigo # $a0 -> matriz del enemigo # $a1 -> puntero a los tamaños de la matriz # $a2 -> puntero al número de barcos # $a3 -> puntero Datos colocarBarcosEnemigo: #guardo retorno addi $sp, $sp, -4 sw $ra, ($sp) #guardo $sX addi $sp, $sp, -4 sw $s0,($sp) addi $sp, $sp, -4 sw $s1,($sp) addi $sp, $sp, -4 sw $s2,($sp) addi $sp, $sp, -4 sw $s3, ($sp) addi $sp, $sp, -4 sw $s4,($sp) addi $sp, $sp, -4 sw $s5,($sp) addi $sp, $sp, -4 sw $s6,($sp) addi $sp, $sp, -4 sw $s7,($sp) move $s0, $a0 # matriz move $s6, $a1 lb $s2, ($s6) #numero de columnas lb $s1, 1($s6) #numero de filas move $s3, $a2 #tamaños move $s7, $a3 #Datos li $s4, 0 #contador tamaño barcos bucleBarcosEnemigos: beq $s4, 5, finBucleBarcosEnemigos addi $s4, $s4, 1 lb $s5, ($s3) #numero barcos de ese tamaño addi $s3, $s3, 1 #incremento contador bucleBarcoEnemigo: beqz $s5, bucleBarcosEnemigos #genero aleatoriamente una casilla move $a0, $s2 addi $a0, $a0, 1 jal generarNumero move $t0, $v0 # columna move $a0, $s1 addi $a0, $a0, 1 jal generarNumero move $t1, $v0 # fila # selecciono aleatoriamente si horizontal o vertical li $a0, 2 jal generarNumero beqz $v0, enemigoVertical # enemigoHorizontal: move $t2, $t0 add $t3, $t1, $s4 j colocacionBarcoEnemigo enemigoVertical: move $t3, $t1 add $t2, $t0, $s4 colocacionBarcoEnemigo: #compruebo un momento que la segunda casilla esté dentro del rango bge $t2, $s2 , bucleBarcoEnemigo bge $t3, $s1, bucleBarcoEnemigo move $a0, $t0 move $a1, $t1 move $a2, $t2 move $a3, $t3 addi $sp, $sp, -4 sw $s0, ($sp) addi $sp, $sp, -1 sb $s2, ($sp) addi $sp, $sp,-1 sb $s4, ($sp) jal colocacionCorrecta bnez $v0, bucleBarcoEnemigo #si no es correcto, salto al bucle a que genere de nuevo la casilla #es correcto y ya lo ha colocado addi $s5, $s5, -1 j bucleBarcoEnemigo finBucleBarcosEnemigos: #recupero los datos de la pila y regreso lw $s7,($sp) addi $sp, $sp, 4 lw $s6,($sp) addi $sp, $sp, 4 lw $s5,($sp) addi $sp, $sp, 4 lw $s4, ($sp) addi $sp, $sp, 4 lw $s3,($sp) addi $sp, $sp, 4 lw $s2,($sp) addi $sp, $sp, 4 lw $s1,($sp) addi $sp, $sp, 4 lw $s0,($sp) addi $sp, $sp, 4 lw $ra, ($sp) addi $sp, $sp, 4 jr $ra # Comprueba que el barco esté bien colocado y entonces lo coloca # Parámetros que recibe: # $a0, letraInicio (valor ajustado) # $a1, numeroInicio (valor ajustado) # $a2, letra final (valor ajustado) # $a3, numero final (valor ajustado) # word en pila, puntero a la matriz del jugador donde se está colocando # byte en pila, numero de columnas máximas # byte en pila, tamaño del barco # Devuelve: # $v0: 0-> correcto # 1 -> mal colocado (solo se puede horizontal o vertical y no se pueden cortar con nada) # 2 -> mal colocado (hay otro barco en medio) # 3 -> no cabe el barco colocacionCorrecta: li $v0, 1 #presupongo mala colocación horizontal/vertical move $t0, $a0 #letra inicio move $t1, $a1 #numero inicio move $t2, $a2 #letra final move $t3, $a3 #letra final lb $t9, ($sp) #tamaño barco addi $sp, $sp, 1 lb $t5, ($sp) #columnas máximas addi $sp, $sp, 1 lw $t4, ($sp) #matriz jugador addi $sp, $sp, 4 #guardo en pila el retorno addi $sp, $sp, -4 sw $ra, ($sp) #me faltan registros $tx, por lo que dejo este en $sx y guardo en pila el valor anterior addi $sp, $sp, -4 sw $s0,($sp) addi $sp, $sp, -4 sw $s1,($sp) move $s0, $t9 #en $s0 está el tamaño del barco move $s1, $t9 beq $t0, $t2, incrementoNumero #están en la misma columna... beq $t1, $t3 incrementoColumna #están en la misma fila.... j establecerSX incrementoColumna: li $v0, 2 #presupongo barcos por el medio bgt $t2, $t0, continuoIncrementoColumna #intercambio los registros move $t6, $t2 move $t2, $t0 move $t0, $t6 continuoIncrementoColumna: #fórmula para hallar la posición dada en la matriz (Ncolumnas*fila+columna) mul $t7, $t5, $t3#hallo la posición final que dará la condición de salida del bucle errónea (debe salir con el contador) add $t7, $t7, $t2 bucleCruceBarcos2: addi $s1, $s1, -1 mul $t6, $t5,$t1 add $t6, $t6, $t0 add $t8, $t4, $t6 #obtengo la posición del puntero en la matriz lb $t9, ($t8) #obtengo el valor de la casilla #comparo valores beq $t9, 3, establecerSX #si es igual a tres, entonces ya hay un barco ahí beqz $s1, finBucleCruceBarcos beq $t7, $t6, errorTamano #si esa casilla ya era la última salgo del ciclo con error porque el barco es más grande #incremento el número de la columna addi $t0, $t0, 1 j bucleCruceBarcos2 incrementoNumero: li $v0, 2 #presupongo barcos por el medio bgt $t3, $t1, continuoIncrementoNumero #intercambio los registros move $t6, $t3 move $t3, $t1 move $t1, $t6 continuoIncrementoNumero: #fórmula para hallar la posición dada en la matriz (Ncolumnas*fila+columna) $t5*$t1+$t0 mul $t7, $t5, $t3#hallo la posición final que dará la condición de salida del bucle add $t7, $t7, $t2 bucleCruceBarcos: addi $s1, $s1, -1 mul $t6, $t5,$t1 add $t6, $t6, $t0 add $t8, $t4, $t6 #obtengo la posición del puntero en la matriz lb $t9, ($t8) #obtengo el valor de la casilla #comparo valores beq $t9, 3, establecerSX #si es igual a tres, entonces ya hay un barco ahí beqz $s1, finBucleCruceBarcos beq $t7, $t6, errorTamano #si esa casilla ya era la última salgo del ciclo con error porque el barco es más grande #incremento el número de la fila addi $t1, $t1, 1 j bucleCruceBarcos finBucleCruceBarcos: li $v0, 0 #no hay errores, coloco el barco, asignando los mismos parámetros que la colocación correcta #las $ax ya están correctamente seteadas al no hacer ninguna llamada en este método addi $sp, $sp, -4 sw $t4, ($sp) #matriz jugador addi $sp, $sp, -1 sb $t5, ($sp) #columnas máximas addi $sp, $sp, -1 sb $s0, ($sp) #tamaño del barco jal ponerBarco j establecerSX finColocacionCorrecta: #recupero el retorno de pila lw $ra, ($sp) addi $sp, $sp, 4 jr $ra errorTamano: li $v0, 3 j establecerSX establecerSX: lw $s1, ($sp) addi $sp, $sp, 4 lw $s0, ($sp) addi $sp, $sp, 4 j finColocacionCorrecta #Coloca el barco en la matriz # Parámetros que recibe: # $a0, letraInicio (valor ajustado) # $a1, numeroInicio (valor ajustado) # $a2, letra final (valor ajustado) # $a3, numero final (valor ajustado) # word en pila, puntero a la matriz del jugador donde se está colocando # byte en pila, numero de columnas máximas # byte en pila, tamaño del barco ponerBarco: move $t0, $a0 #letra inicio move $t1, $a1 #numero inicio move $t2, $a2 #letra final move $t3, $a3 #letra final lb $t9, ($sp) #tamaño barco addi $sp, $sp, 1 lb $t5, ($sp) #columnas máximas addi $sp, $sp, 1 lw $t4, ($sp) #matriz jugador addi $sp, $sp, 4 #me faltan registros $tx, por lo que dejo este en $sx y guardo en pila el valor anterior addi $sp, $sp, -4 sw $s0,($sp) move $s0, $t9 #en $s0 está el tamaño del barco li $t9, 3 #valor a guardar de barco puesto #fórmula para hallar la posición dada en la matriz (Ncolumnas*fila+columna) $t5*$t1+$t0 mul $t7, $t5, $t3#hallo la posición final que dará la condición de salida del bucle add $t7, $t7, $t2 beq $t0, $t2, incrementoNumero2 #están en la misma columna... beq $t1, $t3 incrementoColumna2 #están en la misma fila.... incrementoColumna2: bgt $t2, $t0, continuoIncrementoColumna2 #intercambio los registros move $t6, $t2 move $t2, $t0 move $t0, $t6 continuoIncrementoColumna2: addi $s0, $s0, -1 mul $t6, $t5,$t1 add $t6, $t6, $t0 add $t8, $t4, $t6 #obtengo la posición del puntero en la matriz sb $t9, ($t8) #guardo el valor de la casilla beqz $s0, finBuclePonerBarcos2 beq $t7, $t6, finBuclePonerBarcos2 #si esa casilla ya era la última salgo del ciclo sin errores #incremento el número de la columna addi $t0, $t0, 1 j continuoIncrementoColumna2 incrementoNumero2: bgt $t3, $t1, continuoIncrementoNumero2 #intercambio los registros move $t6, $t3 move $t3, $t1 move $t1, $t6 continuoIncrementoNumero2: addi $s0, $s0, -1 mul $t6, $t5,$t1 add $t6, $t6, $t0 add $t8, $t4, $t6 #obtengo la posición del puntero en la matriz sb $t9, ($t8) #guardo el valor de la casilla beqz $s0, finBuclePonerBarcos2 beq $t7, $t6, finBuclePonerBarcos2 #si esa casilla ya era la última salgo del ciclo sin errores #incremento el número de la fila addi $t1, $t1, 1 j continuoIncrementoNumero2 finBuclePonerBarcos2: lw $s0, ($sp) addi $sp, $sp, 4 jr $ra #recoje la letra y número, comprueba que esté dentro del rango y ajusta los valores para ser usados directamente a la matriz # Parametros que recibe # $a0 letra # $a1, numero # $a2, Datos (puntero) # $a3 limites (puntero) # Devuelve: # $v0: código de error # 0 -> error de rango en letra # 1 -> error de rango en número # 2 -> correcto # $v1: valor letra # byte pila: valor numero ajustesValoresCasilla: move $t0, $a0 #letra move $t1, $a1 #numero lb $t2, ($a2) #A lb $t3, 1($a2) #a lb $t4, ($a3) #limite columna lb $t5, 1($a3) #limite fila add $t6, $t2, $t4 #obtengo la letra máxima referente a las mayúsculas addi $t6, $t6, -1 li $v0, 0 #inicializo el estado de la celda en error, lo guardo directamente a devolver #hago comprobaciones con la letra y ajusto el número bge $t0, $t3, rangoMinus #compruebo si x>=a bge $t0, $t2, rangoMayus #compruebo si x>=A j finAjustarCasilla rangoMayus: bgt $t0, $t6, finAjustarCasilla #compruebo si X>letra máxima addi $t0, $t0, 32 #de mayuscula a minuscula addi $t0, $t0, -96 #lo paso a número li $v0, 1 #cambio el código de error j contenidoCasilla rangoMinus: addi $t6, $t6, 32 #ajusto el límite para las letras pequeñas bgt $t0, $t6, finAjustarCasilla #compruebo si x>letra máxima addi $t0, $t0, -96 #lo paso a número li $v0, 1 #cambio el código de error contenidoCasilla: #compruebo que el número no supere el máximo o mínimo blez $t1, finAjustarCasilla #supera maximo bgt $t1, $t5, finAjustarCasilla #supera minimo li $v0, 2 #cambio el código de error #resto ambos valores para ajustar a la matriz (que empieza en 0 y no en 1) y los devuelvo addi $v1, $t0, -1 addi $t1, $t1, -1 addi $sp, $sp, -1 sb $t1, ($sp) finAjustarCasilla: jr $ra # Comprueba la casilla en la matriz a ver si es agua, tocado, ya está dado... y devuelve el número correspondiente # $a0 columna (letra) # $a1 fila (numero) # $a2 matriz # $a3, datos # word en pila, límites # Devuelve un código de estado: # 0 -> si error letra fuera de rango # 1 -> si error, número fuera de rango # 2 -> si agua # 3 -> si tocado # 4 -> casilla ya seleccionada comprobarCasilla: lw $t0, ($sp) #limites #guardo los $sx que voy a usar y $ra sw $s0, ($sp) addi $sp, $sp, -4 sw $s1, ($sp) addi $sp, $sp, -4 sw $ra, ($sp) move $s0, $a2 #matriz move $s1, $t0 #limites #los parametros $a0 y $a1 ya están correctamente establecidos move $a2, $a3 move $a3, $s1 jal ajustesValoresCasilla beqz $v0, finComprobarCasilla beq $v0, 1, finComprobarCasilla #recojo los returns move $t0, $v1 #letra lb $t1, ($sp) #numero addi $sp, $sp, 1 lb $t2, ($s1) #limite columna #fórmula para hallar la posición dada en la matriz (Ncolumnas*fila+columna) $t2*$t1+$t0 mul $t3, $t2, $t1 add $t3, $t3, $t0 add $s0, $s0, $t3 #obtengo la posición del puntero en la matriz lb $t0, ($s0) #obtengo el valor de la casilla #comparo valores beqz $t0, cero #si es cero beq $t0, 3, tres #si es igual a tres #si es uno o dos, casilla ya usada, error li $v0, 4 j finComprobarCasilla tres: li $t3, 2 sb $t3, ($s0) #guardo un "tocado" li $v0, 3 #casilla libre y tocado j finComprobarCasilla cero: li $t3, 1 sb $t3, ($s0) #guardo un disparado y agua li $v0, 2 #casilla libre/agua finComprobarCasilla: #reestablezco los $sx y $ra lw $ra, ($sp) addi $sp, $sp, 4 lw $s1, ($sp) addi $sp, $sp, 4 lw $s0, ($sp) addi $sp, $sp, 4 jr $ra #Dibuja el tablero con los barcos puestos del jugador y los disparos que le han hecho #paso de parámetros: # $a0 -> Tamaño matriz # $a1 -> matriz del jugador inicializarMatricesCero: lb $t0, ($a0) #tamaño columna lb $t1, 1($a0) #tamaño fila move $t3, $a1 move $t2, $t0 #contador columnas bucleInicializarFilas: beqz $t1, finBucleInicializarFilas #si acabé con las filas, acabé con la matriz addi $t1, $t1, -1 #decremento el contador bucleInicializarColumnas: beqz $t2, finBucleInicializarColumna #si acabé las columnas, fuera addi $t2, $t2, -1 #decremento el contador sb $zero, ($t3) #guardo un cero en la celda addi $t3, $t3, 1 #me situo en la siguiente columna, #si es la última columna, se sitúa en la primera columna de la siguiente fila j bucleInicializarColumnas finBucleInicializarColumna: move $t2, $t0 j bucleInicializarFilas finBucleInicializarFilas: jr $ra #Dibuja el tablero #paso de parámetros: # $a0 -> Datos (guion bajo, 'A'...) # $a1 -> Tamaño matriz # $a2 -> matriz del jugador # $a3 -> muestro los barcos o no (0 si no los muestro, 1 si los muestro) #guardo y saco en pila todos los registros $sx que uso dibujarTablero: #TODOS LOS REGISTROS $tx Y $sx USADOS!!!!menos t3 #guardo en pila los registros addi $sp, $sp, -4 sw $s0, ($sp) addi $sp, $sp, -4 sw $s1, ($sp) addi $sp, $sp, -4 sw $s2, ($sp) addi $sp, $sp, -4 sw $s3, ($sp) addi $sp, $sp, -4 sw $s4, ($sp) addi $sp, $sp, -4 sw $s5, ($sp) addi $sp, $sp, -4 sw $s6, ($sp) addi $sp, $sp, -4 sw $s7, ($sp) #guardo en pila el retorno addi $sp, $sp, -4 sw $ra, ($sp) lb $t4, 6($a0) #salto de linea lb $t6, 7($a0) #espacio lb $s0, 3($a0) #guion bajo lb $s1, 4($a0) #barra vertical lb $s2, 5($a0) #simbolo de agua (<<) lb $s3, ($a0) #A #si no muestro los barcos, la B se queda con el guión bajo move $t9, $s0 #guion bajo beqz $a3, continuoInicializando addi $t9, $s3, 1 #B (de barco) continuoInicializando: addi $s7, $s3, 23 #X de disparo dado move $s4, $a2 #matriz propia lb $s5, ($a1) #columnas lb $s6, 1($a1) #filas li $t0, 0 #contador columnas li $t1, 0 #contador filas li $t7, 2 #contador para la presentación del marco superior de la tabla move $t8, $s3 #caracter a imprimir A bucleInicio:#muestra el marco superior beq $t0, $s5, finBucleInicio move $a0, $t6 #muestro un espacio jal mostrarCaracter move $a0, $t8 #muestro el caracter a imprimir jal mostrarCaracter addi $t0, $t0, 1 #incremento contador beq $t8, $s0, bucleInicio #si el caracter a imprimir es el guion, no le sumo un uno (para la siguiente letra) addi $t8, $t8, 1 j bucleInicio finBucleInicio: move $a0, $t4 jal mostrarCaracter #muestro un salto de linea addi $t7, $t7, -1 beqz $t7, bucleFilas #establezco una linea de guiones move $t8, $s0 #establezo el guión para la siguiente fila li $t0, 0 #reinicializo contador de columnas j bucleInicio bucleFilas: #por cada fila... beq $t1, $s6, finBucleFilas li $t0, 0 #contador columnas, reinicializo move $a0, $s1 jal mostrarCaracter #mostramos la barra del marco izquierdo bucleColumnas: #por cada columna, mostramos el guion bajo o X o B según corresponda y la barra vertical derecha beq $t0, $s5, finColumnas lb $t2, ($s4) #obtengo de la matriz información sobre la celda addi $s4, $s4, 1 #actualizo el puntero para la siguiente celda move $a0, $s0 #presupongo guión bajo (valor de la celda=0) beqz $t2, mostrarCelda #si es igual a cero, directamente a mostrar la celda move $a0, $s2 #presupongo disparo y agua (celda=1) beq $t2, 1, mostrarCelda #si es agua, directamente a mostrar la celda move $a0, $t9 #presupongo B de barco (valor=3) beq $t2, 3, mostrarCelda #si es igual a 3, es barco y muestro celda move $a0, $s7 #si no es ninguna de las anteriores es un barco tocado mostrarCelda: jal mostrarCaracter #muestro el caracter que corresponde move $a0, $s1 jal mostrarCaracter addi $t0, $t0, 1 j bucleColumnas finColumnas: addi $t1, $t1, 1 #incremento contador filas #mostramos el número de fila precedido de un espacio move $a0, $t6 jal mostrarCaracter move $a0, $t1 jal mostrarNumero move $a0, $t4 jal mostrarCaracter#muestro un salto de linea j bucleFilas finBucleFilas: move $a0, $t4 jal mostrarCaracter #muestro un salto de linea #recupero el retorno lw $ra, ($sp) addi $sp, $sp, 4 #recupero los registros #guardo en pila el retorno lw $s7, ($sp) addi $sp, $sp, 4 lw $s6, ($sp) addi $sp, $sp, 4 lw $s5, ($sp) addi $sp, $sp, 4 lw $s4, ($sp) addi $sp, $sp, 4 lw $s3, ($sp) addi $sp, $sp, 4 lw $s2, ($sp) addi $sp, $sp, 4 lw $s1, ($sp) addi $sp, $sp, 4 lw $s0, ($sp) addi $sp, $sp, 4 jr $ra