2010-10-25 16 views
6

Diciamo che sto implementando la mia versione di Scrabble. Attualmente ho una classe Board che contiene molti Squares. A Square a sua volta è composto da un IBonus e un Piece. Le implementazioni dei bonus sono in realtà il solito bonus per Scrabble, ma è possibile che io possa provare ad aggiungere qualche nuovo bonus per rendere più piccante il gioco - la flessibilità qui è fondamentale!Progettare un sistema di bonus flessibile ed estensibile per l'implementazione di un gioco di Scrabble

alt text

Dopo averci pensato per un po 'sono giunto alla conclusione che per IBonus implementazioni di lavorare, avranno bisogno di conoscere l'intera Board e anche la sua posizione attuale (sul Board, quindi sa dove è e può controllare se il pezzo che si trova nella stessa casella del bonus è). Questo mi colpisce tanto quanto fondamentalmente ha bisogno di sapere un sacco di informazioni.

Quindi, la mia ingenua implementazione sarebbe passare lo Board come argomento al metodo IBonus.calculate(), IBonus.calculate(Board board, Point position), ovvero.

Inoltre, sembra creare un riferimento circolare. O mi sbaglio? alt text

Non mi piace particolarmente questo approccio, quindi sto cercando altri possibili approcci. So che posso fare in modo che calculate accetti un'interfaccia invece di una classe concreta, ovvero calculate(IBoard board) ma IMO non è poi così migliore del primo.

Temo di essere troppo concentrato sulla mia attuale implementazione per poter pensare a progetti completamente diversi che potrebbero adattarsi almeno alle soluzioni a questo problema. Forse potrei ri-progettare l'intero gioco e avere i bonus in altro posto, quindi faciliterebbe questo calcolo? Forse sono troppo concentrato per averli sul Board? Spero davvero che ci siano altri approcci a questo problema!

Grazie

+1

+1 per gli schemi utili –

+0

Quale strumento hai utilizzato per creare i diagrammi? –

+0

yUML, ti permette di crearli e li ospita online. –

risposta

4

Presumo Consiglio ha lo stato visibile del gioco, e non ci sarebbero altri oggetti come Rack (uno per ogni giocatore,) e una DrawPile.

"Doppio punteggio se la parola contiene una Z reale (non vuota)" - richiede di passare la Parola, o la Scheda e la posizione della parola.

"Doppio punteggio se la parola è la più lunga alla lavagna" richiede l'intera commissione.

"Doppio punteggio se la prima lettera della parola corrisponde a una lettera selezionata a caso dalla DrawPile" richiede ovviamente DrawPile.

Quindi per me dipende solo dalle regole che implementate. Sarei a mio agio con l'implementazione della Board by IBonus score().

modifica - altri pensieri.

Quindi un tabellone ha 17x17 quadrati, o qualsiasi altra cosa. Assegnerei un'implementazione IBonus a ogni quadrato della scheda (ci sarebbe stata una implementazione chiamata PlainEmptySquare che era inerte.) Avresti solo bisogno di istanziare ogni implementazione di IBonus una volta - potrebbe essere referenziata molte volte. Probabilmente prenderei la strada bassa e istanzerei ognuno esplicitamente, passando gli argomenti necessari. Se un tipo ha bisogno della Board, passala. Se un altro ha bisogno della DrawPile, passala.Nella tua implementazione, avresti forse 12 linee di bruttezza./Scrollarsi

+0

Sono d'accordo; se si desidera la massima flessibilità per progettare bonus folli è necessario il maggior numero di informazioni disponibili. –

1

Qualcosa di simile al seguente potrebbe funzionare:

CurrentGame ha un Board, che ha una collezione di Squares. A Square potrebbe avere un IBonus, tuttavia non esiste un metodo Calculate() su un Square. Un Square può avere un Piece e un Piece può avere un Square (ad esempio un quadrato può o non può essere vuoto, e un pezzo può o non può essere stato collocato sul pannello).

Board ha anche un metodo calculateScoreForTurn() che accetta una raccolta di Pieces che rappresenta i pezzi che sono stati appena posizionati sulla scacchiera per quel turno. Board conosce tutte le informazioni sui pezzi e quadrati appena posizionati, oltre ai pezzi e quadrati circostanti o intersecanti (se applicabile) e quindi ha tutte le informazioni necessarie per calcolare il punteggio.

+0

Ma come gestisci diversi tipi di bonus, quindi? La logica di ogni tipo di bonus diverso non dovrebbe essere incapsulata in una classe diversa? –

+1

Probabilmente non è ideale da un punto di vista progettuale OO, ma per me sembra meglio che tutta la "logica delle regole" esista in un singolo luogo piuttosto che avere un oggetto IBonus (che riguarda un singolo riquadro) eseguire un lavoro che riguarda l'intero Tavola. Potresti forse avere un oggetto Scorer separato, quindi passalo alla scacchiera e una raccolta di pezzi appena posizionati, e restituisce il punteggio per quel turno. Sembra appropriato che un marcatore conosca tutte le regole. – jwaddell

+1

Penso che il fatto che un particolare IBonus possa influenzare più del solo pezzo a cui è associato (compresi i pezzi posizionati nei turni precedenti) significa che non dovresti incapsulare il suo metodo di punteggio nel suo quadrato. – jwaddell

1

Questo mi sembra male come in fondo si bisogno di sapere un sacco di informazioni

Penso che sia necessario. Stai solo passando un riferimento alla lavagna, non causando in realtà grandi quantità di dati da spostare.

1

Il Consiglio stesso dovrà probabilmente guidare il punteggio per un determinato turno. Ogni volta che viene posizionata una tessera, la Commissione ne prende nota. Quando l'ultima tessera (per un turno) è stata piazzata, la commissione deve ottenere tutti i quadrati che hanno una tessera appena aggiunta (il bonus per questi quadrati sarà calcolato) e tutte le tessere precedentemente piazzate che il turno corrente è " riutilizzo".

Ad esempio, giocare CAT

C A T

C cade Lettera doppio punteggio. Quindi, il punteggio per il turno è C.Valore * 2 + A.Valore + T.Valore.

Il giocatore successivo piazza una S per creare CAT. S cade sul Triple Word Score. Quindi, il punteggio per il turno è (C.Valore + A.Valore + T.Valore + S.Valore) * 3. Quando è stato applicato il Bonus di una tessera, deve essere "Disattivato" in modo che i "riutilizzi" futuri di quella Tessera non ottengano anche il Bonus.

L'implicazione è che alcuni bonus applicano la tessera posizionata nel quadrato mentre altri si applicano alla raccolta di tessere che compongono la nuova parola dopo che i bonus per le singole lettere sono stati calcolati.

Dato uno o più riquadri che sono stati riempiti con tessere durante il turno, la commissione può trovare l'inizio della (e) parola (e) che è stata creata attraversando a sinistra fino al bordo della scacchiera (o fino a un quadrato vuoto) e attraversando fino alla stessa condizione. La commissione può trovare la fine della (e) parola (e) che sono state create percorrendo in modo simile a destra e in basso. Devi anche passare all'inizio e alla fine delle parole ogni volta che una tessera appena posizionata è adiacente a una tessera esistente (potresti creare molte parole durante un turno).

Dato un insieme di Parole (ciascuna composta da un quadrato contenente un possibile LetterBonus e una Tile con un valore), la Board (o ogni Word stessa) calcola il BaseValue (somma dei valori delle tile - applicando qualsiasi LetterBonuses) e quindi applica il WordBonus (se presente) per ottenere il valore finale della parola.

Problemi correlati