Giter Club home page Giter Club logo

fastchess's Introduction

Teaching FastText to play Chess

FastChess is a chess engine predicting the next move using the http://fastText.cc text classification library. In other words, it is a simple one-layer + soft-max model, taking the board state as a vector and outputting a vector of probabilities for each possible move.

The project also contains a Monte Carlo Tree Search, following by Alpha Zero, which combines with the simple linear model to provide a higher quality of play.

You can play against FastChess on Lichess: https://lichess.org/@/fastchess-engine (requires log-in). It's current rating (January 2021) is 2052 Bullet and 1901 Blitz.

Screenshot

Screenshot

Run it!

You'll need the following libraries:

pip install git+https://github.com/facebookresearch/fastText.git
pip install git+https://github.com/niklasf/python-chess.git
pip install numpy

Afterwards you can play by

$ python play_chess.py
Do you want to be white or black? white
  8 ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
  7 ♟ ♟ ♟ ♟ ♟ ♟ ♟ ♟
  6
  5
  4
  3
  2 ♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
  1 ♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖
    a b c d e f g h

Your move (e.g. Nf3 or d2d4): e4

To disable MCTS and play directly against the fastText model, add the -no-mcts argument. See python play_chess.py --help for more options.

Train the model

There are two ways to train the model. The first one is to download a set of pgn files, like https://storage.lczero.org/files/training_pgns/ and run

python proc.py 'ccrl/**/*.pgn' -test proc.test -train proc.train
fasttext supervised -input proc.train -output proc.model -t 0 -neg 0 -epoch 1
fasttext test proc.model.bin proc.test 1
mv proc.model.bin model.bin
python play_chess.py -selfplay

The other way is to generate your own data, e.g. using stockfish. You can train your own model as:

python make_data.py -games 1000 | shuf > g1000
/opt/fastText/fasttext supervised -input g1000 -output model -t 0 -neg 0 -epoch 4

And then run the program as:

python play_chess.py model.bin

You can also generate more data by self-play (as default games are generated by stockfish)

python make_data.py -games 1000 -selfplay model.bin > games

fastchess's People

Contributors

ddugovic avatar fsmosca avatar joergoster avatar kennyfrc avatar thomasahle avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fastchess's Issues

Release

Can you release it? I am not a programmer, so I can't compile it by source codes. Please release the engine. Thank you.

tune.py: Don't use won result on the game if engines are terminated by ctrl+c

When user presses ctrl+c, below code is also triggered.

        except chess.engine.EngineError as e:
            game.headers.update(
                {'Result': ('0-1', '1-0')[ply % 2], 'Termination': 'error'})
            node.comment += f'; {("White","Black")[ply%2]} terminated: {e}'
            score += -1 if ply % 2 == 0 else 1
            # await asyncio.wait([enginea.quit(), engineb.quit()])
            error = e

Sample output:

[Event "Tune.py"]
[Round "246"]
[White "AA"]
[Black "BB"]
[Result "1-0"]
[BlackArgs "{}"]
[Termination "error"]
[WhiteArgs "{'PawnValueOp': 78, 'PawnValueEn': 108, 'KnightValueOp': 285, 'BishopValueOp': 310, 'RookValueOp': 515, 'QueenValueOp': 1064}"]

1. Nf3 { book } 1... d5 { book } 2. d4 { book } 2... Nf6 { book } 3. c4 { book } 3... e6 { book } 4. g3 { book } 4... g6 { book } 5. b3 { book } 5... Bg7 { book } 6. Bg2 { 0/0 2.575s } 6... c5 { 0/0 3.124s } 7. O-O { +24/7 0.05s } 7... dxc4 { -25/7 0.05s } 8. bxc4 { +60/8 0.05s } 8... O-O { -50/9 0.05s } 9. Ba3 { +45/9 0.05s } 9... Nbd7 { -38/7 0.051s } 10. Nbd2 { +47/9 0.051s } 10... Re8 { -47/9 0.05s } 11. e3 { +47/8 0.05s } 11... h6 { -64/8 0.052s } 12. Bb2 { +61/8 0.05s; Black terminated: engine process died unexpectedly (exit code: 3221225786) } 1-0

Better is result should just be * or unterminated.

Run games in separate processes

Currently, engines are run in different processes, but all python code runs in the same.
This should be fine if running the engines takes up most of the work, but it seems a lot of time is actually spent in python-chess parsing things, arena checking for draws and whatnot, and occasionally in skopt.

To take better advantage of computers with multiple cpus we should run each encounter in a separate process.

This further has the advantage that more advanced time controls can be implemented without fear of engines timing out while another part of the code calls an expensive routine.

tune.py: changing the number of games per encounter

is almost impossible now. At least, I don't see an easy way. ;-)
The main culprit seems to be the handling of the opening book. I don't want to play with the same opening over and over again, which produces many identical games/outcomes.

I wanted to do some tests with increasing number of games per encounter (8, 16, 64) to see, whether this would help convergence.

tune.py: Include best values to debug log file

Suggestion

When -debug is set, also save the best values to debug log file.

This goes to console.

        print(f'Best expectation (κ={kappa}): {X[i]}'
              f' = {y_pred[i]/2:.3f} ± {sigma[i]/2:.3f}'
              f' (ELO-diff {elo:.3f} ± {pm:.3f})')

This goes to debug log file.
logging.info (...

tune.py consumes too much memory after ctrl+c interruption

Environment

windows 7
python 3.7.3
scikit-optimize v0.5.2
scikit-learn-0.21.3
python-chess 0.28.2
numpy-1.16.2

Description

Tried the tune.py and after 100 / 1000 games I sent ctrl+c, it tried to summarize best values but looking at the task manager it is consuming memory as high as 500 MB per sec. At around 3GB of memory usage (my pc has 12 GB), it crashed with the following later console messages. I could not get the earlier part of the console error messages because it is clipped.

Traceback (most recent call last):
  File "C:\Python37\lib\asyncio\runners.py", line 43, in run
    return loop.run_until_complete(main)
  File "C:\Python37\lib\asyncio\base_events.py", line 571, in run_until_complete

    self.run_forever()
  File "C:\Python37\lib\asyncio\base_events.py", line 539, in run_forever
    self._run_once()
  File "C:\Python37\lib\asyncio\base_events.py", line 1775, in _run_once
    handle._run()
  File "C:\Python37\lib\asyncio\events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "tune.py", line 220, in on_done
    opt.tell(x, -y)  # opt is minimizing
  File "C:\Python37\lib\site-packages\skopt\optimizer\optimizer.py", line 443, i
n tell
    return self._tell(x, y, fit=fit)
  File "C:\Python37\lib\site-packages\skopt\optimizer\optimizer.py", line 486, i
n _tell
    est.fit(self.space.transform(self.Xi), self.yi)
  File "C:\Python37\lib\site-packages\skopt\learning\gaussian_process\gpr.py", l
ine 195, in fit
    super(GaussianProcessRegressor, self).fit(X, y)
  File "C:\Python37\lib\site-packages\sklearn\gaussian_process\gpr.py", line 221
, in fit
    self.kernel_.bounds))]
  File "C:\Python37\lib\site-packages\sklearn\gaussian_process\gpr.py", line 465
, in _constrained_optimization
    fmin_l_bfgs_b(obj_func, initial_theta, bounds=bounds)
  File "C:\Python37\lib\site-packages\scipy\optimize\lbfgsb.py", line 199, in fm
in_l_bfgs_b
    **opts)
  File "C:\Python37\lib\site-packages\scipy\optimize\lbfgsb.py", line 335, in _m
inimize_lbfgsb
    f, g = func_and_grad(x)
  File "C:\Python37\lib\site-packages\scipy\optimize\lbfgsb.py", line 285, in fu
nc_and_grad
    f = fun(x, *args)
  File "C:\Python37\lib\site-packages\scipy\optimize\optimize.py", line 326, in
function_wrapper
    return function(*(wrapper_args + args))
  File "C:\Python37\lib\site-packages\scipy\optimize\optimize.py", line 64, in _
_call__
    fg = self.fun(x, *args)
  File "C:\Python37\lib\site-packages\sklearn\gaussian_process\gpr.py", line 213
, in obj_func
    theta, eval_gradient=True)
  File "C:\Python37\lib\site-packages\sklearn\gaussian_process\gpr.py", line 427
, in log_marginal_likelihood
    K[np.diag_indices_from(K)] += self.alpha
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Python37\lib\asyncio\events.py", line 88, in _run
    self._context.run(self._callback, *self._args)
  File "C:\Python37\lib\asyncio\base_subprocess.py", line 247, in _call_connecti
on_lost
    self._protocol.connection_lost(exc)
  File "C:\Python37\lib\site-packages\chess\engine.py", line 679, in connection_
lost
    self.command._engine_terminated(self, code)
  File "C:\Python37\lib\site-packages\chess\engine.py", line 917, in _engine_ter
minated
    self.finished.set_result(None)
asyncio.base_futures.InvalidStateError: invalid state

Importing Data?

Is it possible to import PGNs instead of using Stockfish to generate them?

Exception in callback run (on tune.py)...

I have these errors:

python tune.py danasah800_uci -opp-engine danasah730_uci -concurrency=7 -movetime 200 -book book.pgn -games-file tune.pgn -opt Parameter1 -opt Parameter2 -n 500 -log-file data.log

Starting game 304/334 with {'Parameter1': 200, 'Parameter2': 80}
[196, 80] => 1

Exception in callback run.<locals>.on_done([200, 80], 2)(<Task finishe...>], -2, None)>) at tune.py:259 handle: <Handle run.<locals>.on_done([200, 80], 2)(<Task finishe...>], -2, None)>) at tune.py:259> Traceback (most recent call last): File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\asyncio\events.py", line 88, in _run self._context.run(self._callback, *self._args) File "tune.py", line 272, in on_done opt.tell(x, -y) # opt is minimizing File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\optimizer\optimizer.py", line 443, in tell return self._tell(x, y, fit=fit) File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\optimizer\optimizer.py", line 502, in _tell acq_func_kwargs=self.acq_func_kwargs) File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\acquisition.py", line 50, in _gaussian_acquisition func_and_grad = gaussian_ei(X, model, y_opt, xi, return_grad) File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\acquisition.py", line 276, in gaussian_ei mu, std = model.predict(X, return_std=True) File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\learning\gaussian_process\gpr.py", line 324, in predict y_var -= np.einsum("ki,kj,ij->k", K_trans, K_trans, K_inv) File "<__array_function__ internals>", line 6, in einsum File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\numpy\core\einsumfunc.py", line 1356, in einsum return c_einsum(*operands, **kwargs) ValueError: iterator is too large

Exception in callback run.<locals>.on_done([197, 80], 0)(<Task finishe...>], -1, None)>) at tune.py:259 handle: <Handle run.<locals>.on_done([197, 80], 0)(<Task finishe...>], -1, None)>) at tune.py:259> Traceback (most recent call last): File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\asyncio\events.py", line 88, in _run self._context.run(self._callback, *self._args) File "tune.py", line 272, in on_done opt.tell(x, -y) # opt is minimizing File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\optimizer\optimizer.py", line 443, in tell return self._tell(x, y, fit=fit) File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\skopt\optimizer\optimizer.py", line 489, in _tell self.gains_ -= est.predict(np.vstack(self.next_xs_)) File "<__array_function__ internals>", line 6, in vstack File "C:\Users\pecas\AppData\Local\Programs\Python\Python37-32\lib\site-packages\numpy\core\shape_base.py", line 282, in vstack return _nx.concatenate(arrs, 0) File "<__array_function__ internals>", line 6, in concatenate ValueError: need at least one array to concatenate

can't isntall pip install git+https://github.com/facebookresearch/fastText.git from cmd in windows help plz

pip install git+https://github.com/facebookresearch/fastText.git
it is not working in cmd in windows
Collecting git+https://github.com/facebookresearch/fastText.git
Cloning https://github.com/facebookresearch/fastText.git to c:\users\vedant\appdata\local\temp\pip-req-build-_draur5m
ERROR: Error [WinError 2] The system cannot find the file specified while executing command git clone -q https://github.com/facebookresearch/fastText.git 'C:\Users\Vedant\AppData\Local\Temp\pip-req-build-_draur5m'
ERROR: Cannot find command 'git' - do you have 'git' installed and in your PATH?

Python3.7 for running tune.py is mandatory?

On my Linux system, current python3 version is 3.6.8. This gives me following error message when trying to run tune.py.

  File "tune.py", line 368, in <module>
    asyncio.run(main())
AttributeError: module 'asyncio' has no attribute 'run'

Is there a workaround?

P.S. Support of different kind of time controls and fixed depth would be great, too!

tune.py: exception raised with RF as base estimator

When summarizing best values of a tuning run with RF as base estimator, following error occured:

Summarizing best values
/usr/lib/python3.7/asyncio/unix_events.py:861: RuntimeWarning: A loop is being detached from a child watcher with pending handlers
RuntimeWarning)
Traceback (most recent call last):
File "tune.py", line 483, in
asyncio.run(main())
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "tune.py", line 463, in main
summarize(opt, samples=args.n)
File "tune.py", line 334, in summarize
pm = max(abs(score_to_elo(y_pred[i] / 2 + sigma[i] / 2) - elo),
File "tune.py", line 332, in score_to_elo
return - 400 * math.log10(2 / (score + 1) - 1)
ValueError: math domain error
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python3/dist-packages/apport/init.py", line 5, in
from apport.report import Report
File "/usr/lib/python3/dist-packages/apport/report.py", line 30, in
import apport.fileutils
File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 23, in
from apport.packaging_impl import impl as packaging
File "/usr/lib/python3/dist-packages/apport/packaging_impl.py", line 24, in
import apt
File "/usr/lib/python3/dist-packages/apt/init.py", line 23, in
import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'

Original exception was:
Traceback (most recent call last):
File "tune.py", line 483, in
asyncio.run(main())
File "/usr/lib/python3.7/asyncio/runners.py", line 43, in run
return loop.run_until_complete(main)
File "/usr/lib/python3.7/asyncio/base_events.py", line 584, in run_until_complete
return future.result()
File "tune.py", line 463, in main
summarize(opt, samples=args.n)
File "tune.py", line 334, in summarize
pm = max(abs(score_to_elo(y_pred[i] / 2 + sigma[i] / 2) - elo),
File "tune.py", line 332, in score_to_elo
return - 400 * math.log10(2 / (score + 1) - 1)
ValueError: math domain error

tune.py: Refactor on get_value()

Use elif

                    if result == '1-0' and i % 2 == 0 or result == '0-1' and i % 2 == 1:
                        score += 1
                    elif result == '1-0' and i % 2 == 1 or result == '0-1' and i % 2 == 0:
                        score -= 1

supply test model.bin file as asset ?

I tried to Train the model according to the readme, but i did not succeed .. i can run fastchess by play_chess.py with stockfish, not but with fastchess while it needs some model.bin .. i found several .bin files concerning chess, but they all seem to have a different format .. can you supply a test model.bin file as an asset ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.