ASIX-M3-UF2-A2.1-Pràctiques paquets

De wikiserver
La revisió el 18:34, 1 des 2022 per Jmoreno (Discussió | contribucions)
(dif) ← Versió més antiga | Versió actual (dif) | Versió més nova → (dif)
Dreceres ràpides: navegació, cerca

Pràctica 2: Combat a l'arena

El joc de combats a l'arena

El programa que serveix com a fil argumental d’aquest apartat és un joc, en el qual el jugador es va enfrontant amb diversos adversaris en una arena. Cada combat es divideix en rondes, a l’inici de les quals el jugador i el seu adversari trien secretament una estratègia a seguir. Cada ronda pot seguir una estratègia diferent. Segons les estratègies triades per cadascú, el combat s’anirà resolent més favorablement cap a un o cap a l’altre, fins que finalment es consideri que un dels dos ha estat derrotat. Si es derrota l’adversari, s’atorga una puntuació al jugador. Si el jugador és derrotat, acaba la partida.

L’objectiu final del jugador és sobreviure deu combats, assolint la màxima puntuació possible en el procés.

Tant per mostrar dades a l’usuari com per introduir les ordres del jugador, s’usa només text.

Funcionament del joc de combats a l'arena

  • Descarregue-vos del Moodle el fitxer JocDeCombat.jar.
  • Accediu per terminal a la carpeta on es troba el fitxer.
  • Executeu-lo: java -jar JocDeCombat.jar

Atributs dels lluitadors

Per descriure tots els lluitadors, tant el jugador com els seus adversaris, aquests disposen d’un seguit d’atributs que indiquen el seu estat en tot moment. Alguns d’aquests atributs serveixen per establir com progressa el combat i poden veure modificats els seus valors.

Tot seguit s’enumeren:

  • Nom: el nom del lluitador. El jugador escull el seu nom, mentre que per als adversaris es referirà a criatures fantàstiques (“Nan”, “Ogre”, “Hidra”, etc.)
  • Nivell: indicador general de la capacitat de combat del lluitador.
  • Punts: els punts que ha acumulat el lluitador fins al moment.
  • Punts de Vida (PV): l’energia del lluitador actual, que pot variar al llarg del combat. Quan arriba a 0 o menys, es considera derrotat.
  • Punts de Vida Màxims: valor màxim que poden tenir els punts de vida en qualsevol moment.
  • Atac actual: la seva capacitat de dur a terme amb èxit estratègies ofensives. S’usa per resoldre el resultat d’una ronda de combat.
  • Defensa actual: igual que l’anterior, però per a estratègies defensives.

El programa es basa en què el jugador va realitzant un combat rere l’altre contra diferents adversaris. Per guanyar, ha de sobreviure a deu combats. Fins que no acaba un combat, i s’ha decidit si el jugador l’ha guanyat o l’ha perdut, no es comença un de nou.

A l’inici de cada combat, es mostra l’estat actual del jugador, el valor actual de tots els seus atributs, i se li pregunta contra quin adversari vol lluitar. El jugador ha d’escriure el nom d’un adversari. Si aquest nom no es troba entre el dels adversaris disponibles en el joc, iniciarà un combat contra un triat a l’atzar entre tots els adversaris disponibles del seu mateix nivell o un de diferència. Això evita que, per sorpresa, es trobi que ha de lluitar contra un adversari massa poderós per a ell, impossible de guanyar.

Si el nom pertany a algun adversari disponible, llavors s’enfronta contra ell. En aquest cas, no hi ha cap restricció de nivell. El jugador pot triar lluitar contra adversaris molt més o menys poderosos que ell.

Aquest plantejament està disposat de manera que, d’entrada, un nou jugador no sap el nom de cap adversari, ja que no es proporciona cap llista (a menys que hagi fet el programa o vist el codi font, és clar). La intenció és que vagi descobrint nous noms d’adversaris a mesura que va jugant partides, o parlant amb amics que també juguin al joc.

Resolució d'una ronda de combat

Cada combat es divideix en un seguit de rondes, en cadascuna de les quals el jugador ha de triar quina estratègia vol usar. Al principi de cada ronda es mostra l’estat actual tant del jugador com del seu adversari, de manera que sigui possible avaluar quina via d’acció li pot convenir més dur a terme. Llavors, el jugador tria l’estratègia entre quatre possibles: Atacar, Defensar, Engany i Maniobra. Un cop triada, l’adversari en triarà la seva i es decidirà el resultat de la ronda.

Primer de tot, cal veure per a cada lluitador el grau d’èxit de la seva estratègia. Si ha triat Atacar o Engany, representa que llença tantes monedes com el seu valor d’Atac. Si ha triat Defensar o Maniobra, fa el mateix usant el seu valor de Defensa. El grau d’èxit serà el nombre de cares obtingudes.

En resoldre la ronda, cada lluitador pot rebre un dels efectes següents. La gravetat de cadascun d’ells depèn del grau d’èxit del lluitador mateix o del seu con trincant.

En resoldre la ronda, cada lluitador pot rebre un dels efectes següents. La gravetat de cadascun d’ells depèn del grau d’èxit del lluitador mateix o del seu con trincant.

  • Res: no passa res.
  • Danyat: el lluitador perd una quantitat de punts de vida igual al grau d’èxit del contrincant.
  • Guarit: el lluitador recupera tants punts de vida, sense superar mai el valor màxim, com el seu propi grau d’èxit.
  • Penalitzat: el lluitador veu penalitzat el seu valor d’atac o de defensa (es tria a l’atzar) en tants punts com el grau d’èxit del contrincant. La penalització mai pot fer baixar el valor per sota d’1. Aquest efecte dura fins a la propera ronda múltiple de cinc (5, 10, 15, etc.). Llavors, retorna al seu valor original.

L’efecte que rep cada lluitador depèn de les interaccions entre les estratègies, de manera semblant al joc de pedra, paper, tisores. Depenent de l’estratègia triada i la de l’adversari, el resultat serà diferent. La taula següent mostra el resultat de les interaccions entre estratègies. Per abreujar, “Jug” es refereix al jugador i “Adv” a l’adversari. Un indicador de “x2” vol dir que a l’hora de resoldre aquest efecte, es doblen els èxits assolits pel contrincant.

Joc combat

Exemple de ronda de combat

Per exemple, suposeu que el jugador té ara mateix 10 punts de vida i els seus valors d’atac i defensa són 4 i 3, respectivament. L’adversari té 6 punts de vida i els seus valors d’atac i defensa són 3 i 5 respectivament. Primer de tot, cadascú tria la seva estratègia. El jugador tria Atac mentre que l’adversari tria Maniobra. Això vol dir que, per veure el grau d’èxit, el jugador llençarà tantes monedes com el seu Atac i l’adversari, en haver triat Maniobra, tantes com la seva defensa. El jugador llença 4 monedes i suposeu que treu dues cares. L’adversari en llença 5 i suposeu que n’obté quatre.

Ara cal veure l’efecte de les estratègies. D’acord a la taula, si el jugador tria Atac i l’adversari tria Maniobra, el resultat és que l’adversari rep l’efecte de “Danyat” (Adv: Danyat). Se li descompten tants punts de vida com el grau d’èxit del jugador (2). Per tant, ara li queden 6 - 2 = 4 punts de vida i acaba aquesta ronda.

S’inicia una nova ronda on es mostra l’estat dels dos lluitadors i es tria una nova estratègia...


Evidentment, a l’hora de triar l’estratègia, l’ordinador no hauria de fer trampes (ja que coneixerà la del jugador abans de triar-ne la seva). Es pot triar a l’atzar, o seguint alguna tàctica segons el seu estat (defensar més sovint si li queden pocs punts de vida, enganyar si el jugador defensa molt sovint, etc.). Això depèn del grau d’intel·ligència que es vol que tingui l’ordinador.

Resolució de la finalització del combat

El combat finalitza quan, en acabar una ronda, un del lluitadors té 0 o menys punts de vida. Si es tracta del jugador, es considera derrotat. La partida acaba i es mostra la seva puntuació final. Aquesta circumstància inclou també el cas d’empat (ambdós lluitadors han arribat a 0 punts de vida). Si, en cas contrari, és l’adversari el derrotat, al personatge se li atorga certa quantitat de punts, que se sumen als que ja disposa. Els punts atorgats dependran dels punts de l’adversari i, normalment, adversaris més difícils tindran sempre punts.

En atorgar punts al jugador, si aquest arriba o supera un valor associat a una centena (100, 200, 300, etc.), es considera que “puja de nivell” i es fa més poderós. Quan això succeeix, el jugador veu incrementat en un punt el seu nivell, el seu màxim de punts de vida s’incrementa en dos, i el seu atac o defensa, un dels dos triat a l’atzar, s’incrementa en un punt. El jugador també és immediatament guarit, recuperant tots els punts de vida actuals fins a aquest nou màxim.

Un cop atorgats els punts i un possible increment del seu nivell, totes les penalitzacions actuals sobre el jugador desapareixen. Ara bé, a menys que hagi pujat de nivell, aquest no recupera cap punt de vida. Començarà el combat següent amb exactament els mateixos punts amb els quals ha finalitzat aquest.

Si aquest era el desè combat, la partida acaba amb un missatge de felicitació i es mostra la puntuació final. En cas contrari, es torna a iniciar un nou combat.

Identificació de les dades a tractar

De la descripció del problema, les dades principals que cal tractar són les dels dos lluitadors, el jugador i els seus adversaris, que seran les mateixes. Afortunadament, la descripció del problema ofereix una visió clara de quina mena de valors cal manipular (Nom, Nivell, Vida, etc.). En aquest cas, atès que són força valors, tots vinculats entre ells, el més fàcil és fer servir una taula, de manera que es gestioni una per al jugador i una per a l’adversari. D’aquesta manera, amb un parell de variables és senzill disposar de totes les dades vinculades a tots dos. Cada posició de la taula pot representar cadascun dels atributs.

Per exemple:

IDENTIFICADOR = 0;
NIVELL = 1;
PUNTS = 2;
VIDA = 3;
VIDA_MAX = 4;
ATAC = 5;
ATAC_MAX = 6;
DEFENSA = 7;
DEFENSA_MAX = 8;

Disseny descendent

En aquest cas, l’objectiu principal del problema plantejat és veure com crear aplicacions complexes de manera modular. Per tant, no es durà a terme un disseny descendent complet fins al darrer detall, sinó que aquest servirà per fer un esquema clar de quines són les accions que ha de dur a terme el programa i, en alguns casos, en quin ordre. Per tant, aquest apartat també té un paper de suport a l’hora de presentar-vos el problema perquè l’entengueu.

De la descripció del problema general, se’n podrien extreure els subproblemes enumerats tot seguit. Recordeu, però, que potser aquesta no és l’única solució vàlida, és una proposta d’interpretació possible de l’enunciat. Hi poden haver altres descomposicions vàlides.

1. Generar els atributs del nou jugador.

2. Anunciar inici del combat.
      (a) Mostrar estat del jugador.

3. Triar l’adversari.

4. Combatre.
      (a) Mostrar estat dels lluitadors.
            i. Mostrar estat del jugador.
            ii. Mostrar estat de l’adversari.
      (b) Triar estratègia del jugador.
      (c) Triar estratègia de l’adversari.
      (d) Resoldre resultats d’estratègies.
            i. Llençar monedes.
            ii. Penalitzar lluitador.
            iii. Danyar lluitador.
            iv. Guarir lluitador.
      (e) Restaurar lluitador.

5. Resoldre resultat del combat.
      (a) Atorgar puntuació.
      (b) Pujar de nivell.
      (c) Finalització del joc.

Aquesta llista ja dóna una bona idea del conjunt de tasques que cal fer. En aquest cas, a mesura que es vagi resolent cada subproblema, si es considera que encara és massa complex o resulta que és un mètode massa llarg, ja es faran noves descomposicions en el mateix moment. Aquesta és una estratègia acceptable per a programes complexos, ja que la descomposició es pot fer molt complicada, en ser difícil veure realment tots els detalls i tenir una idea clara de la mida o complexitat dels mètodes resultants. Però al menys, sempre heu de tenir la disciplina de fer una primera aproximació, per generar el codi font amb una idea clara de per on començar.

Abans de seguir, val la pena fer alguns comentaris. Els subproblemes 4.b i 4.c s’han considerat diferents ja que, si us hi fixeu, hauran de dur a terme tasques força diferents.

En el cas del jugador, es pregunta directament a l’usuari, mentre que en el cas de l’adversari l’ordinador és qui l’ha de generar d’alguna manera (per exemple, simplement a l’atzar). En canvi, per al cas dels subproblemes 4.a.i i 4.a.ii, de ben segur que faran el mateix. Només canviaran les dades a tractar. Per tant és un cas clar de parametrització d’un mètode. Per acabar, aquest plantejament també reaprofita subproblemes, ja que el 4.a.i i el 2.a són exactament el mateix.

Mòduls

Si es vol considerar una aproximació modular, un cop es coneixen les tasques que ha de dur a terme el programa en forma de subproblemes, el pas següent seria agrupar-les d’acord al tipus d’accions que porten a terme. Cada conjunt serà un mòdul diferent. En aquest cas, atès que el programa es fa en Python, ja s’usarà directament una organització en paquets.

El programa principal anirà a la carpeta arrel que es podria anomenar jocDeCombat.

A continuació, és important separar els aspectes relacionats amb la presentació de les dades del seu tractament. Aquesta divisió es pot fer usant dos paquets: regles i interficie.

Per a aquest problema es proposa la divisió següent en mòduls. Al paquet regles hi haurà els mòduls:

  • Constants: amb les constants emprades en la resta de mòduls.
  • Monedes: per a les tasques vinculades al llançament de monedes per resoldre una ronda.
  • Lluitador: per a les tasques vinculades a la manipulació de les dades d’un lluitador (danyar, guarir, etc.).
  • Bestiari: per a les tasques vinculades a la generació d’adversaris i el jugador.
  • Combat: per a les tasques vinculades a la resolució d’estratègies enfrontades.

Al paquet interficie separem la entrada per teclat de la sortida per pantalla, de manera que hi haurà:

  • EntradaTeclat: s’encarrega de les tasques importants que són donades pel que escriu l’usuari usant el teclat.
  • SortidaPantalla: com l’anterior, però per mostrar informació a pantalla.

Un cop es disposa d’aquesta divisió, cada cop que calgui implementar un subproblema en forma de mètode, caldrà fer-ho en el mòdul que correspongui d’acord a aquesta distribució de tasques.

El paquet "regles"

Abans de poder mostrar dades per pantalla, cal poder disposar d’elles i haver-les manipulat. Per tant, el que té més sentit és començar per aquest paquet i no pas per interficie. De fet, de ben segur que des dels mòduls per mostrar o entrar dades al programa s’invocaran mètodes de tractament de dades. O sigui, mètodes dels mòduls d’aquest paquet.

Per tant, el primer paquet a tractar és aquest.

El mòdul Constants

Aquest mòdul contindrà les constants per facilitar la lectura del codi de la resta de mòduls en concret:

# Posicions llista atributs jugador i adversari

NOM = 0
IDENTIFICADOR = 1
NIVELL = 2
PUNTS = 3
VIDA = 4
VIDA_MAX = 5
ATAC_ACT = 6
ATAC_MAX = 7
DEFENSA_ACT = 8
DEFENSA_MAX = 9

# Possibles accions en les rondes del combat

ATAC = 0
DEFENSA = 1
ENGANY = 2
MANIOBRA = 3

# Número màxim de combats

MAX_COMBAT = 10 (el podeu modificar perquè acabi abans)

El mòdul Monedes

Aquests mòdul agrupa els mètodes vinculats als aspectes aleatoris quan es resol un combat. Bàsicament, això es redueix al llançament d’un cert nombre de monedes per comptar quantes cares s’han tret. Això es pot dur a terme usant el paquet random, que permet generar valors a l’atzar. Com que només es vol mirar si es treu cara o creu, es pot usar el mètode ranint(0,1), de manera que si s’avalua a 0, es considera cara, i en cas contrari, creu. Dins d’aquest paquet, seria el mòdul més senzill.

Aquest mòdul només disposa d’un mètode, ja que, donat el plantejament del problema, només hi ha una acció vinculada al llançament de monedes.

El mètode que cal codificar és ferTirada(numMonedes) el qual "tirarà" numMonedes i retornarà quantes cares (0's) ha obtingut.

El mòdul Lluitador

Aquest mòdul és el més important, ja que és el que gestiona la manipulació de l’estat dels lluitadors. I per a la descripció del problema, es pot veure que a un lluitador li poden passar moltes coses...

En aquest cas, hi ha un conjunt de dades molt particulars sobre les quals cal fer unes quantes operacions complexes: la llista que representa cada lluitador.

Mètodes bàsics de manipulació de dades D’acord amb la descripció del problema, com a mínim cal poder fer les operacions següents sobre un lluitador, ja que modifiquen el seu estat:

  • Danyar: restar punts de vida fins un mínim de 0.
  • Guarir: incrementar punts de vida, fins a un màxim.
  • Penalitzar: restar punts d’Atac o Defensa a l’atzar, però mai de manera que el valor final quedi per sota d’1.
  • Restaurar: recuperar-se de les penalitzacions (es fa cada ronda múltiple de 5).
  • Renovar: recuperar tots els punts de vida i eliminar les penalitzacions (en pujar de nivell).
  • Atorgar puntuació: sumar punts guanyats per un combat.
  • Pujar de nivell: dur a terme el procés d’increment d’un nivell.

Mètodes que cal codificar:

  • danyar(lluitador, punts): Li resta els punts de vida. Mai es pot quedar en negatius.
  • guarir(lluitador, punts): Li afegeix punts de vida. Mai pot tenir més del màxim.
  • penalitzar(lluitador, grau): Aplica una penalització al lluitador. Es fa al atzar entre el valor d'atac i el de defensa. Se li resten tants punts com indiqui el grau de penalització, fins un valor mínim d'1.
  • renovar(lluitador): Renova un lluitador, anul·lant totes les penalitzacions i danys.
  • atorgarPunts(jugador, adversari): Resol l'atorgament de punts al jugador al derrotar a un adversari. La quantitat de punts depèn de la diferencia de nivells entre els dos. Si es guanyen prous punts, s'avisa si cal pujar de nivell.

Teniu el codi ja fet.

  • pujarNivell(lluitador): Resol un increment d'un nivell, augmentant un punt a l'atzar atac o defensa i dos punts de vida màxims. A mes a mes, el lluitador es guareix totalment (renova).
Mètodes vinculats a l'estat del lluitador

Donat que aquest mòdul inclou tots els mètodes que depenen de l’estat d’un lluitador per fer la seva feina, també cal incloure, no només els que modifiquen el seu estat, sinó també els mètodes el resultat dels quals depèn d’aquest estat. Aquests inclouen els que fan les operacions següents:

  • Calcular el grau d’èxit d’Atac, ja que depèn del valor d’Atac del lluitador.
  • El mateix per a la defensa.
  • Triar una estratègia a l’atzar, ja que es pot usar l’estat del lluitador per prendre certes decisions. Aquí es farà que si els punts de vida de l’adversari són molt baixos, és més probable que decideixi defensar.
  • tirarAtac(lluitador): Resol una tirada d'atac d'un lluitador. Es llencen tantes monedes com el seu valor d'atac.
  • tirarDefensa(lluitador): El mateix però en defensa.
  • triarEstrategiaAtzar(lluitador): Donat un lluitador, tria a l'atzar quina estratègia usar en una ronda de combat. Ho farem aleatòriament però si té poca vida donarem més opció a la defensa. Teniu el codi ja fet.

Per a que no doni errors primer caldrà que importe entre d'altres el mòdul de constants donat que utilitza:

ATAC = 0
DEFENSA = 1
ENGANY = 2
MANIOBRA = 3

Mètodes per facilitar la lectura de les dades

Finalment, quan es treballa amb conjunts de dades amb una funció molt especial, com és aquest cas, pot valer la pena també incloure mètodes que serveixin com a dreceres per fer lectures de les dades que contenen. Aquests no fan res d’especial que no es podria fer accedint directament a la taula per índex, però poden fer el codi de la resta de classes més aclaridor.

Els mètodes seran del tipus (cal fer-ho per a tots els atributs):

def llegirVida(lluitador):
    return lluitador[VIDA]

Cal també codificar el mètode:

def esMort(int[] lluitador):
    return Boolen

El mòdul Bestiari

Ja el teniu codificat. Fixeu-vos en els mètodes que hi ha.

Aquest mòdul s’encarrega de tots els aspectes vinculats a la generació dels lluitadors, tant de les dades inicials del jugador com la dels adversaris triats pel jugador (veure si hi ha el que s’ha demanat, i si no és el cas, triar-lo a l’atzar. Per emmagatzemar-los, s’usa una llista de llistes: una llista on en cada posició hi ha un altre llista que descriu els valors d’un adversari.

El mòdul Combat

Aquest mòdul s’encarrega dels aspectes vinculats a la resolució d’una ronda de combat, donat l’estat actual dels dos lluitadors (punts de vida, Atac i Defensa) i l’estratègia triada per aquesta ronda. Bàsicament, sobre ella recau el pes del subproblema “Combatre -->Resoldre resultats d'estratègia” resultant del disseny descendent. Com que aquest encara es divideix en altres subproblemes, per fer les seves tasques li caldrà fer invocacions sobre altres mètodes (concretament, de la classe Lluitador).

Per indicar cada estratègia s’usa un valor enter, de manera que fer comparacions és molt més senzill que no pas amb cadenes de text. Per facilitar la lectura del codi, el valor associat a cada estratègia s’assigna a una constant.

A més a més, amb ja certa previsió amb vista a mostrar dades per pantalla, s’inclou un mètode que serveix per transformar una acció donada a la seva representació en format text. Es tracta del mètode estrategiaAText.

def estrategiaAText(accio):
    if accio == ATAC:
       return "ATAC"
    elif accio == DEFENSA: 
       return "DEFENSA"
    elif accio ==ENGANY:
       return "ENGANY"
    elif accio == MANIOBRA:
       return "MANIOBRA"
    else:
       return "DESCONEGUDA"

Mètodes que cal codificar:

  • calcularGrauExit(lluitador, accio): Obté el grau d'èxit corresponent segons l'acció triada pel lluitador.
  • resoldreEstrategies(jugador, accioJug, adversari, accioAdv): Resol una ronda d'accions entre dos Lluitadors, d'acord amb les estratègies individuals de cadascú, segons el funcionament explicat a la taula de les interaccions entre estratègies.

El paquet "interficie"

Els mòduls d'aquest paquet ja les teniu codificades.

Un cop es disposa del codi font de tots els mòduls que gestionen les dades a manipular, ja és possible generar les que les obtenen o les mostren a l’usuari.

El mòdul EntradaTeclat

Donada la descripció del problema general, només hi ha dos casos on l’usuari ha d’entrar dades usant el teclat. Per indicar contra quin adversari vol lluitar en iniciar-se un combat i per dir l’estratègia a seguir en una ronda de combat. Per tant, només cal incloure dos mètodes:

  • triarAdversari, associat al subproblema “Triar l’adversari”.
  • preguntarEstrategia, associat al subproblema “Combatre --> Triar estratègia del jugador”.

Per al cas de l’estratègia, es donarà a triar amb un menú amb quatre opcions, cadascuna associada a una lletra:

[A]tacar, [D]efensar, [E]ngany i [M]aniobra.

Un fet interessant d’aquest mòdul és que, atès que les quatre estratègies possibles estan indicades mitjançant constants definides en el mòdul Constants, cal traduir la lletra que ha escrit l’usuari al valor de la constant associada.

El mòdul SortidaPantalla

En aquest mòdul s'agrupen els mètodes en els quals cal més d’una única instrucció per mostrar informació per pantalla. Concretament es tractaria dels mètodes associats als subproblemes “Anunciar inici de combats --> Mostrar estat del jugador” i “Combatre --> Mostrar l’estat dels lluitadors: Mostrat estat del jugador, Mostrar estat de l’adversari” del resultat d’aplicar disseny descendent.

El programa principal (JocArena)

Quan es genera un programa modular estructurat d’acord a una certa jerarquia de paquets, el programa principal se sol ubicar en el paquet arrel, tot sol. Recordeu que aquest és el que s’encarrega de resoldre el problema general a partir de la invocació de mètodes de tota la resta de mòduls dels paquets.

Disposeu del programa principal ja codificat. A part dels mètodes del paquets, el programa principal fa servir dos mètodes que cal codificar:

  • Mètode combatre
- Ha d’anar fent rondes fins que un jugador es mori. L’execució de cada ronda és com la que es pot veure a l’executar el programa.
- Cada cinc rondes ha de restaurar els jugadors.
  • Mètode fi de combat
- Retorna false quan el lluitador és mort.
- Sinó li atorga els punts i si toca el puja de nivell. Retorna true.

Sortida del programa

Inicialment sortirà una pantalla semblant a aquesta:

Sortida Programa 1

Si posem un adversari que no existeix el programa ens triarà un:

Sortida Programa 2

També podem demanar un adversari existent:

Sortida Programa 3

A cada jugada ens informarà de l'estat del joc:

Sortida Programa 4

Finalment si perdem, s'acabarà el joc:

Sortida Programa 5

Si guanyem podrem fer un altre combat:

Sortida Programa 6


-------   Col·lecció de funcions per manejar dates en cadenes de caràcters.  --------------------

Es realitzarà un programa on s'introdueixin una data i es validi segons l'opció de programa demandada (1-9). Aquest programa trucarà a una funció externa lamada data dins del directori temps = "from temps import data" i es tornarà el resultat previst.

El format de la cadena és: AAAAMMDD. Exemple: El 15 de desembre del 2022 seria: "20221215"

Col·lecció de funcions:

1. data_correcta: diu si la data que es passa com a paràmetre és correcta.

2. data_mas_1dia: suma un dia a la data que es passa com a paràmetre i el torna.

3. data_mas_ndias: suma una sèrie de dies a la data que es passa com a paràmetre i el torna.

4. data_menys_1dia: resta un dia a la data que es passa com a paràmetre i el torna.

5. data_menys_ndias: resta una sèrie de dies a la data que es passa com a paràmetre i el torna.

6. es_de traspàs: diu si la data que es passa com a paràmetre és de traspàs.

7. compara_dates: rep dues dates i torna un valor negatiu si la 1a és anterior a la segona,

  zero si són iguals, i un valor positiu si la 1a és posterior a la segona.

8. data_formatada: rep una data i torna una cadena amb el format:

  DD de {MES} d'AAAA (Exemple: "15 de Desembre de 2022")

9. any, mes, dia, nom_mes: rep una data i torna aquests valors.