Coder Social home page Coder Social logo

fsmosca / position-trainer Goto Github PK

View Code? Open in Web Editor NEW
1.0 1.0 1.0 28.34 MB

Test your skill to find the best move from the given test position.

License: GNU General Public License v3.0

Python 100.00%
chess chess-positions chess-training python-chess streamlit

position-trainer's Introduction

Position-Trainer

Streamlit App Python 3.9+

Test your skill to find the best move from the given test position where the player from the test sets fails to find. It generates a summary table with your selected move, the game move and the engine move. The test sets in json format can be found under the data folder.

image

You can also generate test positions with the use of test_generator.py which can be found in this repository. You need the stockfish engine to analyze the positions where the test_generator saves interesting positions in json format. There is also a stockfish 15 compiled for modern hardware under the engine folder.

Take a pgn file from the week in chess for example and generate test positions. It is better if the players have WhiteElo and BlackElo in the PGN because Position-Trainer can filter rating range and you can train on positions from those players with that filtered rating.

Setup

1. Open the app from the cloud.

Go to this address https://position-trainer.streamlit.app/

Download the json training file inside the data folder or from here. It is a test file that is needed for training.

2. Run the app locally from your browser

  • Download and Install python version >= 3.7
  • Clone this repository see sample below.
PS F:\Tmp> python --version
Python 3.10.6
PS F:\Tmp> git clone https://github.com/fsmosca/position-trainer.git
Cloning into 'position-trainer'...
remote: Enumerating objects: 42, done.
remote: Counting objects: 100% (42/42), done.
remote: Compressing objects: 100% (28/28), done.
remote: Total 42 (delta 12), reused 34 (delta 10), pack-reused 0
Unpacking objects: 100% (42/42), done.
PS F:\Tmp> cd position-trainer
PS F:\Tmp\position-trainer> ls


    Directory: F:\Tmp\position-trainer


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022-09-16     00:03                engine
d-----        2022-09-16     00:03                library
d-----        2022-09-16     00:03                pgn
-a----        2022-09-16     00:03           1928 .gitignore
-a----        2022-09-16     00:03           6130 app.py
-a----        2022-09-16     00:03          35823 LICENSE
-a----        2022-09-16     00:03             61 README.md
-a----        2022-09-16     00:03             18 requirements.txt


PS F:\Tmp\position-trainer> pip install -r requirements.txt
PS F:\Tmp\position-trainer> streamlit run app.py

The command streamlit run app.py will run streamlit server and a browser will be opened.

  You can now view your Streamlit app in your browser.

  Local URL: http://localhost:8501
  Network URL: http://192.168.254.104:8501

Generate training positions

Use the test_generator.py program to generate test positions. The output is in json format that can be used by Position-Trainer.

You need to install python chess with:

pip install chess

Run from the command line

python test_generator.py --pgn-file ./pgn/stlbli22_4games.pgn --engine-file ./engine/sf15.exe --engine-hash-mb 128 --output-file mytest.json --movetime 1000

Sample output

The rate is based on the formula.

def score_proba(score_cp):
    K = 6
    score_p = score_cp/100
    return 1 / (1 + 10 **(-score_p/K))

fmvn is fullmove number
hmvc is half-move clock

The "analysis_movetime": 1.0, is in seconds.

{
    "5rk1/6pp/1q6/p2p1pQ1/1n3N2/6P1/2r2P1P/R4RK1 w - -": {
        "stm": "white",
        "fmvn": 34,
        "hmvc": 6,
        "game": {
            "move": "Nh5",
            "score": -237,
            "rate": 0.29
        },
        "engine": {
            "move": "Qe7",
            "score": 0,
            "rate": 0.5
        },
        "user": {
            "Qd8": {
                "score": -1229,
                "rate": 0.01
            },
            "Qxg7+": {
                "score": -1090,
                "rate": 0.02
            },
            "Qe7": {
                "score": -20,
                "rate": 0.48
            },
            "Qh6": {
                "score": -1159,
                "rate": 0.01
            },
            "Qg6": {
                "score": -1210,
                "rate": 0.01
            },
            "Qf6": {
                "score": -1194,
                "rate": 0.01
            },
            "Qh5": {
                "score": -91,
                "rate": 0.41
            },
            "Qxf5": {
                "score": -1132,
                "rate": 0.01
            },
            "Qh4": {
                "score": -84,
                "rate": 0.42
            },
            "Qg4": {
                "score": -1272,
                "rate": 0.01
            },
            "Ng6": {
                "score": -832,
                "rate": 0.04
            },
            "Ne6": {
                "score": -799,
                "rate": 0.04
            },
            "Nh5": {
                "score": -232,
                "rate": 0.29
            },
            "Nxd5": {
                "score": -794,
                "rate": 0.05
            },
            "Nh3": {
                "score": -262,
                "rate": 0.27
            },
            "Nd3": {
                "score": -850,
                "rate": 0.04
            },
            "Ng2": {
                "score": -297,
                "rate": 0.24
            },
            "Ne2": {
                "score": -900,
                "rate": 0.03
            },
            "Kg2": {
                "score": -144,
                "rate": 0.37
            },
            "Kh1": {
                "score": -272,
                "rate": 0.26
            },
            "Rfe1": {
                "score": -31998,
                "rate": 0.0
            },
            "Rfd1": {
                "score": -31998,
                "rate": 0.0
            },
            "Rfc1": {
                "score": -31998,
                "rate": 0.0
            },
            "Rfb1": {
                "score": -31998,
                "rate": 0.0
            },
            "Rxa5": {
                "score": -682,
                "rate": 0.07
            },
            "Ra4": {
                "score": -132,
                "rate": 0.38
            },
            "Ra3": {
                "score": -111,
                "rate": 0.4
            },
            "Ra2": {
                "score": -888,
                "rate": 0.03
            },
            "Rae1": {
                "score": -121,
                "rate": 0.39
            },
            "Rad1": {
                "score": -79,
                "rate": 0.42
            },
            "Rac1": {
                "score": -141,
                "rate": 0.37
            },
            "Rab1": {
                "score": -209,
                "rate": 0.31
            },
            "g4": {
                "score": -499,
                "rate": 0.13
            },
            "h3": {
                "score": -84,
                "rate": 0.42
            },
            "h4": {
                "score": -79,
                "rate": 0.42
            }
        },
        "analysis_engine": "Stockfish 15",
        "analysis_movetime": 1.0,
        "analysis_depth": 1000,
        "header": {
            "Event": "44th Olympiad 2022",
            "Date": "2022.07.29",
            "Round": "1.1",
            "White": "Masango, Spencer",
            "Black": "Erigaisi, Arjun",
            "WhiteElo": "2170",
            "BlackElo": "2689"
        }
    }
}

Show the help

python test_generator.py --help

Credits

position-trainer's People

Contributors

fsmosca avatar

Stargazers

 avatar

Watchers

 avatar

Forkers

augusto158

position-trainer's Issues

Calculate user performance rating

To calculate the performance rating of the user, we need to get the rating of the opponent of the side not to move in the test position. We also need the score rate of the engine and the score rate of the user selected move. Depending on the test position, the rating of the opponent can be a ?, in this case, we will not be able to calculate the user performance rating and we just have to skip it. The engine score rate and user selected move score rate are available from the test file itself.

In the example below, the test position is r3r1k1/pR3p1p/2n1b2B/3p4/3Pp3/2P3P1/P3P1B1/5RK1 w - -. The actual move played by "White": "Sarrau, Jelle", is game.move or Bh3. The best move according to the "analysis_engine": "Stockfish 15" is engine.move or Rb5 with a score rate of engine.score or 0.58 meaning it is expected to win at 58%. If the user selected the move Rb8 it has a score rate of 0.04. Whatever move the user selects the test file has an equivalent score rate.

{
    "r3r1k1/pR3p1p/2n1b2B/3p4/3Pp3/2P3P1/P3P1B1/5RK1 w - -": {
        "stm": "white",
        "fmvn": 21,
        "hmvc": 2,
        "game": {
            "move": "Bh3",
            "score": -343,
            "rate": 0.21
        },
        "engine": {
            "move": "Rb5",
            "score": 82,
            "rate": 0.58
        },
        "user": {
            "Rb8": {
                "score": -854,
                "rate": 0.04
            },
            "Rbxf7": {
                "score": -653,
                "rate": 0.08
            },

...

        "analysis_engine": "Stockfish 15",
        "analysis_movetime": 1.0,
        "analysis_depth": 1000,
        "header": {
            "Event": "22nd ch-EUR Indiv 2022",
            "Date": "2022.03.27",
            "Round": "1.1",
            "White": "Sarrau, Jelle",
            "Black": "Navara, David",
            "WhiteElo": "2401",
            "BlackElo": "2700"
        }
    },
...

Formula 1

performance_rating = opponent_rating + rating_difference

where:  
rating_difference is derived from the engine score rate and the user selected move score rate.

The following is the formula for the expected score that we are going to use.

Formula 2

es = 1 / (1 + 10 ^ (-rd/600))

where:
es = expected_score or score rate, [0.0 - 1.0]
rd = rating difference

For reference, the FIDE Elo uses around 400 instead of 600.

We can get the rd based from formula 2.

Formula 3

rd = -600 * log10((1-es)/es)

Let's have an example calculation

A test position has:

epd: r3r1k1/pR3p1p/2n1b2B/3p4/3Pp3/2P3P1/P3P1B1/5RK1 w - -

engine_score_rate = 0.58
user_score_rate = 0.08
opponent_rating = 2700

With formula 3 we can calculate the engine rd.

rd = -600 * log10((1-es)/es)
rd = -600 * log10((1-0.58)/0.58)
rd = 84

The user rd is:

rd = -600 * log10((1-es)/es)
rd = -600 * log10((1-0.08)/0.08)
rd = -636

According to the engine, the expected rd is 84 meaning the engine move is stronger, but the user selected move is only -636, which means it is 636 weaker. The rating difference between these 2 numbers are:

rd_diff = user_rd - engine_rd
rd_diff = -636 - 84 = -720

Going back to formula 1.

performance_rating = opponent_rating + rating_difference

The user performance rating is:

performance_rating = opponent_rating + rating_difference
performance_rating = opponent_rating + rd_diff

performance_rating = 2700 + (-720)
performance_rating = 1980

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.