kz04px / 4ku Goto Github PK
View Code? Open in Web Editor NEWA UCI compatible chess engine that fits into 4,096 bytes.
License: MIT License
A UCI compatible chess engine that fits into 4,096 bytes.
License: MIT License
these days i keep testing your (newest) 4KU2 version(s) .. it seems 4KU2 plays the endgame rather well, but i saw some severe mistakes .. here are two examples, 4KU2 played Black in both games.
this is from the game against Little Wing v0.7.0 (2169).
FEN: 8/6k1/5pp1/2Q5/4K1Pp/P4Pq1/8/8 b - - 0 45
both teams have equal material, it's a difficult endgame where both players only have a Queen and a few pawns .. here accurate moves are required : win, loss or draw are all possible .. Black has only 1 move which wins : ...Qe1+. Your 4KU2 finds it, but does not win the game, it ended in a draw.
this is from the game against Dabbaba v6.52 (1939).
FEN: 8/8/8/8/2k2p2/5P1p/4K2P/8 b - - 0 65
both teams have equal material, it's a drawn endgame but 4KU2 tries to win .. here Black must not let the White King come to d3, but this is what happened and 4KU2 lost ..
Congrats with the new v2.0! The Changelog is impressive .. you guys certainly know how to build a chess engine, using all known techniques optimally, to even get all code into 4 Kb !! Regarding that size : why is the released (linux) asset 2.9 Mb ? Is it because that version will optimally run on ALL linux distros ? My compiled version is only 59.7 Kb !
i was wondering : while testing some UCI engines with some interesting position, i stumbled upon the fact that 2 or more moves might have equal eval (cp) .. i'm using MultiPV for that .. i'm not asking for MPV in 4KU here, but does it have some table alike while calculating ? Sometimes, early in a game, 4KU thinks for 2 minutes while doing about 30 sec most moves : did the top variations have such equal eval and 4KU took more time / depth to distinguish ?
i was wondering : some (weaker) engines can not do mate with only B & N, they don't know the concerning 'pattern' and often lose by 50 moves .. maybe 4KU can solve it ? Until now i did not test that .. without having a #-piece-end-game-TB, is some hard coded KKBN pattern allowed ? Does such even exist in chess programming ?
Environment: macOS 13.1, g++ 12.2.0
Commands:
sh build-mini.sh
./build/4ku-mini
Error message:
<stdin>: In function 'int64_t a()':
<stdin>:11:82: error: invalid conversion from 'int' to 'clockid_t' [-fpermissive]
In file included from /opt/homebrew/Cellar/gcc/12.2.0/include/c++/12/ctime:42,
from <stdin>:5:
/Library/Developer/CommandLineTools/SDKs/MacOSX13.sdk/usr/include/time.h:178:29: note: initializing argument 1 of 'int clock_gettime(clockid_t, timespec*)'
178 | int clock_gettime(clockid_t __clock_id, struct timespec *__tp);
| ~~~~~~~~~~^~~~~~~~~~
./build/4ku-mini: line 5: /var/folders/5m/v_lfr66s1mg7l9qhv3mjfkfc0000gn/T/tmp.4DH2RQex: Undefined error: 0
Cause of error occurs in src/main-mini.cpp
, line 11:
using namespace std;int b=1<<15;int c=1<<16;int64_t a(){timespec d;clock_gettime(6,&d);return d.tv_sec*1000+d.tv_nsec/1000000;}
In turn this is caused by main.cpp line 52:
clock_gettime(CLOCK_MONOTONIC, &t);
the following code line works with most UCI engines :
p = Popen( [ "sh", "my/path/to/engine/run.sh" ], stdout=PIPE, stdin=PIPE, universal_newlines=True )
those engines only seem to use stderr for their starting "uci settings output", their info lines are all in stdout, which i can catch and filter .. for my script i don't need the stderr info .. however, 4KU seems to (also) use stderr for its output, am i right? .. not sure .. i tried several coding solutions and examples i found on StackOverflow, but i can't create a working PIPE construction to catch both stderr and stdout .. can you help me with this ?
many chess engines have this issue .. it's unclear to me why this happens : in such case an engine often thinks for many seconds, which could easily be saved .. btw. i encounter this with 10m+3s games, the only ones i do at this moment.
could there be an easy fix, not taking much byte space, creating this logical and efficient improvement ?
Congrats with the newer 4KU2 ! Lately i compiled and tested the version "18", where you implemented some eval functions, and it playes very well against 2000 rated engines .. i let 4KU2 play Black in several 10 min + 3 sec games, using CuteChess on Linux (no books, no pondering, 128 Mb Hash, 2 Threads). Here's the ZIPped PGN 4KU2_games.zip
1827 Apollo v1.2.1 0-1
1868 Rustic Alpha v3.0.2 0-1
1882 Princhess v0.8.0 0-1
1888 Surprise v4.3 0-1
1907 Claudia v0.5.1 0-1
1918 Presbyter v1.3.0 0-1
1925 Heracles v0.6.16 0-1
1932 Quokka v2.1 0-1
1939 Dabbaba v6.52 1-0
1950 Monik v2.2.7 0-1
1954 Wowl v1.3.8 0-1
1968 ZetaDVA 0310 1/2-1/2
1990 ALChess v1.84 0-1
1990 Sapeli v2.1 0-1
1992 Fatalii v0.4.0 alpha 0-1
2008 Leonidas v8.3 1/2-1/2
2026 Cupcake v1.1c 1-0
2027 ArabianKnight v1.55 0-1
2032 Poor Little Pinkus (PLP) 1-0
2033 Clunk_v1.2 1/2-1/2
4KU2 plays good chess - i see that, being a club player .. it develops naturally, it prefers to let pieces being captured, it exchanges pieces only when needed .. it seems to have plans to place the pieces and use the pawns, in a logical harmonious way .. it can sacrifice pawns when needed .. it may guard pieces by attacking those of the opponent .. also the endgame is played rather well, in most cases - in a few games 4KU2 was lost (-3 / -4) according to the opponent eval, but managed to win.
so, compared to many other well-known (?) amateur engines 4KU2 performs very well, i estimate its rating around 2000.
Note the few Black games with the Berlin Defence, a variation of the Spanish game 'Ruy Lopez' :
the moves 4...Bd6 and also 4KU2's solution 6...a6 are weird, but seem playable .. in general 4KU2 plays the openings rather well and consistently.
i just encountered a strange playing by 4KU : it fails to mate when clearly winning (eval is +296 or so) : it had Queen and kNight to mate a lone opponent King but lost due to the 50-move rule .. i never saw that with previous versions .. i tried to reproduce this by re-entering such position (by the CuteChess opening book feature) but then 4KU plays well : it mates !? Here is a ZIPped pgn 4KU-fails-mate.zip the first game is the original, the other 2 games start after move 74 to setup such winning endgame position.
Hi
you can save some byte if you delete these lines (in the main function) after the line
goto search_start;
cin >> word >> time_left;
if (pos.flipped)
cin >> word >> time_left;
these lines are never used.
Hi,
I think there is a bug with the node count and thread > 1.
With monitoring the thread number is here but the node count is same with one or more threads used.
do you have the same issue ?
Regards
i'm still testing the (newest) 4KU2 versions by compiling them and let them play with several engines in CuteChess (on Linux). I gathered a lot of (weaker) open source engines and i try to match opponents with similar rating - my current guess of 4KU2 rating is 2100. These are all seperate games (10 min + 3 sec bonus), i mean i do no tournament in CuteChess.
i like your minimalistic approach .. although i'm not a C++ programmer (but mainly Python and JS), your code seems very well written and is just one small cpp file! The UCI subset which you use is enough for playing in CuteChess (or similar), it understands just "position startpos moves [...]" and "go wtime 603000 btime 603000 winc 3000 binc 3000" or similar.
i guess 4KU2 is not for playing in terminal, but it can be done. Looking at the games 4KU2 plays in CuteChess, i see it has a natural way of developing the pieces and pawns. Using the same time settings in all games, 4KU2 seems rather consistent in its openings, only a few times it plays another variation (when the opponent played known opening moves). I guess in such case both moves have almost equal eval, maybe the hash 'decided' the "best move" ? To test a position with different settings, i used terminal by entering the proper (large) move list to reach that position .. i had some odd results, maybe hash is involved ? Then how ? Could such tests help your development ? Can you reproduce them anyway ? - myself i didn't redo the same terminal sessions to see if they would lead to the exact same results .. btw. i use a rather modern avx2 notebook and Xubuntu 22.04
i want to show the terminal output concerning this position :
UCI : position startpos moves e2e4 b8c6 d2d4 d7d5 e4e5
FEN : r1bqkbnr/ppp1pppp/2n5/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq - 0 3
This is a well known position in chess theory. Most positions can be reached by altered move order, but normally the game went like this :
This opening is called the Nimzowitch Defence. 4KU2 also prefers e4 on move 1, but with Black it would answer the good standard e7e5 :
ucinewgame
id name 4ku2
id author kz04px
uciok
position startpos moves e2e4
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove e7e5
Our game continues with :
2. d4 d5
4KU2 prefers Nf3 on move 2, but after 2.d4 it also prefers to answer d5 with Black :
position startpos moves e2e4 b8c6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove g1f3
position startpos moves e2e4 b8c6 d2d4
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove d7d5
Our game continues with :
3. e5 ...
Here 4KU2 prefers not to advance the e-pawn, it likes to keep the initiative by e4xd5 :
position startpos moves e2e4 b8c6 d2d4 d7d5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove e4d5
position startpos moves e2e4 b8c6 d2d4 d7d5 e4e5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
We reached the position of the diagram. Here 4KU2 seems to prefer 3...f6 when given 10 minutes (per game), but when i let 4KU2 think again (same hash?) it finds other moves too ?! :
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
quit
And what about my test below (after restarting 4KU2 in terminal) .. same position, other best move :
(Note: the move Bd7 was once picked also)
ucinewgame
id name 4ku2
id author kz04px
uciok
position startpos moves e2e4 b8c6 d2d4 d7d5 e4e5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove f7f6
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8d7
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
go wtime 603000 btime 603000 winc 3000 binc 3000
bestmove c8f5
quit
And this test, using a longer time :
ucinewgame
id name 4ku2
id author kz04px
uciok
position startpos moves e2e4 b8c6 d2d4 d7d5 e4e5
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove f7f6
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove f7f6
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove c8f5
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove c8f5
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove c8f5
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove f7f6
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove c8f5
go wtime 1603000 btime 1603000 winc 3000 binc 3000
bestmove f7f6
quit
Here, the two moves Bf5 and f6 (which indeed are best according to SF) are both 'best move' after some time, but why do they toggle ?
in your README you state:
Both "position fen [fen]" and "position startpos" are ignored.
indeed, if you want a very simple engine which can only play from the startposition, you don't need those .. but when i look into the source of main.cpp
(although i'm not a C++ programmer) i discover no definition of the start position .. i wanted to adjust the code a little to implement some position fen [..]
command - just for learning. Your code seems readable though ..
Warning: Illegal PV move e7g7 from 4ku (0)
That's because there's no move legality check for the move from the hashtable, and especially in multi-thread scenarios stomping is possible.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.