#The inaugural Unofficial Gleam Chess Bot Tournament!
1 messages Β· Page 2 of 1
I feel like with FFI on JS, you could commit some real crimes for performance gains
But of course that's not allowed in this competition
I wonder how different Gleam 1.11 would make the JS version
I'm not sure it's really the pattern matching that's the problem tbh
javascript's whole "you can have any type of int you like as long as it's a float" thing is a pretty big problem for a chess engine
and then using the bigint type slows down everything massively 
javascript engines have to do some wacky shit to get around it
yeah, same problem is there in erlang too though tbf
i think if we do this again with more standard utils, some debugging functions would be nice. I'm very partial to my generate.display function, made tests super easy
they automatically promote to a bigint one they're bigger than 60 bits, so 64 bit bitboards are slowwwwww
60 bits for the number plus a little header :')))
yeah that's cool too, we had a similar thing
simply remove a row from the chessboard, problem solved
what did the output of yours look like?
not quite as cool as yours I must admit
I greatly enjoy that it's using the Minecraft font too
Not because I particularly like the font. It's just funny
it's my terminal font!
also if I were doing it again I'd probably have preferred stockfish style
+-+
| |
+-+
squares
i only use it because I think it's incredibly readable
I find it very hard to read which annoys me so much because I love minecraft 
i think pixel fonts are amazing
My favourite fonts all are the opposite of pixely
I used to be a big bitmap font girlie
somehow when you only have a few pixels, a font feels more readable to me
I probably should have written more tests for my eval function
fractional scaling go brrrr though :(
kde solves this :3
I tested move generation well but evaluation was all just manual testing and vibes
(used to be on gnome, I don't miss it)
wait it does?? damn, I use kde lol
ah well though, berkeley mono my beloved
it has great support for fractional scaling in my experience
oh yeah the fractional scaling in general is fantastic
I thought you meant it did something cool with bitmap fonts in particular
no no
only bad part about kde is how spread out the settings are. dconf was an innovation
my eval was literally just summing up piece quantity (with weights ofc), so tests wouldn't exactly do much
I do like negamax though, eval not being color-dependent made it a lot more intuitive to me
Yeah it's pretty cool
Mine's a bit more complex than that, for better or for worse
I'm sure it's for better
I did find that sometimes adding something new made the bot worse in some situations
We'll find out soon enough π
-# Once I write the competition runner
I also need to decide on the tournament format and exactly how each match will play out
I think there's somewhere between 6-8 entries, so I'm thinking something like a round robin with a grand final for the top two entries
6 on CC + girlchesser I think
Round robin then semi finals and finals? That was my thought, but maybe semis aren't needed
If we had semis, the rr would only be eliminating 2-3 bots
Yeah
We'll see
Maybe it could be top 2 go to a final and 3/4 play to determine 3rd place overall
I'm planning on each match basically having a set sequence of starting positions, then two games are played for each position (one white one black) until one bot has an advantage over the other
Yeah that sounds good
why not play until the end of the game?
it's very much possible to turn an advantage into a loss haha
Sorry, I meant advantage as in tennis
ohhhh gotcha
i.e. it has 2 more wins than the other
Then for the finals games I'll use a different sequence of starting positions
So we're not seeing the same matches twice
yeah definitely a plan
That's good, because I get the impression not many of the bots do much about opening strategy
the main reason is that deterministic bots would play the same game against each other every time
Yeah. Just need to decide where to get the moves from
Ideally they should all be early game positions
Yeah that's sort of what I mean
So in summary:
- Round robin
- Top 2 play for the cup, next 2 play for third and fourth
- Each match is a sequence of starting positions alternating each side
- A match is won when one bot has won 2 more games than the other (minimum of four games total)
- All RR matches will use the same sequence of moves
- Finals matches will also all use the same sequence, but it'll be a different sequence to RR
If folks could π π this that'd be great π
would it be an idea to have a minimum number of games before advantage wins? feels a bit volatile if a round could be decided by just two games
Yeah I've had that in my head too
Perhaps four games (2 positions) minimum
The first position for RR will be the opening position, I think
I do wanna see how bots cope with that
There's also gonna be around 30 matches, and if each game could take minutes, the whole process is likely to take me a couple hours to get through
Five seconds per move was very generous, but I was trying to account for the fact these are running in Erlang/JS
"generous" i see you're calling me out
you underestimate how bad my code can really be
I honestly don't know how these usually run
usually with fischer time, so both engines have a clock and have to budget their time, plus they get an increment every move
what the time is depends on the tournament, tcec uses 30 mins + 3 secs but for a tournament like this you could probably get by with less than a minute main time
we ended up using a dictionary of squares using 0x88 representation to the piece type
also turns out that dicts are extra good when they're 32 entries or less
and there happens to be a max of 32 chess pieces
oh neat! yeah similar idea to 16x12 then
yeah
i think we did try that type of approach but we couldn't get the board access to be faster
there's no real easy mutate-able "array" type unfortunately
I went for 16x12 because the sentinel value check was a bit faster than doing the & 0x88 check
yeah, iv is the next best thing there
yeah, i think our code was a bit too set in stone maybe
also: did you know that case statements are generally fast
you will see some gleam crimes in here
On the BEAM they use the same tree representation that Jak added to the JS target
So they're really quick
i think ours measured like, it ended up being faster to do a huge case expression than doing a bit operation
Yeah bitwise operations don't seem to be super fast on the BEAM
they're totally fine as long as your ints aren't bigger than 60 bits
otherwise they're horrendous
I think the way a match is won could cause cases where a weaker bot could win against a stronger bot, (it has happened in our testing). This could be solved by having way more games, or.
Each game a win gives +2 points, a draw gives +1 to both, a loss gives +0. Each bot plays round robin where it plays every other bot X times, then the final score is tallied and the bot with the most wins is 1st. This scoring is iirc pretty common way of doing it, and it's not quite the "all or nothing" of the current system
and also, you have a fixed # of games you need to actually run, so you can kinda expect approx how long it will take
Gotcha, but then what happens in the case of a tie?
if there's a tie in the final rankings, you could look at the tied players' performances against each other directly
or run a few tiebreakers if they're still tied there
but at that point it's pretty rare
If you want to learn more about the hash I basically just implemented what's described at chessprogramming's Zobrist Hash page. Tbf I kinda forgot about the memory limit, so I can't tell you π
Also some things I'd like to do: replace the 2D array with a 1D one for the board (I had a module for this but ended up not using it), switch the dict in the TT to a fixed size array (kinda the point of calculating the hashes π€¦ββοΈ ) and, obviously, add an opening book
When I measured (admittedly not recently), reads were much more of a performance costs than writes for me. Maybe less so for you because you pre-compute the attack info?
I got them to add a get_or_default which makes a big difference indeed.
It really depends on the type of data you're holding/manipulating
in the right circumstances the BEAM will modify tuples in-place, I'm not sure if glearray is able to
dang I should've done this
Nope, doesn't work across module boundaries so to do that within the constraints of the competition you'd have to use a gleam custom type for your field data
Interestingly, I tried both replacing my 64-bit hashes with 60-bit ones, as well as changing my transposition table from a Dict to an array, and both of them seemed to decrease performance, counter to what I would have expected
Yeah, maybe there's something I missed but I didn't really have time to investigate too much within this competition
I'd be interested to have someone else help me try to optimise various things in my code afterwards, because most if it was just trial and error
We also reduced the hash size for the transposition table, but then you definitely get way more collisions
there was a whole bit where we had to figure out the strategy of pruning the transposition table
incrementally updating the zobrist hashes was also really important
Yep that was something I did too
(finally) started working on the runner π
Eek
If anyone's interested, I'm picking openings from a collection called the Silversuite
who's winning
No comment
definitely not me
not me either
Nobody because I haven't started running the actual competition yet
So cool
being employed is definitely more impressive 
can you tell when i got employed π
my github enterprise profile is looking great
would be cool if anyone could see it
Oh, makes more sense then
Whoβs winning?
That's for me to know and you to find out when the video is released π
Lol, fair
is it close or not ποΈ
we should elect 1 (one) person to watch the video and give us the results, lets not play into this blatant viewer manipulation
It may or may not be
uhhh interesting
I'm winning and it isn't even close
Are we placing bets
Not sure Louis would let us gamble in the server
what's my cut
I was going to say, it can't be that difficult to convince him
Awesome
Yes, taking bets
But I have no idea how to calculate odds
So it's gonna be an all-in situation
If I bet against my bot then I win even if I lose
Nah I'm just taking bets on the winner
Big pot, winner(s) take all split according to how much they bet
Minus fees, naturally
Are you open to bribes?
Sure
Not sure how I influence the outcome of a set of deterministic competitions
But sure
just lie obviously
Aight, betting is open, you can bet on any of the following:
The GearsDatapacks Bot, by Gears
2716 lines of Gleam
96KB of code
Gert's bot, by gertvv
12,034 lines of Gleam
840KB of code
girlchesser, by Hayleigh and Lucy
1784 lines of Gleam
92KB of code
Journeybot, by llakala
1958 lines of Gleam
172KB of code
The mine-tech-oficial bot, by MineTech
1772 lines of Gleam
76KB of code
Pieter's bot, by PieterJanVdb
1203 lines of Gleam
52KB of code
gnomeschesser, by PumpkinMouse and tonyd333
14,877 lines of Gleam
5MB of code
You can place bets at https://ihh.dev/chess
wow gnomeschesser is big
Yes. Whether that's an indication of quality... who knows? π€·ββοΈ
The round robin games have just concluded
I guess that's the one with the hardcoded opening tables
git commit -m 'inline jpg of a chess board to teach code how to chess'
Also clearly I missed the part where you could choose the name of your bot
gert also has approx the same loc but way smaller size
let's just say we didn't write idiomatic gleam code
Fuck sake π
I know! More people should bet
I'm contemplating how egotistical it would be to bet for my own bot
and also how confident I am
Wow you put that betting page together hella fast
Nah it's just a redirect through to Polar
In all seriousness, if people wanna try and guess the winner, the people who guess right can have brownie points
I'm gonna guess myself for double the disappointment if I lose 
My money is on Hayleigh and Lucy (Lucy is good at maths and Hayleigh is Hayleigh)
Results for the round robin have been calculated π
When will the video come out?
I'm aiming for the first weekend of July
hey nice I got the least amount of code, I'll be amazed if any of my moves don't time out
I didn't really continue working on my openings with the negamax algo in place so it's very likely it just times out on the first two moves, while after those it gets pretty speedy
My openings are terrible, but hopefully I can checkmate you in the endgame
I'm pretty sure your bot was consistently the fastest
My bot is consistently the slowest because I try to spend as much time computing moves as possible
Most of them use a hard 5s calculation time
yeah bec I lowered it to 3 plies 2 seconds before committing lmao
Or just below 5s
I'm scared that we timed out (we've had issues with this commonly)
and didn't properly implement a thing where I can just let it run and where it aborts the calculation to just pick w/e if it's close to 5s
Nah I mean like most of them are taking 5s, yours generally finishes moves in under 50ms
well yeah, it's not really doing much I think π₯Έ
either way im happy itβs doing something
Hopefully my bot plays lol
Me too lol
Third place has been decided π
Is it possible for me to change my bot's name?
Sure
At least there is a third place, and they didn't all just make random moves until draw by repetition or 50 moves
There's been a lot of threefold repetition, actually
No 50 move draws
Currently watching the finals play out (slowly)
After trying to think about an acronym, I'll just go with Pedro's bot I think
at some point, I think I want to rewrite my bot in rust and see if I can get it to actually be performant
maybe I'll also do all the performance optimizations I put off this time (bitboards and true legal move generation, mostly)
Yep, there's no easy way to track that because it's not encoded in the FEN. Could have done something with actors but I didn't in the end. I imagine others didn't either
That's obviously the reason why I didn't track it
-# definitely not because I didn't have time + didn't want to do it + didn't know how
my bot constantly went into fifty move draws when I had it play against itself
i was just hoping that other people's bots would be smarter and prevent that from hapening
which, it seems like they did!
we just passed around a dict of previous game states
how did you do that? doesn't the bot only respond to a move with the fen data, meaning you can't preserve previous states?
the bot doesn't get restarted per-move afaik right
We had a couple actors but nothing really sophisticated
I love that you named them
that was all my partner's decision lol
he also implemented all the state monad stuff that I barely understand
the word partner has become very ambiguous, i meant like project partner to be clear
friend* that's the word
The tl;dr as I understand it, is that it's a way of replacing functions where you pass in a state, and it returns a state
instead the function returns a state monad (which effectively is a function that modifies the state)
haskellers cant help themselves
but you can compose it and stuff
It ended up being pretty nice once I got the hang of it
anything in our repo that is haskelly isn't me 
we also did the whole parser combinator thing
for 3 fold there's a nifty trick where once an "irreversible" move is made, you can just clear the game history
which is conveniently encoded in the halfmove clock
but there's some edge cases where if you time out and you receive a new request with the exact same position and you'd have to handle that
or maybe if you receive a position that's not exactly the next move or whatever
and dicts (erlang maps) turned out to be really fast and cheap (especially when 32 entries or below), at least when we measured it
I spent like an entire week (many many hours) getting bitboards to work, and it ended up being like 10x slower. Made me so sad
I meant the word "friend" but okay π
This is still cool
i'm incapable of recognising jokes
I wanted to look into your interruptable stuff more anyway
yeah that's all my friend
i don't understand it at all
So who's going to do a UCI parser library and a general chess library 
I would do it but I'm so burned out from chess I don't want to look at it for a few months
You've got plenty of time π
The results are in! Congratulations to ||the winner|| and commiserations to ||my wallet||
oh, true
Time to run that starting position with every combination of bots to figure out which two were in the final
I'm not actually going to do that
Fair
The position is EC0 E99 if anyone cares
I'm tempted tbh
Are you saying that to reverse psychology us
are you trying to nerd snipe us haha
Because it's sorta working
ah you beat me
I do wanna try that doubled u32 trick, I might try making a library out of that
If you mean bitboards you might wanna take a look at my bot, it already has it
Did you profile it vs regular ints/what was the result?
Actually no, just implemented it like that because someone said that when ints get larger than 62 bits on Erlang they auto-promote to BigInt and it becomes slow (it might be lucy who said it lol)
I'll give it a go and measure and see the difference then
yeah that was me haha
doing bitwise operations on ints bigger than 64 bits is very slow
did you use pairs of 32 bit ints then?
Well, it's just Ints, tho they shouldn't get bigger than 32 bits, if that's what you meant
yeah exactly, there aren't any sized int types in erlang anyway
it'd be nicer to have bitwise operations on bitarrays but I'm not sure if the datatype is suited for that
I imagine there isn't much control over how those are implemented, bitarrays are an erlang type
you'd either have to convert to the appropriate int (which would still have to be 60 bits or less to be fast in erlang), which you can do in gleam anyway, or write the bitwise ops in software which would be just as slow as doing them on bigints
oh wow I profiled it, it's definitely measurably slower to use the bigint rather than 2 smaller ints
thought it seems to differ based on the specific operation
How so?
yeah, small ints get to use the CPU's bitwise instructions whereas bitwise ops on bigints are implemented in software
some operations like shifts are a bit more complicated when you use pairs of 32 bit ints, because you have to shift things across the gap, but it's still much faster than doing software shifts on a bigint in my testing
in fact even the letterbox movegen in girlchesser is much faster than the bitboard implementation I knocked together with 64 bit ints
##### With input 0 False #####
Name ips average deviation median 99th %
bigint get 67.94 M 14.72 ns Β±208.68% 10.24 ns 102.40 ns
bigint set 42.69 M 23.42 ns Β±2775.94% 0 ns 1024 ns
two ints set 35.56 M 28.12 ns Β±200.15% 0 ns 102.40 ns
two ints get 16.93 M 59.08 ns Β±5145.82% 0 ns 20.48 ns
##### With input 0 True #####
Name ips average deviation median 99th %
two ints get 64.41 M 15.53 ns Β±185.47% 10.24 ns 102.40 ns
bigint set 46.99 M 21.28 ns Β±230.96% 10.24 ns 102.40 ns
two ints set 35.43 M 28.23 ns Β±207.25% 0 ns 102.40 ns
bigint get 15.57 M 64.22 ns Β±5118.82% 0 ns 102.40 ns
##### With input 63 False #####
Name ips average deviation median 99th %
bigint get 67.67 M 14.78 ns Β±34.56% 10.24 ns 20.48 ns
two ints get 64.42 M 15.52 ns Β±186.70% 10.24 ns 102.40 ns
two ints set 35.39 M 28.25 ns Β±200.57% 0 ns 102.40 ns
bigint set 15.28 M 65.43 ns Β±637.00% 0 ns 1024 ns
##### With input 63 True #####
Name ips average deviation median 99th %
bigint get 67.83 M 14.74 ns Β±34.66% 10.24 ns 20.48 ns
two ints get 64.63 M 15.47 ns Β±213.88% 0 ns 102.40 ns
two ints set 36.43 M 27.45 ns Β±189.86% 0 ns 102.40 ns
bigint set 17.63 M 56.71 ns Β±745.25% 0 ns 1024 ns
It's pretty hard to measure because of how fast the operation is
I was benchmarking moves generated per second, that seemed to work well
ahaha
sure thing grandpa
Damn i got excited for a sec
I've started writing the results video
I need to load the game outputs into a database so I can do some analysis on them
Interesting stats, etc.
damnnn yeah I was excited too
Hellooooo, just want to apologise for taking so long to get the results video out. I've been doing some consulting work for friends who own a small startup and I've been in the office 9am-8pm most days for the past couple of weeks, so any other free time has been spent on other priorities. I'm trying to make the most of my day off today to get the script finished, though!
I have no plans to contact the winners in advance, so don't worry if you've not heard anything from me by the time the video goes up π
think of all the exposure you could be getting!! who needs money
I've started editing the video, and it's, uh, super duper boring π I'm not a chess expert so I can't commentate on games, and I feel like the rest of the information I have available to give isn't that interesting.
Would people be okay with not having a results video? Obviously I'll still announce the winners.
Also happy to trim it down and release just the audio if folks are interested
Is a shorter video possible?
In theory, but it would probably require reworking from the ground up
And I'm really short on time at the moment
so bad at being unemployed
Horrendous, really
Maybe you could comment on the implementations?
The video didn't really go too deep into the implementations. I'll finish cleaning up the audio and A-roll and just release that as an unlisted video so you have something π
Video is available here. I would kindly ask that you don't mention the results in this thread for a little while - gives everyone a chance to watch the video first - but feel free to comment on the implementations etc.!
(cc @grand lodge @normal latch @eternal basalt @fluid venture @ruby forge @formal fiber @twin crag @burnt raptor @fathom delta)
And if the winners would reach out to me once you've seen the video, that would be great.
Well done everyone who submitted! It's certainly no small task making a chess bot from scratch.
I personally think I would have enjoyed watching a fully edited version of this, but maybe that's just because I'm invested in the results of the competition.
I'm interested to read the implementations of all the different bots, now that I know how they did, to see what worked well and what didn't.
The stats are interesting too! There were fewer draws than I expected to be honest. I thought there might have been some pairs of bots which couldn't win against each other, and perpetually drew.
Maybe someone who is less busy than IHH could do a bit of a dive into the different bots
I'd be really interested in what approachs people took!
I don't know if the games themselves were released but if anyone is chess savvy maybe they could see if anything interesting happened there
I'd definitely be down to do some type of analysis on the games/bots
I'd love to have been able to watch the bots play each other (with stockfish(?) analysing each move made)
I have little time today so I could only see my bot, and ||I genuinely thought it would detect all checks lol, guess I should have tested it|| (kinda spoiler but not my position)
Unfortunately I cannot do videos for the life of me otherwise I'd volunteer
The game PGNs are all going to be included in the data dump
oh nice
Also thanks for hosting this event it was a lot of fun to participate in π
Yeah, it was really cool! Will have to take a look at the other bots later
What a cool idea
Amazing!
Iβd love to peek at the code but from the video it looks like itβs not public yet?
It loads for me
Link? π
Which code do you mean?
The botsβ code
ah
Oh sorry I thought you meant the video was private
hayleigh + lucy https://github.com/lucymcphail/girlchesser
pumpkinmouse + tony: https://github.com/tonyd33/gnomeschesser
gears: https://github.com/GearsDatapacks/gleam-chess-tournament
minetech: https://github.com/mine-tech-oficial/gleam-chess-bot
llakala: https://github.com/llakala/chess
gertv: https://github.com/gertvv/gleam-chess-bot
piege: https://github.com/PieterJanVdb/gleam-chess-bot
not sure if that was on purpose, but congrats on timing: today's International Chess Day π
Iβll upload it to github when i can but itβs very standard stuff Iβd imagine π
||Immensely surprised at my results lmao||
i wouldnt mind if someone else just lifted the uci stuff we did and published it into a package as long as there was some credit somewhere; it should be pretty robust
honestly the interruptable stuff is all smoke and mirrors XD it looks a lot fancier than it actually is because it's done in a pure-ish language. it ends up just translating to javascript code like:
const deadline = seconds_later(Date.now(), 5)
let best_move = null;
function iteratively_deepen(game, depth) {
if (Date.now() > deadline) return best_move;
best_move_at_depth = minimax(game, depth)
best_move = best_move_at_depth || best_move;
iteratively_deepen(depth + 1)
}
function minimax(...) {
if (Date.now() > deadline) return null;
return minimax_actual_implementation(...)
}
thank god i got employed only right after the submission deadline heheh
That's basically what I did for my impl of iterative deepening
yeah i assume most ppl did something like that. what was neat about our interruption check was that it didn't actually check the time, and instead checked for a message that was queued with process.send_after, which made sprinkling the interruption checks everywhere super performant
it also allowed for arbitrary interruptions through message passing which was nice QOL for the uci stop command
I'm tempted tbh
I didn't get to do much with girlchesser since I started a new job halfway through, plenty of stuff I still wanna try
yeah, it would be nice for the next tournament to start us off with pre-existing libraries because scaffolding a chess implementation and utilities like uci can take a while, which gives us unemployed folk a big advantage
efficient general chess library seems hard tho, the chess implementation we ended up with was super tightly coupled with our search/evaluation
Could definitely adapt ours to a library that people can use as a starting point
the erlang backend made this pretty nice though actually, we had a separate process running the iterative deepening search and sending a message back to the parent process every time it had a new best move guess, so the parent can just keep a timer and kill the child when it runs out
would probably end up being less efficient than the optimal one though
also i might rewrite some parts now that we can use FFI again 
this was our approach to for a while
but you lose out on some transposition table data when you kill the child
ours is pretty nicely decoupled from the search logic but there's still lots of room to make it faster
and i think there was race conditions you had to handle where the process returns a best move after you kill the process
oh our child persisted between depths, so it kept the transposition table itself
ooo
yeah especially with ffi now
yep thats what we ended up with
I'm kinda tempted to do it without ffi though
honestly tony redid a lot of the search by the end so i don't actually remember the exact details 
there was a huge grind near the end
funny thing about neither erlang nor javascript having actual 64 bit ints is that storing bitboards as pairs of u32s is probably the fastest approach on both
i'm tempted to have a board implementation in NIF so you can just use u64
yeah i think we considered the u32 pairs at one point too, i forgot why we never tried it
at that point you may as well just do the whole movegen in another language and pass the results to gleam though
well NIFs would be against the rules cuz it counts as ffi didn't read correctly
otherwise the FFI overhead might be pretty bad
ohhh sorry you mean writing erlang? nah the 60 bit int limitation is an erlang thing :(
I just didn't have the time :')
damn this needing to get a job stuff
imagine working an actual job when you could be working on the chess bot
couldn't be me
(now employed unfortunately)
clearly we need a gleam->python target
they don't want to introduce any new languages that they'd have to upskill new hires on :')
which does make sense
I might clean up my code a bit and release it as a library
We're gonna have 5 chess libraries by the end of this
Could definitely do that
mine should absolutely not be a library
although I would be happy to contribute the best of my testing framework to a library
(also, made a friend request, Isaac!)
this reminds me - I'd love to rewrite my bot in rust and actually make it good this time
yes, that would be my first rust project
but as you can tell by now, I enjoy chess as a means of learning a language
Results video?
2
4
I think only gertv that doesn't seem to have seen the results
but they haven't been active for a month or so
I have now seen the full results, congrats to the winners! I really hope ||I do better the next time lol||
should've taken the time to implement that cancellation thing instead of just dropping the depth of the negamax right before submission to keep the movegen under 5s
i was quite chuffed with how @normal latch and i handled that
that was mostly you tbf :)
hayleigh writes very pretty gleam, who'd have guessed it
Hey folks, the results data has been released to https://github.com/isaacharrisholt/gleam-chess-tournament. It's mostly in the runner/results directory
https://lichess.org/study/JtPXneJl
https://lichess.org/study/WuqsG7xv
https://lichess.org/study/57j0DCZ2
https://lichess.org/study/KcnzI0qO
https://lichess.org/study/aRqa2TsQ
https://lichess.org/study/18kSo9Pu
https://lichess.org/study/12UBOwuC
https://lichess.org/study/KnfdfS77
https://lichess.org/study/ksLru20a
https://lichess.org/study/yOIC7FHC
https://lichess.org/study/CtYgWbco
https://lichess.org/study/ynFHadzB
https://lichess.org/study/SUskhgpZ
https://lichess.org/study/02UCDg7a
https://lichess.org/study/yq1To6IN
https://lichess.org/study/3htWWuum
https://lichess.org/study/kIEEObgj
https://lichess.org/study/DeK3ftsg
https://lichess.org/study/SmZwPmSJ
https://lichess.org/study/nDKlIMNc
https://lichess.org/study/qd5dRhWH
I uploaded the round robin games to lichess studies
Lmk if you want me to link your directly, it's kinda hard to show a bunch of games from studies like this
Each study is each pair of bots
Hey folks, the tournament winners should now have CodeCrafters memberships! Make good use of them!
cc. @fluid venture @eternal basalt @formal fiber @grand lodge @normal latch @twin crag
congrats to the victors π
Awesome! Enjoy