Posted on
Artificial Intelligence

Artificial Intelligence Gaming Projects

Author
  • User
    linuxbash
    Posts by this author
    Posts by this author

Artificial Intelligence Gaming Projects on Linux: A Bash-First Playbook

Ever watched an AI nail a perfect run in a game and thought, “I want to build that”? The good news: you can, and Linux gives you the cleanest, most reproducible path from blank terminal to a trained agent. In this guide, we’ll spin up a fast dev stack, walk through real projects you can finish in a weekend, and show the exact Bash commands you need along the way.

Why this matters:

  • Games are a practical, visual way to learn AI concepts like reinforcement learning, search, and procedural generation.

  • Linux simplifies builds, headless training, automation, and reproducibility.

  • Open-source tools mean you can go from prototype to publishable results without license drama.

What you’ll build

  • A reinforcement learning agent that learns CartPole (and optional Atari) using Stable-Baselines3.

  • A Monte Carlo Tree Search bot for Tic-Tac-Toe (extensible to other board games).

  • A simple “vision + keyboard” bot that interacts with a windowed game via xdotool and OpenCV (for offline/personal use).

  • A tiny procedural level generator for roguelike-style ASCII maps.

Each includes runnable code and terminal-friendly steps.


Prerequisites: System packages (apt, dnf, zypper)

Install core packages once. These cover Python, build tools, Git, FFmpeg (for videos), and xdotool (for scripted key presses).

Debian/Ubuntu (apt):

sudo apt update
sudo apt install -y python3 python3-venv python3-pip git build-essential cmake ffmpeg xdotool

Fedora/RHEL (dnf):

sudo dnf groupinstall -y "Development Tools"
sudo dnf install -y python3 python3-virtualenv python3-pip git cmake ffmpeg xdotool

openSUSE (zypper):

sudo zypper install -y python3 python3-pip python3-virtualenv git gcc-c++ make cmake ffmpeg xdotool

Set up a clean Python environment:

mkdir -p ~/ai-gaming && cd ~/ai-gaming
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip setuptools wheel

Core AI and RL packages (CPU-only PyTorch wheel for maximum compatibility):

pip install gymnasium stable-baselines3[extra] shimmy ale-py autorom[accept-rom-license]
pip install torch --index-url https://download.pytorch.org/whl/cpu

If you have a CUDA GPU and drivers, install the matching GPU-enabled torch from pytorch.org instead of the CPU wheel above.


Project 1: Train your first game-playing agent (CartPole in minutes)

Goal: Use Stable-Baselines3 (PPO) to balance the classic CartPole. This is the “Hello, World!” of reinforcement learning.

Install (already covered above). Optional: Atari support with AutoROM has been installed as part of the prerequisites; run it once to fetch ROMs:

AutoROM --accept-license

Train and evaluate (save as train_cartpole.py):

import gymnasium as gym
from stable_baselines3 import PPO

def main():
    env = gym.make("CartPole-v1")
    model = PPO("MlpPolicy", env, verbose=1)
    model.learn(total_timesteps=50_000)
    model.save("ppo-cartpole")

    # Quick evaluation
    obs, _ = env.reset(seed=0)
    total_reward = 0
    for _ in range(2000):
        action, _ = model.predict(obs, deterministic=True)
        obs, reward, terminated, truncated, _info = env.step(action)
        total_reward += reward
        if terminated or truncated:
            break
    print(f"Eval reward: {total_reward}")

if __name__ == "__main__":
    main()

Run:

python train_cartpole.py

Going bigger (optional): Swap in Atari after running AutoROM. For example, Pong:

import gymnasium as gym
from stable_baselines3 import PPO

env_id = "ALE/Pong-v5"  # requires ale-py + ROMs via AutoROM
env = gym.make(env_id, render_mode=None)
model = PPO("CnnPolicy", env, verbose=1)
model.learn(total_timesteps=1_000_000)  # Atari needs more steps
model.save("ppo-pong")

Why this is valuable:

  • Teaches the full RL training loop and evaluation cycle.

  • Reproducible on any Linux box or remote server.

  • You can scale up with the same tooling (tmux, systemd, SSH).


Project 2: Monte Carlo Tree Search (MCTS) bot for Tic-Tac-Toe

Goal: Implement a search-based agent that plays a perfect game—no neural nets needed. This demonstrates planning and value estimation via rollouts.

Save as ttt_mcts.py:

import math, random, copy

EMPTY, X, O = 0, 1, 2

def new_board():
    return [EMPTY]*9

def legal_moves(board):
    return [i for i, v in enumerate(board) if v == EMPTY]

def play(board, move, player):
    b = board[:]
    b[move] = player
    return b

def winner(board):
    lines = [(0,1,2),(3,4,5),(6,7,8),
             (0,3,6),(1,4,7),(2,5,8),
             (0,4,8),(2,4,6)]
    for a,b,c in lines:
        if board[a] != EMPTY and board[a] == board[b] == board[c]:
            return board[a]
    if EMPTY not in board:
        return -1  # draw
    return 0      # ongoing

class Node:
    def __init__(self, board, player, parent=None, move=None):
        self.board = board
        self.player = player
        self.parent = parent
        self.move = move
        self.children = []
        self.wins = 0
        self.visits = 0
        self.untried = legal_moves(board)

    def ucb(self, c=1.41):
        if self.visits == 0: return float('inf')
        return self.wins/self.visits + c*math.sqrt(math.log(self.parent.visits)/self.visits)

def mcts(root_board, root_player, iters=5000):
    root = Node(root_board, root_player)
    for _ in range(iters):
        node = root

        # Select
        while not node.untried and node.children:
            node = max(node.children, key=lambda n: n.ucb())

        # Expand
        if node.untried:
            m = random.choice(node.untried)
            node.untried.remove(m)
            nxt = play(node.board, m, node.player)
            node = Node(nxt, O if node.player == X else X, parent=node, move=m)
            node.parent.children.append(node)

        # Simulate
        sim_board = node.board[:]
        sim_player = node.player
        while True:
            w = winner(sim_board)
            if w != 0: break
            moves = legal_moves(sim_board)
            sim_board = play(sim_board, random.choice(moves), sim_player)
            sim_player = O if sim_player == X else X

        # Backpropagate (assume root_player cares about X)
        r = 0.5 if w == -1 else (1.0 if w == X else 0.0)
        while node:
            node.visits += 1
            node.wins += r if root_player == X else (1.0 - r)
            node = node.parent

    # Choose best move
    best = max(root.children, key=lambda n: n.visits)
    return best.move

def pretty(board):
    s = {EMPTY:'.', X:'X', O:'O'}
    rows = [" ".join(s[board[i+j]] for j in range(3)) for i in (0,3,6)]
    return "\n".join(rows)

if __name__ == "__main__":
    board = new_board()
    player = X
    while True:
        if player == X:
            move = mcts(board, X, iters=2000)
        else:
            # simple opponent: random
            move = random.choice(legal_moves(board))
        board = play(board, move, player)
        print(pretty(board), "\n")
        w = winner(board)
        if w != 0:
            print("Winner:", "Draw" if w == -1 else ("X" if w == X else "O"))
            break
        player = O if player == X else X

Run:

python ttt_mcts.py

Why this is valuable:

  • Teaches search, rollouts, and the exploration-exploitation tradeoff.

  • Extendable to Connect Four, 2048, or custom turn-based games.


Project 3: Automate simple gameplay with OpenCV + xdotool

Goal: Detect something on screen and press keys accordingly—useful for prototyping bots, automating tests, or analyzing reaction timing.

Ethics note: Use responsibly on your own/offline games and respect game ToS. This is a learning tool, not a cheat engine.

Install Python deps:

pip install opencv-python mss numpy

Example: Watch a small screen region and press space when a dark obstacle appears (tune coordinates to your game window). Save as vision_bot.py:

import time
import numpy as np
import cv2
from mss import mss
import subprocess

# Define a capture box (x, y, width, height)
BOX = {"left": 100, "top": 200, "width": 300, "height": 80}

def press(key="space"):
    subprocess.run(["xdotool", "key", key])

def main():
    sct = mss()
    print("Starting... Ctrl+C to stop.")
    while True:
        img = np.array(sct.grab(BOX))[:, :, :3]  # BGRA -> BGR
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # Simple obstacle heuristic: count dark pixels
        dark = (gray < 60).sum()
        if dark > 500:  # tune threshold
            press("space")
            time.sleep(0.2)  # debounce
        time.sleep(0.01)

if __name__ == "__main__":
    main()

Run with the target game window focused:

python vision_bot.py

Why this is valuable:

  • Shows how to close the loop from vision to action on Linux using pure Bash-friendly tools.

  • Forms the base for automated game testing pipelines.


Project 4: Procedural ASCII level generator (tiny PCG)

Goal: Create quick, varied maps for prototyping. We’ll carve rooms and connect them with corridors.

Save as pcg_dungeon.py:

import random

W, H = 50, 20
FLOOR, WALL = '.', '#'

def empty_map():
    return [[WALL]*W for _ in range(H)]

def carve_room(m, x, y, w, h):
    for r in range(y, y+h):
        for c in range(x, x+w):
            if 0 <= r < H and 0 <= c < W:
                m[r][c] = FLOOR

def carve_h_corridor(m, x1, x2, y):
    for x in range(min(x1,x2), max(x1,x2)+1):
        if 0 <= y < H and 0 <= x < W:
            m[y][x] = FLOOR

def carve_v_corridor(m, y1, y2, x):
    for y in range(min(y1,y2), max(y1,y2)+1):
        if 0 <= y < H and 0 <= x < W:
            m[y][x] = FLOOR

def generate(n_rooms=8):
    m = empty_map()
    centers = []
    for _ in range(n_rooms):
        w, h = random.randint(4,10), random.randint(3,6)
        x = random.randint(1, W-w-2)
        y = random.randint(1, H-h-2)
        carve_room(m, x, y, w, h)
        centers.append((x+w//2, y+h//2))
    # connect rooms in order
    for i in range(1, len(centers)):
        (x1, y1), (x2, y2) = centers[i-1], centers[i]
        if random.random() < 0.5:
            carve_h_corridor(m, x1, x2, y1)
            carve_v_corridor(m, y1, y2, x2)
        else:
            carve_v_corridor(m, y1, y2, x1)
            carve_h_corridor(m, x1, x2, y2)
    return m

if __name__ == "__main__":
    m = generate()
    print("\n".join("".join(row) for row in m))

Run:

python pcg_dungeon.py

Why this is valuable:

  • Demonstrates quick content generation without heavy ML.

  • Great for prototyping RL environments or game jams.


Why Linux is the ideal base for AI gaming projects

  • Reproducibility: Package managers, virtualenv, and deterministic builds help you share and rerun experiments.

  • Scale-up path: SSH, tmux/screen, and headless servers make long jobs manageable.

  • Tooling: xdotool, FFmpeg, and CLI-first workflows are frictionless.

  • Open ecosystem: Gymnasium, Stable-Baselines3, PyTorch, AutoROM, and more are first-class citizens.


Pro tips

  • Use a project layout:
ai-gaming/
  .venv/
  cartpole/
  mcts/
  vision-bot/
  pcg/
  • Log and visualize:
pip install tensorboard
tensorboard --logdir ./tb --port 6006
  • Record rollouts:
pip install imageio[ffmpeg]
  • For longer runs, keep processes alive:
tmux new -s training
# ... run python scripts here

Conclusion and next steps (CTA)

You now have a Linux-native toolkit for AI gaming:

  • You trained a baseline RL agent.

  • You wrote a search-based bot.

  • You automated simple play-testing.

  • You generated levels on the fly.

Next:

  • Extend MCTS to Connect Four or 2048.

  • Swap CartPole for Atari or a custom Gymnasium env.

  • Wrap your experiments in Makefiles or bash scripts to automate training/eval loops.

  • Publish your results and code—open a repo right now:

git init
git add .
git commit -m "AI gaming projects: RL, MCTS, vision bot, PCG"

Questions or want a deeper dive (e.g., Ray RLlib, curriculum learning, or Godot/Unity integrations on Linux)? Tell me your target game and hardware, and I’ll tailor a build-and-train plan you can run today.