This commit is contained in:
Thomas Lindner 2022-12-28 15:50:26 +01:00
parent db38497dea
commit 7c8b703cbc
11 changed files with 119 additions and 224 deletions

18
.gitignore vendored
View file

@ -1,18 +0,0 @@
.*.swp
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
blunderboard
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/

View file

@ -1,69 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AutoImportSettings">
<option name="autoReloadType" value="SELECTIVE" />
</component>
<component name="ChangeListManager">
<list default="true" id="3e262a23-1a63-4818-97cf-591091cd1e52" name="Changes" comment="">
<change beforePath="$PROJECT_DIR$/blunderboard.py" beforeDir="false" afterPath="$PROJECT_DIR$/blunderboard.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="MarkdownSettingsMigration">
<option name="stateVersion" value="1" />
</component>
<component name="ProjectId" id="2JHA16UVCORl9oGXtkokQL85N3r" />
<component name="ProjectViewState">
<option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" />
</component>
<component name="PropertiesComponent"><![CDATA[{
"keyToString": {
"RunOnceActivity.OpenProjectViewOnStart": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
"WebServerToolWindowFactoryState": "false",
"last_opened_file_path": "/home/hagenest/Repos/blunderboard/blunderboard-py",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
"node.js.selected.package.tslint": "(autodetect)",
"vue.rearranger.settings.migration": "true"
}
}]]></component>
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
<component name="TaskManager">
<task active="true" id="Default" summary="Default task">
<changelist id="3e262a23-1a63-4818-97cf-591091cd1e52" name="Changes" comment="" />
<created>1671724416846</created>
<option name="number" value="Default" />
<option name="presentableId" value="Default" />
<updated>1671724416846</updated>
<workItem from="1671724417946" duration="16204000" />
</task>
<servers />
</component>
<component name="TypeScriptGeneratedFilesManager">
<option name="version" value="3" />
</component>
<component name="UnknownFeatures">
<option featureType="com.intellij.fileTypeFactory" implementationName="requirements.txt" />
</component>
<component name="Vcs.Log.Tabs.Properties">
<option name="TAB_STATES">
<map>
<entry key="MAIN">
<value>
<State />
</value>
</entry>
</map>
</option>
</component>
<component name="com.intellij.coverage.CoverageDataManagerImpl">
<SUITE FILE_PATH="coverage/blunderboard_py$blunderboard.coverage" NAME="blunderboard Coverage Results" MODIFIED="1671828227830" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="true" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="$PROJECT_DIR$" />
</component>
</project>

View file

@ -1,17 +0,0 @@
stockfish
<<<<<<< Updated upstream
playsound
=======
<<<<<<< Updated upstream
playsound
pygobject
pgn_parser
=======
<<<<<<< Updated upstream
playsound
=======
pygame
pgn_parser
>>>>>>> Stashed changes
>>>>>>> Stashed changes
>>>>>>> Stashed changes

View file

@ -1,91 +0,0 @@
package main
import (
"fmt"
"github.com/notnil/chess"
"github.com/notnil/chess/uci"
"math"
"os"
)
// stolen^H^H inspired from lichess https://github.com/ornicar/lila/blob/master/modules/analyse/src/main/Advice.scala#L79
func WinningChance(cp int) float64 {
winning_chance := 2 / (1 + math.Exp(-0.004 * float64(cp))) - 1
return winning_chance
}
func main() {
reader, err := os.Open("spongeboyahoy_vs_tomlx.pgn")
if err != nil {
panic(err)
}
pgn, err := chess.PGN(reader)
if err != nil {
panic(err)
}
spongeboyahoy_vs_tomlx := chess.NewGame(pgn)
fmt.Println(spongeboyahoy_vs_tomlx)
engine, err := uci.New("stockfish")
if err != nil {
panic(err)
}
defer engine.Close()
if err := engine.Run(uci.CmdUCI, uci.CmdIsReady, uci.CmdUCINewGame); err != nil {
panic(err)
}
game := chess.NewGame()
// prevprev_winning_chance := 0.0
prev_winning_chance := 0.0
for game.Outcome() == chess.NoOutcome {
num_of_moves := len(game.Moves())
if err := engine.Run(uci.CmdPosition{Position: game.Position()}, uci.CmdGo{Depth: 12}); err != nil {
panic(err)
}
search_results := engine.SearchResults()
cp := search_results.Info.Score.CP
if (num_of_moves % 2 == 1) {
cp *= -1
}
winning_chance := WinningChance(cp)
if (num_of_moves > 0) {
delta := prev_winning_chance - winning_chance
if (num_of_moves % 2 == 0) {
delta *= -1;
}
if delta > 0.3 {
fmt.Print("B-b-b-blunder!!")
} else if delta > 0.2 {
fmt.Print("That was a mistake.")
} else if delta > 0.1 {
fmt.Print("Meh...")
} else {
fmt.Print("Ok")
}
fmt.Printf(" (%0.2f, %0.2f, %0.2f)\n", float64(cp) / 100, winning_chance, -delta)
}
// prevprev_winning_chance = prev_winning_chance
prev_winning_chance = winning_chance
// fmt.Println(game.Position().Board().Draw())
// fmt.Println("Score (centipawns):", cp, "Winning chance:", winning_chance, "Best Move: ", search_results.BestMove)
// fmt.Println("Move: ", search_results.BestMove)
move := spongeboyahoy_vs_tomlx.Moves()[num_of_moves]
fmt.Print(num_of_moves / 2 + 1, move, "\t")
if err := game.Move(move); err != nil {
panic(err)
}
// for {
// var move string
// fmt.Print("Move: ")
// fmt.Scanln(&move)
// if err := game.MoveStr(move); err == nil {
// break
// }
// fmt.Println("Illegal move!")
// }
}
fmt.Println(game.Outcome())
fmt.Println(game.Position().Board().Draw())
}

3
go.mod
View file

@ -1,3 +0,0 @@
module git.0x90.space/0x90/blunderboard
require github.com/notnil/chess v1.5.0

3
go.sum
View file

@ -1,3 +0,0 @@
github.com/ajstarks/svgo v0.0.0-20200320125537-f189e35d30ca/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/notnil/chess v1.5.0 h1:BcdmSGqZYhoqHsAqNpVTtPwRMOA4Sj8iZY1ZuPW4Umg=
github.com/notnil/chess v1.5.0/go.mod h1:cRuJUIBFq9Xki05TWHJxHYkC+fFpq45IWwk94DdlCrA=

6
pyproject.toml Normal file
View file

@ -0,0 +1,6 @@
[build-system]
requires = [
"setuptools>=42",
"wheel"
]
build-backend = "setuptools.build_meta"

View file

@ -1,3 +0,0 @@
home = /usr/bin
include-system-site-packages = false
version = 3.10.8

58
setup.cfg Normal file
View file

@ -0,0 +1,58 @@
[metadata]
name = blunderboard
version = 0.0.1
author = 0x90.space
author_email = people@schleuder.0x90.space
description = Blunderboard
url = https://git.0x90.space/0x90/blunderboard
project_urls =
Bug Tracker = https://git.0x90.space/0x90/blunderboard/issues
classifiers =
Programming Language :: Python :: 3 :: Only
License :: OSI Approved :: ISC License (ISCL)
Operating System :: POSIX :: Linux
Topic :: Games/Entertainment :: Board Games
[options]
package_dir =
= src
packages = find:
python_requires = >=3.9
install_requires =
pygame
RPi.GPIO
stockfish
[options.packages.find]
where = src
[options.entry_points]
console_scripts =
blunderboard = blunderboard:main
[tox:tox]
envlist = lint
isolated_build = True
[testenv:lint]
skip_install = True
deps =
black
flake8
mypy
commands =
black --check --diff src
flake8 src
mypy src
#[testenv]
#deps =
# pytest
#commands =
# pytest tests
[flake8]
max_line_length = 88
[mypy]
ignore_missing_imports = True

View file

@ -0,0 +1,2 @@
def main():
pass

View file

@ -1,22 +1,22 @@
from stockfish import Stockfish
from pygame import mixer
import time
from pathlib import Path
import random
import os import os
#import RPi.GPIO as GPIO from pathlib import Path
from pygame import mixer
import random
from stockfish import Stockfish
import time
settings = { settings = {
"Debug Log File": "", "Debug Log File": "",
"Contempt": 0, "Contempt": 0,
"Min Split Depth": 0, "Min Split Depth": 0,
"Threads": 10, "Threads": 1,
# More threads will make the engine stronger, but should be kept at less than the number of logical processors on # More threads will make the engine stronger, but should be kept at less than the
# your computer. # number of logical processors on your computer.
"Ponder": "false", "Ponder": "false",
"Hash": 8100, "Hash": 16,
# Default size is 16 MB. It's recommended that you increase this value, but keep it as some power of 2. E.g., # Default size is 16 MB. It's recommended that you increase this value, but keep it
# if you're fine using 2 GB of RAM, set Hash to 2048 (11th power of 2). # as some power of 2. E.g., if you're fine using 2 GB of RAM, set Hash to 2048
# (11th power of 2).
"MultiPV": 1, "MultiPV": 1,
"Skill Level": 20, "Skill Level": 20,
"Move Overhead": 10, "Move Overhead": 10,
@ -67,10 +67,12 @@ class Game:
self.settings = engine_settings self.settings = engine_settings
self.engine.update_engine_parameters(self.settings) self.engine.update_engine_parameters(self.settings)
self.matrix = BoardReader() self.matrix = BoardReader()
self.current_evaluation = self.engine.get_evaluation() # This is not necessary, now that I think about it. self.current_evaluation = (
self.evaluations = [] self.engine.get_evaluation()
) # This is not necessary, now that I think about it.
self.evaluations: list[dict] = []
self.current_wdl = self.engine.get_wdl_stats() self.current_wdl = self.engine.get_wdl_stats()
self.wdls = [] self.wdls: list[tuple[int, int, int]] = []
self.engine.set_position() self.engine.set_position()
def move_was_blunder(self) -> bool: def move_was_blunder(self) -> bool:
@ -86,6 +88,7 @@ class Game:
return True return True
else: else:
return False return False
return False
def make_move(self, move) -> None: def make_move(self, move) -> None:
""" """
@ -102,8 +105,9 @@ class Game:
print(self.current_wdl) print(self.current_wdl)
print(self.current_evaluation) print(self.current_evaluation)
if self.move_was_blunder(): if self.move_was_blunder():
# If the played move was a blunder play a random sound from the sound path # If the played move was a blunder play a random sound from the sound
#play_sound() # path
# play_sound()
print("Blunder!") print("Blunder!")
else: else:
print("Invalid move") print("Invalid move")
@ -114,9 +118,38 @@ class Game:
test_game = Game(settings) test_game = Game(settings)
moves_manual = ["e2e4", "e7e6", "e4e5", "d7d5", "e5d6", "c7d6", "b1c3", "b8c6", "f1b5", "a7a6", "b5a4", "b7b5", "a4b3", moves_manual = [
"d6d5", "a2a4", "c8b7", "a4b5", "a6b5", "a1a8", "d8a8", "c3b5", "a8a5", "c2c4", "b7a6", "b5c3", "a6c4", "e2e4",
"b3c4", "d5c4", "d1g4", "a5a1"] "e7e6",
"e4e5",
"d7d5",
"e5d6",
"c7d6",
"b1c3",
"b8c6",
"f1b5",
"a7a6",
"b5a4",
"b7b5",
"a4b3",
"d6d5",
"a2a4",
"c8b7",
"a4b5",
"a6b5",
"a1a8",
"d8a8",
"c3b5",
"a8a5",
"c2c4",
"b7a6",
"b5c3",
"a6c4",
"b3c4",
"d5c4",
"d1g4",
"a5a1",
]
for move in moves_manual: for move in moves_manual:
print(move) print(move)
test_game.make_move(move) test_game.make_move(move)