Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/elliotpenson/n-gram-chess
https://github.com/elliotpenson/n-gram-chess
Last synced: 5 days ago
JSON representation
- Host: GitHub
- URL: https://github.com/elliotpenson/n-gram-chess
- Owner: ElliotPenson
- License: mit
- Created: 2016-06-06T23:13:41.000Z (over 8 years ago)
- Default Branch: master
- Last Pushed: 2016-06-11T02:19:41.000Z (over 8 years ago)
- Last Synced: 2024-11-07T20:52:19.439Z (about 2 months ago)
- Language: Common Lisp
- Size: 62.1 MB
- Stars: 5
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
#+TITLE: n-gram-chess
#+AUTHOR: Elliot Penson
#+OPTIONS: num:nilA chess engine powered by an n-gram model. Inspired by [[https://news.ycombinator.com/item?id=8945231][this post]] on
Hacker News. The project depends on my chess library [[https://github.com/ElliotPenson/knight-owl][knight-owl]].The n-gram level may be specified by the user. The model is trained on
a set of chess games in portable game notation (PGN). Such a
collection exists in the corpus directory. These files are taken from
the [[http://www.pgnmentor.com/files.html#players][PGN Mentor Database]]. During training, the engine establishes a
frequency map. Various functions use this map to find conditional
probabilities of chess moves (i.e. the likelihood of a move given n-1
previous ones).** Usage
First, train the model. The ~train~ function begins by searching
the corpus directory for PGN files. The function evaluates to a
~hash-table~ of n-gram counts from the moves of these games. This
table needs to be stored for future use:#+BEGIN_SRC lisp
(defparameter *count-map* (train 3))
#+END_SRCThe required parameter (in this case ~3~) indicates the n of the
model. 2 would be a bigram model, 3 trigram, and so on.The quality (or /probability/) of a move can now be
tested. ~move-probability~ takes a move in algebraic chess
notation, a list of previous moves, and the n-gram count map. For
example:#+BEGIN_SRC lisp
(move-probability "Nc6" '("e5" "Nf3") *count-map*)
-> 0.5555556
#+END_SRCThe model also has the ability to select the best move given a
chess board's state. Let's begin by setting up a board.#+BEGIN_SRC lisp
(defparameter *test-board* (new-board))
#+END_SRC
Now let's do some moves.#+BEGIN_SRC lisp
(loop for move in '("e4" "e5" "Nf3" "Nc6" "Bb5")
for whitep = t then (not whitep)
do (make-move move *test-board* whitep))
(print-board *test-board*)
-> 8 |♜||_||♝||♛||♚||♝||♞||♜|
7 |♟||♟||♟||♟||_||♟||♟||♟|
6 |_||_||♞||_||_||_||_||_|
5 |_||♗||_||_||♟||_||_||_|
4 |_||_||_||_||♙||_||_||_|
3 |_||_||_||_||_||♘||_||_|
2 |♙||♙||♙||♙||_||♙||♙||♙|
1 |♖||♘||♗||♕||♔||_||_||♖|
A B C D E F G H
#+END_SRCLooking good! Now for the most likely move. The ~best-move~
function accepts a board (like *test-board*), if the player is
white or black, a list of previous moves, and the n-gram count
map.#+BEGIN_SRC lisp
(best-move *test-board* nil '("Nc6" "Bb5") *count-map*)
-> "a6"
0.45833334
#+END_SRC
We receive the most probable move and it's associated
probability. Note that we only handed ~best-move~ the last two
moves. This is because we are working with a trigram model.** TODO Future Improvements