added lichess bot
This commit is contained in:
95
lichess_bot/lib/strategies.py
Normal file
95
lichess_bot/lib/strategies.py
Normal file
@@ -0,0 +1,95 @@
|
||||
"""
|
||||
Some example strategies for people who want to create a custom, homemade bot.
|
||||
|
||||
With these classes, bot makers will not have to implement the UCI or XBoard interfaces themselves.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
import chess
|
||||
from chess.engine import PlayResult, Limit
|
||||
import random
|
||||
from lib.engine_wrapper import MinimalEngine, MOVE
|
||||
from typing import Any
|
||||
import logging
|
||||
|
||||
|
||||
# Use this logger variable to print messages to the console or log files.
|
||||
# logger.info("message") will always print "message" to the console or log file.
|
||||
# logger.debug("message") will only print "message" if verbose logging is enabled.
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ExampleEngine(MinimalEngine):
|
||||
"""An example engine that all homemade engines inherit."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
# Strategy names and ideas from tom7's excellent eloWorld video
|
||||
|
||||
class RandomMove(ExampleEngine):
|
||||
"""Get a random move."""
|
||||
|
||||
def search(self, board: chess.Board, *args: Any) -> PlayResult:
|
||||
"""Choose a random move."""
|
||||
return PlayResult(random.choice(list(board.legal_moves)), None)
|
||||
|
||||
|
||||
class Alphabetical(ExampleEngine):
|
||||
"""Get the first move when sorted by san representation."""
|
||||
|
||||
def search(self, board: chess.Board, *args: Any) -> PlayResult:
|
||||
"""Choose the first move alphabetically."""
|
||||
moves = list(board.legal_moves)
|
||||
moves.sort(key=board.san)
|
||||
return PlayResult(moves[0], None)
|
||||
|
||||
|
||||
class FirstMove(ExampleEngine):
|
||||
"""Get the first move when sorted by uci representation."""
|
||||
|
||||
def search(self, board: chess.Board, *args: Any) -> PlayResult:
|
||||
"""Choose the first move alphabetically in uci representation."""
|
||||
moves = list(board.legal_moves)
|
||||
moves.sort(key=str)
|
||||
return PlayResult(moves[0], None)
|
||||
|
||||
|
||||
class ComboEngine(ExampleEngine):
|
||||
"""
|
||||
Get a move using multiple different methods.
|
||||
|
||||
This engine demonstrates how one can use `time_limit`, `draw_offered`, and `root_moves`.
|
||||
"""
|
||||
|
||||
def search(self, board: chess.Board, time_limit: Limit, ponder: bool, draw_offered: bool, root_moves: MOVE) -> PlayResult:
|
||||
"""
|
||||
Choose a move using multiple different methods.
|
||||
|
||||
:param board: The current position.
|
||||
:param time_limit: Conditions for how long the engine can search (e.g. we have 10 seconds and search up to depth 10).
|
||||
:param ponder: Whether the engine can ponder after playing a move.
|
||||
:param draw_offered: Whether the bot was offered a draw.
|
||||
:param root_moves: If it is a list, the engine should only play a move that is in `root_moves`.
|
||||
:return: The move to play.
|
||||
"""
|
||||
if isinstance(time_limit.time, int):
|
||||
my_time = time_limit.time
|
||||
my_inc = 0
|
||||
elif board.turn == chess.WHITE:
|
||||
my_time = time_limit.white_clock if isinstance(time_limit.white_clock, int) else 0
|
||||
my_inc = time_limit.white_inc if isinstance(time_limit.white_inc, int) else 0
|
||||
else:
|
||||
my_time = time_limit.black_clock if isinstance(time_limit.black_clock, int) else 0
|
||||
my_inc = time_limit.black_inc if isinstance(time_limit.black_inc, int) else 0
|
||||
|
||||
possible_moves = root_moves if isinstance(root_moves, list) else list(board.legal_moves)
|
||||
|
||||
if my_time / 60 + my_inc > 10:
|
||||
# Choose a random move.
|
||||
move = random.choice(possible_moves)
|
||||
else:
|
||||
# Choose the first move alphabetically in uci representation.
|
||||
possible_moves.sort(key=str)
|
||||
move = possible_moves[0]
|
||||
return PlayResult(move, None, draw_offered=draw_offered)
|
||||
Reference in New Issue
Block a user