New to Python, which I really like BTW.

First serious prog. Hope you like it. I know it needs a 'can't move if your King would be put into check' test. But the weighted value of the King piece does a surprising emergent job.

#!/usr/bin/python -tt
# -*- coding: utf-8 -*-
# Copyright (C) 2013 Chris Hinsley, GPL V3 License

import sys
import random
import os

PLY = 3

EMPTY = 0
BLACK = 1
WHITE = 2
NO_CAPTURE = 3
MAY_CAPTURE = 4
MUST_CAPTURE = 5

def piece_type(piece):
   return EMPTY if piece == 32 else BLACK if chr(piece) in 'KQRBNP' else WHITE

def display_board(board):
   print '  a   b   c   d   e   f   g   h'
   print '+---+---+---+---+---+---+---+---+'
   for row in range(8):
       for col in range(8):
           sys.stdout.write('| ')
           sys.stdout.write(chr(board[row * 8 + col]))
           sys.stdout.write(' ')
       sys.stdout.write('|')
       print 8 - row
       print '+---+---+---+---+---+---+---+---+'

def piece_moves(board, index, dx, dy, capture_flag, distance):
   piece = board[index]
   type = piece_type(piece)
   cx = index % 8
   cy = index / 8
   for step in range(distance):
       nx = cx + (dx * (step + 1))
       ny = cy + (dy * (step + 1))
       if nx in range(8) and ny in range(8):
           newindex = ny * 8 + nx
           newpiece = board[newindex]
           newtype = piece_type(newpiece)
           if capture_flag == MUST_CAPTURE:
               if newtype != EMPTY and newtype != type:
                   board[index] = ' '
                   if (ny == 0 or ny == 7) and chr(piece) in 'Pp':
                       for promote in 'QRBN' if type == BLACK else 'qrbn':
                           board[newindex] = promote
                           yield board
                   else:
                       board[newindex] = piece
                       yield board
                   board[index], board[newindex] = piece, newpiece
           elif capture_flag == MAY_CAPTURE:
               if newtype == EMPTY or newtype != type:
                   board[index], board[newindex] = ' ', piece
                   yield board
                   board[index], board[newindex] = piece, newpiece
               break
           elif newtype == EMPTY:
               board[index] = ' '
               if (ny == 0 or ny == 7) and chr(piece) in 'Pp':
                   for promote in 'QRBN' if type == BLACK else 'qrbn':
                       board[newindex] = promote
                       yield board
               else:
                   board[newindex] = piece
                   yield board
               board[index], board[newindex] = piece, newpiece
       else:
           break

def pawn_moves(board, index, options):
   for x, y, flag, distance in options:
       for new_board in piece_moves(board, index, x, y, flag, distance):
           yield new_board

def other_moves(board, index, options, distance):
   for x, y in options:
for new_board in piece_moves(board, index, x, y, MAY_CAPTURE, distance):
           yield new_board

def black_pawn_moves(board, index):
   distance = 2 if index in range(8, 16) else 1
for new_board in pawn_moves(board, index, [(0, 1, NO_CAPTURE, distance), (-1, 1, MUST_CAPTURE, 1), (1, 1, MUST_CAPTURE, 1)]):
       yield new_board

def white_pawn_moves(board, index):
   distance = 2 if index in range(48, 56) else 1
for new_board in pawn_moves(board, index, [(0, -1, NO_CAPTURE, distance), (-1, -1, MUST_CAPTURE, 1), (1, -1, MUST_CAPTURE, 1)]):
       yield new_board

def rook_moves(board, index):
for new_board in other_moves(board, index, [(0, -1), (-1, 0), (0, 1), (1, 0)], 7):
       yield new_board

def bishop_moves(board, index):
for new_board in other_moves(board, index, [(-1, -1), (-1, 1), (1, 1), (1, -1)], 7):
       yield new_board

def knight_moves(board, index):
for new_board in other_moves(board, index, [(-2, 1), (2, -1), (2, 1), (-1, -2), (-1, 2), (1, -2), (1, 2)], 1):
       yield new_board

def queen_moves(board, index):
   for new_board in bishop_moves(board, index):
       yield new_board
   for new_board in rook_moves(board, index):
       yield new_board

def king_moves(board, index):
for new_board in other_moves(board, index, [(0, -1), (-1, 0), (0, 1), (1, 0), (-1, -1), (-1, 1), (1, 1), (1, -1)], 1):
       yield new_board

moves = {'P' : black_pawn_moves, 'p' : white_pawn_moves, \
       'R' : rook_moves, 'r' : rook_moves, \
       'B' : bishop_moves, 'b' : bishop_moves, \
       'N' : knight_moves, 'n' : knight_moves, \
       'Q' : queen_moves, 'q' : queen_moves, \
       'K' : king_moves, 'k' : king_moves}

def all_moves(board, turn):
   for index, piece in enumerate(board):
       if piece_type(piece) == turn:
           for new_board in moves[chr(piece)](board, index):
               yield new_board

piece_values = {'K' : (1000000, 0), 'k' : (0, 1000000), \
               'P' : (1, 0), 'p' : (0, 1), \
               'N' : (3, 0), 'n' : (0, 3), \
               'B' : (3, 0), 'b' : (0, 3), \
               'R' : (5, 0), 'r' : (0, 5), \
               'Q' : (9, 0), 'q' : (0, 9)}

position_values = [0, 0, 0, 0, 0, 0, 0, 0, \
                   0, 1, 1, 1, 1, 1, 1, 0, \
                   0, 1, 2, 2, 2, 2, 1, 0, \
                   0, 1, 2, 3, 3, 2, 1, 0, \
                   0, 1, 2, 3, 3, 2, 1, 0, \
                   0, 1, 2, 2, 2, 2, 1, 0, \
                   0, 1, 1, 1, 1, 1, 1, 0, \
                   0, 0, 0, 0, 0, 0, 0, 0]

def score_board(board):
   black_score, white_score = 0, 0
   for index, piece in enumerate(board):
       type = piece_type(piece)
       if type != EMPTY:
           position_value = position_values[index]
           if type == BLACK:
               black_score += position_value
           else:
               white_score += position_value
           black_value, white_value = piece_values[chr(piece)]
           black_score += black_value
           white_score += white_value
   return (black_score, white_score)

def turn_score(board, turn):
   black_score, white_score = score_board(board)
return (white_score - black_score) if turn == WHITE else (black_score - white_score)

def best_move(board, turn, ply):
   best_score = -10000000
   best_boards = []
   for new_board in all_moves(board, turn):
       if ply:
           next_turn = BLACK if turn == WHITE else WHITE
           score = turn_score(best_move(new_board, next_turn, ply - 1), turn)
       else:
           score = turn_score(new_board, turn)
       if score > best_score or not best_boards:
           best_score = score
           best_boards = [new_board[:]]
       elif score == best_score:
           best_boards.append(new_board[:])
   if best_boards:
       return random.choice(best_boards)
   return board[:]

def main():
board = bytearray('RNBQKBNRPPPPPPPP pppppppprnbqkbnr')
   turn = WHITE
   while True:
       board = best_move(board, turn, PLY)
       turn = BLACK if turn == WHITE else WHITE
       os.system('clear')
       display_board(board)
       #raw_input()

if __name__ == '__main__':
   main()

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to