Skip to content

Commit 3cdc37d

Browse files
author
miskibin
committed
feat: Add examples for custom engine implementation and server integration
1 parent 16edeff commit 3cdc37d

File tree

1 file changed

+74
-2
lines changed

1 file changed

+74
-2
lines changed

docs/source/engine.rst

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,91 @@ With time limits::
125125
Custom Engine Implementation
126126
-----------------------------
127127

128-
To create your own engine, inherit from the ``Engine`` class and implement
129-
the ``get_best_move`` method::
128+
To create your own engine, inherit from the ``Engine`` abstract class and implement
129+
the ``get_best_move`` method. Your engine can use any search algorithm or heuristic.
130+
131+
Basic Example - Random Engine::
130132

131133
from draughts.engine import Engine
132134
import random
133135
134136
class RandomEngine(Engine):
137+
"""A simple engine that makes random legal moves."""
138+
135139
def get_best_move(self, board, with_evaluation=False):
136140
move = random.choice(list(board.legal_moves))
137141
if with_evaluation:
138142
return move, 0.0
139143
return move
140144

145+
Advanced Example - Greedy Capture Engine::
146+
147+
from draughts.engine import Engine
148+
149+
class GreedyEngine(Engine):
150+
"""Prioritizes capturing moves over quiet moves."""
151+
152+
def get_best_move(self, board, with_evaluation=False):
153+
legal_moves = list(board.legal_moves)
154+
155+
# Prefer captures (sorted by length)
156+
captures = sorted(
157+
[m for m in legal_moves if m.captured_list],
158+
key=lambda m: len(m.captured_list),
159+
reverse=True
160+
)
161+
162+
move = captures[0] if captures else legal_moves[0]
163+
164+
# Simple evaluation: count remaining pieces
165+
white_count = (board._pos == -1).sum() + (board._pos == -2).sum()
166+
black_count = (board._pos == 1).sum() + (board._pos == 2).sum()
167+
score = (black_count - white_count) if board.turn.value == 0 else (white_count - black_count)
168+
169+
if with_evaluation:
170+
return move, float(score)
171+
return move
172+
173+
Running Custom Engines with the Server
174+
---------------------------------------
175+
176+
The ``Server`` class accepts any engine implementation through the ``engine`` parameter
177+
or via the ``get_best_move_method`` callback.
178+
179+
Method 1: Using the ``engine`` Parameter (Recommended)::
180+
181+
from draughts import StandardBoard
182+
from draughts.engine import AlphaBetaEngine
183+
from draughts.server import Server
184+
import uvicorn
185+
186+
# Create board and engine
187+
board = StandardBoard()
188+
engine = AlphaBetaEngine(depth=6)
189+
190+
# Create server with engine
191+
server = Server(board=board, engine=engine)
192+
193+
# Run server on http://localhost:8000
194+
uvicorn.run(server.APP, host="127.0.0.1", port=8000)
195+
196+
Method 2: Using ``get_best_move_method`` Callback::
197+
198+
from draughts import StandardBoard
199+
from draughts.server import Server
200+
import uvicorn
201+
202+
board = StandardBoard()
203+
204+
# Define custom move selection function
205+
def my_move_strategy(board):
206+
# Your custom logic here
207+
legal_moves = list(board.legal_moves)
208+
return legal_moves[0] # Simple example
209+
210+
server = Server(board=board, get_best_move_method=my_move_strategy)
211+
uvicorn.run(server.APP, host="127.0.0.1", port=8000)
212+
141213

142214
Benchmarking the Engine
143215
-----------------------

0 commit comments

Comments
 (0)