Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions .github/workflows/hexchess-board-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Deploy Hexchess Board Client

on:
workflow_dispatch:
push:
branches:
- main
paths:
- 'hexchess-board/**'
- '.github/workflows/hexchess-board-pages.yml'

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: hexchess-board-pages
cancel-in-progress: true

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Prepare static site
env:
PYENGINE2_BASE_URL: ${{ vars.PYENGINE2_BASE_URL }}
run: |
mkdir -p _site
cp -R hexchess-board/. _site/
ENGINE_URL_JSON=$(node -e "console.log(JSON.stringify(process.env.PYENGINE2_BASE_URL || ''))")
cat > _site/app-config.js <<EOF
window.HEXCHESS_CONFIG = {
engineUrl: ${ENGINE_URL_JSON},
}
EOF
touch _site/.nojekyll

- name: Upload Pages artifact
uses: actions/upload-pages-artifact@v3
with:
path: _site

deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
5 changes: 2 additions & 3 deletions docs/sandbox/use-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function log(...args: unknown[]) {
export type EngineKind = 'rust-worker' | 'python-api' | 'cyengine-api'

const ENGINE_MAX_DEPTH: Record<EngineKind, number | null> = {
'rust-worker': 4,
'rust-worker': null,
'python-api': null,
'cyengine-api': null,
}
Expand All @@ -49,8 +49,7 @@ function timeoutMsFor(kind: EngineKind, options: EvaluateOptions) {
return 120000
}

const depth = Math.max(1, options.depth)
return Math.max(120000, depth * 120000)
return null
}

export function useEngine() {
Expand Down
20 changes: 12 additions & 8 deletions engine/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export interface EvaluateOptions {
}

export interface WorkerCommandOptions {
timeoutMs?: number
timeoutMs?: number | null
}

export interface SearchMetrics {
Expand Down Expand Up @@ -44,7 +44,7 @@ export function execute<T extends Record<string, any> = {}>(
worker: Worker,
command: string,
options: Record<string, any> = {},
timeoutMs = 120000,
timeoutMs: number | null = 120000,
) {
const id = crypto.randomUUID()

Expand All @@ -53,9 +53,11 @@ export function execute<T extends Record<string, any> = {}>(
messageListener: (evt: MessageEvent) => void,
errorListener: (evt: ErrorEvent) => void,
messageErrorListener: (evt: MessageEvent) => void,
timeoutId: ReturnType<typeof setTimeout>,
timeoutId: ReturnType<typeof setTimeout> | null,
) => {
clearTimeout(timeoutId)
if (timeoutId !== null) {
clearTimeout(timeoutId)
}
worker.removeEventListener('message', messageListener)
worker.removeEventListener('error', errorListener)
worker.removeEventListener('messageerror', messageErrorListener)
Expand Down Expand Up @@ -95,10 +97,12 @@ export function execute<T extends Record<string, any> = {}>(
reject(new Error(`Engine worker message error while running ${command}`))
}

const timeoutId = setTimeout(() => {
cleanup(messageListener, errorListener, messageErrorListener, timeoutId)
reject(new Error(`Engine command timed out after ${timeoutMs}ms: ${command}`))
}, timeoutMs)
const timeoutId = timeoutMs === null
? null
: setTimeout(() => {
cleanup(messageListener, errorListener, messageErrorListener, timeoutId)
reject(new Error(`Engine command timed out after ${timeoutMs}ms: ${command}`))
}, timeoutMs)

worker.addEventListener('message', messageListener)
worker.addEventListener('error', errorListener)
Expand Down
82 changes: 82 additions & 0 deletions hexchess-board/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# hexchess-board client

Do not open `index.html` directly via `file://`.

Modern browsers block JavaScript ES module loading from `file://` origins (`origin null`), which is why you see CORS errors for `app.js`.

Use a local HTTP server instead.

## Windows PowerShell

From repo root:

```powershell
./hexchess-board/start-server.ps1
```

Then open:

- http://127.0.0.1:4175/index.html

## Alternative (manual)

```powershell
cd hexchess-board
python -m http.server 4175 --bind 127.0.0.1
```

Open the same URL above.

## Engine Selection

The game setup now supports these engine-side values:

- `pyengine2`
- `pyrustengine`

Local defaults:

- `pyengine2` -> `http://127.0.0.1:8000`
- `pyrustengine` -> `http://127.0.0.1:8081`

If `app-config.js` provides a global `engineUrl`, that override is used for any selected engine. If it provides an `engineUrls` object, the client uses the matching per-engine base URL.

## pyengine2

Start pyengine2 separately:

```powershell
python -m uvicorn pyengine2.main:app --reload --host 127.0.0.1 --port 8000
```

When the selected engine is `pyengine2`, the board client also sends earlier game positions together with the current FEN on each evaluation request. That lets `pyengine2` recognize threefold-repetition lines from the current game history instead of treating every request as a completely fresh position.

## pyrustengine

Start pyrustengine separately:

```powershell
python -m pyrustengine
```

## GitHub Pages Engine URL Configuration

The client loads runtime config from `app-config.js`.

For GitHub Pages deploys, the workflow [.github/workflows/hexchess-board-pages.yml](../.github/workflows/hexchess-board-pages.yml)
injects a repository variable into that file.

1. In GitHub, open repository `Settings` -> `Secrets and variables` -> `Actions` -> `Variables`.
2. Create a variable named `PYENGINE2_BASE_URL`.
3. Set it to your HTTPS engine endpoint, for example:

```text
https://your-pyengine2.example.com
```

4. Run or let the `Deploy Hexchess Board Client` workflow run on `main`.

Notes:

- If `PYENGINE2_BASE_URL` is empty, GitHub Pages builds with an empty global engine URL and local defaults are used outside GitHub Pages.
- The UI also stores the last entered engine URL in localStorage.
12 changes: 12 additions & 0 deletions hexchess-board/app-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
window.HEXCHESS_CONFIG = {
// Optional global override for any engine selection.
// Example: "https://pyengine2.example.com"
engineUrl: "",

// Optional per-engine overrides.
// Example:
// engineUrls: {
// pyengine2: "https://pyengine2.example.com",
// pyrustengine: "https://pyrustengine.example.com",
// },
}
Loading
Loading