Sure. Run -

python chess.py


2014-03-21 19:50 GMT+02:00 Maciej Fijalkowski <[email protected]>:

> can you share the script?
>
> On Fri, Mar 21, 2014 at 4:27 PM, KoDer <[email protected]> wrote:
> > Hi all,
> >
> > I have a quite simple python script, which mostly don't use python
> dynamic
> > features,
> > but it almost two times slower unded latest pypy than under python 2.6.7.
> >
> > Is there any way to check, that jit actually working?
> >
> > pypy is builded from source with
> >> python ../../rpython/bin/rpython -Ojit targetpypystandalone
> >
> > [PyPy 2.2.1 with GCC 4.8.1] on linux2
> >
> >
> > Thanks
> > --
> > K.Danilov aka koder
> > Skype:koder.ua
> > Tel:+38-050-4030512
> >
> > _______________________________________________
> > pypy-dev mailing list
> > [email protected]
> > https://mail.python.org/mailman/listinfo/pypy-dev
> >
>



-- 
K.Danilov aka koder
ICQ:214286120
Skype:koder.ua
Tel:+38-050-4030512
import time
from abc import abstractmethod


from chess_base import board_letters, to_str_pos, to_tuple_pos, all_valid_poses, rev_color


class ChessPiece(object):
    name = None
    def_cost = None

    precached_moves = {}

    def __init__(self, pos, color):
        self.pos = to_tuple_pos(pos)
        self.color = color
        self.cost = self.def_cost if self.color == "W" else -self.def_cost

    def move(self, pos):
        self.pos = to_tuple_pos(pos)

    @abstractmethod
    def get_move_cells(self):
        pass

    def get_hit_cells(self):
        return self.get_move_cells()

    def hit_cells(self):
        return self.move_cells()

    def move_cells(self):
        res = self.precached_moves.get((self.pos, self.color))
        if res is None:
            res = self.get_move_cells()
            self.precached_moves[(self.pos, self.color)] = res
        return res

    def full_name(self):
        return self.color + self.name

    def __str__(self):
        return "{}({!r}, {!r})".format(self.__class__.__name__, self.pos, self.color)

    def __repr__(self):
        return str(self)


class Pawn(ChessPiece):
    name = "P"
    def_cost = 1

    precached_moves = {}
    precached_hits = {}

    def get_hit_cells(self):
        x, y = self.pos
        if self.color == "W":
            poses = [(x + 1, y + 1), (x - 1, y + 1)]
        else:
            poses = [(x + 1, y - 1), (x - 1, y - 1)]

        return [[i] for i in poses if i in all_valid_poses]

    def get_move_cells(self):
        x, y = self.pos
        if self.color == "W":
            poses = [(x, y + 1)]
            if y == 1:
                poses.append((x, y + 2))
        else:
            poses = [(x, y - 1)]
            if y == 6:
                poses.append((x, y - 2))
            
        return [[i for i in poses if i in all_valid_poses]]

    def hit_cells(self):
        res = self.precached_hits.get((self.pos, self.color))
        if res is None:
            res = self.get_hit_cells()
            self.precached_hits[(self.pos, self.color)] = res
        return res


class Knight(ChessPiece):
    name = "N"
    def_cost = 3

    precached_moves = {}
    precached_hits = {}

    def get_move_cells(self):
        x, y = self.pos
        poses = [
                 (x + 2, y + 1), 
                 (x + 2, y - 1),
                 (x + 1, y + 2),
                 (x + 1, y - 2),
                 (x - 2, y + 1), 
                 (x - 2, y - 1),
                 (x - 1, y + 2),
                 (x - 1, y - 2),
                 ]

        return [[i] for i in poses if i in all_valid_poses]


class Rook(ChessPiece):
    name = "R"
    def_cost = 4

    precached_moves = {}
    precached_hits = {}

    def get_move_cells(self):
        x, y = self.pos

        res = []
        poses = []
        for i in range(1, 8):
            poses.append((x, y + i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x, y - i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x + i, y))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x - i, y))
        res.append([i for i in poses if i in all_valid_poses])

        return res


class Bishop(ChessPiece):
    name = "B"
    def_cost = 3
    
    precached_moves = {}
    precached_hits = {}

    def get_move_cells(self):
        res = []
        x, y = self.pos

        poses = []
        for i in range(1, 8):
            poses.append((x + i, y + i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x + i, y - i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x - i, y + i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x - i, y - i))
        res.append([i for i in poses if i in all_valid_poses])

        return res


class Queen(ChessPiece):
    name = "Q"
    def_cost = 8

    precached_moves = {}
    precached_hits = {}

    def get_move_cells(self):
        x, y = self.pos

        res = []

        poses = []
        for i in range(1, 8):
            poses.append((x, y + i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x, y - i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x + i, y))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x - i, y))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x + i, y + i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x + i, y - i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x - i, y + i))
        res.append([i for i in poses if i in all_valid_poses])

        poses = []
        for i in range(1, 8):
            poses.append((x - i, y - i))
        res.append([i for i in poses if i in all_valid_poses])

        return res 

class King(ChessPiece):
    name = "K"    
    def_cost = 1000000

    precached_moves = {}
    precached_hits = {}

    def get_move_cells(self):
        x, y = self.pos

        poses = [(x + 1, y + 1)]
        poses.append((x - 1, y + 1))
        poses.append((x + 1, y - 1))
        poses.append((x - 1, y - 1))

        poses.append((x, y + 1))
        poses.append((x, y - 1))
        poses.append((x + 1, y))
        poses.append((x - 1, y))

        return [[i] for i in poses if i in all_valid_poses]

def position_evaluate(board):
    return board.sum_cost

def hit_chain(board, pos):
    w_chain = []
    b_chain = []

    def add_to_chain(p, to_new):
        c = w_chain if p.color == "W" else b_chain
        if to_new:
            c.append([p])
        else:
            c[-1].append(p)

    x,y = pos

    # check for knights
    for npos in ((x + dx, y + dy) 
                    for dx in (1, 2, -1, -2) 
                        for dy in (3 - abs(dx), -3 + abs(dx))):
        p = board.get(npos)
        if isinstance(p, Knight):
            add_to_chain(p, True)

    # check for other figures
    bishop_vec = [(1, 1), (1, -1), (-1, 1), (-1, -1)]

    for dx, dy in bishop_vec:
        w_chain.append([])
        b_chain.append([])
        for step in range(7):
            
            nx = x + step * dx
            ny = y + step * dy

            if (nx, ny) not in all_valid_poses:
                break

            p = board.get((nx, ny))
            if p is not None:
                if isinstance(p, Pawn) and step == 1:
                    if pos in [i[0] for i in p.hit_cells()]:
                        add_to_chain(p, False)
                elif isinstance(p, King) and step == 1:
                    add_to_chain(p, False)
                elif isinstance(p, (Bishop, Queen)):
                    add_to_chain(p, False)
                else:
                    # find a piece, which can't hit - it will block all firther pieces from hit
                    break

    # check for other figures
    rook_vec = [(1, 0), (-1, 0), (0, 1), (0, -1)]

    for dx, dy in rook_vec:
        w_chain.append([])
        b_chain.append([])
        for step in range(7):
            
            nx = x + step * dx
            ny = y + step * dy

            if (nx, ny) not in all_valid_poses:
                break

            p = board.get((nx, ny))
            if p is not None:
                if isinstance(p, King) and step == 1:
                    add_to_chain(p, False)
                elif isinstance(p, (Rook, Queen)):
                    add_to_chain(p, False)
                else:
                    # find a piece, which can't hit - it will block all firther pieces from hit
                    break

    res_w = []
    res_b = []
    for hc, res_c in ((b_chain, res_b), (w_chain, res_w)):
        hc = [i for i in hc if i != []]
        while hc != []:
            hc.sort(key = lambda x: x[0].def_cost)
            res_c.append(hc[0][0])
            del hc[0][0]
            hc = [i for i in hc if i != []]

    return res_w, res_b


def get_next_step(board, for_color, level=2):
    moves = None
    best_evaluate = None
    
    cfunc = lambda val: val if for_color == "W" else -val

    for piece in board:
        if piece.color == for_color:
            for mv in board.get_all_moves(piece):
                ppos = piece.pos
                board.move(piece, mv)

                if level != 1:
                    next_moves, new_val = get_next_step(board, rev_color[for_color], level - 1)
                    new_val = -new_val
                else:
                    new_val = cfunc(position_evaluate(board))
                    next_moves = []

                board.move(piece, ppos)

                if new_val > best_evaluate or best_evaluate is None :
                    best_evaluate = new_val
                    moves = [(piece.pos, mv)] + next_moves

            for hit in board.get_all_hits(piece):
                
                ppos = piece.pos
                removed_piece = board.get(hit)

                board.remove(hit)
                board.move(piece, hit)

                if level != 1:
                    next_moves, new_val = get_next_step(board, rev_color[for_color], level - 1)
                    new_val = -new_val
                else:
                    new_val = cfunc(position_evaluate(board))
                    next_moves = []
                
                board.move(piece, ppos)
                board.add(removed_piece)

                if best_evaluate is None or new_val > best_evaluate:
                    best_evaluate = new_val
                    moves = [(piece.pos, hit)] + next_moves

    return moves, best_evaluate


def knorre_vs_neumann():
    p = [Pawn(i, "B") for i in "A6,B7,C6,C7,G4,H5".split(",")]
    p += [Pawn(i, "W") for i in "A2,B2,C2,E4,H4,G2".split(",")]
    p += [Rook("D1", "W"), Rook("F5", "W"), Rook("G8", "B"), Rook("E8", "B")]
    p += [Knight("G5", "W"), Bishop("G3", "W"), Knight("E5", "B"), Bishop("D6", "B")]    
    return p + [King("B8", "B"), King("H1", "W"), Queen("C3", "W"), Queen("E7", "B")]    

def get_start_board():
    pieces = [Pawn("{}2".format(i), "W") for i in board_letters]
    pieces += [Pawn("{}7".format(i), "B") for i in board_letters]
    pieces += [Bishop("C1", "W"), Bishop("F1", "W")]
    pieces += [Bishop("C8", "B"), Bishop("F8", "B")]
    pieces += [Knight("B1", "W"), Knight("G1", "W")]
    pieces += [Knight("B8", "B"), Knight("G8", "B")]
    pieces += [Rook("A1", "W"), Rook("H1", "W")]
    pieces += [Rook("A8", "B"), Rook("H8", "B")]
    pieces += [Rook("A8", "B"), Rook("H8", "B")]
    pieces += [Queen("E8", "B"), Queen("E1", "W")]
    pieces += [King("D8", "B"), King("D1", "W")]
    return pieces

class Board(object):

    # board is list of pieces
    def __init__(self, pieces):
        self.pieces = pieces
        self.pieces_map = {piece.pos:piece for piece in self}
        self.sum_cost = sum(piece.cost for piece in pieces)

    def __iter__(self):
        return iter(self.pieces)

    def get_all_moves(self, piece):
        for linked_moves in piece.move_cells():
            for pos in linked_moves:
                if pos in self.pieces_map:
                    break
                yield pos

    def get_all_hits(self, piece):
        for linked_hits in piece.hit_cells():
            for pos in linked_hits:
                hited_piece = self.pieces_map.get(pos)
                if hited_piece is None:
                    continue
                elif hited_piece.color != piece.color:
                    yield pos
                break

    def get(self, pos):
        return self.pieces_map.get(pos)

    def remove(self, pos):
        piece = self.pieces_map[pos]
        del self.pieces_map[pos]
        self.pieces.remove(piece)
        self.sum_cost -= piece.cost

    def add(self, piece):
        self.sum_cost += piece.cost
        self.pieces.append(piece)
        self.pieces_map[piece.pos] = piece

    def move(self, piece, pos):
        del self.pieces_map[piece.pos]
        piece.move(pos)
        self.pieces_map[pos] = piece


if __name__ == "__main__":
    board = Board(knorre_vs_neumann())

    t = time.time()
    moves, val = get_next_step(board, "W", 3)
    print time.time() - t

    print "best val =", val
    for frm, to in moves:
        print to_str_pos(frm), to_str_pos(to)

#print hit_chain(board, to_tuple_pos("E5"))
board_letters = "ABCDEFGH"

def to_str_pos(tuple_pos):
    return board_letters[tuple_pos[0]] + str(tuple_pos[1] + 1)

def to_tuple_pos(str_pos):
    if isinstance(str_pos, tuple):
        return str_pos
    char, pos = str_pos
    return (board_letters.index(char), int(pos) - 1)

all_valid_poses = {(x,y) for x in range(8) for y in range(8)}

def check_pos_valid(val):
    assert val in all_valid_poses
    #assert isinstance(val, tuple)
    #assert len(val) == 2
    #assert isinstance(val[0], int)
    #assert isinstance(val[1], int)
    #assert 0 <= val[0] <= 7
    #assert 0 <= val[1] <= 7

def is_valid_cell(pos):
    try:
        check_pos_valid(pos)
    except AssertionError:
        return False
    return True

rev_color = {"B":"W", "W":"B"}
_______________________________________________
pypy-dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-dev

Reply via email to