shodan ha scritto:
I vari giocatori hanno e fanno le stesse cose: un nome, un tot di carte, pescano (ricevono), scartano e hanno le carte in una certa posizione.
La differenza sta che mentre GiocatoreBriscola ha tre carte in mano e può contare i punti, GiocatoreScopone ne ha dieci e può non contare i punti.
Tradotto in codice significa che GiocatoreCarte è "quasi" un giocatore qualsiasi, ma che in alcuni tipi di gioco deve sapersi adattare.
sì, forse mi sono spiegato un po' male. intendevo dire che GiocatoreCarte è "l'insieme" di tutti i metodi e attributi (appunto, le carte che ha in mano) che sono in comune con ogni gioco di carte. magari ce ne sono tanti altri, ma non conoscendo milioni di giochi di carte, ciò che tutti i giocatori hanno in comune ho pensato fosse l'insieme di carte che hanno in mano, il nome e l'indice vuoto, che è un piccolo escamotage per non dover fare la ricerca della posizione libera ogni volta che il giocatore deve aggiungere una carta alla propria mano.
il punteggio invece credo sia meglio vederlo solo in GiocatoreBriscola o GiocatoreScopone (e tutti gli altri giochi in cui c'è un punteggio), dato che un GiocatoreUno, per dire, non lo ha. magari si potrebbe comunque mettere il punteggio in GiocatoreCarte per un qualche escamotage. a rubamazzo non c'è il punteggio per esempio, ma per fare una "furbata" si può mettere che il giocatore con più carte ha punteggio 1 e gli altri con punteggio 0. ma per ora, penso che terrò il punteggio come attributo di un giocatore di un gioco specifico.
shodan ha scritto:
Come vedi le funzioni daiCarteA e controllo ricevono un GiocatoreCarte e usano gli stessi metodi. Per cui GiocatoreCarte può essere usata come classe base polimorfa (non la chiamo interfaccia perché da quel che ho capito intendiamo cose un attimo diverse).
Quel "vedi sotto" si riferisce al fatto che se usi i puntatori, gli operatori non sono invocati. In questo caso si usa una funzione.
per interfaccia intendo la parolina di java e c#, ovvero una classe astratta senza attributi e contenente solo dei metodi virtuali, ma mi sa che usarla in c++ è un po' azzardato dato che le interfacce non esistono grazie all'ereditarietà multipla.
comunque ho capito l'utilità dei puntatori alle classi astratte, grazie.
shodan ha scritto:
Nel caso di Tavolo la cosa è più complicata, in quanto i tavoli di gioco hanno regole diverse. Ad esempio TavoloBriscola ha setBriscola() mentre un TavoloScopone non può avere quel metodo. Entrambi avranno un metodo reset() che può svolgere un algoritmo di reset diverso da tavolo a tavolo. Entrambi i tavoli avranno un trovaVincitore() il cui algoritmo dipende dal tavolo. Entrambi hanno un metodo trovaVincitore(), entrambi avranno un metodo getCarteAttuali.
Per cui questi metodi saranno parte dell'interfaccia di Tavolo, ma non sono certi sufficienti per definire una briscola invece di una partita a scopone.
certo, come intendevo fare io (anche se forse mi sono spiegato male di nuovo). il tavolo per me è l'insieme di tutte quelle carte che si trovano appunto sul tavolo: un giocatore che scarta una carta, la briscola di una partita, le 5 carte del texas holdem, le carte in mezzo a scopa/rubamazzo, sono tutte carte che vengono memorizzate nel vector di Tavolo; poi giustamente, come dici tu, ogni tavolo ha metodi specifici per realizzare quel determinato gioco.
shodan ha scritto:
Una nota su vector.
reserve() riserva memoria, ma non costruisce locazioni nel vector, quindi non puoi accedere con l'operatore[] ai vari elementi per inserirli, ma devi usare push_back; per evitare problemi usa direttamente resize(). Nei cicli for usa size() non capacity() per sapere quanti elementi sono contenuti.
sì, hai ragione. reserve l'ho usato nei costruttori con parametri per dare la capacità iniziale al vector.
vedrò di dare un'aggiustata al codice, sto già iniziando a portarlo in c# per dargli una gui decente
migliorabile ha scritto:
Prima di scrivere il codice, devi avere chiaro come mettere in piedi tutto il marchingegno.
A livello di classe astratta, o di interfaccia, devi ragionare in modo il piu' generico possibile.
Per fare questo devi avere sotto mano piu' esempi e cercare di raccogliere a fattor comune le funzionalita' comuni, e identificare quali siano le funzionalita' che richiedono specializzazione.
Per il gioco delle carte, come esempi puoi prendere: poker, scala 40, briscola, ramino, i giochi solitari (perche' no!), e qualunque altro gioco ti venga in mente.
Da questo puoi dedurre che:
c'e' un certo numero di giocatori, uno o piu'
c'e' un mazzo di carte. Quante? Dipende
ogni mazzo ha un certo numero di colori (magari solo uno), di segni (quadri, cuori, fiori, picche, oppure danari, bastoni, spade, coppe, ecc), e di carte (10, 13, ...)
ogni giocatore deve avere un certo numero di carte iniziale
ci possono essere 0 o piu' carte sul tavolo
ogni giocatore deve scegliere una o piu' carte in base a qualche euristica, legata alle carte che ha in mano, a quelle sul tavolo e a quelle che sono gia' uscite, ...
il giocatore fa la sua giocata
si valuta se ha vinto, perso, o non e' ancora successo nulla
...
c'e' un turno da rispettare
ecc
Poi, dovrai fare le implementazioni specifiche per ogni gioco: il tipo e umero di carte, quante carte assegnare ad ogni giocatore, come scegliere la carta o le carte, come valutare la vincita ...
Immaginare tutto questo, in modo corretto, e come implementarlo, non e' una cosa che si impara in 5 minuti
inizialmente il progetto era di realizzare un gioco a piacere, o single player (contro n computer) o multiplayer (senza connettersi a nessuna rete, multiplayer locale insomma) e ho avuto varie "illuminazioni" durante il corso del progetto.
subito mi era difficile vedere una classe "partita", dato che mi sembrava strano sentire "oggetto partita" (proprio dalle parole, quando mai la partita, nel mondo reale, si può definire "oggetto"?), poi dopo sono riuscito a implementarla (ed è molto meglio che usare un solo main).
poi ho avuto anche altre idee: all'inizio ero portato al farlo multiplayer con giocatori o computer a scelta, ma dopo ho pensato alla realtà: a cosa serve un multiplayer locale? a niente, è impossibile giocare a briscola localmente, ecco quindi che ho definito il giocatore come unico e il resto erano tutti dei computer (contenuti in un vector).