Il miglior approccio per scrivere un motore di scacchi? [chiuso]


15

Sono un appassionato di scacchi e un programmatore. Di recente ho deciso di iniziare a creare un motore di scacchi usando le mie conoscenze di scacchi e programmazione. Quindi, ecco la mia domanda:

Quale linguaggio (ho familiarità con Java, C ++ e Python) e la metodologia dovrei adattare mentre scrivo un motore di scacchi?

Una piccola guida sarebbe molto apprezzata.

Modificare:

Quindi ho deciso di farlo in JavaScript. Scarica questa interfaccia utente di scacchi da github e ora sono pronto! Il mio primo passo sarebbe quello di scrivere mosse legali per questo. Qualcuno può indicarmi la giusta direzione? (Sono nuovo di jQuery ma ho molta esperienza di programmazione).

PS: Non sto cercando di creare un motore molto efficiente (lo conosco troppo difficile), voglio solo familiarizzare con il processo e apprendere alcune nuove tecniche lungo la strada.


5
Qualsiasi linguaggio e metodologia mainstream farebbe, niente di speciale su un motore di scacchi (a tale riguardo).
yannis,

3
Sarei più specifico sugli obiettivi. Se vuoi semplicemente ridurlo a una serie di regole di voto, è un grosso compito, ma qualsiasi programmatore può risolverlo in modo brutale. Se vuoi entrare in cose come il riconoscimento dei modelli o la ponderazione del rischio rispetto alla ricompensa, è qui che le risposte potrebbero diventare succose.
Erik Reppen,

Hai controllato la sezione pedagogica sotto il wiki di Chess Engine. Questi sembrano essere pensati specificamente per insegnare la programmazione degli scacchi e sono tutti Open Source. Anche se non si utilizza il codice sorgente effettivo, la documentazione di solito spiega cosa c'è dietro lo sviluppo: en.wikipedia.org/wiki/Chess_engine#Categorizations
user60812

1
La parte davvero difficile è come valutare una determinata posizione perché devi scegliere se la posizione A è migliore della posizione B.

1
Non è affatto chiaro ciò che vuoi sapere. Hai deciso di rappresentare una posizione? In tal caso, il passaggio successivo è scrivere e testare un generatore di spostamento. Non sono sicuro di cosa pensi che abbia a che fare JQuery.
Kevin Cline,

Risposte:


19

Giocatore di scacchi con rating 2072 qui. Ho realizzato questo sito Web in puro JavaScript per un fine settimana. Non è un motore di scacchi (l'ho progettato per creare posizioni di apertura divertenti come una specie di motore Chess960 perverso), ma è un punto di partenza. Il codice sorgente è qui .

Ci sono molte complicazioni nel creare una scheda funzionale. Questi includono:

  • Innanzitutto, capire come rappresentare le mosse legali di base. Devi fare un po 'di matematica con le coordinate di inizio e fine. Ad esempio, con i movimenti della torre, una delle coordinate deve essere la stessa prima e dopo. Con i movimenti del cavaliere, la somma del valore assoluto delle modifiche delle coordinate deve essere 3, ed entrambe le coordinate devono cambiare. Con le mosse dei vescovi, o la somma delle coordinate rimane la stessa, oppure entrambe aumentano dello stesso importo. Le pedine sono più complicate perché non devi solo capire se possono muovere due quadrati o uno (controlla la riga e il colore invece di memorizzare quante mosse hanno fatto), ma devi anche gestire l'intera cattura in diagonale, mossa -a cosa in anticipo.
  • Catturare è una sfida a causa di pedine e controllo. Non puoi semplicemente dire che se un pezzo si sposta nella casella di un altro pezzo, allora è una cattura. Dopotutto, i pedoni non possono spostarsi nel riquadro di un altro pezzo per catturare - hanno il loro modo speciale di catturare.
  • Devi capire un modo efficace per vedere se i pezzi nemici si frappongono alla mossa di un pezzo per decidere se è legale o meno.
  • Controllare è una sfida da affrontare. Dopo ogni mossa, devi controllare tutte le caselle in cui i pezzi nemici possono andare e vedere se uno di essi coinvolge il tuo re e, in tal caso, è una mossa illegale.
  • Castling, en passant, promozione, stallo, pareggi forzati, ripetizione - nessuno di questi è banale da gestire data l'entità del problema.

Tutti i motori di scacchi funzionano osservando tutti (possibilmente un sottoinsieme determinato euristicamente) delle mosse legali in una posizione e valutando i numeri per rappresentare i loro valori relativi facendo quelle mosse e facendo ricorsivamente la stessa cosa per le posizioni risultanti. I tuoi problemi gemelli qui sono

  • Come archiviare questi dati in modo efficiente
  • Come procedere con questa ricerca ricorsiva - dopo tutto, non puoi lasciarlo andare avanti per sempre, quindi devi mettere un limite e poi capire come progettare il tuo algoritmo per fare la ricerca più ottimale e completa entro quel limite. Ad esempio, vuoi assicurarti che almeno fornisca una valutazione per ogni possibile mossa iniziale, ma potresti anche voler passare più tempo a valutare mosse più promettenti invece di dedicare un uguale tempo a ciascuna mossa.

Tutto ciò in cima alla progettazione dell'algoritmo, in primo luogo, su cui sono disponibili molte informazioni.

Per quanto riguarda quale lingua scegliere (anche se immagino che tu abbia già deciso su JavaScript), penso che dipenda più dal tuo obiettivo che da qualsiasi altra cosa. Volevo creare il mio online (e migliorare su JavaScript), quindi JavaScript è stata la mia scelta. Qualsiasi linguaggio di programmazione orientato agli oggetti lo farà comunque.

Una volta che ti senti a tuo agio con quello che stai facendo, probabilmente le seguenti risorse si riveleranno davvero utili:

In bocca al lupo!


Grazie mille, sicuramente mi ha aiutato molto a iniziare. Anche se c'è ancora molto da imparare e implementare, i motori di scacchi non sono mai facili da scrivere. Ma penso che sia bello lavorare con qualcosa che ami!
Adnan Zahid,

Sono d'accordo. Volevo avere un curriculum di progetti davvero diversificato, ma onestamente mi piace solo sviluppare di più le cose degli scacchi.
Andrew Latham,

Il dominio lathamcity.com è attualmente in vendita. Il codice è ora disponibile su un sito Web diverso?
IkWeetHetOokNiet

14

Il problema con il "programma di scacchi" come concetto è che ci sono molti pezzi che possono assorbire molto tempo e che al momento non ti interessano necessariamente. Puoi passare anni lavorando solo sulla grafica, o una ricerca alfa-beta, o una visualizzazione per aiutare a sviluppare per il motore di ricerca, o ... beh, ci sono molti pezzi.

Consiglio di trovare un programma di scacchi open source (ce ne devono essere molti) e di migliorare le parti che ti interessano di più. Puoi eventualmente sostituire l'intero programma, una funzione alla volta, oppure potresti imparare abbastanza ed essere motivato a buttarlo via e progettare il tuo programma da zero. In ogni caso, la chiave è avviare la "luce" e apprendere le corde prima di provare a progettare un intero programma.


Conformandosi a uno dei protocolli di interfaccia stabiliti, è possibile utilizzare qualsiasi frontend esistente con il proprio motore.

Spero che la beta alfa non impieghi anni a scrivere
Kevin,

1
Non anni da scrivere, ma anni da brontolare :)
oscuro

9

Se hai familiarità con le regole degli scacchi, un buon punto di partenza sulle tecniche di base è http://www.frayn.net/beowulf/theory.html Una vasta raccolta di materiali e collegamenti che puoi trovare qui: http: // chessprogramming .wikispaces.com / Terzo: impara dagli altri codici. Dai un'occhiata alle fonti di Crafty . È il principale motore open source. Sarà molto importante pensare ai casi di test, per vedere se si apportano miglioramenti: iniziare ad esempio con alcune semplici posizioni di fine gioco a 3 o 4 cifre.


3

Come accennato, non c'è nulla di terribilmente difficile nel costruire un motore di scacchi. Forse, dovresti concentrarti su come desideri utilizzare e (potenzialmente) distribuire questa applicazione poiché ciò determinerà probabilmente la tua scelta della lingua.

Se questo è solo un esercizio divertente, potresti voler codificarlo in Javascript e distribuirlo come una pagina web. Se non vuoi mai trasformarlo in una partita a scacchi esperta, almeno altri saranno in grado di giocarci e il suo codice sorgente.

Se desideri imparare una particolare tecnologia allo stesso tempo, ad esempio WPF, questo potrebbe essere un buon modo per uccidere due uccelli con una fava. MVVM potrebbe essere eccessivo per questa app, ma lo impareresti almeno.

Se desideri scegliere come target dispositivi Android, Java sarebbe una buona scelta. Allo stesso modo, Objective-C per dispositivi iOS.

Lunga e breve, la scelta della lingua non esiste nel vuoto.


3

Presumo che tu conosca già il concetto di Min-Max, alberi e potatura, euristiche e altre basi e ciò che scrivo qui sono solo alcuni dettagli che potrebbero essere stati sottovalutati.

Io con la compagnia un amico ho scritto il nostro motore di scacchi qualche volta fa. Condivido alcuni problemi e idee che abbiamo avuto e spero che li troviate utili.

Dato che entrambi eravamo programmatori Java, il nostro linguaggio si è trasformato in Java e abbiamo iniziato con un approccio orientato agli oggetti. I pezzi erano oggetti, la tavola era oggetto, i file e le file (file e colonne nella letteratura sugli scacchi) erano oggetti. E questo era sbagliato. Il sovraccarico era enorme e il programma stava lottando per andare oltre 2 mosse (4 strati) nella struttura di ricerca.

Quindi con un po 'di ricerca siamo finiti con un'idea geniale (non la nostra però!): Rappresentare pezzi e tavola come numeri interi lunghi (64 bit). Questo ha senso perché una scacchiera ha 64 quadrati. Il resto è stato un'operazione un po 'saggia (molto vicino a cpu = estremamente veloce). Ad esempio, considera un numero intero binario a 64 bit in cui quelli presentano i quadrati sul tabellone che il tuo pezzo può attaccare. Ora se esegui un "AND" logico tra due numeri come questo, un risultato diverso da zero indica che hai un quadrato con attaccanti. Esistono diversi modi per presentare la scacchiera e i pezzi, quindi:

1 - Decidi la presentazione del tuo consiglio

Quindi è necessario e aprire il database. L'apertura degli scacchi è in qualche modo risolta e si consiglia di avere e aprire il libro. In questo caso, hai un sacco di tempo extra nei giochi blitz.

2 - Trovati un libro di apertura.

Li abbiamo fatti, ma non eravamo ancora bravi:

3 - Un buon motore di scacchi dovrebbe essere in grado di vedere 6 mosse (12 strati) in avanti.

Quindi quello che abbiamo fatto è stato usare i tempi morti (se si tratta di un motore umano vs un computer).

4 - Usa il tempo in cui l'avversario sta pensando di creare alcuni livelli del tuo albero.

Eppure eravamo lontani dai 12 strati. Con ulteriori studi, scopriamo alcuni trucchi! Ad esempio, è stato suggerito di saltare uno strato dell'albero e di iniziare dallo strato successivo (come se non ci fosse un avversario). L'idea è che se una mossa è estremamente idiota, allora perché perdere tempo e vedere quali sono le risposte degli avversari a quella mossa. Tuttavia, un buon motore dovrebbe essere in grado di distinguere tra mossa idiota e sacrificio geniale della regina.

5 - Impara i trucchi di programmazione per questo problema specifico (scacchi).

Io e il mio amico, in questo stato, eravamo ancora pessimi: / Quello che potevamo fare - e in parte lo facevamo - era salvare le posizioni calcolate. Se calcoli una posizione, salvala per il futuro! Lo stesso vale per i loop nella struttura di ricerca. Il punto era salvare / recuperare in modo efficiente:

6 - Salva i dati che generi ... In modo efficiente!

e infine:

7 - Codice con la massima ottimizzazione.

Questo problema è estremamente costoso sia in termini di tempo della CPU che di memoria. È molto importante scrivere il codice in modo molto efficiente. Ricorda che stiamo parlando del fattore ramo di 35. Ciò significa che un "se" inutile da qualche parte nel tuo euristico, può essere trasformato in 3.3792205e+18inutile "se" è da qualche parte in profondità nel tuo albero di ricerca.

La programmazione degli scacchi è una sfida molto interessante ed è il momento in cui puoi mettere alla prova le tue capacità di programmazione. Ci sono alcuni altri punti che posso suggerire, ma sono sicuro che li scoprirai da solo. Ci sono molti altri punti che non conosco ma li puoi trovare su Internet!

Buona fortuna e buon divertimento!

ps non conosco molto bene javascript ma qualcosa mi sta dicendo sulla base della difficoltà del problema, forse, considerando tutto ciò che il C ++ può offrire, sarebbe meglio lasciare javascript e farlo in C ++.


2

Come per la tua modifica, sei nella fase di definizione delle mosse "legali".

Esistono due modi per descrivere le mosse negli scacchi. Notazione descrittiva e notazione algebrica . Quello che probabilmente vuoi è una funzione che prende il pezzo, la posizione iniziale e la posizione finale come parametri. per esempio. Knight da QN1 a QB2 non è valido, ma Knight da QN1 a Q2 è valido. Pensandoci, la notazione algebrica potrebbe essere più semplice a causa della capacità di calcolare facilmente il posizionamento "relativo".

Per assicurarsi che si sta scrivendo la quantità minima di codice richiesto, mi piacerebbe iniziare con la scrittura dei test per quella funzione prima . Se stai usando la notazione algebrica, probabilmente non hai bisogno di un test per pezzo / inizio / fine. Far funzionare ogni test ed eseguire il refactoring della duplicazione prima di passare alla 'mossa' successiva. Il tuo codice finirà per essere più pulito.

Una volta che hai coperto sufficientemente le mosse legali e illegali per ogni pezzo, inizierei ad aggiungere controlli per altre variabili (come spostare un re in condizioni "check" e "mate").

Raccomando qunit per test unitari e gelsomino per test comportamentali in JavaScript.


1

In realtà ho scritto un motore di scacchi. Preparati sia per una sorpresa che per un incubo. Quando lo abbiamo fatto io e i miei amici, era in un concorso di programmazione a tempo e la lingua con cui abbiamo deciso di andare era Java. Sento che Java o C sono la scelta migliore, ma vedo che hai deciso di utilizzare Javascript. Non riesco davvero a batterlo perché non mi è familiare.

Il problema principale qui sarà che ci sono così tanti scenari di mossa / vincita per ogni pezzo di cui devi tenere conto, quindi ti consiglio di scrivere tutte queste possibili situazioni per ogni pezzo prima di iniziare effettivamente la codifica. Basta saltare senza pianificare trasformerà questo divertente progetto in un lavoro ripetitivo. Ma questa è davvero la cosa principale. Pianifica prima al di fuori del codice e assicurati di ottenere ogni scenario per un pezzo alla volta.

In bocca al lupo


1

Per la parte del gioco del giocatore che prende le decisioni, non posso raccomandare abbastanza il libro "Artificial Intelligence: A Modern Approach" (sito web del libro http://aima.cs.berkeley.edu/ ). A seconda del tuo background in matematica (la teoria dei grafi aiuta) può essere un po 'di alto livello, ma è scritto semplicemente come può essere questa roba accademica e contiene una panoramica molto aggiornata (e una certa profondità) di tecniche per fare in modo che i programmi decidano le cose.

Ti indicherà cose come affermare un obiettivo (cioè scacco matto o null), valutare quanto è vicino uno stato particolare (layout della scheda) a quell'obiettivo, come generare i diversi possibili stati seguenti a partire da quello attuale, e come attraversare quello che è un immenso spazio problematico.

Una cosa che potrebbe aiutare a progettare un algoritmo AI è capire come decidere quale mossa giocare dopo come se avessi tutto il tempo nel mondo, a partire da una situazione molto vicina a una partita vinta. Lo ottimizzi in modo che trovi una soluzione in un ragionevole lasso di tempo (ore), quindi trovi i modi per scegliere un percorso vincente anche se non hai ancora esplorato tutti i risultati, in modo da poter effettivamente interrompere il "pensiero" per un turno vale il tempo.

Solo allora avrei cercato di ottimizzare la rappresentazione per rendere più veloci i singoli calcoli, come l'uso di interi lunghi come suggerito. Non importa quanto velocemente puoi fare un singolo confronto, se il modo in cui attraversi lo spazio problematico non ha una buona euristica, ci vorranno anni per farlo.


0

Puoi andare davvero come vuoi, ma questi sono i miei pensieri sull'argomento:

Userei Java in quanto ti permette di essere di altissimo livello e avere librerie di interfacce utente (AWT, Swing) a tua disposizione diretta. È possibile utilizzare un approccio orientato agli oggetti per modellare la scacchiera e i pezzi. Altri oggetti potrebbero sostituire la cronologia delle mosse e il punteggio. Anche i giocatori potrebbero essere oggetti, e in futuro potresti ampliare la tua Playerclasse per fornire un giocatore artificiale artificiale.

Potresti dare un'occhiata a model-view-controller (MVC) in quanto è un approccio molto utile in questo caso per legare i tuoi oggetti modello (modello di dominio) all'interfaccia utente (vista) e per consentire all'utente di manipolare il modello (tramite il controller).

Potresti anche voler applicare lo sviluppo test-driven , che non solo garantisce che tutti i metodi si comportino come previsto, ma ti costringe anche a scrivere codice modulare testabile.


4
Un motore di scacchi non ha nulla a che fare con l'interfaccia utente, solo la "mente", che calcola la mossa migliore.
CSE

@CSE - Dipende dalla tua definizione di motore .
Daniel AA Pelsmaeker,

@CSE - Come mostra la modifica di Adnan, stava effettivamente cercando anche un'interfaccia utente. Quindi la mia risposta è pertinente.
Daniel AA Pelsmaeker,

-8

Le regole degli scacchi sono abbastanza semplici. Devi solo essere in grado di creare una matrice (matrice bidimensionale) per il tabellone e trovare un modo per codificare i concetti dei pezzi, le regole di movimento per ogni pezzo, la convalida che una mossa è legale e le condizioni che segnalano la fine del gioco. Niente di particolarmente difficile. Dovresti usare qualunque linguaggio tu abbia più familiarità.

Ora, se vuoi creare un'intelligenza artificiale per giocare a scacchi che assumerà il ruolo di uno dei giocatori, è lì che le cose si complicano. Ma ancora una volta, la scelta della lingua non è il problema più grande qui; è la comprensione dei principi dell'IA coinvolti. Questo sarà un fattore molto più importante.

(Detto questo, questo tipo di processo decisionale può essere estremamente intensivo dal punto di vista computazionale e probabilmente vorrai usare qualcosa che si compila in codice nativo piuttosto che in un linguaggio di scripting. E C ++ è una pessima scelta, non perché non va bene -adatto a questo problema ma semplicemente perché è un linguaggio molto cattivo in generale, e cercare di implementare cose complesse in esso è un buon modo per codificare tutti i tipi di mal di testa per te.)


15
Penso che dovresti essere un po 'più specifico sul perché il C ++ non è adatto a questo particolare compito al fine di evitare Holy Warz.
Erik Reppen,

9
-1 per il tentativo di iniziare una guerra santa.
Doc Brown,

1
Perché pensi che il C ++ sia un linguaggio molto brutto in generale?
Anthony,

Penso che tu abbia sicuramente sbagliato. Io per primo condivido la sua opinione, il C ++ è un buon linguaggio per cominciare, ma diventa un dolore quando hai a che fare con cose complesse!
Adnan Zahid,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.