<?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: Tahmid Fayaz </title>
    <description>The latest articles on DEV Community by Tahmid Fayaz  (@tzinef).</description>
    <link>https://dev.to/tzinef</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3263585%2Fad6d989e-5afd-4a02-9db8-b622e8af8f84.png</url>
      <title>DEV Community: Tahmid Fayaz </title>
      <link>https://dev.to/tzinef</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tzinef"/>
    <language>en</language>
    <item>
      <title>Building an Abalone Game Using Amazon Q CLI &amp; Pygame</title>
      <dc:creator>Tahmid Fayaz </dc:creator>
      <pubDate>Fri, 13 Jun 2025 12:36:01 +0000</pubDate>
      <link>https://dev.to/tzinef/building-an-abalone-game-using-amazon-q-cli-pygame-1d42</link>
      <guid>https://dev.to/tzinef/building-an-abalone-game-using-amazon-q-cli-pygame-1d42</guid>
      <description>&lt;p&gt;🚀 &lt;strong&gt;Introduction&lt;/strong&gt;&lt;br&gt;
I’ve always been fascinated by board games that combine elegant mechanics with deep strategy, and Abalone is the perfect example. In this post, I’ll walk you through how I used the Amazon Q Developer CLI alongside Pygame to create my own digital version of Abalone—from scaffolding the project to polishing the UI.&lt;/p&gt;

&lt;p&gt;✨&lt;strong&gt;Amazon Q Developer CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To install the Amazon Q Developer CLI on my Windows machine, I first set up the Windows Subsystem for Linux (WSL). With a Linux distribution like Ubuntu installed, I open the WSL terminal to run the installer script using the command: curl -o- &lt;a href="https://s3.amazonaws.com/amazon-q-cli/install.sh" rel="noopener noreferrer"&gt;https://s3.amazonaws.com/amazon-q-cli/install.sh&lt;/a&gt; | bash. Once the installation is complete, I just need to restart my WSL terminal. After that, I'm all set to start using the q command.&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.amazonaws.com%2Fuploads%2Farticles%2Ffunyvxkpmw42z04d3a5i.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.amazonaws.com%2Fuploads%2Farticles%2Ffunyvxkpmw42z04d3a5i.jpg" alt="Image description" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites 🛠️&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we dive in, make sure you have:&lt;br&gt;
1.Python 3.7+ installed 🐍&lt;br&gt;
2.Pygame library (pip install pygame) 🎨&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Folder Structure 📂&lt;/strong&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.amazonaws.com%2Fuploads%2Farticles%2Fbq25fbh5speb47hkb793.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.amazonaws.com%2Fuploads%2Farticles%2Fbq25fbh5speb47hkb793.jpg" alt="Image description" width="218" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Initializing Pygame and Defining Constants 💡&lt;/strong&gt;&lt;br&gt;
In abalone_game.py, I start by importing modules and initializing Pygame:&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.amazonaws.com%2Fuploads%2Farticles%2Fvwi3r8kh92ajqaee33iy.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.amazonaws.com%2Fuploads%2Farticles%2Fvwi3r8kh92ajqaee33iy.png" alt="Image description" width="536" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, I define window dimensions, hexagon sizing, and colors for the board, marbles, and UI elements:&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.amazonaws.com%2Fuploads%2Farticles%2F9r50qdwb3yrkhqok48g5.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.amazonaws.com%2Fuploads%2Farticles%2F9r50qdwb3yrkhqok48g5.png" alt="Image description" width="528" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and so on &lt;/p&gt;

&lt;p&gt;These constants make it easy to tweak the look and feel of the board later. 🎨&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Representing Hexagonal Positions 🔢&lt;/strong&gt;&lt;br&gt;
Abalone uses a hex grid, so I created a HexPosition class that stores cube coordinates (q, r, s) and implements equality, hashing, and a string method:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Initializing the Board ⚙️&lt;/strong&gt;&lt;br&gt;
Inside the AbaloneGame class, I set up a dictionary self.board mapping every valid HexPosition (from r = -4 to 4 and appropriate q ranges) to an integer:&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.amazonaws.com%2Fuploads%2Farticles%2Fhr8eg5k3nq28o50tu7yv.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.amazonaws.com%2Fuploads%2Farticles%2Fhr8eg5k3nq28o50tu7yv.png" alt="Image description" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;0 = empty ➖&lt;/p&gt;

&lt;p&gt;1 = black marble ⚫&lt;/p&gt;

&lt;p&gt;2 = white marble ⚪&lt;/p&gt;

&lt;p&gt;I then fill initial positions for both players&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Coordinate Conversion 🔄&lt;/strong&gt;&lt;br&gt;
To render and detect clicks, I convert between hex coordinates and pixel coordinates:&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.amazonaws.com%2Fuploads%2Farticles%2Frsqbpugqegg5ebsfs3vb.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.amazonaws.com%2Fuploads%2Farticles%2Frsqbpugqegg5ebsfs3vb.png" alt="Image description" width="800" height="327"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Selection and Move Validation ✅&lt;/strong&gt;&lt;br&gt;
Abalone rules allow selecting 1–3 marbles in a line and either sidestep or push opponent marbles. I implemented:&lt;/p&gt;

&lt;p&gt;is_valid_selection() to ensure up to 3 marbles belong to the current player and are in line.get_valid_moves() which loops through six directions and calls either can_sidestep_to_positions() or can_push_in_direction().&lt;/p&gt;

&lt;p&gt;This logic checks board bounds, empty target spaces, and the “sumito” push rules (only if you have a larger chain than your opponent’s). 🤜🤛&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Making a Move ⏩&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once the player clicks a highlighted green circle, make_move():&lt;br&gt;
Clears original marble positions ➖&lt;br&gt;
Shifts marbles (or opponent chain) in the chosen direction 🔄&lt;br&gt;
Increments score if an opponent marble is pushed off 📈&lt;br&gt;
Checks for win (first to push off 6 marbles 🏆)&lt;br&gt;
Switches the current player 🔁&lt;/p&gt;

&lt;p&gt;Everything happens smoothly in one method! 👍&lt;/p&gt;

&lt;p&gt;Step 7: Drawing the Board and UI 🎨&lt;/p&gt;

&lt;p&gt;In draw_board(), I:&lt;br&gt;
Draw a large hexagon border and fill for the wooden board&lt;br&gt;
Loop over all hex positions, draw holes, shadows, and marbles&lt;br&gt;
Highlight selected marbles in yellow&lt;br&gt;
Mark valid destinations with small green circles&lt;/p&gt;

&lt;p&gt;In draw_ui(), I render scores, current player, and simple instructions. If the game is over, I display a “Game Over” banner with the winner. 🖥️&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Step: Game Loop 🔁&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The run() method handles Pygame’s event loop:&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.amazonaws.com%2Fuploads%2Farticles%2F4zb2jvit0mdokd937024.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.amazonaws.com%2Fuploads%2Farticles%2F4zb2jvit0mdokd937024.png" alt="Image description" width="800" height="656"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Play and Extend 🚀&lt;br&gt;
I’m thrilled with how the Abalone game turned out! You can:&lt;/p&gt;

&lt;p&gt;Customize colors or board size by tweaking constants 🎨&lt;/p&gt;

&lt;p&gt;Add sound effects when marbles move or are pushed off 🔊&lt;/p&gt;

&lt;p&gt;Implement AI: a simple minimax over valid moves would be a fun next step 🤖&lt;/p&gt;

&lt;p&gt;Save and load game states to disk 💾&lt;/p&gt;

&lt;p&gt;Grab the full source on GitHub and let me know how you’d improve it! 🛠️&lt;br&gt;
&lt;a href="https://github.com/TahmidFayaz/Abalone" rel="noopener noreferrer"&gt;https://github.com/TahmidFayaz/Abalone&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion 🏁&lt;/strong&gt;&lt;br&gt;
Implementing Abalone in Pygame was a rewarding dive into hex-grid math, move validation, and UI polish. I hope this walkthrough inspires you to build your own board games—feel free to fork the code, file issues, or submit pull requests. Happy coding! 💻🎉&lt;/p&gt;

</description>
      <category>python</category>
    </item>
  </channel>
</rss>
