TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

A minimax chess engine in regular expressions

557 pointsby ilya_m4 months ago

36 comments

basementcat4 months ago
This is from the same gentleman who (among other things) demonstrated that printf() is Turing complete and wrote a first person shooter in 13kB of Javascript.<p><a href="https:&#x2F;&#x2F;github.com&#x2F;HexHive&#x2F;printbf">https:&#x2F;&#x2F;github.com&#x2F;HexHive&#x2F;printbf</a><p><a href="https:&#x2F;&#x2F;github.com&#x2F;carlini&#x2F;js13k2019-yet-another-doom-clone">https:&#x2F;&#x2F;github.com&#x2F;carlini&#x2F;js13k2019-yet-another-doom-clone</a>
评论 #42620103 未加载
评论 #42620513 未加载
评论 #42622089 未加载
评论 #42620327 未加载
vintagedave4 months ago
This point was where this changed from crazy&#x2F;fun to absolutely extraordinary, where calculations of multiple possible positions all occurred in parallel, running a regex over an increasing series of state &amp; variable sets, aka threads:<p>&gt; And now for my absolute favorite part of the language we&#x27;ve developed. By the magic of regular expressions (and the fact that they perform substitution globally over the entire string), we can run multiple threads simultaneously!<p>Also:<p>&gt; What do you want out of a conclusion to a blog post like this? I don&#x27;t really have much to conclude. I guess I&#x27;ll just say that I think more people should do entirely pointless things like this. It&#x27;s a lot of fun, no one cares how long it takes you to finish, no one cares if it works or not, and incidentally, it teaches you more than you wanted to know about dozens of areas of computer science outside your field.<p>What a wonderful ethos.
评论 #42621163 未加载
reader92744 months ago
There&#x27;s a bug somewhere it seems like, as it ends the following game with &quot;Illegal move, you lose&quot;, even though it&#x27;s not an illegal move:<p>1. e2e4, e7e5 2. d2d4, e5d4 3. d1d4, a7a5 4. g1f3, b7b5 5. b1c3, a5a4 6. c3b5, a4a3 7. b5a3, a8a3 8. b2a3 --&gt; <i>Illegal Move</i> You Lose. Game over.<p>FEN of game above: 1nbqkbnr&#x2F;2pp1ppp&#x2F;8&#x2F;8&#x2F;3QP3&#x2F;P4N2&#x2F;P1P2PPP&#x2F;R1B1KB1R b KQk - 0 8
评论 #42621514 未加载
评论 #42620309 未加载
comonoid4 months ago
I fear not the man who plays chess with 84,688 regular expressions, but I fear the man who plays chess with one regular expression.
评论 #42627921 未加载
评论 #42621705 未加载
thot_experiment4 months ago
When I see this sort of thing I just I want to take my hat off and stand in solemn appreciation for the true heroes among men.
DylanSp4 months ago
The bug with a-file moves has been fixed: <a href="https:&#x2F;&#x2F;github.com&#x2F;carlini&#x2F;regex-chess&#x2F;issues&#x2F;1">https:&#x2F;&#x2F;github.com&#x2F;carlini&#x2F;regex-chess&#x2F;issues&#x2F;1</a>.
lifthrasiir4 months ago
Previously: Chess written in sed <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=6261314">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=6261314</a><p>Of course, the sed version does make use of control flow commands in sed and only probes 1ply (I think) so this version is significantly different in that regard.
z3t44 months ago
This is not only a chess engine, it&#x27;s a computer and an assembly language, built in only using Regexp
dstrek4 months ago
I normally don’t lose so quickly opening with a2a4 !
评论 #42620205 未加载
评论 #42620425 未加载
eru4 months ago
Compare also <a href="https:&#x2F;&#x2F;codegolf.stackexchange.com&#x2F;q&#x2F;3503&#x2F;32575" rel="nofollow">https:&#x2F;&#x2F;codegolf.stackexchange.com&#x2F;q&#x2F;3503&#x2F;32575</a>
评论 #42620280 未加载
QuentinCh4 months ago
The idea of doing something without a defined &quot;productive&quot; goal might help to do things differently, discover new ways, and in the end stumble on an innovation?<p>Tried it, 2 comments:<p>1) Engine gives a piece early with: 1. b3 b6 2. Bb2 Bb7 3. e4 ??Bxg2<p>2) when you enter an uppercase letter it says illegal move<p>Edit: and here I am trying to &quot;stumble&quot; on an innovation and be productive again. Erh... Humans
评论 #42621101 未加载
评论 #42620908 未加载
magnusisapuxxy4 months ago
As it&#x27;s already been reported in this comment section, at a seemingly random stage of the game when it&#x27;s the player to move, an error caused by an illegal move is triggered. Happened to me twice already in the opening. Once for a King&#x27;s knight move to f3 and once for a simple pawn move as follows: 1.Nc3(b1c3) Nc6(b8c6) 2.g3(g2g3) g6(g7g6) 3.Bg2(f1g2) Bg7(f8g7) 4.e3(e2e3) Bxc3(g7c3) 5.bxc3(b2c3) a6(a7a6) 6.c4(c3c4) a5(a6a5) 7.Ne2(g1e2) a4(a5a4) 5.a3(a2a3) saying a2a3 is illegal.<p>Creative approach. Very impressive if it&#x27;d work, but you cannot finish the game, because it doesn&#x27;t recognize the moves properly. The program understanding and strength is poor, but it was to be expected and it&#x27;s beyond the point of this intellectual exercise, I guess.
mtlmtlmtlmtl4 months ago
This is truly impressive, I&#x27;m in complete awe.<p>I do think there are some bugs based on playing a game against it. It has a tendency to give up its queen and other pieces. and it blundered mate in 1 at the end of the game when it had moves that led to mate in 2 or 3.<p>Usually even a 2-ply engine should avoid these mistakes unless the evaluation function is completely silly, which may be the case here, I don&#x27;t know. I tried looking at the code but it didn&#x27;t make much sense to me, I&#x27;m not smart enough to understand this regex &quot;runtime&quot; based code. Could also be a bug of using &lt; instead of &gt; somewhere, or vice versa, making it choose the worst move instead of the best one.
评论 #42623482 未加载
Hackbraten4 months ago
How long does one single move take to calculate for you folks on a normal phone? On mine (running an i.MX 8M quad-core on Firefox), the first move took several minutes.
评论 #42624584 未加载
3ple_alpha4 months ago
It does seem to play worse than it should, by game went: 1. d4 d5 2. c4 dxc4 3. e4 Qxd4 4. Qxd4 5. Bc4 6. Nf3 7. O-O 8. Rd1 9. Qd8#
评论 #42625163 未加载
tromp4 months ago
That&#x27;s some impressive code wizardry! I thought the 2-ply search would make it respond to a mate-in-1 threat, but the following game demonstrates otherwise:<p>1. e4 e5 2. Nf3 Nf6 3. Nxe5 Nxe4 4. Qe2 Nxd2 5. Nc6+ Ne4 6. Qxe4+ Qe7 7. Nxe7 Bxe7 8. Nc3 a5 9. Nd5 a4 10. Qxe7#<p>9. .., Nc6&#x2F;O-O&#x2F;Kf8 would have avoided mate in 1. Maybe this is related to the a2-a4 bug noticed by others?!
评论 #42625298 未加载
desireco424 months ago
I love the author&#x27;s philosophy of doing &#x27;entirely pointless things&#x27; for the joy of learning. This project reminds me why I got into programming in the first place - not just to solve practical problems, but to explore the weird and wonderful possibilities of code. The fact that this works at all is just mind-blowing!
bennythomsson4 months ago
Kudoa for this, but it feels like there should be a more direct way? I mean, he first invented basically a general-purpose execution platform. That in itself is cool, but the fact that it then can execute a chess program is not actually <i>that</i> surprising.<p>What about directly encoding the rules of the game plus some basic strategy?
评论 #42623351 未加载
bigiain4 months ago
This is totally what jwz needed for xmas...
neuroelectron4 months ago
a2a3 gives me illegal move game over. What am I missing here?
评论 #42620254 未加载
grumpyprole4 months ago
This is fantastic, but of course strictly speaking the use of back references means these aren&#x27;t true <i>regular language</i> expressions but the &quot;enhanced&quot; kind that give security headaches for all the big tech firms.
lxgr4 months ago
Amazing!<p>And just in time when the novelty of playing chess in Postscript (<a href="https:&#x2F;&#x2F;seriot.ch&#x2F;projects&#x2F;pschess.html" rel="nofollow">https:&#x2F;&#x2F;seriot.ch&#x2F;projects&#x2F;pschess.html</a>) has worn off :)
Glyptodon4 months ago
I&#x27;d be really helpful if you added some faded square outlines in the background. I think maybe I made an illegal move with a bishop because of misreading the diagonal.
lilyball4 months ago
assign_pop() is implemented a bit oddly. In particular, the second regex starts off with<p><pre><code> (%%)([^`]\n?#stack:\n) </code></pre> This should have just been written like the following (which in fact eq() does do, though eq() is itself missing the %%` -&gt; %% regex):<p><pre><code> (%%)(\n#stack:\n) </code></pre> As it is the [^`] matches the newline, which is why the \n has to be marked as optional and in practice will always be skipped.
dointheatl4 months ago
It doesn&#x27;t seem to know how to handle pawn promotion. It told me it was an illegal move and that I&#x27;d lost the game.
sjducb4 months ago
It has an interesting response to the queens gambit accepted. Immediate queen sac<p>d2d4 d7d5 c2c4 d5d4 e2e4 d8d4 !? d1d4
RobRivera4 months ago
I read &#x27;cheese engine&#x27; and excitedly clicked.<p>I think my priorities are out of line
michaAtKE4 months ago
Tried the queens gambit and the computer hung the queen on move three :)
proteal4 months ago
“Now comes the clever part.”<p>God bless our soldiers who see that regex is turing complete and choose to implement fun programs. Yall are truly a different breed :)
评论 #42620101 未加载
xrd4 months ago
Sure, but it really should be done using PEG.<p>&lt;&#x2F;Joke&gt;<p>This is seriously brilliant.
Beefin4 months ago
anyone that can read and understand regex i have concerns for
teivah4 months ago
That&#x27;s awesome!
adamredwoods4 months ago
I love this.
GistNoesis4 months ago
Playing chess with strings to build datasets for text generation.<p>I want to share this quick win.<p>The other day I was asking myself some theoretical chess questions, and wanted to answer them programmatically and needed to build some custom chess datasets for that.<p>I needed the chess basic routines, like getting the next legal moves, displaying the board, and some rudimentary position scores. I contemplated writing from scratch. I contemplated using some library. But instead I settled for a higher level choice : interfacing with Stockfish game engine over a text interface.<p>There is something called UCI, which stands for Universal Chess Interface, ( <a href="https:&#x2F;&#x2F;official-stockfish.github.io&#x2F;docs&#x2F;stockfish-wiki&#x2F;UCI-&amp;-Commands.html" rel="nofollow">https:&#x2F;&#x2F;official-stockfish.github.io&#x2F;docs&#x2F;stockfish-wiki&#x2F;UCI...</a> ), to use it you start a new stockfish process and write and read from the standard inputs.<p>So instead of writing bug prone routines to check the validity of board positions, it turn the basic routines into a simple wrapper of parsing task to read and write UCI protocol to use a battle tested engine.<p>A chess position state is simply defined as a vector&lt;string&gt; representing the sequence of moves. Moves are string in long algebraic notation.<p>This architectural decision allows for very quick (LLM-powered development) prototyping.<p>namespace bp = boost::process; bp::ipstream is; bp::opstream os;<p>bp::child c(&quot;..&#x2F;Stockfish&#x2F;src&#x2F;stockfish&quot;, bp::std_in &lt; os, bp::std_out &gt; is);<p>void displayBoard( const vector&lt;string&gt; &amp; moveSeq, bp::ipstream&amp; is, bp::opstream&amp; os );<p>void getLegalMoves( const vector&lt;string&gt; &amp; moveSeq, vector&lt;string&gt;&amp; legalMoves, bp::ipstream&amp; is, bp::opstream&amp; os );<p>void getTopKMoveAndScoreAtDepthFromPosition(const vector&lt;string&gt; &amp; moveSeq,int K, int D, vector&lt;pair&lt;string,int&gt; &gt;&amp; topkmoves, bp::ipstream&amp; is, bp::opstream&amp; os , bool debug = false);<p>void displayBoard( const vector&lt;string&gt; &amp; moveSeq, bp::ipstream&amp; is, bp::opstream&amp; os ) {<p>os &lt;&lt; &quot;position startpos moves&quot;;<p>for( int i = 0 ; i &lt; moveSeq.size() ; i++)<p>{<p><pre><code> os &lt;&lt; &quot; &quot; &lt;&lt; moveSeq[i]; </code></pre> }<p>os &lt;&lt; endl;<p>os &lt;&lt; &quot;d&quot; &lt;&lt; endl;<p>os &lt;&lt; &quot;isready&quot; &lt;&lt; endl;<p>string line;<p>while (getline(is, line)) { if (!line.compare(0, 7, &quot;readyok&quot;)) break; cout &lt;&lt; line &lt;&lt; endl; }<p>}<p>You get the gist...
x0n4 months ago
c4, Qa4, Qxa5, Qc7, Qxc8# lol
neuroelectron4 months ago
I wonder if this is inspired by LLMs which similarly do tons of repetitive processing most of which is unrelated to the final answer.
评论 #42620416 未加载