1. Aigua, tocat, enfonsat (6 punts)¶
L’objectiu d’aquest exercici és crear una classe de Python que representa un tauler del joc de la guerra de vaixells. Es tracta d’un conegut joc per a dues persones. Cada jugador situa una sèrie de vaixells de longituds diverses sobre el seu tauler quadriculat, horitzontalment o verticalment, sense que l’oponent sàpiga on. Per torns, els jugadors «disparen» sobre una coordenada i el contrincant respon «aigua», «tocat» o «enfonsat», depenent de si la tirada no ha tocat cap vaixell, n’ha encertat un parcialment o ha encertat l’última part indemne d’un vaixell ja tocat. Guanya el jugador que primer enfonsa la flota del contrincant.
El tauler de joc de cada jugador serà un espai quadrat de dimensions fixes. Cada casella del tauler contindrà un caràcter, que serà '-' si la casella no conté una part d’un vaixell, 'V' si la casella està ocupada per una part no tocada d’un vaixell o bé 'X' si la casella conté una part d’un vaixell encertada pel contrincant. Caldrà emmagatzemar aquesta informació en una llista de llistes.
A l’esquerra, tauler d’un dels dos jugadors, de 5x5 caselles i amb tres vaixells, un d’ells indemne, l’altre parcialment tocat i el tercer enfonsat. A la dreta, matriu (llista de llistes) de caràcters que representa el tauler de l’esquerra. Fixeu-vos que la primera subllista correspon a la coordenada y=0, és a dir, a la fila de més avall del tauler.¶
Una casella del tauler té coordenades (x, y), essent x la coordenada horitzontal i y la vertical. La casella de coordenades (0,0) serà la de la cantonada inferior esquerra del tauler i la de la cantonada superior dreta tindrà coordenades màximes. Direm que unes coordenades són vàlides si no superen aquests límits.
Implementeu la classe TaulerVaixells i deseu-la al mòdul vaixells (fitxer vaixells.py) tal com queda especificada:
- class vaixells.TaulerVaixells(dim=5)¶
Crea un tauler quadrat amb \(dim \times dim\) caselles, inicialment tot buit (sense cap vaixell).
Atributs públics:
- num_tirades¶
Nombre de tirades que ha fet el contrincant sobre el tauler; inicialment 0.
Operacions:
Operació
Resultat
t[coords]Caràcter que indica què hi ha a la casella de coordenades
coords('-','V'o'X'). del tauler t. Es compleix que les coordenades són vàlides.Mètodes:
- dimensio()¶
Retorna el nombre de files del tauler (o equivalentment el nombre de columnes, perquè el tauler és quadrat).
- afegeix_vaixell_H(coords, n)¶
Afegeix un vaixell de longitud n en horitzontal al tauler, essent coords les coordenades de més a l’esquerra. Es compleix que n és tal que totes les coordenades de les caselles on s’afegeix el vaixell són vàlides.
- afegeix_vaixell_V(coords, n)¶
Afegeix un vaixell de longitud n en vertical al tauler, essent coords les coordenades de més avall. Es compleix que n és tal que totes les coordenades de les caselles on s’afegeix el vaixell són vàlides.
- dispara(coords)¶
Realitza una tirada del contrincant a la casella de coordenades coords del tauler. En primer lloc, incrementa el nombre de tirades. En segon lloc, si la casella conté part d’un vaixell no encertada, es marca com a «tocada». Es compleix que les coordenades coords són vàlides.
Per emmagatzemar les caselles al tauler fareu servir un atribut privat, que ha de ser una llista de llistes de caràcters. Cada subllista correspon al contingut de les caselles d’una fila del tauler. Vegeu l’exemple de la figura.
Exemples d’ús:
>>> from vaixells import TaulerVaixells
--ini-enunciat
>>> t = TaulerVaixells()
>>> t.num_tirades
0
>>> t.dimensio()
5
>>> for y in range(4, -1, -1): # Dibuixem el tauler, fent ús de la consulta per índex
... for x in range(5):
... print(t[x, y], end='')
... print()
-----
-----
-----
-----
-----
>>> t.afegeix_vaixell_H((0,0), 3)
>>> t.afegeix_vaixell_V((1,3), 2)
>>> t.afegeix_vaixell_V((3,2), 2)
>>> for y in range(4, -1, -1): # Dibuixem el tauler, fent ús de la consulta per índex
... for x in range(5): # Dibuixem les files en ordre invers, ja que y=0 és la fila inferior
... print(t[x, y], end='')
... print()
-V---
-V-V-
---V-
-----
VVV--
>>> t.dispara((1,3)) # TOCAT!
>>> t.dispara((2,1)) # AIGUA!
>>> t.dispara((1,0)) # TOCAT!
>>> t.num_tirades
3
>>> for y in range(4, -1, -1): # Dibuixem el tauler, fent ús de la consulta per índex
... for x in range(5):
... print(t[x, y], end='')
... print()
-V---
-X-V-
---V-
-----
VXV--
Disposeu de jocs de prova al fitxer tests-vaixells.txt