When you run the MICS client, you can tell it which AI to load with the -a argument. So if you run 'client.py -a myai' the program will load 'myai.py' in the 'ai' folder, and instantiate the 'Brain' class. The client comes with 4 basic AI's: simple, count, greedy, and raw. The simplest possible ai (raw) looks like this:
class Brain(object):
def __init__(self, initial_depth, move_callback, output_callback, opening_book, randomness_factor):
self.cb = move_callback
def __call__(self, board):
self.cb(raw_input("enter from:"), raw_input("enter to:"))
This, unfortunately, doesn't really do any thinking for you. Here's greedy, a bot that actually does something:
from chesstools.ai import AI
WEIGHT = {'King':100, 'Queen':9, 'Rook':5, 'Bishop':3, 'Knight':2, 'Pawn':1}
class Brain(AI):
def evaluate(self, board):
score = 0
for piece in board.pieces():
mult = piece.color == board.turn and 1 or -1
score += mult*WEIGHT[piece.name]
return score
The key here is chesstools.ai.AI, which takes care of all the messy stuff, like alpha-beta pruning, transposition tables, and opening book searching, leaving you with a single function to implement: evaluate. This function takes a "board" object and returns a numerical score. That's it.
The board object can tell you a lot about a position. Here are some key functions that will tell you everything you need to know to score a position. (the "dest" parameter is a chesstools.Move.destination-like matrix of the form [row (0-7), column (0-7)])
board.turn
'white' or 'black'
board.kings
a dictionary with 'white' and 'black' corresponding to the white and black kings
board.pieces()
returns a list of all the pieces on the board. narrow your search with optional parameters "color", "row", "column", and "type"
board.pawns()
returns a list of all the pawns on the board. narrow your search with optional parameters "color", "row", and "column"
board.all_focused(dest)
returns a list of all the pieces on the board that can attack dest. board.all_focused(dest, 'white') or board.all_focused(dest, 'black') returns the pieces of that color that can target dest
board.all_legal_moves()
returns a list of the moves that the current player can make in the current position
board.all_opponent_moves()
returns a list of the moves that the other player could make if it were her turn
You can get more detailed information about the pieces, as well.
piece.color
the piece's color
piece.name
piece type: "Pawn", "Rook", etc
piece.row()
returns the piece's 'row' index in the board's position matrix
piece.column()
returns the piece's 'column' index in the board's position matrix
piece.can_move()
returns True or False
piece.can_target(dest)
returns True or False
piece.can_take(dest)
returns whether a move to dest constitutes a legal capture (True or False). does _not_ take king safety into account
piece.legal_move(dest)
returns whether this move is possible without endangering the King (True or False)
piece.all_legal_moves()
returns a list of the moves that the piece can make in the current position
Certain pieces have more specialized information, such as the Pawn:
pawn.advancement()
returns a positive integer between 1 and 6, representing how close the pawn is to promotion
pawn.supporting_pawns()
returns the number of friendly flanking pawns
pawn.opposing_pawns()
returns the number of enemy pawns that hinder advancement
Check out the
source, too. It's clean and should be helpful. Comments welcome.