{"id":30852624,"url":"https://github.com/kigster/gomoku-ansi-c","last_synced_at":"2026-04-04T00:03:56.203Z","repository":{"id":303326543,"uuid":"1015091200","full_name":"kigster/gomoku-ansi-c","owner":"kigster","description":"This repo contains both the ASCII Terminal implementation of the Gomoku game, with MiniMax algorithm \u0026 Alpha/Beta pruning. It only requires arrow keys to choose and Enter to make a move. Separately there is also a networked HTTPD version that powers the ReactJS web app via a cluster behind a reverse proxy.","archived":false,"fork":false,"pushed_at":"2026-02-12T16:54:05.000Z","size":20019,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-13T00:42:32.968Z","etag":null,"topics":["gomoku","gomoku-game","minimax-algorithm","minimax-alpha-beta-pruning"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kigster.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-07T01:53:57.000Z","updated_at":"2026-02-12T16:58:25.000Z","dependencies_parsed_at":"2025-08-08T22:04:27.272Z","dependency_job_id":"13e46f5e-3951-4037-9cb3-a1add34c10e9","html_url":"https://github.com/kigster/gomoku-ansi-c","commit_stats":null,"previous_names":["kigster/gomoku-ansi-c"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/kigster/gomoku-ansi-c","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kigster%2Fgomoku-ansi-c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kigster%2Fgomoku-ansi-c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kigster%2Fgomoku-ansi-c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kigster%2Fgomoku-ansi-c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kigster","download_url":"https://codeload.github.com/kigster/gomoku-ansi-c/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kigster%2Fgomoku-ansi-c/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29398144,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-13T06:24:03.484Z","status":"ssl_error","status_checked_at":"2026-02-13T06:23:12.830Z","response_time":78,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gomoku","gomoku-game","minimax-algorithm","minimax-alpha-beta-pruning"],"created_at":"2025-09-07T08:06:41.022Z","updated_at":"2026-04-04T00:03:56.188Z","avatar_url":"https://github.com/kigster.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![C99 Test Suite](https://github.com/kigster/gomoku-ansi-c/actions/workflows/c99.yml/badge.svg)](https://github.com/kigster/gomoku-ansi-c/actions/workflows/c99.yml) [![API Tests](https://github.com/kigster/gomoku-ansi-c/actions/workflows/api-test.yml/badge.svg)](https://github.com/kigster/gomoku-ansi-c/actions/workflows/api-test.yml) [![API Lint](https://github.com/kigster/gomoku-ansi-c/actions/workflows/api-lint.yml/badge.svg)](https://github.com/kigster/gomoku-ansi-c/actions/workflows/api-lint.yml) [![Frontend Tests](https://github.com/kigster/gomoku-ansi-c/actions/workflows/frontend.yml/badge.svg)](https://github.com/kigster/gomoku-ansi-c/actions/workflows/frontend.yml)\n\n# Gomoku (Five-in-a-Row)\n\nA full-stack Gomoku game: C99 AI engine, FastAPI backend, React frontend, global leaderboard. Play online at **[gomoku.games](https://app.gomoku.games)**.\n\n\u003cimg src=\"doc/img/gomoku-web-version.png\" width=\"700\" border=\"1\" style=\"border-radius: 10px\"/\u003e\n\n## 1. Build and Play the Terminal Game\n\nThe terminal game is a standalone C99 binary with **zero runtime dependencies** — just a C compiler and Make.\n\n### Build\n\n```bash\n# Using just (recommended)\njust build-game\n\n# Or directly with Make\nmake -C gomoku-c all install\n```\n\nThis compiles three binaries into `bin/`:\n\n| Binary | Purpose |\n|---|---|\n| `gomoku` | Interactive terminal game (ANSI color, arrow-key input) |\n| `gomoku-httpd` | Stateless HTTP daemon for networked play |\n| `gomoku-http-client` | CLI client for testing `gomoku-httpd` |\n\n### Play\n\n```bash\nbin/gomoku                                    # Human (X) vs AI (O), depth 3\nbin/gomoku -d 5                               # Harder AI (depth 5)\nbin/gomoku -l hard                            # Same as -d 6\nbin/gomoku -x ai -o ai -d 3:5                # AI vs AI, asymmetric depths\nbin/gomoku -x ai -o ai -d 4 -q -j game.json  # Headless AI game, save to JSON\nbin/gomoku -p game.json -w 0.5                # Replay saved game, 0.5s per move\nbin/gomoku -b 19 -r 4 -t 60                  # 19x19 board, radius 4, 60s timeout\nbin/gomoku -i                                 # Show threat hints (blink highlights)\n```\n\n### CLI Reference\n\n```\ngomoku [options]\n\nGameplay:\n  -b, --board 15|19    Board size (default: 15)\n  -x, --player-x TYPE  human or ai (default: human)\n  -o, --player-o TYPE  human or ai (default: ai)\n  -u, --undo           Enable undo (default: on)\n  -U, --undo-limit N   Max undo moves per game (default: 5, 0 = unlimited)\n  -s, --skip-welcome   Skip the welcome screen\n  -i, --hints          Highlight threatening patterns with blink\n  -t, --timeout T      Seconds per move (AI picks best so far; human forfeits)\n\nAI:\n  -d, --depth N        Search depth 1-10 (or N:M for asymmetric)\n  -l, --level M        easy (2), medium (4), hard (6)\n  -r, --radius 1-5     Move generation radius (default: 3)\n\nRecording:\n  -j, --json FILE      Save game to JSON\n  -p, --replay FILE    Replay a saved game\n  -w, --wait SECS      Auto-advance replay (default: wait for keypress)\n  -q, --quiet          Headless mode (AI vs AI, JSON output only)\n  -h, --help           Show help\n```\n\n### AI Evaluations\n\n```bash\njust evals              # Run tactical tests + depth tournament\njust eval-tactical      # Tactical position tests only\njust eval-tournament    # AI vs AI depth tournament (depths 2,3,4)\njust evals-ruby         # Ruby tournament against httpd cluster via envoy\n```\n\nSee [doc/AI-ENGINE.md](doc/AI-ENGINE.md) for algorithm details and threat scoring.\n\n## 2. Run the Networked Cluster Locally\n\nThe full stack runs on your dev machine: nginx for TLS, envoy for load balancing across a pool of `gomoku-httpd` workers, FastAPI for auth/scoring/leaderboard, and a Vite dev server for the React frontend.\n\n### Prerequisites\n\n| Dependency | Version | Purpose |\n|---|---|---|\n| C compiler (gcc/clang) | any | Build game engine |\n| Make | any | Build system |\n| [just](https://github.com/casey/just) | 1.0+ | Monorepo task runner |\n| Python | 3.12+ | FastAPI backend |\n| [uv](https://docs.astral.sh/uv/) | latest | Python package/venv manager |\n| Node.js | 20+ | React frontend |\n| PostgreSQL | 17+ | Leaderboard, user accounts, game history |\n| [direnv](https://direnv.net/) | optional | Auto-loads `bin/` into `$PATH` |\n\n### One-Time Setup\n\n```bash\nbin/gctl setup           # Installs deps, creates log files, generates local SSL certs (mkcert)\n```\n\nThis runs four sub-setup steps: installs packages (`clang-format`, `shfmt`, `btop`, etc.), creates log files under `/var/log/`, generates SSL certs for `dev.gomoku.games`, and configures envoy/nginx templates.\n\n### Create the Database\n\n```bash\npsql -X -c \"CREATE DATABASE gomoku\"\npsql -X -d gomoku -f iac/cloud_sql/setup.sql\n```\n\nThen create `api/.env`:\n\n```env\nDATABASE_URL=postgresql://postgres@localhost/gomoku\nGOMOKU_HTTPD_URL=http://localhost:10000\nJWT_SECRET=local-dev-secret-not-for-prod\nCORS_ORIGINS=[\"http://localhost:5173\",\"https://dev.gomoku.games\"]\n```\n\n### Start the Cluster\n\n```bash\nbin/gctl start           # Start nginx + envoy + gomoku-httpd workers + FastAPI\nbin/gctl start -w 4      # Start with 4 workers instead of default (one per CPU core)\n```\n\nOpen **https://dev.gomoku.games** (local SSL via mkcert).\n\n### `gctl` Command Reference\n\n```bash\nbin/gctl start [-w N]       # Start cluster (default: 1 worker per CPU core)\nbin/gctl stop               # Stop everything\nbin/gctl restart            # Restart all components\nbin/gctl status             # Show running processes\nbin/gctl ps                 # Process table (PID, PPID, CPU, MEM, ARGS)\nbin/gctl start nginx api    # Start individual components\nbin/gctl observe btop       # Launch monitoring (btop, htop, ctop, btm)\n```\n\nComponents: `nginx`, `envoy`, `gomoku` (httpd workers), `api` (FastAPI), `frontend` (Vite dev server).\n\n\u003e **Tip:** Use `direnv` so that `bin/` is on your `$PATH` — then you can just type `gctl start`.\n\n### Architecture\n\n```mermaid\ngraph TB\n    subgraph Client\n        Browser[\"Browser\u003cbr/\u003e(React + TypeScript)\"]\n    end\n\n    subgraph \"Local Dev Cluster\"\n        Nginx[\"nginx :443\u003cbr/\u003e(TLS termination)\"]\n\n        subgraph \"FastAPI (:8000)\"\n            API[\"Auth, Scoring, Leaderboard\u003cbr/\u003eGame Proxy, Static SPA\"]\n        end\n\n        subgraph \"Game Engine Pool\"\n            Envoy[\"Envoy :10000\u003cbr/\u003e(least-request LB)\"]\n            W1[\"gomoku-httpd :9500\"]\n            W2[\"gomoku-httpd :9501\"]\n            WN[\"gomoku-httpd :950N\"]\n        end\n\n        PG[(\"PostgreSQL\")]\n    end\n\n    Browser --\u003e|\"HTTPS\"| Nginx\n    Nginx --\u003e API\n    API --\u003e|\"POST /gomoku/play\"| Envoy\n    Envoy --\u003e W1 \u0026 W2 \u0026 WN\n    API --\u003e|\"asyncpg\"| PG\n\n    style Browser fill:#4A90D9,color:#fff\n    style Nginx fill:#009639,color:#fff\n    style API fill:#2D6A4F,color:#fff\n    style Envoy fill:#E76F51,color:#fff\n    style PG fill:#7B68EE,color:#fff\n```\n\nEach `gomoku-httpd` worker is single-threaded, so envoy distributes requests across the pool using least-request load balancing. See [doc/DEPLOYMENT.md](doc/DEPLOYMENT.md) for the full local cluster guide.\n\n### justfile Recipes\n\n```bash\njust --list             # See all recipes\njust build-game         # Build terminal game only\njust build              # Build everything (C + frontend + API assets)\njust test               # Run C tests + daemon tests + API tests + frontend tests\njust test-api           # Run API tests (43 tests)\njust test-frontend      # Run frontend tests (27 tests)\njust docker-build-all   # Build all Docker images\njust ci                 # Run all pre-commit checks (lefthook)\n```\n\n## 3. Deploy to Production\n\nThe application needs two containers and a PostgreSQL database. All three deployment options below assume you outsource PostgreSQL to a managed provider.\n\n### Database: Use Neon (or any managed Postgres)\n\n[Neon](https://neon.tech) offers a generous free tier with serverless Postgres. Alternatives: [Supabase](https://supabase.com), [Aiven](https://aiven.io), Google Cloud SQL, AWS RDS.\n\n1. Create a Neon project and database named `gomoku`.\n2. Run the schema migration:\n   ```bash\n   psql \"$NEON_DATABASE_URL\" -f iac/cloud_sql/setup.sql\n   ```\n3. Copy the connection string — you'll set it as `DATABASE_URL` below.\n\n\u003e The schema creates `users`, `games`, and `password_reset_tokens` tables plus leaderboard views. See [iac/README.md](iac/README.md) for details.\n\n### Option A: Google Cloud Run (Recommended)\n\nServerless, scales to zero, cheapest for low/medium traffic. Managed by Terraform.\n\nTwo Cloud Run services:\n- **gomoku-api** — FastAPI + React SPA (nginx), handles auth, scoring, leaderboard, and proxies game moves\n- **gomoku-httpd** — C game engine, single-threaded, concurrency=1, auto-scales per demand\n\n#### Prerequisites\n\n- GCP project with billing enabled\n- `gcloud` CLI authenticated (`gcloud auth login`)\n- Terraform installed\n- Docker with `buildx` (for cross-compiling `linux/amd64` on Apple Silicon)\n\n#### First-Time Deploy\n\n```bash\n# Generate a JWT signing secret\nexport TF_VAR_jwt_secret=\"$(openssl rand -base64 32)\"\n\n# Set your Neon (or other) database URL\nexport TF_VAR_database_url=\"postgresql://user:pass@ep-xyz.us-east-2.aws.neon.tech/gomoku?sslmode=require\"\n\n# Build Docker images (linux/amd64) and deploy via Terraform\njust cr-init\n```\n\nThis runs `iac/cloud_run/deploy.sh`, which:\n1. Initializes Terraform and enables Cloud Run + Artifact Registry APIs\n2. Creates an Artifact Registry repository (`gomoku-repo`)\n3. Builds both Docker images for `linux/amd64` and pushes them\n4. Applies the full Terraform plan (Cloud Run services, IAM, networking)\n\n#### Subsequent Updates\n\n```bash\njust cr-update           # Rebuild images, push, update Cloud Run services\n```\n\nOr update individual services:\n\n```bash\ncd iac/cloud_run\n./update.sh httpd        # Game engine only\n./update.sh api          # API + frontend only\n./update.sh httpd api    # Both\n```\n\n#### DNS\n\nPoint your domain to the frontend service URL from the deploy output. Cloud Run handles TLS automatically.\n\nSee [iac/README.md](iac/README.md) for the full infrastructure reference, environment variables, and architecture diagram.\n\n### Option B: AWS (ECS Fargate or App Runner)\n\nIf you prefer AWS, the Docker images work without modification.\n\n#### With App Runner (simplest)\n\n```bash\n# Push images to ECR\naws ecr create-repository --repository-name gomoku-httpd\naws ecr create-repository --repository-name gomoku-api\n\njust docker-build-all-amd64\n\n# Tag and push (replace 123456789.dkr.ecr.us-east-1.amazonaws.com with your ECR URI)\ndocker tag gomoku-httpd:latest $ECR_URI/gomoku-httpd:latest\ndocker tag gomoku-api:latest $ECR_URI/gomoku-api:latest\ndocker push $ECR_URI/gomoku-httpd:latest\ndocker push $ECR_URI/gomoku-api:latest\n```\n\nThen create two App Runner services in the AWS console or via `aws apprunner create-service`, setting these environment variables on the `gomoku-api` service:\n\n```env\nDATABASE_URL=postgresql://user:pass@ep-xyz.us-east-2.aws.neon.tech/gomoku?sslmode=require\nGOMOKU_HTTPD_URL=https://\u003chttpd-app-runner-url\u003e\nJWT_SECRET=\u003cyour-generated-secret\u003e\nCORS_ORIGINS=[\"https://yourdomain.com\"]\n```\n\n#### With ECS Fargate\n\nFor more control (custom VPC, ALB, autoscaling policies), define an ECS task definition with two containers and an ALB. The `gomoku-httpd` container should have `desiredCount` scaled based on CPU, since each instance handles one game move at a time.\n\n### Option C: Any VPS with Docker Compose\n\nRun on a $5/mo VPS (DigitalOcean, Hetzner, Fly.io).\n\n```bash\njust docker-build-all\ndocker compose up -d\n```\n\nMinimum setup: two containers (`gomoku-api:latest` on port 8000, `gomoku-httpd:latest` on port 8787), a reverse proxy (nginx/Caddy) for TLS. Set environment variables as shown in the [Configuration](#configuration) section.\n\n\n## Configuration\n\nThe FastAPI server reads environment variables from `api/.env`:\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `DATABASE_URL` | *(required)* | PostgreSQL DSN |\n| `GOMOKU_HTTPD_URL` | `http://localhost:8787` | Upstream game engine (or envoy at `:10000`) |\n| `JWT_SECRET` | `change-me-in-production` | HMAC signing key |\n| `CORS_ORIGINS` | `[\"*\"]` | Allowed origins (JSON array) |\n| `EMAIL_PROVIDER` | `stdout` | `stdout` or `sendgrid` |\n\nSee the full configuration reference in the [Application Configuration](#application-configuration) section below.\n\n## Project Structure\n\n```\ngomoku-c/               C game engine + HTTP daemon\n  src/gomoku/             AI, board, game, UI, CLI\n  src/net/                Stateless HTTP daemon (JSON API)\n  tests/                  Google Test suite + AI evals\napi/                    FastAPI service\n  app/                    Auth, scoring, leaderboard, game proxy\n  public/                 Frontend assets (built by justfile)\n  tests/                  43 integration tests\nfrontend/               React + TypeScript + Tailwind\niac/                    Infrastructure (Cloud Run, Cloud SQL, nginx, envoy)\nbin/                    gctl cluster manager, helper scripts\ndoc/                    Technical documentation\njustfile                Monorepo orchestration\n```\n\n## Documentation\n\n| Document | Description |\n|---|---|\n| [doc/DEPLOYMENT.md](doc/DEPLOYMENT.md) | Local cluster, Cloud Run, and GKE deployment |\n| [doc/DEVELOPER.md](doc/DEVELOPER.md) | C engine technical overview and architecture |\n| [doc/AI-ENGINE.md](doc/AI-ENGINE.md) | AI algorithm analysis, threat scoring, known issues |\n| [doc/HTTPD.md](doc/HTTPD.md) | HTTP daemon API reference and cluster setup |\n| [doc/GAME-RULES.md](doc/GAME-RULES.md) | Gomoku/Renju rules and variant support proposal |\n| [doc/DTRACE.md](doc/DTRACE.md) | DTrace investigation of CPU busy-spin fix |\n| [iac/README.md](iac/README.md) | Cloud Run infrastructure and Terraform |\n| [frontend/CLAUDE.md](frontend/CLAUDE.md) | Frontend architecture and API endpoints |\n\n## Application Configuration\n\nThe FastAPI server (`api/`) is configured via environment variables. Place them in `api/.env` for local development or set them in your Cloud Run / container environment.\n\n### Database\n\n| Variable | Default | Description |\n|---|---|---|\n| `DATABASE_URL` | *(none)* | Full PostgreSQL DSN, e.g. `postgresql://user:pass@host/gomoku`. Takes precedence over `DB_*` vars. |\n| `DB_SOCKET` | *(none)* | Unix socket path for Cloud SQL Proxy. |\n| `DB_NAME` | `gomoku` | Database name. |\n| `DB_USER` | `postgres` | Database user. |\n| `DB_PASSWORD` | *(none)* | Database password. |\n\n### Game Engine\n\n| Variable | Default | Description |\n|---|---|---|\n| `GOMOKU_HTTPD_URL` | `http://localhost:8787` | Upstream game engine. With envoy: `http://localhost:10000`. |\n\n### Authentication (JWT)\n\n| Variable | Default | Description |\n|---|---|---|\n| `JWT_SECRET` | `change-me-in-production` | HMAC signing key. Generate: `openssl rand -base64 32`. |\n| `JWT_ALGORITHM` | `HS256` | JWT signing algorithm. |\n| `JWT_EXPIRE_MINUTES` | `1440` | Token lifetime (default 24h). |\n\n### CORS\n\n| Variable | Default | Description |\n|---|---|---|\n| `CORS_ORIGINS` | `[\"*\"]` | JSON array of allowed origins. |\n\n### Email\n\n| Variable | Default | Description |\n|---|---|---|\n| `EMAIL_PROVIDER` | `stdout` | `stdout` or `sendgrid`. |\n| `EMAIL_FROM` | `noreply@gomoku.games` | Sender address. |\n| `SENDGRID_API_KEY` | *(none)* | Required when `EMAIL_PROVIDER=sendgrid`. |\n\n### Example `.env` (Local)\n\n```env\nDATABASE_URL=postgresql://postgres@localhost/gomoku\nGOMOKU_HTTPD_URL=http://localhost:10000\nJWT_SECRET=local-dev-secret-not-for-prod\nCORS_ORIGINS=[\"http://localhost:5173\"]\n```\n\n## License\n\nMIT License. Copyright 2025-2026, Konstantin Gredeskoul.\n\n## Acknowledgments\n\n- [Claude](https://claude.ai) (Sonnet, Opus) -- AI pair programming partner\n- Google Test framework for C++ testing\n- Pattern recognition adapted from traditional Gomoku AI research\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkigster%2Fgomoku-ansi-c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkigster%2Fgomoku-ansi-c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkigster%2Fgomoku-ansi-c/lists"}