Oh, adoro questi giochi!
Quindi prima di tutto, affinché un computer possa giocare, ha bisogno di:
- una struttura con cui lavorare
- regole da seguire
- una condizione vincente per cui lavorare
Affrontiamo questo pezzo alla volta.
Struttura
Poiché la scheda è una griglia 8x8 (ma potrebbe facilmente ridimensionarsi) e ogni spazio della griglia può esistere solo in uno dei cinque stati, definiamo questi stati:
[EMPTY, WHITE_PIECE, BLACK_PIECE, WHITE_PIECE_PROMOTED, BLACK_PIECE_PROMOTED]
Rispettivamente ENUM dovrebbe:
[0, 1, 2, 3, 4]
Ora che sappiamo cosa può essere ogni spazio, abbiamo bisogno di un modo per rappresentare tutti gli spazi, o la lavagna, se vuoi. Quasi ogni linguaggio forte supporterà un array multidimensionale (un array in cui ogni elemento è un array che contiene dati). Quindi prendi il seguente codice lento per definire il nostro array:
BOARD_ARRAY = array(8, 8)
Questo ci darà un array 8 x 8 in cui possiamo memorizzare numeri interi (i nostri enum di prima):
(
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
)
Ora puoi già vedere come questo inizia a sembrare una tavola! Non ho mai giocato alla variante menzionata nel video di YouTube, ma sembra iniziare con 2 file di pezzi bianchi una fila dal basso e 2 file di pezzi neri una fila dall'alto. Il che significherebbe quando iniziamo un gioco il nostro array dovrebbe apparire così:
(
[0, 0, 0, 0, 0, 0, 0, 0],
[2, 2, 2, 2, 2, 2, 2, 2],
[2, 2, 2, 2, 2, 2, 2, 2],
[0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 0, 0, 0, 0],
)
(Ricorda che 2 rappresenta "BLACK_PIECE" e 1 rappresenta "WHITE_PIECE")
Quindi ora il computer ha una struttura con cui lavorare. Passaggio 1 completato!
Regole
Immaginiamo che tu abbia una vera e propria plancia piazzata davanti a te, giocando contro un maestro. Se provassi a spostare uno dei suoi pezzi, ti farebbe schiaffeggiare la mano. Se provassi a spostare un pezzo in un modo impossibile, ti farebbe schiaffeggiare la mano. Se hai provato a imbrogliare bene ... hai avuto l'idea. Ma il problema è che i computer no. Quindi è nostro compito fornire regole rigorose per giocare all'interno.
Dobbiamo creare un modo per verificare se una determinata mossa è "legale". Ciò significa che per prima cosa abbiamo bisogno di un modo per rappresentare una "mossa". Un modo sarebbe usare le posizioni dell'array; Ad esempio per spostare un pezzo da [0, 0] a [0, 1], potremmo creare una funzione che aggiornerà la tavola dato quella mossa. Quindi torniamo al gioco:
MY_MOVE = array( [0, 0], [0, 1] )
Quanto sopra rappresenta un pezzo, spostando uno spazio verso il basso dall'angolo superiore del tabellone (supponendo che 0, 0 sia l'angolo in alto a sinistra). Potresti anche notare che ho scelto di utilizzare un array multidimensionale per lo spostamento. Questo perché i pezzi possono teoricamente spostarsi un gran numero di volte in un turno (per "saltare" altri pezzi). Quindi facciamo finta che a 0, 1 ci sia stato un pezzo avversario, il che significa che atterreremo a 0, 2:
MY_MOVE = array( [0, 0], [0, 2] )
Abbastanza semplice eh. Il programma dovrebbe capire che se saltiamo uno spazio stiamo saltando un altro pezzo (oppure è una mossa illegale e dovremmo lanciare un errore). Ora saltiamo due pezzi:
MY_MOVE = array ( [0, 0], [0, 2], [0, 4] )
Questo ci dà un modo per descrivere qualsiasi mossa sulla scacchiera. Sìì! Ora, poiché non capisco appieno le regole del gioco esatto in questione (anche se ai miei tempi ho giocato un po 'di pedine canadesi), la legalità delle mosse esatte dovrà essere definita da te. Un buon flusso fino a questo punto sarebbe simile a:
FUNCTION_FIND_ALL_LEGAL_MOVES( MY_BOARD ) Returns: array ALL_LEGAL_MOVES
FUNCTION_FIND_BEST_MOVE( MY_BOARD, ALL_LEGAL_MOVES ) Returns: array MY_MOVE
FUNCTION_DO_MOVE( MY_BOARD, MY_MOVE ) Throws: error ILLEGAL_MOVE Updates: MY_BOARD
repeat from start for each turn
Quanto sopra presuppone che sia possibile scorrere ogni pezzo per trovare tutte le sue mosse legali, quindi data una raccolta di tutte le mosse legali in qualche modo scegliere la migliore (strategia qui). La mossa viene quindi applicata al tabellone o genera un errore. Quindi il giocatore successivo fa il proprio turno. Quindi abbiamo un'intelligenza artificiale che sa giocare! Gioia! Andare avanti.
vincente
I giochi semplici sono meravigliosi, perché vincere è definito da uno stato molto semplice. Non ci sono pezzi bianchi sul tabellone? Beh, immagino tu abbia vinto! Questo è implementato nel passaggio 2 quando scegliamo la mossa migliore per avvicinarci alla condizione vincente.
Per creare un'intelligenza artificiale molto intelligente, è possibile mantenere un database che memorizza ogni possibile board come uno stato, con ogni possibile spostamento da ogni possibile stato, per trovare catene per vincere.
Puoi anche creare strategie, come: se c'è un pezzo che verrà saltato, salva quel pezzo o se un pezzo è in grado di saltare più di un altro pezzo fai quel salto.
Questo dovrebbe darti un buon punto di partenza, è solo un metodo di possibilità letteralmente illimitate. Potresti teoricamente costruire un robot gigante per disegnare con i pastelli e condurre analisi spettrali sul disegno per scegliere le mosse ... ma non funzionerebbe molto bene o velocemente. In questo modo ha funzionato in passato e ha funzionato bene (: Spero che aiuti!
Alcune parole sull'attuazione
Dama è ciò che viene definito un gioco "risolto", in quanto possiamo calcolare ogni mossa senza incognite. Ma è tutta una serie di mosse! Quindi non c'è modo di fare tutto manualmente ... se solo ci fosse un po '... oh, giusto, siamo programmatori. pompa a pugno
SQL è uno strumento meraviglioso per memorizzare tutte queste mosse apparentemente infinite. Per chi non ha esperienza con SQL, mySQL è un server SQL gratuito (abbastanza facile da usare) e open source. SQL viene utilizzato per la gestione di database, una specie di foglio di calcolo sugli steroidi. È anche in grado di contenere una grande quantità di dati e di lavorarci molto rapidamente.
Quindi come possiamo usarlo? Poiché sappiamo che se la scacchiera è in uno stato esatto (ogni pezzo in una certa posizione) possiamo calcolare tutte le mosse disponibili e salvarle. Per esempio:
+Board State+ +All Possible Moves+ +Best Move+
([0,0,1,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([7,6],[7,7])
([0,0,2,2,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([5,5],[5,4])
([0,0,1,3,3],[3..) ([0,1],[0,2]), ([7,6],[7,7],[5..) ([4,4],[4,3])
etc...
Quindi, quando il computer deve effettuare una mossa, cerca semplicemente lo stato della scheda (memorizzato come chiave primaria) nel database e può scegliere la mossa migliore (dovrebbe essere imbattibile) o una delle altre mosse per rendere più amichevole AI.
Bene, ora costruiamo questo database. Innanzitutto dobbiamo calcolare ogni stato della scheda. Il che può essere fatto con un grande brutto ciclo, se qualcuno vuole passare un po 'di tempo e risolverlo sarebbe fantastico. Guarda l'array come un numero grande, quindi conta verso l'alto, tranne che nella base 5 (0, 1, 2, 3, 4) e condiziona che ogni giocatore possa avere solo 16 pezzi.
A questo punto dovremmo avere tutti gli stati della tavola memorizzati e possiamo passare attraverso il calcolo di tutte le mosse possibili.
Una volta che sono state calcolate tutte le mosse possibili, la parte divertente del percorso è trovare le mosse migliori possibili. È qui che la mia conoscenza inizia a scarseggiare e iniziano a entrare in gioco cose come Minimax o A *. Spiacente, non posso esserti di più di aiuto in merito: /