summaryrefslogtreecommitdiff
path: root/scripts/setup-chess.sh
blob: a19bf1d13f8aeff88cb1da05560090dfd82e8174 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
#!/usr/bin/env bash
set -euo pipefail

# En Croissant + lc0 + Maia + Stockfish setup script
# Targets Arch Linux. No sudo required (prerequisites must be pre-installed).

APPIMAGE_DIR="$HOME/.local/bin"
APPIMAGE_PATH="$APPIMAGE_DIR/en-croissant.AppImage"
LC0_BIN="$HOME/.local/bin/lc0"
MAIA_WEIGHTS_DIR="$HOME/.local/share/maia"
MAIA_BASE_URL="https://github.com/CSSLab/maia-chess/releases/download/v1.0"
STOCKFISH_TAR_URL="https://github.com/official-stockfish/Stockfish/releases/latest/download/stockfish-ubuntu-x86-64-avx2.tar"
STOCKFISH_DIR="$HOME/.local/share/org.encroissant.app/engines/stockfish"
STOCKFISH_BIN="$STOCKFISH_DIR/stockfish-ubuntu-x86-64-avx2"
ENGINES_JSON="$HOME/.local/share/org.encroissant.app/engines/engines.json"
DESKTOP_FILE="$HOME/.local/share/applications/en-croissant.desktop"

info()  { printf '\033[1;34m==> %s\033[0m\n' "$*"; }
ok()    { printf '\033[1;32m  -> %s\033[0m\n' "$*"; }
skip()  { printf '\033[1;33m  -> %s (skipped)\033[0m\n' "$*"; }
err()   { printf '\033[1;31mERROR: %s\033[0m\n' "$*" >&2; }

# ---------------------------------------------------------------------------
# 1. Check prerequisites
# ---------------------------------------------------------------------------
info "Checking prerequisites"

missing=()
for cmd in git meson ninja python3 curl; do
    command -v "$cmd" &>/dev/null || missing+=("$cmd")
done
# Check libraries via pacman
for pkg in openblas eigen; do
    pacman -Qi "$pkg" &>/dev/null || missing+=("$pkg")
done

if (( ${#missing[@]} )); then
    err "Missing packages: ${missing[*]}"
    echo "Install them with:  sudo pacman -S ${missing[*]}"
    exit 1
fi
ok "All prerequisites found"

# ---------------------------------------------------------------------------
# 2. Install En Croissant AppImage
# ---------------------------------------------------------------------------
info "Installing En Croissant AppImage"

if [[ -f "$APPIMAGE_PATH" ]]; then
    skip "Already exists at $APPIMAGE_PATH"
else
    mkdir -p "$APPIMAGE_DIR"
    # Get latest release AppImage URL from GitHub API
    appimage_url=$(curl -sL "https://api.github.com/repos/franciscoBSalgueiro/en-croissant/releases/latest" \
        | python3 -c "import sys,json; assets=json.load(sys.stdin)['assets']; print([a['browser_download_url'] for a in assets if a['name'].endswith('_amd64.AppImage')][0])")
    echo "  Downloading: $appimage_url"
    curl -L -o "$APPIMAGE_PATH" "$appimage_url"
    chmod +x "$APPIMAGE_PATH"
    ok "Installed to $APPIMAGE_PATH"
fi

# ---------------------------------------------------------------------------
# 3. Build and install lc0 from source
# ---------------------------------------------------------------------------
info "Building lc0"

if [[ -x "$LC0_BIN" ]]; then
    skip "Already exists at $LC0_BIN"
else
    LC0_BUILD_DIR=$(mktemp -d /tmp/lc0-build.XXXXXX)
    echo "  Cloning to $LC0_BUILD_DIR"
    git clone --recurse-submodules https://github.com/LeelaChessZero/lc0.git "$LC0_BUILD_DIR/lc0"
    pushd "$LC0_BUILD_DIR/lc0" >/dev/null
    INSTALL_PREFIX="$HOME/.local" ./build.sh
    popd >/dev/null
    mkdir -p "$HOME/.local/bin"
    cp "$LC0_BUILD_DIR/lc0/build/release/lc0" "$LC0_BIN"
    chmod +x "$LC0_BIN"
    ok "Installed to $LC0_BIN"
    rm -rf "$LC0_BUILD_DIR"
fi

# ---------------------------------------------------------------------------
# 4. Download Maia weights
# ---------------------------------------------------------------------------
info "Downloading Maia weights"
mkdir -p "$MAIA_WEIGHTS_DIR"

for elo in 1100 1200 1300 1400 1500 1600 1700 1800 1900; do
    file="maia-${elo}.pb.gz"
    dest="$MAIA_WEIGHTS_DIR/$file"
    if [[ -f "$dest" ]]; then
        skip "$file already exists"
    else
        echo "  Downloading $file"
        curl -sL -o "$dest" "$MAIA_BASE_URL/$file"
        ok "$file"
    fi
done

# ---------------------------------------------------------------------------
# 5. Create Maia wrapper scripts
# ---------------------------------------------------------------------------
info "Creating Maia wrapper scripts"
mkdir -p "$HOME/.local/bin"

for elo in 1100 1200 1300 1400 1500 1600 1700 1800 1900; do
    wrapper="$HOME/.local/bin/maia-${elo}"
    cat > "$wrapper" <<SCRIPT
#!/bin/sh
exec "$LC0_BIN" --weights="$MAIA_WEIGHTS_DIR/maia-${elo}.pb.gz" "\$@"
SCRIPT
    chmod +x "$wrapper"
done
ok "Created 9 wrapper scripts in ~/.local/bin/"

# ---------------------------------------------------------------------------
# 6. Download Stockfish binary
# ---------------------------------------------------------------------------
info "Installing Stockfish"

if [[ -x "$STOCKFISH_BIN" ]]; then
    skip "Already exists at $STOCKFISH_BIN"
else
    mkdir -p "$STOCKFISH_DIR"
    echo "  Downloading Stockfish"
    curl -sL "$STOCKFISH_TAR_URL" | tar -xf - -C "$STOCKFISH_DIR" --strip-components=1
    chmod +x "$STOCKFISH_BIN"
    ok "Installed to $STOCKFISH_BIN"
fi

# ---------------------------------------------------------------------------
# 7. Write engines.json
# ---------------------------------------------------------------------------
info "Writing engines.json"
mkdir -p "$(dirname "$ENGINES_JSON")"

# Generate a UUID via python3
genuuid() { python3 -c "import uuid; print(uuid.uuid4())"; }

# Build the JSON with python3 for correctness
python3 - "$STOCKFISH_BIN" "$HOME/.local/bin" <<'PYEOF' > "$ENGINES_JSON"
import json, sys, uuid

stockfish_bin = sys.argv[1]
maia_bin_dir = sys.argv[2]

engines = []

# Stockfish
engines.append({
    "type": "local",
    "id": str(uuid.uuid4()),
    "name": "Stockfish",
    "version": "",
    "path": stockfish_bin,
    "image": "https://upload.wikimedia.org/wikipedia/commons/3/3a/NewLogoSF.png",
    "elo": 3635,
    "downloadSize": 79953920,
    "downloadLink": "https://github.com/official-stockfish/Stockfish/releases/latest/download/stockfish-ubuntu-x86-64-avx2.tar",
    "loaded": True,
    "go": {"t": "Infinite"},
    "settings": [
        {"name": "Threads", "value": 1},
        {"name": "Hash", "value": 16},
        {"name": "MultiPV", "value": 1}
    ]
})

# Maia engines
for elo in range(1100, 2000, 100):
    engines.append({
        "type": "local",
        "id": str(uuid.uuid4()),
        "name": f"Maia {elo}",
        "version": "1.0",
        "path": f"{maia_bin_dir}/maia-{elo}",
        "image": None,
        "elo": elo,
        "loaded": True,
        "go": {"t": "Nodes", "c": 1},
        "settings": [
            {"name": "MultiPV", "value": 1}
        ]
    })

print(json.dumps(engines, indent=4))
PYEOF

ok "Wrote $ENGINES_JSON with 10 engines"

# ---------------------------------------------------------------------------
# 8. Create .desktop file
# ---------------------------------------------------------------------------
info "Creating .desktop file"
mkdir -p "$(dirname "$DESKTOP_FILE")"

cat > "$DESKTOP_FILE" <<EOF
[Desktop Entry]
Name=En Croissant
Comment=Chess GUI for analysis, puzzles, and play
Exec=$APPIMAGE_PATH
Icon=chess
Type=Application
Categories=Game;BoardGame;
StartupWMClass=En Croissant
EOF

update-desktop-database "$HOME/.local/share/applications/" 2>/dev/null || true
ok "Created $DESKTOP_FILE"

# ---------------------------------------------------------------------------
# Done
# ---------------------------------------------------------------------------
echo ""
info "Setup complete!"
echo "  En Croissant: $APPIMAGE_PATH"
echo "  lc0:          $LC0_BIN"
echo "  Stockfish:    $STOCKFISH_BIN"
echo "  Maia weights: $MAIA_WEIGHTS_DIR/"
echo "  engines.json: $ENGINES_JSON"
echo ""
echo "  Launch with:  $APPIMAGE_PATH"