kekavigi.xyz

Membuat Database Posisi Catur

Andai ada program yang memungkinkan saya mendapatkan info suatu posisi catur, seperti analisis skor oleh mesin-mesin, distribusi balasan berdasarkan rentang Elo, dll. Kenapa saya tidak melihat orang membuatnya? Harusnya ini mudah kan?

Ditulis tanggal oleh A. Keyka Vigiliant. Konten diterbitkan dibawah lisensi CC BY-SA 4.0.


Di awal tahun ini, saya mencoba membuat lebih banyak tulisan untuk blog. Ini adalah salah satu bentuk tulisan yang saya coba: log dalam mengembangkan suatu program/proyek. Karena kurang pandai dalam mencetuskan nama/istilah, saya namakan ini Log Pengembang, "LogP" singkatnya. Di dalamnya saya akan membuat catatan mingguan/bulanan perkembangan suatu program: apapun yang telah dikerjakan, beberapa masalah yang sedang terjadi, dan rencana kedepannya.

Proyek yang sekarang saya kembangkan adalah chess-db. Ini adalah program yang memungkinkan kita mencari posisi catur, dan mendapatkan informasi seperti: analisis skornya (menurut Stockfish, Leela, Komodo, dll.); analisis WDL (Win/Draw/Lose) dan realitanya; distribusi balasan setiap pemain, dikelompokkan berdasarkan rentang Elo mereka; dan lain sebagainya. Di satu sisi, ini kurang-lebih sama seperti halaman analisis-nya Lichess maupun Chess.com. Namun, saya ingin sesuatu yang sedikit berbeda: program ini bisa dipasang di laptop maupun peladen (server). Program dapat memperbarui hasil analisis yang sudah usang. Juga, orang dapat mengirimkan info ke program, seperti hasil analisis mesin dan hasil permainan seseorang.

Program seperti itu akan sangat keren. Malangnya, semakin hari saya semakin menyadari sulitnya membuat program seperti itu: apa sistem basis data yang bagus? bagaimana cara mengatasi serangan Sybil? bagaimana cara membuat kenyataan skor Elo pemain di setiap tempat hampir pasti berbeda, menjadi masuk akal? Mungkin saya tidak berhasil menjawab itu, atau malah mengubah tujuan akhir dari proyek. Saya tidak berkeberatan, karena salah satu tujuan utama mengerjakan proyek ini adalah untuk belajar menerapkan Python dan SQL.

Versi 0.0.1

Proyek ini dimulai bulan Oktober 2024. Berikut beberapa hal yang saya gunakan, dan alasannya:

Pengalaman yang menyenangkan, sampai belajar membuat TRIGGER dan WAL. Namun, saya akhirnya menyadari lebih banyak waktu digunakan untuk "mempersiapkan" proyek ketimbang mengerjakannya. Proses migrasi basis data yang melelahkan: "uhm… dimana saja ini digunakan?" Penerapan MVC yang berantakan karena banyak membuat "jalan pintas". Di samping itu, saya akhirnya juga menyadari lamanya proses analisis, dan pertumbuhan basis data yang eksponensial (terhadap fullmove dari posisi catur).

Sepertinya SQLAlchemy memang lebih baik. Lagipula, ada kemungkinan saya nantinya mengubah SQLite ke Postgres; dan saya tidak mau merombak banyak hal ketika masa itu datang. Ada baiknya saya juga belajar framework selain Flask; FastAPI terlihat cocok.

Versi 0.0.2

Pengembangan versi ini dimulai pada awal Januari 2025. Sebagian besar pekerjaan adalah mengubah kode agar menggunakan FastAPI dan SQLModel (suatu wrapper untuk SQLAlchemy). Membuat fungsi logging sederhana yang menyimpan semua traceback suatu Exception ke berkas JSON (tetapi belum diintegrasikan dengan modul standar logging). Membuat dokumentasi terasa lebih mudah dan alami. Test menjadi lebih sederhana.

Saya juga mengembangkan cara untuk memproses dump evaluasi posisi dari Lichess (ukuran uncompressed 47GB), sampai menyesuaikan struktur basis data agar dapat langsung menerima ekstraksi dari data dump. Sialnya, setelah menghabiskan waktu mengoptimasi kode -- seperti menggunakan bulk insert, hanya memproses evaluasi yang baru/berbeda, sampai menggunakan banyak PRAGMA sampai PRAGMA optimize -- saya baru menyadari data tersebut tidak dapat digunakan. Data evaluasi yang Lichess gunakan merupakan agregat dari banyak varian catur (meliputi Atomic dan King of the Hill). Untuk sebarang FEN, mustahil menentukan evaluasi mana yang bersesuaian dengan varian catur standar.

Walaupun cukup rugi cara ini tidak dapat dilanjutkan, saya senang berhasil mengoptimasi proses ekstraksi dump, dari awalnya sekitar 60 iterasi/detik menjadi sekitar 200 iterasi/detik. Saya juga menyaksikan batas dari kemampuan SQLite. Agar lebih yakin, saya ingin mencoba mengakses SQLite secara async dengan aiosqlite. Untungnya, Lichess juga menyediakan versi API dari dump, yang memungkinkan saya menentukan varian catur untuk "dievaluasi." Juga ada beberapa endpoint lain yang mungkin berguna; waktunya scraping. Oh, juga perbaiki kode analisis, di worker.py, siapa tahu nanti dapat dijalankan di Google Colab.

Versi 0.0.3

Dalam pengembangan