<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nicholas</title>
    <description>The latest articles on DEV Community by Nicholas (@eren_poger).</description>
    <link>https://dev.to/eren_poger</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3993828%2Fc19a7c67-2e75-4dc0-85ea-b43cde21a54e.jpg</url>
      <title>DEV Community: Nicholas</title>
      <link>https://dev.to/eren_poger</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/eren_poger"/>
    <language>en</language>
    <item>
      <title>Building a Chess Engine &amp; Book Scraper - Part 4: Capping the Catalog &amp; 4,500+ Games Cooked</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Sat, 18 Jul 2026 15:45:38 +0000</pubDate>
      <link>https://dev.to/eren_poger/building-a-chess-engine-book-scraper-part-4-capping-the-catalog-4500-games-cooked-462k</link>
      <guid>https://dev.to/eren_poger/building-a-chess-engine-book-scraper-part-4-capping-the-catalog-4500-games-cooked-462k</guid>
      <description>&lt;h2&gt;
  
  
  "The data pipeline is perfectly stable, the automation is running smoothly, but I'm not pushing these changes to GitHub yet." 😅
&lt;/h2&gt;

&lt;p&gt;Hey guys ;)&lt;br&gt;&lt;br&gt;
I’m a bit tired after this week's data marathon, so I'll let the numbers and the architecture do the talking today. &lt;/p&gt;

&lt;p&gt;Over the last seven days, my workstation has been split into two universes: generating high-quality training datasets for my chess AI on a strict daily quota, and building a scalable market analysis tool for the book industry. &lt;/p&gt;

&lt;p&gt;Here is the weekly recap, some crucial optimizations, and the roadmap ahead.&lt;/p&gt;


&lt;h3&gt;
  
  
  ♟️ Chess Database: 4,500+ Games Cooked
&lt;/h3&gt;

&lt;p&gt;The automated parallel self-play setup I described in my previous post is performing beautifully. My hardware survived the daily quota of 716 games per day. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Weekly Total:&lt;/strong&gt; 6 * 716 games + 260 baseline test games = 4,556 games successfully generated and saved into the local database. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The dataset is expanding exactly as planned, laying down a bulletproof foundation before I open the Jira backlog for the Reinforcement Learning model training phase.&lt;/p&gt;


&lt;h3&gt;
  
  
  📖 The Book Scraper: Smart Capping &amp;amp; Strategy
&lt;/h3&gt;

&lt;p&gt;While the chess engine runs its daily simulations, I’ve been heavily focusing on my new target platform: &lt;strong&gt;Yakaboo&lt;/strong&gt; (the largest book platform in Ukraine). The platform contains &lt;strong&gt;16 distinct main categories&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Initially, I went deep and scraped over 410 pages for the Fiction category alone. But looking at the data, I realized I needed to optimize my traversal mechanics. I decided to introduce a strict limit: &lt;strong&gt;a maximum of 200 pages per category.&lt;/strong&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Why cap the dataset at 200 pages? 🤔
&lt;/h4&gt;

&lt;p&gt;Online retail storefronts naturally sort their catalog by popularity, search volume, and sales velocity on the initial pages. The deeper you go into page 300+, the higher the density of out-of-print titles, placeholders, or niche products. Scraping thousands of deep pages won't help us identify active consumer trends-it just adds unnecessary noise and processing bloat to the database.&lt;/p&gt;

&lt;p&gt;Here is a sneak peek of how the raw item structure looks right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    {
        "title": "Generations in the World of Work",
        "author": "Корі Сіміллер",
        "price": "2947 грн",
        "rating": "0",
        "reviews": "0",
        "status": "Фізична книга",
        "href": "https://www.yakaboo.ua/ua/generations-in-the-world-of-work.html"
    },
    {
        "title": "Paralegal Career For Dummies",
        "author": "Ліза Зіммер Хатч",
        "price": "1832 грн",
        "rating": "0",
        "reviews": "0",
        "status": "Фізична книга",
        "href": "https://www.yakaboo.ua/ua/paralegal-career-for-dummies-3295617.html"
    },
    {
        "title": "Performance Appraisals &amp;amp; Phrases For Dummies",
        "author": "Кен Ллойд",
        "price": "1513 грн",
        "rating": "0",
        "reviews": "0",
        "status": "Фізична книга",
        "href": "https://www.yakaboo.ua/ua/performance-appraisals-phrases-for-dummies.html"
    },
    {
        "title": "A Pluralistic Approach to Leadership: Interdisciplinary Perspectives",
        "author": "Натан В. Хартер",
        "price": "3982 грн",
        "rating": "0",
        "reviews": "0",
        "status": "Фізична книга",
        "href": "https://www.yakaboo.ua/ua/a-pluralistic-approach-to-leadership-interdisciplinary-perspectives.html"
    },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And of course some screenshots&lt;/p&gt;

&lt;p&gt;It's a chess database fragment. Yep some games is short, and some is more then 100 moves.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3i0rq4m3qewxeoi1qp2g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3i0rq4m3qewxeoi1qp2g.png" alt="Chess database fragment" width="799" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I parsed Yakaboo for 3 days and already parsed almost 23MB of data.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fil3pkbgqp3jbxyyqy9sg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fil3pkbgqp3jbxyyqy9sg.png" alt="Size of parsed data" width="768" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My laptop straggling to parse data while I'm writing posts.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23duyqb7y05cynmwiysm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F23duyqb7y05cynmwiysm.png" alt="Btop when I run my parser script" width="800" height="806"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And what I see as a progress. Of course I could just open Chrome and watch how pages scrolling.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwe9754arnvfcpzo34qn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frwe9754arnvfcpzo34qn.png" alt="Console logs with parsing progress" width="799" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Chess Engine in Python - Part 3: Letting the DB Cook &amp; Launching a New Book Market Scraper</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Thu, 16 Jul 2026 11:29:29 +0000</pubDate>
      <link>https://dev.to/eren_poger/building-a-chess-engine-in-python-part-3-letting-the-db-cook-launching-a-new-book-market-5e42</link>
      <guid>https://dev.to/eren_poger/building-a-chess-engine-in-python-part-3-letting-the-db-cook-launching-a-new-book-market-5e42</guid>
      <description>&lt;h2&gt;
  
  
  "What do you do when your laptop is too weak to train a neural network and run game simulations at the same time? I'm letting the database cook, and starting a new small project."
&lt;/h2&gt;

&lt;p&gt;Hey guys ;)&lt;br&gt;&lt;br&gt;
Sorry for being a bit late with this update, but I promise I have some very exciting news. &lt;/p&gt;

&lt;p&gt;Right now, my main Chess Project is entering a transition phase. To train a proper Reinforcement Learning model, I need a massive, high-quality dataset of self-play games. But running heavy simulations and coding at the same time is a heavy burden for my hardware. &lt;/p&gt;

&lt;p&gt;So, I made a strategic decision: &lt;strong&gt;take a 2-week development break to generate the database, while kicking off a brand new Data Science project on the side.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here is what's happening on both fronts!&lt;/p&gt;




&lt;h3&gt;
  
  
  ♟️ Chess Project: The Daily Generation Quota
&lt;/h3&gt;

&lt;p&gt;To keep my laptop healthy while still building a solid dataset, I’ve set up a strict automated daily schedule. From now until &lt;strong&gt;July 27th&lt;/strong&gt;, I am running my parallelized self-play script with a specific daily quota:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;716 games per day&lt;/strong&gt; in total (distributed as 358 games per active CPU core).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The depth distribution:&lt;/strong&gt; 300 games at depth 2, 55 games at depth 3, and 3 games at depth 4.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Even this "limited" run takes about &lt;strong&gt;2 hours and 30 minutes&lt;/strong&gt; every single day. Once the database reaches its target size on July 27th, I will officially close the generation phase and jump straight into the model training backlog, which is already fully planned and ready in my Jira!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6f99mewc1ufii45el7b9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6f99mewc1ufii45el7b9.png" alt="Screenshot of Jira Board for RL sprint" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  📖 New Project: Analyzing the Book Industry
&lt;/h3&gt;

&lt;p&gt;While the chess script is running in the background, I decided to tackle a question that has been on my mind for a while: &lt;strong&gt;Are people actually reading fewer books nowadays?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To answer this with cold, hard data, I decided to build a custom web scraper to gather, clean, and analyze retail book market trends. &lt;/p&gt;

&lt;h4&gt;
  
  
  The Pivot: From Amazon to Yakaboo
&lt;/h4&gt;

&lt;p&gt;Initially, my first target was &lt;strong&gt;Amazon&lt;/strong&gt;. However, I quickly ran into two major roadblocks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Aggressive Anti-Bot Protection:&lt;/strong&gt; Amazon does &lt;em&gt;not&lt;/em&gt; like scrapers, making automated extraction highly inefficient without expensive proxy setups. Yep I parsed some book data from Amazon via undetected-chromedriver, but there is second problem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Limitations:&lt;/strong&gt; The accessible, free-tier product details were too sparse for the deep analysis I wanted to conduct. To compare on Yakaboo there is a books cards with title, author, rating and count of reviews, of course price. So for my analysis I only need to get amount of pages(for example via GoogleBooks API or just right from Yakaboo details page) and interest in certain book(I'm planning to get it via Google Trends)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, I pivoted! My new target is &lt;strong&gt;Yakaboo&lt;/strong&gt;, the largest online book platform in Ukraine. It has incredibly rich metadata regarding which is exactly what I need. And of course their web source code is pretty easier to read.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe8i2ozi0hlflnokxd6yd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fe8i2ozi0hlflnokxd6yd.png" alt="Yakaboo fiction page" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m currently writing the automation scripts combining &lt;strong&gt;Selenium&lt;/strong&gt; and &lt;strong&gt;BeautifulSoup&lt;/strong&gt; to handle paginated lists and extract the raw dataset.&lt;/p&gt;




&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;For the next two weeks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;My CPU will be sweating to generate those 716 chess games daily.&lt;/li&gt;
&lt;li&gt;I will be finalizing the Yakaboo parser, cleaning the scraped book data, and preparing my first analytical dashboard.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I’m super excited to share actual data insights about what people are reading (and buying) in one of the next post!&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you ever had to pause a heavy computational task to prevent your machine from melting? What’s your go-to tool for bypassing anti-bot systems? Let’s share some stories in the comments!&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#python&lt;/code&gt; &lt;code&gt;#datascience&lt;/code&gt; &lt;code&gt;#webscraping&lt;/code&gt; &lt;code&gt;#chess&lt;/code&gt; &lt;code&gt;#showdev&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Chess Engine in Python - Part 2: Achieving 100% Correctness &amp; Setting Up Multicore Self-Play</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Sat, 11 Jul 2026 18:18:27 +0000</pubDate>
      <link>https://dev.to/eren_poger/building-a-chess-engine-in-python-part-2-achieving-100-correctness-setting-up-multicore-4bo1</link>
      <guid>https://dev.to/eren_poger/building-a-chess-engine-in-python-part-2-achieving-100-correctness-setting-up-multicore-4bo1</guid>
      <description>&lt;h2&gt;
  
  
  It’s PEAK.
&lt;/h2&gt;

&lt;p&gt;Hey guys ;)&lt;/p&gt;

&lt;p&gt;Since my last post, I’ve done a massive amount of under-the-hood work. Honestly, writing the code this time felt surprisingly smooth, but the results are a huge milestone for the project: I built a performance/correctness tester, implemented a parallelized self-play system using multiple CPU cores, and hooked it up to a database. &lt;/p&gt;

&lt;p&gt;We are officially at the doorstep of Reinforcement Learning. Let’s break down how it all came together.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Heartbreak (and Triumph) of Perft Testing
&lt;/h3&gt;

&lt;p&gt;In my previous update, I mentioned that I was moving toward &lt;strong&gt;Perft (Performance Test)&lt;/strong&gt; to verify the engine's correctness. A Perft test recursively walks the move tree to a specific depth, counts all total leaf nodes, and compares that number to standard chess data. &lt;/p&gt;

&lt;p&gt;When I ran my first test to depth 3 and 4, my numbers were lower than the official benchmarks on &lt;code&gt;chessprogramming.org&lt;/code&gt;. I'm not going to lie - I was really sad. After days of wrestling with bitwise masks, realizing your engine is missing thousands of moves feels brutal. &lt;/p&gt;

&lt;p&gt;But instead of giving up, I used the test to isolate the discrepancies. It turned out the missing paths weren't deep architectural flaws, but rather sneaky edge cases in pawn logic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The En Passant Ghost:&lt;/strong&gt; A bug where specific en passant capture rights weren't being cleared or generated correctly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Out of Index Crash:&lt;/strong&gt; A rare boundary issue when pawns reached the absolute edges of the board during specific masking checks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once those pawn bugs were squashed, I ran the numbers again. &lt;strong&gt;Success!&lt;/strong&gt; The engine officially proves its 100% mathematical correctness up to depth 4 across multiple complex custom test positions. &lt;/p&gt;




&lt;h3&gt;
  
  
  Multicore Self-Play &amp;amp; Epsilon-Greedy Exploration
&lt;/h3&gt;

&lt;p&gt;With a bulletproof bitboard engine, the next challenge was generating data for our future Reinforcement Learning (RL) agent. To train a model, you need games—thousands of them. &lt;/p&gt;

&lt;p&gt;To achieve this, I implemented a &lt;strong&gt;Self-Play system&lt;/strong&gt;. Here is how the architecture works right now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Epsilon-Greedy Minimax:&lt;/strong&gt; I modified my classic Minimax algorithm into an &lt;em&gt;epsilon-greedy&lt;/em&gt; version. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Opening Imitation:&lt;/strong&gt; To prevent the engine from playing the exact same game over and over, the first 4 moves of every match are completely random. This effectively imitates traditional chess openings and forces the engine to explore a massive variety of board states.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multicore Scaling:&lt;/strong&gt; Running games sequentially takes ages. I utilized Python's multiprocessing features to distribute the self-play simulation across multiple CPU cores simultaneously.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Storage:&lt;/strong&gt; Every single generated game, position, evaluated score, and move state is now being piped and safely recorded into a local database. &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Next Stop: Reinforcement Learning
&lt;/h3&gt;

&lt;p&gt;The infrastructure is ready. The engine is fast, verified as correct, scales across my CPU, and logs clean training data directly to a DB. &lt;/p&gt;

&lt;p&gt;The next station is implementing and training the actual RL models. This is where the real experiment begins.&lt;/p&gt;




&lt;p&gt;&lt;code&gt;#python&lt;/code&gt; &lt;code&gt;#chess&lt;/code&gt; &lt;code&gt;#performance&lt;/code&gt; &lt;code&gt;#multiprocessing&lt;/code&gt; &lt;code&gt;#showdev&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a Chess Engine in Python - Part 1: The Immortal King &amp; Bitboard Grid Synchronization</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Wed, 08 Jul 2026 15:40:12 +0000</pubDate>
      <link>https://dev.to/eren_poger/building-a-chess-engine-in-python-part-1-the-immortal-king-bitboard-grid-synchronization-1ong</link>
      <guid>https://dev.to/eren_poger/building-a-chess-engine-in-python-part-1-the-immortal-king-bitboard-grid-synchronization-1ong</guid>
      <description>&lt;h2&gt;
  
  
  "I spent days writing logic masks, only to realize my Chess King became an immortal god who could capture the opposing King."
&lt;/h2&gt;

&lt;p&gt;Connecting a classic &lt;code&gt;8x8&lt;/code&gt; Pygame matrix UI to a new, high-performance bitboard engine felt like a great idea until the synchronization bugs started crawling out. Over the last few days, I've been hunting down some of the most hilarious and stubborn logical errors I've encountered so far. &lt;/p&gt;

&lt;p&gt;Let's dive into what went wrong and how I fixed it.&lt;/p&gt;




&lt;h3&gt;
  
  
  1. The Mirror Dimension (&lt;code&gt;[row]&lt;/code&gt; vs &lt;code&gt;[7 - row]&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;After building the adapter bridge, the standard pieces moved fine, but two visual elements broke entirely: &lt;strong&gt;move history highlights&lt;/strong&gt; and &lt;strong&gt;available move hint dots&lt;/strong&gt;. They were rendering perfectly on the wrong side of the board.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Cause:&lt;/strong&gt; A classic coordinate mapping issue. While matrices count rows from top to bottom (0 to 7), bitboards index squares from bottom to top. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; The engine was fetching the raw matrix row. Adjusting the coordinate transformation to &lt;code&gt;[7 - row]&lt;/code&gt; instantly brought both worlds into perfect harmony.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. The Absolute Monarch Bug (King vs. King)
&lt;/h3&gt;

&lt;p&gt;The funniest logical flaw happened during checkmate testing. The King under attack refused to lose. He would block the enemy slider's ray of attack with his own body, consider the squares behind him "safe," and happily wander around until he was literally pinned to the edge of the board. Even worse: kings could stand on adjacent squares and &lt;em&gt;capture each other&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Cause:&lt;/strong&gt; The King was accidentally included in the blocking occupancy masks while generating specific check masks. He was effectively shading himself from the attack rays.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Fix:&lt;/strong&gt; Excluded the King's square from the ray-blocking lookup so that attacks correctly pass through his position during validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2074877950629953802-990" src="https://platform.twitter.com/embed/Tweet.html?id=2074877950629953802"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2074877950629953802-990');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2074877950629953802&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Missing Check Restrictions (Code Refactor)
&lt;/h3&gt;

&lt;p&gt;Another major flaw allowed other pieces (like knights, queens, and bishops) to make random moves even when the King was actively under check. The &lt;code&gt;check_mask&lt;/code&gt; generation logic was breaking down when dealing with sliders.&lt;/p&gt;

&lt;p&gt;Here is how the calculation evolved:&lt;/p&gt;

&lt;h4&gt;
  
  
  How it looked before:
&lt;/h4&gt;

&lt;h1&gt;
  
  
  The mask didn't differentiate piece types, leading to broken lookup tables
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elif count == 1:
    self.in_check_flag = True
    checker_square = check_ers.bit_length() - 1
    checker_bit = 1 &amp;lt;&amp;lt; checker_square
    check_mask = ray_from_king &amp;amp; ray_from_checker | checker_bit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How it looks now (Working Version):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;elif count == 1:
    self.in_check_flag = True
    checker_square = check_ers.bit_length() - 1
    checker_bit = 1 &amp;lt;&amp;lt; checker_square
    if checker_bit &amp;amp; (enemy_knight | enemy_pawns):
        check_mask = checker_bit
    else:
        # Properly determining slider type and intersection masks
        is_rook_type = ((checker_bit &amp;amp; enemy_rooks) or (checker_bit &amp;amp; enemy_queen)) and ((king_square // 8 == checker_square // 8) or (king_square % 8 == checker_square % 8))
        if is_rook_type:
            ray_from_king = self.attack_tables.get_rook_attacks(king_square, all_occ)
            ray_from_checker = self.attack_tables.get_rook_attacks(checker_square, all_occ)
        else:
            ray_from_king = self.attack_tables.get_bishop_attacks(king_square, all_occ)
            ray_from_checker = self.attack_tables.get_bishop_attacks(checker_square, all_occ)
        check_mask = ray_from_king &amp;amp; ray_from_checker | checker_bit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By explicitly checking if the attacking piece is a knight/pawn versus a sliding piece (rook/bishop/queen) and calculating the intersecting ray paths properly, all non-evasion moves are now correctly blocked during a check state.&lt;/p&gt;

&lt;p&gt;Minor Fixes &amp;amp; Quality of Life&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Pawn Promotion Crash: The matrix engine identified objects as strings ("w_pawn"), while the bitboard engine uses character notation ("P", "Q", "b"). Added a quick mapper to prevent token crashes during promotion.&lt;/li&gt;
&lt;li&gt;    Draw States: Implemented proper engine detection for Threefold Repetition and Insufficient Material (e.g., King vs King + Knight) to ensure matches can actually end legally.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's Next? (Proof of Correctness)&lt;/p&gt;

&lt;p&gt;Now that the visual bugs are squashed, I need to make sure the math is 100% accurate. My next milestones in Jira are setting up a Perft (Performance Test) function. It will recursively walk the move tree to a specific depth, count the total leaf nodes, and cross-reference them with official chess move datasets to catch any hidden logical edge cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1b7a5efvdwc5blik2gy8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1b7a5efvdwc5blik2gy8.png" alt="Tasks in Jira" width="577" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Have you ever had a bug where your game pieces completely ignored the laws of physics or rules? Let’s talk about your favorite debugging horror stories in the comments!&lt;/p&gt;

&lt;h1&gt;
  
  
  python #chess #debugging #showdev
&lt;/h1&gt;

</description>
    </item>
    <item>
      <title>Chess Project X is Working Again... But With Some Hilarious Bugs!</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Sat, 04 Jul 2026 13:27:18 +0000</pubDate>
      <link>https://dev.to/eren_poger/chess-project-x-is-working-again-but-with-some-hilarious-bugs-31i7</link>
      <guid>https://dev.to/eren_poger/chess-project-x-is-working-again-but-with-some-hilarious-bugs-31i7</guid>
      <description>&lt;h2&gt;
  
  
  Hey guys ;)
&lt;/h2&gt;

&lt;p&gt;I’m so glad that from this milestone forward, I can finally share not just lines of code, but actual gameplay footage and visual progress. But let’s take it one step at a time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rewriting the Core &amp;amp; Fighting IDE Autocomplete
&lt;/h3&gt;

&lt;p&gt;After finishing the bitboard engine backend, I duplicated my core architecture files to keep a backup. I started by rewriting the main controller file responsible for game logic and move generation. &lt;br&gt;
Right away, I hit my first roadblock: the new bitboard engine lacked game state tracking variables, so I had to refactor and add state arguments directly to the &lt;code&gt;BitboardEngine&lt;/code&gt; class. &lt;br&gt;
Once that was done, I moved on to the renderer. After adapting all the UI rendering logic to read bitmasks instead of a matrix grid, I hit "Run" with high hopes.&lt;/p&gt;

&lt;p&gt;Guess what? Instead of a beautiful chess UI, I was greeted by a wall of terminal errors. 😅 &lt;br&gt;
One of the funniest bugs was caused by my IDE's autocomplete. It generated &lt;code&gt;move.Move()&lt;/code&gt; even though the &lt;code&gt;Move&lt;/code&gt; class was located in the exact same file. I didn't even notice it until python crashed during execution. &lt;/p&gt;
&lt;h3&gt;
  
  
  The Invasion of the White Pawns &amp;amp; Regicide
&lt;/h3&gt;

&lt;p&gt;After about 30 minutes of polishing micro-bugs, the Pygame window finally opened! I clicked the "Play" button, fixed a few more runtime errors, and could finally move pieces around. &lt;/p&gt;

&lt;p&gt;However, the game state is currently a beautiful mess:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The Pawn Uprising:&lt;/strong&gt; Due to a string formatting bug in the asset loader, &lt;em&gt;every single piece on the board rendered as a white pawn&lt;/em&gt;. Funnily enough, they still moved according to their actual hidden piece types (e.g., a "pawn" sliding across the board like a rook).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;King-on-King Violence:&lt;/strong&gt; I forgot to properly include the king in certain restriction masks. As a result, the King could happily walk into check, stand directly next to the opposing king, and even &lt;em&gt;capture&lt;/em&gt; the enemy king straight off the board. Talk about aggressive diplomacy.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;I also need to tweak the promotion logic because there’s currently an issue with argument parsing between the frontend and the new backend. &lt;br&gt;
On Monday, I'll begin a massive bug-hunting session to stabilize special moves (en passant, castling, promotions) and ensure total state synchronization. Once the board state is bulletproof, the environment will be fully ready for Reinforcement Learning training.&lt;br&gt;
I've attached a video of this chaotic gameplay below. I hope you find it entertaining!&lt;/p&gt;



&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-2073396164523626861-786" src="https://platform.twitter.com/embed/Tweet.html?id=2073396164523626861"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2073396164523626861-786');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2073396164523626861&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What’s the funniest visual bug you’ve ever encountered during a major code refactor?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0lu67ovr2vl7hn7g07x7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0lu67ovr2vl7hn7g07x7.jpg" alt=" " width="800" height="434"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqnekzh4zpg0owfleympw.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqnekzh4zpg0owfleympw.jpg" alt=" " width="799" height="432"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu2tyj21ttsk8u5s09s9k.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu2tyj21ttsk8u5s09s9k.jpg" alt=" " width="799" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#python&lt;/code&gt; &lt;code&gt;#pygame&lt;/code&gt; &lt;code&gt;#gamedev&lt;/code&gt; &lt;code&gt;#debugging&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Ended Bitboard engine, what's next?</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Tue, 30 Jun 2026 21:16:27 +0000</pubDate>
      <link>https://dev.to/eren_poger/ended-bitboard-engine-whats-next-3dmp</link>
      <guid>https://dev.to/eren_poger/ended-bitboard-engine-whats-next-3dmp</guid>
      <description>&lt;h2&gt;
  
  
  Hey guys ;)
&lt;/h2&gt;

&lt;p&gt;Today I finally finished my bitboard engine! Let me take you through its architecture, and then we'll explore the next steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Core Architecture
&lt;/h3&gt;

&lt;p&gt;All the engine logic lives in &lt;code&gt;bitboard_engine.py&lt;/code&gt;, which contains the &lt;code&gt;Move&lt;/code&gt; and &lt;code&gt;BitboardEngine&lt;/code&gt; classes. However, for everything to sync up, we rely on a few other modules: &lt;code&gt;board.py&lt;/code&gt; (with the &lt;code&gt;Board&lt;/code&gt; class), &lt;code&gt;move_gen.py&lt;/code&gt; (with &lt;code&gt;AttackTables&lt;/code&gt;), and &lt;code&gt;bitboard_utils.py&lt;/code&gt; (housing &lt;code&gt;BitboardConstants&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Here is a breakdown of what each component does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BitboardConstants:&lt;/strong&gt; Contains static methods for fundamental bitwise operations like setting, popping, or getting a bit (&lt;code&gt;set_bit&lt;/code&gt;, &lt;code&gt;pop_bit&lt;/code&gt;, &lt;code&gt;get_bit&lt;/code&gt;), along with constant masks for the board edges (like the A/H files or ranks 1/8).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Board:&lt;/strong&gt; Implements the state of all pieces on the board, handles the initial setup, and tracks tracking piece movements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AttackTables:&lt;/strong&gt; Pre-computes static attack tables for knights and kings, and builds sliding attack tables for rooks, bishops, and queens using &lt;strong&gt;magic numbers&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Move:&lt;/strong&gt; Describes individual moves, storing data like &lt;code&gt;piece_moved&lt;/code&gt;, &lt;code&gt;piece_captured&lt;/code&gt;, and flags for special moves (&lt;code&gt;is_enpassant&lt;/code&gt;, &lt;code&gt;is_castling&lt;/code&gt;, &lt;code&gt;is_promotion&lt;/code&gt;). It also handles dictionaries for correct chess notation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Heart of the Engine
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;BitboardEngine&lt;/code&gt; is where all these components unite. The core functionality is split into two types of functions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Move Generation:&lt;/strong&gt; The &lt;code&gt;get_valid_moves&lt;/code&gt; function generates legal moves using complex bitwise masking (check masks, pin masks, enemy attack masks, and edge masks). &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Management:&lt;/strong&gt; Functions responsible for tracking the game state (like checkmate or draws) and preparing data for the future RL model.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Honestly, this was one of the hardest parts of the project due to the sheer amount of math and theory involved, but the performance payoff compared to the matrix engine will be massive.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's Next?
&lt;/h3&gt;

&lt;p&gt;Next, I’m going to write two "bridge" functions to map bitboard indices back to the matrix format for the UI. After that, it’s time for rigorous testing. To be honest, I won't rest easy until I test it thoroughly—especially regarding special moves and check detection states. &lt;br&gt;
Once the tests pass, the Reinforcement Learning phase officially begins! &lt;/p&gt;




&lt;p&gt;&lt;em&gt;Thanks for reading! If you have any questions or suggestions about magic numbers or bitboard optimization, let's chat in the comments below!&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9a9729ikmd1hjuj83vjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9a9729ikmd1hjuj83vjr.png" alt=" " width="800" height="483"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhgzg3jakw9am30752wmt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhgzg3jakw9am30752wmt.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffigok5lxouajv8e2avvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ffigok5lxouajv8e2avvp.png" alt=" " width="799" height="427"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ymjikv8ve1f39g1qfgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6ymjikv8ve1f39g1qfgy.png" alt=" " width="800" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#python&lt;/code&gt; &lt;code&gt;#chess&lt;/code&gt; &lt;code&gt;#bitboards&lt;/code&gt; &lt;code&gt;#showdev&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>My first post</title>
      <dc:creator>Nicholas</dc:creator>
      <pubDate>Sat, 27 Jun 2026 19:42:20 +0000</pubDate>
      <link>https://dev.to/eren_poger/my-first-post-4hdl</link>
      <guid>https://dev.to/eren_poger/my-first-post-4hdl</guid>
      <description>&lt;h2&gt;
  
  
  Hey everyone, it’s my first post here ;)
&lt;/h2&gt;

&lt;p&gt;Today I want to show you the project I’m currently working on. It’s &lt;strong&gt;Chess Project X&lt;/strong&gt; (available as &lt;code&gt;chess-project&lt;/code&gt; on GitHub). The development is divided into two main milestones.&lt;/p&gt;

&lt;h3&gt;
  
  
  Milestone 1: The Matrix Engine &amp;amp; UI
&lt;/h3&gt;

&lt;p&gt;The first step was creating a basic chess engine from scratch along with a graphical interface. I built the initial core using matrix logic in pure Python and used the &lt;strong&gt;Pygame&lt;/strong&gt; library for the UI. It includes all the neat features I personally enjoy on Chess.com: analysis arrows, highlighted squares, visual move hints, and even the native sound effects. &lt;br&gt;
For the AI at this stage, I implemented a classic &lt;strong&gt;Minimax algorithm with Alpha-Beta pruning&lt;/strong&gt; running at a maximum depth of 4.&lt;br&gt;
Check video of gameplay on X:&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-2046898283264495656-673" src="https://platform.twitter.com/embed/Tweet.html?id=2046898283264495656"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-2046898283264495656-673');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=2046898283264495656&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h3&gt;
  
  
  Milestone 2: Transitioning to Bitboards &amp;amp; RL
&lt;/h3&gt;

&lt;p&gt;The ultimate goal is to implement a Reinforcement Learning (RL) agent. Doing this on top of a matrix-based engine would be heavily bottlenecked by performance, so I decided to rewrite the entire engine using &lt;strong&gt;bitboards&lt;/strong&gt;. &lt;br&gt;
&lt;strong&gt;Current state of the rewrite:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Implemented a new &lt;code&gt;Board&lt;/code&gt; class.&lt;/li&gt;
&lt;li&gt;Wrote basic bitwise utility functions (&lt;code&gt;set_bit&lt;/code&gt;, &lt;code&gt;get_bit&lt;/code&gt;, &lt;code&gt;pop_bit&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Generated pre-computed attack masks for every piece type.
For the last two days, I’ve been heavily focused on the move validation logic. There are two ways to find legal moves:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Matrix Way:&lt;/strong&gt; Execute &lt;code&gt;make_move&lt;/code&gt;, check if the king is under attack, and then &lt;code&gt;undo_move&lt;/code&gt;. It's easy to code but much slower.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Bitboard Way:&lt;/strong&gt; Generate all possible pin and check masks via bitwise operations. It's significantly harder to implement, but the performance payoff is massive.
Right now, I've finished the logic for the king and knights. Next up: rooks, bishops, queens, and pawns. Once done, I’ll hook it up to the Pygame UI, run tests, and finally start training the RL model!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;I hope you found this breakdown interesting! If you have any questions, tech suggestions, or ideas about bitboards, feel free to drop them in the comments below. See you in the next update!&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwhk9ocppmvlg6tric6wg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwhk9ocppmvlg6tric6wg.png" alt=" " width="800" height="205"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6s5b9fhmwp0aexldfxc7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6s5b9fhmwp0aexldfxc7.png" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F881m8pnf1z6qxre1yrxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F881m8pnf1z6qxre1yrxe.png" alt=" " width="799" height="427"&gt;&lt;/a&gt;&lt;br&gt;
&lt;code&gt;#python&lt;/code&gt; &lt;code&gt;#chess&lt;/code&gt; &lt;code&gt;#reinforcementlearning&lt;/code&gt; &lt;code&gt;#bitboards&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
