Come decomporre / modellare una scacchiera

6

Come qualcuno nuovo alla programmazione, sto costruendo un'applicazione web di scacchi in JavaScript, sia per divertimento che per saperne di più sui modelli di design. Continuo a correre contro un muro, che è come decomporre il programma.

Per iniziare, ho scelto una semplice rappresentazione di una scacchiera, qui:

Board = function() {
  var turn = 0;
  var model = [[-4, -2, -3, -5, -6, -3, -2, -4],
               [-1, -1, -1, -1, -1, -1, -1, -1],
               [ 0,  0,  0,  0,  0,  0,  0,  0],
               [ 0,  0,  0,  0,  0,  0,  0,  0],
               [ 0,  0,  0,  1,  0,  0,  0,  0],
               [ 0,  0,  0,  0,  0,  0,  0,  0],
               [ 1,  1,  1,  1,  1,  1,  1,  1],
               [ 4,  2,  3,  5,  6,  3,  2,  4]];

con alcune routine di accesso di base, come

  this.move = function(pt1, pt2) {
    turn += 1;
    model[pt2.x][pt2.y] = model[pt1.x][pt1.y];
    model[pt1.x][pt1.y] = 0;
  };
  ...

Ha senso che la scacchiera incapsuli lo stato ed è responsabile del cambiamento di stato ma potrebbe non conoscere le regole del gioco - Mi piace l'idea di poter inserire una sorta di RulesContoller e cambiare completamente la natura di il gioco in fase di esecuzione. Ma oltre a ciò, sono un po 'paralizzato da quanto sia granulare modellare i pezzi. Vedo alcune opzioni.

In primo luogo, potrei definire un costruttore di Piece e istanziare un nuovo pezzo per ogni indice nell'array nidificato, qualcosa del tipo:

  _.each(state, function(row, y) {
    _.each(row, function(val, x) {
      state[y][x] = new Piece(x, y, val);
    });
  });

Piece potrebbe facilmente dedurre il suo colore, il tipo (ad esempio "king") e la posizione da tale informazione. Ma è anche ridondante, dal momento che sto solo traducendo un modello che rappresenta già completamente la lavagna. Inoltre, non sembra che lo scopo principale di Piece 'classe' sia questa traduzione, ad es. "Oh, sono un -5, deve essere una Regina oscura."

Un'altra opzione è di rendere i pezzi più stupidi, cioè non in grado di dedurre queste informazioni dal modello. Ma poi costruisco la matrice in linea, come

  var model = [new Rook(1,1,'dark'), new Knight(1,2,'dark'), new Bishop(1,3,'dark')... ],
  ...

Questo sembra più vicino al modo in cui una scacchiera è effettivamente impostata: non c'è una formula elegante; piuttosto, metti i pezzi nella loro posizione corretta. Ma è anche solo forza bruta. Ci sono alcune simmetrie coinvolte e schemi che potrebbero essere semplificati.

Ad ogni modo, sono solo spitballing a questo punto. Qualsiasi idea sarebbe utile. Grazie.

    
posta gwg 08.02.2014 - 07:34
fonte

3 risposte

13

La risposta è smettere di progettare, dal momento che non hai abbastanza esperienza per sapere cosa fare e iniziare a scrivere qualcosa . Magari iniziare con solo pedine; aggiungere funzioni che possono calcolare le mosse legali se ci sono solo pedine sulla scacchiera. Quindi aggiungi un re e guarda cosa fa al tuo codice. E così via.

Ho un sacco di esperienza nella programmazione, e continuo a lavorare principalmente in questo modo, implementando una cosa alla volta e ripulendo mentre vado. Molte applicazioni complesse sono state costruite in modo incrementale.

    
risposta data 08.02.2014 - 08:03
fonte
1

Questo tipo di applicazione è perfettamente adatto per la programmazione funzionale. Crea alcune strutture di dati (utilizzando pseudo classi di ereditarietà prototipale) che monitorano lo stato del gioco: essenzialmente lo stato della scheda e lo stato di svolta. Tracce di stato della scheda in cui sono presenti tutti i pezzi. Attiva le tracce di stato di turno. Insieme, queste due strutture costituiscono lo stato del gioco.

var state = new Game(new Board());
console.log(state.activePlayer) //white
console.log(state.board) //multi-dimensional array or some other construct
state = state.board.move(["Kf5", "Kd5"]);

Tutte le strutture di dati persistenti supportate sono lo stato reale visibile del gioco. Non si cambiano mai realmente i valori della struttura dati, ma invece li si copia in una versione nuova, ma modificata della struttura dati. Questo è l'ideale per consentire al computer di esplorare diverse mosse (all'interno dei Web Workers?).

Quindi tutto quello che devi fare è iniziare a sviluppare alcune funzioni di supporto che effettivamente fanno il lavoro di proporre mosse. Il più generico sarebbe:

var suggest = AI.suggestMove(state); // ["Kf5", "Kd5"]
state = state.board.move(suggest);

Usando tecniche funzionali ti rimangono solo strutture e funzioni dati e non avrai bisogno di troppi costruttori di oggetti. Questo ti lascia principalmente pensare alle tue funzioni (come rendere l'intelligenza artificiale abbastanza intelligente per vincere).

    
risposta data 12.02.2014 - 08:30
fonte
-2

Il design dell'oggetto della scheda dovrebbe riflettere un po 'come viene visualizzato nel mondo reale. Un quadrato sulla scacchiera è definito da una corda x, y dove uno è un carattere alfabetico e l'altro è un numero intero. Ogni "spazio" nella struttura dati può essere un puntatore a un oggetto pezzo. Il pezzo dovrebbe essere in grado di ottenere la sua posizione sulla scacchiera, ma non cambia lo stato della scacchiera stessa. L'idea del controller regole suona bene, può prendere un pezzo per cercare le sue mosse legali e quindi riposizionare il pezzo sulla scacchiera. Può colpire qualsiasi configurazione di regole che usi, come, sostituendo i pedoni con pedine.

    
risposta data 08.02.2014 - 10:38
fonte

Leggi altre domande sui tag