160 likes | 311 Views
Elementi di programmazione ad oggetti a. a. 2009/2010. Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria Informatica, Gestionale e dell’Automazione. Esercitazione 1.
E N D
Elementi di programmazione ad oggettia. a. 2009/2010 Corso di Laurea Magistrale in Ingegneria Elettronica Docente: Mauro Mazzieri, Dipartimento di Ingegneria Informatica, Gestionale e dell’Automazione
Esercitazione 1 Progettazione ad oggetti di una semplice applicazione: il gioco del Nim.
Progettazione di un sistema orientato agli oggetti • La progettazione di un sistema orientato agli oggetti (Object Oriented, OO) parte da due domande: • Quali sono gli oggetti da prendere in considerazione? • Quali caratteristiche hanno questi oggetti? • Le funzionalità del sistema sono distribuite come responsabilità date a determinati oggetti
Esempio: gioco del Nim • Regole del gioco • Ci sono alcune pile di bastoncini • Due giocatori rimuovono a turno da una e una sola pila a scelta, un numero a piacere di bastoncini • Da uno solo a tutto il mucchio • Il giocatore che rimuove l’ultimo bastoncino ha perso Quali oggetti?
Oggetti del gioco del Nim • Pila di bastoncini • Giocatore • Partita Quali sono le responsabilità di un oggetto della classe Pila?
Oggetti della classe Pila • Un oggetto della classe Pila deve • Conoscere (query) • Bastoncini() • Il numero di bastoncini rimasti • Eseguire (command) • Rimuovi(int) • Rimuovere un certo numero di bastoncini Quali sono le responsabilità di un oggetto della classe Giocatore?
Oggetti della classe Giocatore • Un oggetto della classe Giocatore deve • Conoscere (query) • Nome() • L’identità del giocatore (nome) • Eseguire (command) • EseguiTurno() • Agire nel proprio turno di gioco, scegliendo quanti bastoncini rimuovere da quale pila Quali sono le responsabilità di un oggetto della classe Gioco?
Oggetti della classe Gioco • Un oggetto della classe Gioco deve • Conoscere (query) • Pile() • Quanti e quali pile sono presenti (vettore di pile) • Eseguire (command) • EseguiPartita() • Gestire una partita del gioco: preparare le pile di bastoncini, far eseguire a turno ai giocatori la loro mossa, dichiarare il vincitore
Costruttori • Classe Pila • Numero iniziale di bastoncini • Classe Giocatore • Nome del giocatore • Classe Gioco • ???
Pila.h namespace Nim { class Pila { int bastoncini; public: Pila(int n) : bastoncini(n) {} int Bastoncini() const { return bastoncini; } void Rimuovi(int n) { bastoncini -= n; } }; }
Giocatore.h #include <string> #include <iostream> #include <vector> #include "Pila.h“ namespace Nim { class Giocatore { std::string nome; void rimuovi(Pila& p, int i, int n) { p.Rimuovi(n); std::cout << nome << ": rimossi " << n << " bastoncini dalla pila " << i+1 << std::endl; } public: Giocatore(const std::string nome) : nome(nome) { } std::string Nome() const { return nome; } void EseguiTurno(std::vector<Pila>& pile); }; }
Giocatore.cpp #include "Giocatore.h" void Nim::Giocatore::EseguiTurno(std::vector<Pila>& pile) { int x = 0; for(int i = 0; i < pile.size(); i++) x ^= pile[i].Bastoncini(); if (x == 0) { // perdiamo comunque... rimoviamo tutti i bastoncini da una pila qualsiasi for(int i = 0; i < pile.size(); i++) if(pile[i].Bastoncini() > 0) { rimuovi(pile[i], i, pile[i].Bastoncini()); return; } } else { // cerca la pila il cui xor con x decresce e la riduce a x bastoncini for(int i = 0; i < pile.size(); i++) { int nim_sum = x ^ pile[i].Bastoncini(); if(nim_sum < pile[i].Bastoncini()) { rimuovi(pile[i], i, pile[i].Bastoncini() - nim_sum); return; } } } }
Gioco.h #include <vector> #include <iostream> #include "Pila.h" #include "Giocatore.h" namespace Nim { class Gioco { std::vector<Pila>* pile; Giocatore* giocatore1; Giocatore* giocatore2; bool giocoFinito() const { for (int j = 0; j < pile->size(); j++) if ((*pile)[j].Bastoncini() > 0) return false; return true; } public: Gioco(); void EseguiGioco(); }; }
Gioco.cpp #include "Gioco.h" Nim::Gioco::Gioco() { pile = new std::vector<Pila>(); pile->push_back(3); pile->push_back(4); pile->push_back(5); giocatore1 = new Giocatore("Giocatore 1"); giocatore2 = new Giocatore("Giocatore 2"); } void Nim::Gioco::EseguiGioco() { Giocatore* g = giocatore1; while (!giocoFinito()) { g->EseguiTurno(*pile); g = g == giocatore1 ? g = giocatore2 : g = giocatore1; } std::cout << "Vince " << g->Nome() << std::endl; }
main #include "Gioco.h" int main() { Nim::Gioco nim; nim.EseguiGioco(); system("pause"); return 0; }