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
