NNTP-Posting-Date: Wed, 13 Feb 2013 17:25:09 -0600 From: Chris Hinsley Newsgroups: comp.lang.python Date: Wed, 13 Feb 2013 23:25:09 +0000 Message-ID: <2013021323250974803-chrishinsley@gmailcom> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1; format=flowed Content-Transfer-Encoding: 8bit Subject: First attempt at a Python prog (Chess) User-Agent: Unison/2.1.10 Lines: 210 X-Usenet-Provider: http://www.giganews.com X-Trace: sv3-lOTzNB0DTxBSvLooMPcxDtk9pDJm/wXK7GFpxmngfMrqC4JvZQI188SzExAiAJu98SR3/mBSQUiZVlF!numcNDm8dCbied5xppxKNCVYxrX9h0bUQPvRrwUTS0bDo1XzkQ+Bk0VXGWchAiZplCTNazGu X-Complaints-To: abuse@giganews.com X-DMCA-Notifications: http://www.giganews.com/info/dmca.html X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.40 X-Original-Bytes: 8410 Path: csiph.com!usenet.pasdenom.info!news.stben.net!border3.nntp.ams.giganews.com!Xl.tags.giganews.com!border1.nntp.ams.giganews.com!nntp.giganews.com!local2.nntp.ams.giganews.com!news.giganews.com.POSTED!not-for-mail Xref: csiph.com comp.lang.python:38832 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()