Example #1
0
 def setUp(self):
     self.camera = Camera(self.url)
     self.chessEngine = ChessEngine()
     self.board = 0
     self.current = 0
     self.previous = 0
     self.CPULastMove = "0"
Example #2
0
    def __init__(self):
        self._loadWorld('./main.xml')
        self._loadSensor('./camera.rob')

        self.chessEngine = ChessEngine(self.world,
                                       self.world.terrain('tabletop'))
        self.chessEngine.loadPieces()
        self.chessEngine.loadBoard()

        self.chessEngine.arrangeBoard(90)
        self.chessEngine.arrangePieces()

        self._imageDir = 'image_dataset'

        self._colorDir = self._imageDir + '/color'
        self._depthDir = self._imageDir + '/depth'
        self._rectifiedDir = self._imageDir + '/rectified'

        self._metaDataFN = self._imageDir + '/metadata.csv'

        self._dirs = [
            self._imageDir, self._colorDir, self._depthDir, self._rectifiedDir
        ]

        self._colorFNFormat = self._colorDir + '/%06d_%02d.png'
        self._depthFNFormat = self._depthDir + '/%06d_%02d.png'
        self._rectifiedFNFormat = self._rectifiedDir + '/%06d.png'

        self._rectifiedPictureCorners = np.float32(
            [[DataUtils.IMAGE_SIZE, 0], [0, 0], [0, DataUtils.IMAGE_SIZE],
             [DataUtils.IMAGE_SIZE, DataUtils.IMAGE_SIZE]])
        self._boardWorldCorners = self.chessEngine.getBoardCorners()
Example #3
0
 def __init__(self):
     pg.init()
     self.screen = pg.display.set_mode((WIDTH + TF_WIDTH, HEIGHT),
                                       pg.SRCALPHA, 32)
     self.clock = pg.time.Clock()
     pg.display.set_caption(TITLE)
     icon = pg.image.load(IMAGE_FILE_DICT["wR"])
     pg.display.set_icon(icon)
     self.load_data()
     self.engine = ChessEngine()
     self.AI = ChessAI(MAX_SEARCH_DEPTH)
    def test_set_board(self):
        expected_result = [[2,3,4,5,6,4,3,2],
                           [1,1,1,1,1,1,1,1],
                           [0,0,0,0,0,0,0,0],
                           [0,0,0,0,0,0,0,0],
                           [0,0,0,0,0,0,0,0],
                           [0,0,0,0,0,0,0,0],
                           [7,7,7,7,7,7,7,7],
                           [8,9,10,11,12,10,9,8]]

        # Create chess engine
        engine = ChessEngine()
        engine.set_board(self.initial_board_description)
        self.assertEqual(engine.board, expected_result)
    def test_move(self):
        commands_to_test = ['e4', 'e5', 'Qh5', 'Nc6', 'Bc4', 'Nf6']
        expected_results = []
        expected_results.append([[2,3,4,5,6,4,3,2],
                                 [1,1,1,1,0,1,1,1],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,0,0,1,0,0,0],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,0,0,0,0,0,0],
                                 [7,7,7,7,7,7,7,7],
                                 [8,9,10,11,12,10,9,8]])
        expected_results.append([[2,3,4,5,6,4,3,2],
                                 [1,1,1,1,0,1,1,1],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,0,0,1,0,0,0],
                                 [0,0,0,0,7,0,0,0],
                                 [0,0,0,0,0,0,0,0],
                                 [7,7,7,7,0,7,7,7],
                                 [8,9,10,11,12,10,9,8]])
        expected_results.append([[2,3,4,0,6,4,3,2],
                                 [1,1,1,1,0,1,1,1],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,0,0,1,0,0,0],
                                 [0,0,0,0,7,0,0,5],
                                 [0,0,0,0,0,0,0,0],
                                 [7,7,7,7,0,7,7,7],
                                 [8,9,10,11,12,10,9,8]])
        expected_results.append([[2,3,4,0,6,4,3,2],
                                 [1,1,1,1,0,1,1,1],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,0,0,1,0,0,10],
                                 [0,0,0,0,7,0,0,5],
                                 [0,0,0,0,0,0,0,0],
                                 [7,7,7,7,0,7,7,7],
                                 [8,9,0,11,12,10,9,8]])
        expected_results.append([[2,3,4,0,6,0,3,2],
                                 [1,1,1,1,0,1,1,1],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,4,0,1,0,0,10],
                                 [0,0,0,0,7,0,0,5],
                                 [0,0,0,0,0,0,0,0],
                                 [7,7,7,7,0,7,7,7],
                                 [8,9,0,11,12,10,9,8]])
        expected_results.append([[2,3,4,0,6,0,3,2],
                                 [1,1,1,1,0,1,1,1],
                                 [0,0,0,0,0,0,0,0],
                                 [0,0,4,0,1,0,0,10],
                                 [0,0,0,0,7,0,0,5],
                                 [0,0,0,0,0,9,0,0],
                                 [7,7,7,7,0,7,7,7],
                                 [8,9,0,11,12,10,0,8]])

        # Create chess engine
        engine = ChessEngine()
        engine.set_board(self.initial_board_description)

        # Movement
        for move, result in zip(commands_to_test, expected_results):
            engine.parse(move)
            self.assertEqual(engine.board, expected_results)
Example #6
0
class DataGenerator:
    def __init__(self):
        self._loadWorld('./main.xml')
        self._loadSensor('./camera.rob')

        self.chessEngine = ChessEngine(self.world,
                                       self.world.terrain('tabletop'))
        self.chessEngine.loadPieces()
        self.chessEngine.loadBoard()

        self.chessEngine.arrangeBoard(90)
        self.chessEngine.arrangePieces()

        self._imageDir = 'image_dataset'

        self._colorDir = self._imageDir + '/color'
        self._depthDir = self._imageDir + '/depth'
        self._rectifiedDir = self._imageDir + '/rectified'

        self._metaDataFN = self._imageDir + '/metadata.csv'

        self._dirs = [
            self._imageDir, self._colorDir, self._depthDir, self._rectifiedDir
        ]

        self._colorFNFormat = self._colorDir + '/%06d_%02d.png'
        self._depthFNFormat = self._depthDir + '/%06d_%02d.png'
        self._rectifiedFNFormat = self._rectifiedDir + '/%06d.png'

        self._rectifiedPictureCorners = np.float32(
            [[DataUtils.IMAGE_SIZE, 0], [0, 0], [0, DataUtils.IMAGE_SIZE],
             [DataUtils.IMAGE_SIZE, DataUtils.IMAGE_SIZE]])
        self._boardWorldCorners = self.chessEngine.getBoardCorners()

    def _loadWorld(self, world_fn):
        world = WorldModel()
        res = world.readFile(world_fn)

        if not res:
            print("Unable to read file", world_fn)
            exit(0)
        for i in range(world.numRigidObjects()):
            obj = world.rigidObject(i)
            #this will perform a reasonable center of mass / inertia estimate
            m = obj.getMass()
            m.estimate(obj.geometry(), mass=0.454, surfaceFraction=0.2)
            obj.setMass(m)

        self.world = world

    def _loadSensor(self, sensor_fn):
        try:
            self.world.readFile(sensor_fn)
        except Exception as e:
            print(f'Error in loading filename: {e}')

        robot = self.world.robot(0)

        if robot is None:
            print("Robot is none: check sensor filename")
            exit(1)

        sensor = self.world.robot(0).sensor(0)

        if sensor is None:
            print("Sensor is none: check sensor filename")
            exit(1)

        self.robot = robot
        self.sensor = sensor

    def _createDatasetDirectory(self):
        for d in self._dirs:
            try:
                os.mkdir(d)
            except Exception:
                pass

    def deleteDataset(self):
        try:
            shutil.rmtree(self._imageDir)
        except OSError as e:
            print(f'Error deleting {self._imageDir}: {e}')

    def _randomlyRotateCamera(self, min_r=0, max_r=70, dist=DIST_FROM_BOARD):
        """
        Randomly rotates camera about x-axis and zooms out from the center of the 
        tabletop

        :param: min_r: the minimum random rotation in degrees
        :param: max_r: the maximum random rotation in degrees
        :param: dist: the distance to zoom out from center of the table 

        :return: the angle of rotation sampled
        """
        min_r = math.radians(min_r)
        max_r = math.radians(max_r)

        table_center = self.chessEngine.getTableCenter()

        table_R = so3.from_axis_angle(([1, 0, 0], -math.pi))
        table_t = table_center

        rot_deg = random.uniform(min_r, max_r)
        zoom_out_R = so3.from_axis_angle(([1, 0, 0], rot_deg))
        zoom_out_t = vectorops.mul(
            [0, math.sin(rot_deg), -math.cos(rot_deg)], dist)

        xform = se3.mul((table_R, table_t), (zoom_out_R, zoom_out_t))

        sensing.set_sensor_xform(self.sensor, xform)

        return rot_deg

    def _rotateCamera(self, r, dist=DIST_FROM_BOARD):
        """
        Rotates a camera and zooms out from center of the tabletop

        :param: r: rotation in degrees
        :param: dist: distance to zoom out from center of the table

        :return: angle of rotation
        """
        return self._randomlyRotateCamera(r, r, dist)

    def generateImages(self, max_pics=100, data_distribution=None):
        assert max_pics > 0

        if data_distribution is None:
            data_distribution = DataUtils.LIMITED_DISTRIBUTION

        assert len(data_distribution) == 13

        self._createDatasetDirectory()

        for i in range(self.world.numRigidObjects()):
            self.world.rigidObject(i).appearance().setSilhouette(0)

        metadata_f = open(self._metaDataFN, mode='w+')
        metadata_f.write('color,depth,piece\n')

        DEPTH_SCALE = 8000

        def loop_through_sensors(world=self.world,
                                 sensor=self.sensor,
                                 max_pics=max_pics):
            for counter in tqdm(range(max_pics)):
                if counter > 0:
                    self.chessEngine.randomizePieces(32)

                # Arrange pieces and model world
                self.chessEngine.arrangePieces()

                self._randomlyRotateCamera(20, 40, 0.6)

                sensor.kinematicReset()
                sensor.kinematicSimulate(world, 0.01)

                rgb, depth = sensing.camera_to_images(self.sensor)

                # Project RGB and depth images to rectify them
                local_corner_coords = np.float32([
                    sensing.camera_project(self.sensor, self.robot, pt)[:2]
                    for pt in self._boardWorldCorners
                ])

                H = cv2.getPerspectiveTransform(local_corner_coords,
                                                self._rectifiedPictureCorners)

                color_rectified = cv2.warpPerspective(
                    rgb, H, (DataUtils.IMAGE_SIZE, DataUtils.IMAGE_SIZE))
                depth_rectified = cv2.warpPerspective(
                    depth, H, (DataUtils.IMAGE_SIZE, DataUtils.IMAGE_SIZE))

                depth_rectified = np.uint8(
                    (depth_rectified - depth_rectified.min()) /
                    (depth_rectified.max() - depth_rectified.min()))

                pieces_arrangement = self.chessEngine.getPieceArrangement()

                images, classes = DataUtils.split_image_by_classes(
                    color_rectified, depth_rectified, data_distribution,
                    pieces_arrangement)

                rectified_fname = self._rectifiedFNFormat % (counter)
                Image.fromarray(color_rectified).save(rectified_fname)

                for idx in range(sum(data_distribution)):
                    color_fname = self._colorFNFormat % (counter, idx)
                    depth_fname = self._depthFNFormat % (counter, idx)

                    Image.fromarray(images[idx, :, :, :3]).save(color_fname)
                    Image.fromarray(images[idx, :, :, 3]).save(depth_fname)

                    metadata_f.write(
                        f'{color_fname},{depth_fname},{classes[idx]}\n')

            vis.show(False)

        vis.loop(callback=loop_through_sensors)

        metadata_f.close()
Example #7
0
import pygame as p
from ChessEngine import ChessEngine
from pygame.constants import MOUSEBUTTONDOWN
p.init()
boardObject = ChessEngine.Board(p)
board = boardObject.board
boardObject.drawBoard()
boardObject.drawPieces()
p.display.update()
running = True
position = (-1, -1)
piece = (-1, -1)
while running:
    for event in p.event.get():
        if event.type == p.QUIT:
            running = False
        if event.type == p.MOUSEBUTTONDOWN:
            position = p.mouse.get_pos()
            piece = board[int(position[0] / boardObject.sqWidth)][int(position[1] / boardObject.sqHeight)]
            if(not boardObject.whiteTurn and piece.isWhite):
                piece = (-1, -1)
            elif(boardObject.whiteTurn and not piece.isWhite):
                piece = (-1, -1)
        if event.type == p.MOUSEBUTTONUP:
            if not piece == (-1, -1):
                nextPos = p.mouse.get_pos()
                if piece.move(position, nextPos, boardObject):
                    boardObject.switchTurn()
                
Example #8
0
class Game():
    def __init__(self):
        pg.init()
        self.screen = pg.display.set_mode((WIDTH + TF_WIDTH, HEIGHT),
                                          pg.SRCALPHA, 32)
        self.clock = pg.time.Clock()
        pg.display.set_caption(TITLE)
        icon = pg.image.load(IMAGE_FILE_DICT["wR"])
        pg.display.set_icon(icon)
        self.load_data()
        self.engine = ChessEngine()
        self.AI = ChessAI(MAX_SEARCH_DEPTH)

    def load_data(self):
        self.image_dict = {}
        for name in IMAGE_FILE_DICT:
            image = pg.image.load(IMAGE_FILE_DICT[name])
            image = pg.transform.scale(image, (TILESIZE, TILESIZE))
            self.image_dict[name] = image

    def new(self):
        self.piece_matrix = [x[:] for x in STARTING_PIECE_MATRIX]
        self.start_pos = ()
        self.board_canvas = BoardCanvas(self)
        self.screen.fill(MAHOGANY)
        self.board_canvas.draw()
        self.text_panel = TextPanel()
        self.checked = ""
        self.computer_turn = False

    def run(self):
        self.running = True
        while self.running:
            self.clock.tick(FPS)
            if self.computer_turn:
                self.handle_computer_turn()
            self.events()
            self.draw()

    def handle_computer_turn(self):
        move = self.AI.search(self.piece_matrix, -sys.maxsize, sys.maxsize)
        piece = self.piece_matrix[move[0][0]][move[0][1]]
        self.move_piece(move[0], move[1], 'C')
        text = "Computer moved " + CHAR_TO_STR[
            piece[1]] + " to " + BOARD_CANVAS_CHARS[move[1][1]] + str(
                7 - move[1][0] + 1) + ". Score: " + str(
                    move[2]) + ". Nodes: " + str(
                        move[3][0]) + " CutOffs: " + str(move[3][1])
        self.text_panel.write(text)

    def animate_movement(self, start_tile, end_tile, piece):
        current_pos = vector(start_tile[1] * TILESIZE + MARGIN,
                             start_tile[0] * TILESIZE + MARGIN)
        end_pos = vector(end_tile[1] * TILESIZE + MARGIN,
                         end_tile[0] * TILESIZE + MARGIN)
        direction = end_pos - current_pos
        direction = direction.normalize() * 8
        image = self.image_dict[piece]
        while (end_pos.x - 10 > current_pos.x or current_pos.x > end_pos.x + 10
               ) or (end_pos.y - 10 > current_pos.y
                     or current_pos.y > end_pos.y + 10):
            self.clock.tick(FPS)
            self.events()
            self.draw()
            self.screen.blit(image, (current_pos.x, current_pos.y))
            pg.display.update()
            current_pos += direction

    def move_piece(self, start_tile, end_tile, mover):
        if self.engine.is_move_allowed(self.piece_matrix, start_tile,
                                       end_tile):
            piece = self.piece_matrix[start_tile[0]][start_tile[1]]
            self.piece_matrix[start_tile[0]][start_tile[1]] = ".."
            self.animate_movement(start_tile, end_tile, piece)
            self.piece_matrix[end_tile[0]][end_tile[1]] = piece
            self.checked = ""
            self.computer_turn = not self.computer_turn
            if "P" in piece:
                if "w" in piece and end_tile[0] == 0:
                    self.piece_matrix[end_tile[0]][end_tile[1]] = "wQ"
                elif "b" in piece and end_tile[0] == 7:
                    self.piece_matrix[end_tile[0]][end_tile[1]] = "bQ"
            if mover == "P":
                text = "Player moved " + \
                    CHAR_TO_STR[piece[1]] + " to " + \
                    BOARD_CANVAS_CHARS[end_tile[1]] + str(7 - end_tile[0] + 1)
                self.text_panel.write(text)
                self.check_mate('b')
            else:
                self.check_mate('w')

    def quit(self):
        self.running = False
        pg.quit()
        sys.exit()

    def check_mate(self, color):
        if self.engine.check(self.piece_matrix, color):
            if self.engine.check_mate(self.piece_matrix, color):
                self.text_panel.write("Check-mate!",
                                      RED if color == 'w' else GREEN)
                self.GO_screen(color)
            else:
                self.text_panel.write("Check!", RED if color == 'w' else GREEN)
                self.checked = color

    # Returns the mouse positions tranlated into rows and columns of the board
    def get_mouse_pos_rc(self):
        pos = pg.mouse.get_pos()
        col = floor((pos[0] - MARGIN) / TILESIZE)
        row = floor((pos[1] - MARGIN) / TILESIZE)
        return (row, col)

    def events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.quit()

            if event.type == pg.KEYDOWN:
                if event.key == pg.K_ESCAPE:
                    self.quit()
                if event.key == pg.K_r:
                    self.running = False

            elif event.type == pg.MOUSEBUTTONDOWN and event.button == LEFT:
                mouse_pos = pg.mouse.get_pos()
                if mouse_pos[0] > MARGIN and mouse_pos[
                        0] < WIDTH - MARGIN and mouse_pos[
                            1] > MARGIN and mouse_pos[
                                1] < HEIGHT - MARGIN and not self.computer_turn:
                    if self.start_pos:
                        self.move_piece(self.start_pos,
                                        self.get_mouse_pos_rc(), 'P')
                        self.start_pos = ()
                    else:
                        self.start_pos = self.get_mouse_pos_rc()
                        if "w" not in self.piece_matrix[self.start_pos[0]][
                                self.start_pos[1]]:
                            self.start_pos = ()
            elif event.type == pg.MOUSEBUTTONDOWN and event.button == RIGHT:
                self.start_pos = ()

    def draw(self):
        self.screen.fill(MAHOGANY)
        self.board_canvas.draw()
        # Drawing pieces:
        for row_index, row in enumerate(self.piece_matrix):
            for col_index, piece in enumerate(row):
                if piece in self.image_dict.keys():
                    image = self.image_dict[piece]  # Load Image
                    # Scale image to tilesize
                    y = MARGIN + TILESIZE * row_index
                    x = MARGIN + TILESIZE * col_index
                    self.screen.blit(image, (x, y))
                    if piece == self.checked + "K":
                        pg.draw.rect(self.screen, DARKRED,
                                     pg.Rect(x, y, TILESIZE, TILESIZE), 4)

        if self.start_pos:  # if start position is defined, mark it and show allowed moves
            mark_surface = pg.Surface((TILESIZE, TILESIZE))
            mark_surface.set_alpha(80)
            mark_surface.fill(ORANGE)
            y = MARGIN + TILESIZE * self.start_pos[0]
            x = MARGIN + TILESIZE * self.start_pos[1]
            self.screen.blit(mark_surface, (x, y))
            self.show_allowed_moves(self.start_pos)

        if self.is_mouse_over_piece() and not self.computer_turn:
            self.show_allowed_moves(self.get_mouse_pos_rc())

        # Text field:
        self.screen.blit(self.text_panel.surface, (WIDTH, MARGIN))

        pg.display.update()

    def is_mouse_over_piece(self):
        mouse_pos = self.get_mouse_pos_rc()
        for r in range(len(self.piece_matrix)):
            for c in range(len(self.piece_matrix[0])):
                if (r, c) == mouse_pos and (
                        r, c
                ) != self.start_pos and 'w' in self.piece_matrix[r][c]:
                    return True
        return False

    def show_allowed_moves(self, pos):
        moves = self.engine.get_allowed_moves(self.piece_matrix, pos)
        if moves:
            for move in moves["M"]:
                mark_surface = pg.Surface((TILESIZE, TILESIZE))
                mark_surface.set_alpha(150)
                y = MARGIN + TILESIZE * move[0]
                x = MARGIN + TILESIZE * move[1]
                self.screen.blit(mark_surface, (x, y))

    def GO_screen(self, color):
        self.running = False
        self.draw()
        font = pg.font.SysFont("consolas", 40)
        text = "The computer won, press a key to play again."
        if color == 'b':
            text = "Congratulation you won, press a key to play again."
        text_surface = font.render(text, True, WHITE)
        self.screen.blit(text_surface, (WIDTH / 8, HEIGHT / 3))
        pg.display.update()
        self.wait_for_key()

    def wait_for_key(self):
        pg.event.wait()
        waiting = True
        while waiting:
            self.clock.tick(FPS)
            for event in pg.event.get():
                if event.type == pg.QUIT:
                    waiting = False
                    self.quit()
                if event.type == pg.KEYUP:
                    waiting = False
import imutils
from BoardRecognition import BoardRecognition
from Board import Board
from ChessEngine import ChessEngine
from Game import Game

imgpath = '../board/28.jpg'
img = cv2.imread(imgpath)
img = imutils.resize(img, width=500)
cv2.imshow('img', img)

br = BoardRecognition(img)
thresh, img = br.cleanImage(img)
extracted = br.initializeMask(thresh, img)
edges, colorEdges = br.detectEdges(extracted)
horizontal, vertical = br.detectLines(edges, colorEdges)
corners = br.detectCorners(horizontal, vertical, colorEdges)
squares = br.detectSquares(corners, colorEdges)

board = Board(squares)
board.draw(img)
cv2.imshow('img2',img)
board.assignState()

engine = ChessEngine()
engine.updateMove('a2a4')
print()
engine.feedToAI()

#game = Game()
Example #10
0
class Game:
    '''
    Holds the whole game information
    Interacting with Board and Chess Engine
    '''
    def __init__(self, url):
        self.over = False
        self.CPUMoveError = False
        self.PlayerMoveError = False
        self.isCheck = False
        self.winner = "Me"
        self.url = url

    def setUp(self):
        self.camera = Camera(self.url)
        self.chessEngine = ChessEngine()
        self.board = 0
        self.current = 0
        self.previous = 0
        self.CPULastMove = "0"

    def analyzeBoard(self):
        boardRec = BoardRecognition(self.camera)
        self.board = boardRec.initializeBoard()
        self.board.assignState()

    def checkBoardIsSet(self):
        self.current = self.camera.takePicture()

        cv2.imwrite('./ProcessImage/SetUpBoard.jpg', self.current)

    def playerMove(self):
        self.previous = self.current
        self.current = self.camera.takePicture()
        move = self.board.determineChanges(self.previous, self.current)
        code = self.chessEngine.updateMove(move)
        print('Your move:', move)

        if code == 1:
            # Illegal move
            self.PlayerMoveError = True
        else:
            self.PlayerMoveError = False
            f = open('./Gamelog/Game.txt', 'a+')
            f.write(chess.Move.from_uci(move).uci() + '\r\n')
            f.close()
        # Check game over
        if self.chessEngine.engBoard.is_checkmate():
            self.winner = 'You win'
            self.over = True

    def playerPromotion(self, move):
        print(move)
        code = self.chessEngine.updateMove(move)

        if code == 1:
            # Illegal
            print('Error')
            self.PlayerMoveError = True
        else:
            self.PlayerMoveError = False
            f = open('./Gamelog/Game.txt', 'a+')
            f.write(chess.Move.from_uci(move).uci() + '\r\n')
            f.close()

        if self.chessEngine.engBoard.is_checkmate():
            self.winner = 'You win'
            self.over = True

    def CPUMove(self):
        self.CPULastMove = self.chessEngine.feedToAI()
        self.isCheck = self.chessEngine.engBoard.is_check()

        copy = self.current.copy()
        if len(self.CPULastMove.uci()) == 4:
            position1 = self.CPULastMove.uci()[:2]
            position2 = self.CPULastMove.uci()[2:]
            CPUMoveSquares = []

            for square in self.board.squares:
                if square.position == position1 or square.position == position2:
                    CPUMoveSquares.append(square)

            CPUMoveSquares[0].draw(copy, (255, 0, 0), 2)
            CPUMoveSquares[1].draw(copy, (255, 0, 0), 2)
            cv2.imwrite('./ProcessImage/CPUMove.jpg', copy)

        if self.chessEngine.engBoard.is_checkmate():
            self.winner = 'CPU win'
            self.over = True

        return self.CPULastMove

    def updateCurrent(self):
        self.previous = self.current
        self.current = self.camera.takePicture()

        move = self.board.determineChanges(self.previous, self.current)
        move = chess.Move.from_uci(move)
        print('Your move for cpu:', move)
        print('Cpu move:', self.CPULastMove)

        # Check if player moved CPU piece correctly
        if move == self.CPULastMove:
            self.CPUMoveError = False
        else:
            self.CPUMoveError = True
Example #11
0
 def __init__(self, max_depth):
     self.color = "b"
     self.max_depth = max_depth
     self.engine = ChessEngine()
Example #12
0
class ChessAI():
    def __init__(self, max_depth):
        self.color = "b"
        self.max_depth = max_depth
        self.engine = ChessEngine()

    def search(self,
               board,
               alfa,
               beta,
               is_maximizer=True,
               depth=0,
               is_root=True,
               N_C=[0, 0]):
        """
            returns a tuple containing: (start_pos, end_pos, score, visited_nodes)
        """
        # Beta is the minimizing players value
        # alfa is the maximizing player value.
        N_C[0] += 1
        if depth >= self.max_depth:
            return self.engine.board_score(board, self.color)
        elif is_maximizer:
            moves = self.engine.get_all_moves_dict(board, self.color)
            best_score = -0.1
            for start_pos in moves:
                for end_pos in moves[start_pos]:
                    board_with_move = [row[:] for row in board]
                    self.engine.move(board_with_move, start_pos, end_pos)
                    score = self.search(board_with_move,
                                        alfa,
                                        beta,
                                        is_maximizer=False,
                                        depth=depth + 1,
                                        is_root=False,
                                        N_C=N_C)
                    alfa = max(alfa, best_score)
                    if alfa >= beta:
                        N_C[1] += 1
                        return best_score
                    if best_score == -0.1 or score > best_score:
                        best_move = end_pos
                        best_score = score
                        result = (start_pos, end_pos, best_score, N_C)
            if is_root:
                return result
            return best_score
        else:
            moves = self.engine.get_all_moves_dict(
                board, 'w' if self.color == 'b' else 'b')
            best_score = 99999999
            for start_pos in moves:
                for end_pos in moves[start_pos]:
                    board_with_move = [row[:] for row in board]
                    self.engine.move(board_with_move, start_pos, end_pos)
                    best_score = min(
                        best_score,
                        self.search(board_with_move,
                                    alfa,
                                    beta,
                                    is_maximizer=True,
                                    depth=depth + 1,
                                    is_root=False,
                                    N_C=N_C))
                    beta = min(beta, best_score)
                    if alfa >= beta:
                        N_C[1] += 1
                        return best_score
            return best_score
Example #13
0
                    boardPhase.board_status[254-i]=tmp
                if boardPhase.player == 0:
                    boardPhase.player = 1
                else:
                    boardPhase.player = 0
            return     
"""

computer_first = False
pygame.mixer.pre_init(44100, 16, 2, 4096)
pygame.init()
boardWindow = BoardWindow(computer_first)
boardPhase = MCTSBoardPhase()
#boardPhase = BoardPhase()
boardWindow.drawBoard(boardPhase)
chessEngine = ChessEngine(3)
stop = False
train_flag = True
while True:
    if train_flag:
        pygame.event.pump()
        ret = boardWindow.computer_move(boardPhase, chessEngine)
        if not ret:
            boardPhase.reset()
    else:
        if computer_first and boardPhase.getSide() == 0 and not stop:
            if not boardWindow.computer_move(boardPhase, chessEngine):
                stop = True
        game_input(pygame.event.get(), boardWindow, boardWindow, chessEngine)
    boardWindow.drawBoard(boardPhase)
    pygame.display.flip()
Example #14
0
	def __init__(self):
		self.state = UserInterface.STATE_WAITING_FOR_START_POS
		self.engine = ChessEngine()
		self.startingPos = np.array(
			[[-1,-1,-1,-1,-1,-1,-1,-1],
			[-1,-1,-1,-1,-1,-1,-1,-1],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 1, 1, 1, 1, 1, 1, 1, 1],
			[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8)
		if sys.platform == 'darwin':
			self.cv = MockCV()
			UserInterface.ROTATIONS_RIGHT = 0
		else:
			self.cv = ChessCV()
		self.cv.continuous = True
		thread.start_new_thread(self.cvThread, (self,))
		self.boardscan = np.ndarray(shape=(8,8), dtype=np.int8)
		self.boardscan.fill(0)
		self.chess = None
		self.lastFullScreenToggle = 0
		self.boardScale = 2
		self.considering = []
		self.lastConsider = None
		self.requestedMove = None
		self.dirtyUi = True
		pygame.init()
		#self.screen = pygame.display.set_mode((800, 800))
		#self.screen = pygame.display.set_mode((1824, 1016))
		self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)

		self.bgimage = pygame.image.load("./img/background.png")
		self.light_sabers = pygame.image.load("./img/light_sabers2.png")
		self.would_you_like_to_play = pygame.image.load("./img/headings/would_you_like_to_play.png")
		self.checkmate_suckah = pygame.image.load("./img/headings/checkmate_suckah.png")
		self.my_turn = pygame.image.load("./img/headings/my_turn.png")
		self.my_turn_move_piece = pygame.image.load("./img/headings/my_turn_move_piece.png")
		self.one_moment_please = pygame.image.load("./img/headings/one_moment_please.png")
		self.would_you_like_to_play = pygame.image.load("./img/headings/would_you_like_to_play.png")
		self.your_turn = pygame.image.load("./img/headings/your_turn.png")
		self.your_turn_cheater = pygame.image.load("./img/headings/your_turn_cheater.png")

		self.check = pygame.image.load("./img/bottom_headers/check.png")
		self.checkmate_suckah = pygame.image.load("./img/bottom_headers/checkmate_suckah.png")

		self.topHeading = None
		self.bottomHeading = None
		self.boardbg = self.loadImage("board_v2.gif")
		self.pieces = {}
		self.pieces['r'] = self.loadImage("br.png")
		self.pieces['n'] = self.loadImage("bn.png")
		self.pieces['b'] = self.loadImage("bb.png")
		self.pieces['k'] = self.loadImage("bk.png")
		self.pieces['q'] = self.loadImage("bq.png")
		self.pieces['p'] = self.loadImage("bp.png")
		self.pieces['R'] = self.loadImage("wr.png")
		self.pieces['N'] = self.loadImage("wn.png")
		self.pieces['B'] = self.loadImage("wb.png")
		self.pieces['K'] = self.loadImage("wk.png")
		self.pieces['Q'] = self.loadImage("wq.png")
		self.pieces['P'] = self.loadImage("wp.png")
		pygame.display.flip()
Example #15
0
class UserInterface:

	ROTATIONS_RIGHT = 2

	STATE_WAITING_FOR_START_POS = 0
	STATE_WAITING_FOR_BOARD_CHANGE = 1
	STATE_WAITING_FOR_ENGINE = 2
	STATE_GAME_OVER = 3

	def __init__(self):
		self.state = UserInterface.STATE_WAITING_FOR_START_POS
		self.engine = ChessEngine()
		self.startingPos = np.array(
			[[-1,-1,-1,-1,-1,-1,-1,-1],
			[-1,-1,-1,-1,-1,-1,-1,-1],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 0, 0, 0, 0, 0, 0, 0, 0],
			[ 1, 1, 1, 1, 1, 1, 1, 1],
			[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8)
		if sys.platform == 'darwin':
			self.cv = MockCV()
			UserInterface.ROTATIONS_RIGHT = 0
		else:
			self.cv = ChessCV()
		self.cv.continuous = True
		thread.start_new_thread(self.cvThread, (self,))
		self.boardscan = np.ndarray(shape=(8,8), dtype=np.int8)
		self.boardscan.fill(0)
		self.chess = None
		self.lastFullScreenToggle = 0
		self.boardScale = 2
		self.considering = []
		self.lastConsider = None
		self.requestedMove = None
		self.dirtyUi = True
		pygame.init()
		#self.screen = pygame.display.set_mode((800, 800))
		#self.screen = pygame.display.set_mode((1824, 1016))
		self.screen = pygame.display.set_mode((0,0), pygame.FULLSCREEN)

		self.bgimage = pygame.image.load("./img/background.png")
		self.light_sabers = pygame.image.load("./img/light_sabers2.png")
		self.would_you_like_to_play = pygame.image.load("./img/headings/would_you_like_to_play.png")
		self.checkmate_suckah = pygame.image.load("./img/headings/checkmate_suckah.png")
		self.my_turn = pygame.image.load("./img/headings/my_turn.png")
		self.my_turn_move_piece = pygame.image.load("./img/headings/my_turn_move_piece.png")
		self.one_moment_please = pygame.image.load("./img/headings/one_moment_please.png")
		self.would_you_like_to_play = pygame.image.load("./img/headings/would_you_like_to_play.png")
		self.your_turn = pygame.image.load("./img/headings/your_turn.png")
		self.your_turn_cheater = pygame.image.load("./img/headings/your_turn_cheater.png")

		self.check = pygame.image.load("./img/bottom_headers/check.png")
		self.checkmate_suckah = pygame.image.load("./img/bottom_headers/checkmate_suckah.png")

		self.topHeading = None
		self.bottomHeading = None
		self.boardbg = self.loadImage("board_v2.gif")
		self.pieces = {}
		self.pieces['r'] = self.loadImage("br.png")
		self.pieces['n'] = self.loadImage("bn.png")
		self.pieces['b'] = self.loadImage("bb.png")
		self.pieces['k'] = self.loadImage("bk.png")
		self.pieces['q'] = self.loadImage("bq.png")
		self.pieces['p'] = self.loadImage("bp.png")
		self.pieces['R'] = self.loadImage("wr.png")
		self.pieces['N'] = self.loadImage("wn.png")
		self.pieces['B'] = self.loadImage("wb.png")
		self.pieces['K'] = self.loadImage("wk.png")
		self.pieces['Q'] = self.loadImage("wq.png")
		self.pieces['P'] = self.loadImage("wp.png")
		pygame.display.flip()

	def loadImage(self, file):
		img = pygame.image.load("./img/%s" % file).convert(32, pygame.SRCALPHA)
		rect = img.get_rect()
		return pygame.transform.smoothscale(img, (int(rect.w * self.boardScale), int(rect.h * self.boardScale)))

	def getFont(self, size):
		return pygame.font.SysFont("freesans", size, bold=True)

	def mainLoop(self):    
		clock = pygame.time.Clock()
		self.renderBoard()

		while 1:
			clock.tick(30)

			for event in pygame.event.get():
				if event.type == QUIT:
					return
				elif event.type == KEYDOWN:
					print event.key
					if event.key == K_ESCAPE:
						return
					if event.key == 102: # F
						if time.time() - self.lastFullScreenToggle > 1:
							self.lastFullScreenToggle = time.time() 
							pygame.display.toggle_fullscreen()
					if event.key == 32: # space
						self.cv.snapshot = True
					if event.key == 49:	# 1
						self.cv.set_board(self.startingPos.copy())
					if event.key == 50:	# 2
						self.cv.set_board(np.array(
							[[-1,-1,-1,-1,-1,-1,-1,-1],
							[-1,-1,-1,-1,-1,-1,-1,-1],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 1, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 1, 1, 1, 1, 0, 1, 1, 1],
							[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8))
					if event.key == 51:	# 3
						self.cv.set_board(np.array(
							[[-1,-1,-1,-1,-1,-1,-1,-1],
							[-1,-1,-1, 0,-1,-1,-1,-1],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0,-1, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 1, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 1, 1, 1, 1, 0, 1, 1, 1],
							[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8))
					if event.key == 52:	# 4
						self.cv.set_board(np.array(
							[[-1,-1,-1,-1,-1,-1,-1,-1],
							[-1,-1,-1, 0,-1,-1,-1,-1],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 1, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 0, 0, 0, 0, 0, 0, 0, 0],
							[ 1, 1, 1, 1, 0, 1, 1, 1],
							[ 1, 1, 1, 1, 1, 1, 1, 1]], np.int8))
			self.gameTick()


	def gameTick(self):
		self.updateConsideringLine()
		if self.state == UserInterface.STATE_WAITING_FOR_START_POS:
			if np.array_equal(self.boardscan, self.startingPos):
				print "NEW GAME: Creating chess board"
				self.chess = ChessBoard()
				self.lastBoardscan = self.boardscan
				self.engine.newGame()
				self.topHeading = self.your_turn
				self.dirtyUi = True
				self.state = UserInterface.STATE_WAITING_FOR_BOARD_CHANGE
		elif self.state == UserInterface.STATE_WAITING_FOR_ENGINE:
			if self.engine.bestmove is not None:
				self.requestedMove = self.engine.bestmove
				self.considering = []
				self.state = UserInterface.STATE_WAITING_FOR_BOARD_CHANGE
				self.topHeading = self.my_turn_move_piece
				self.dirtyUi = True
			self.renderBoard()
		elif self.state == UserInterface.STATE_WAITING_FOR_BOARD_CHANGE:
			changes = self.boardscan - self.lastBoardscan
			numChanges = np.count_nonzero(changes)
			if numChanges == 2 or numChanges == 3 or numChanges == 4:
				self.dirtyUi = True
				print ""
				print "changes:\n" + str(changes)
				moveFrom = ()
				moveTo = ()
				nonzeroChanges = changes.nonzero()
				print "nonzeroChanges: " + str(nonzeroChanges)
				print "len(nonzeroChanges[0]) = %d" % len(nonzeroChanges[0])
				for i in range(len(nonzeroChanges[0])):
					change = (nonzeroChanges[1][i], nonzeroChanges[0][i])
					value = changes[change[1], change[0]]
					colorBefore = self.lastBoardscan[change[1], change[0]]
					print "\tchange: %s\tvalue: %s\tcolorBefore: %s" % (str(change), value, colorBefore)
					if self.chess.getTurn() == ChessBoard.WHITE:
						# WHITE's turn
						if value == -1:
							if numChanges != 4 or (change == (4,7)):
								moveFrom = change
						else:
							if numChanges == 4:
								if change == (6,7) or change == (2,7):
									moveTo = change
							elif numChanges == 3:
								if colorBefore == 0:
									moveTo = change
							else:
								moveTo = change
					else:
						# BLACK's turn
						if value == 1:
							if numChanges != 4 or (change == (4,0)):
								print "setting moveFrom to ", change
								moveFrom = change
						else:
							if numChanges == 4:
								if change == (6,0) or change == (2,0):
									print "setting moveTo to ", change
									moveTo = change
							elif numChanges == 3:
								if colorBefore == 0:
									print "setting moveTo to ", change
									moveTo = change
							else:
								moveTo = change
				print "moveFrom: " + str(moveFrom)
				print "moveTo:   " + str(moveTo)
				if moveFrom and moveTo:
					print "getTurn before:", self.chess.getTurn()
					result = self.chess.addMove(moveFrom, moveTo)
					print "getTurn after:", self.chess.getTurn()
					if result is False:
						print "Could not make move: ", self.chess.getReason()
					else:
						lastMove = string.replace(self.chess.getLastTextMove(ChessBoard.AN), '-', '')
						cheater = False
						if self.requestedMove is not None and self.requestedMove != lastMove:
							cheater = True
						if self.chess.isCheck():
							print "**** CHECK ****"
							self.bottomHeading = self.check
						else:
							self.bottomHeading = None
						self.requestedMove = None
						self.lastBoardscan = self.boardscan
						self.chess.printBoard()
						print "Last move type: " + str(self.chess.getLastMoveType())
						print "New FEN: " + self.chess.getFEN()
						# Check if game is over
						if self.chess.isGameOver():
							result = self.chess.getGameResult()
							if result == ChessBoard.WHITE_WIN:
								print "**** WHITE WINS ****"
							elif result == ChessBoard.BLACK_WIN:
								print "**** BLACK WINS ****"
								self.bottomHeading = self.checkmate_suckah
							else:
								print "**** STALEMATE ****"
							self.state = UserInterface.STATE_GAME_OVER
						elif self.chess.getTurn() == ChessBoard.BLACK:
							# It's black's turn, engage the engine
							self.topHeading = self.one_moment_please
							self.engine.makeMove(self.chess.getFEN())
							self.state = UserInterface.STATE_WAITING_FOR_ENGINE
						else:
							if cheater:
								self.topHeading = self.your_turn_cheater
							else:
								self.topHeading = self.your_turn
						self.renderBoard()

			elif numChanges != 0:
				print "Invalid number of board changes: ", numChanges
				self.cv.reset_board()
			# Set boardscan to the last one just so we don't keep analyzing it until next scan comes in
			self.boardscan = self.lastBoardscan
			self.renderBoard()


	def updateConsideringLine(self):
		now = time.time()
		engine_considering = self.engine.considering
		if self.state == UserInterface.STATE_WAITING_FOR_ENGINE and engine_considering is not None:
			if len(self.engine.considering) > 0:
				latest = engine_considering[0]
				if len(latest) == 0:
					engine_considering.pop()
					self.considering = []
					self.updateConsideringLine()
					return
				self.considering.append(latest.pop())
			self.lastConsider = now
			self.dirtyUi = True
			self.renderBoard()


	def renderBoard(self):

		if not self.dirtyUi:
			return

		self.dirtyUi = False

		self.screen.blit(self.bgimage, (0,0))
		if self.chess is None:
			self.screen.blit(self.would_you_like_to_play, (587, 395))
			pygame.display.flip()
			return
			
		files = 'abcdefgh'
		boardOffsetX = 64
		boardOffsetY = 64
		square_size = self.pieces['r'].get_rect().w

		# First the background
		bgsize = self.boardbg.get_rect().w
		for y in range(4):
			for x in range(4):
				self.screen.blit(self.boardbg, (boardOffsetX+x*bgsize, boardOffsetY+y*bgsize))

		# Render the pieces
		y = 0
		for rank in self.chess.getBoard():
			x = 0
			for p in rank:
				if p != '.':
					self.screen.blit(self.pieces[p],(boardOffsetX+x*square_size, boardOffsetY+y*square_size))
				x += 1
			y += 1

		# Heading
		if self.topHeading is not None:
			self.screen.blit(self.topHeading, (1105, 84))

		# Sabers
		self.screen.blit(self.light_sabers, (1105, 84 + 140))

		# Render considering moves (if any)
		if len(self.considering) > 0:
			for move in self.considering:
				x1 = boardOffsetX+files.find(move[0])*square_size+int(square_size/2)
				y1 = boardOffsetY+((8-int(move[1]))*square_size)+int(square_size/2)
				x2 = boardOffsetX+files.find(move[2])*square_size+int(square_size/2)
				y2 = boardOffsetY+((8-int(move[3]))*square_size)+int(square_size/2)
				pygame.draw.line(self.screen, (164, 119, 131), (x1,y1), (x2,y2), 15)
				pygame.draw.circle(self.screen, (127, 91, 102), (x1,y1), 15)
				pygame.draw.circle(self.screen, (127, 91, 102), (x2,y2), 15)

		# Render requested move (if any)
		if self.requestedMove is not None:
			x1 = boardOffsetX+files.find(self.requestedMove[0])*square_size+int(square_size/2)
			y1 = boardOffsetY+((8-int(self.requestedMove[1]))*square_size)+int(square_size/2)
			x2 = boardOffsetX+files.find(self.requestedMove[2])*square_size+int(square_size/2)
			y2 = boardOffsetY+((8-int(self.requestedMove[3]))*square_size)+int(square_size/2)
			pygame.draw.line(self.screen, (229, 72, 84), (x1,y1), (x2,y2), 15)
			pygame.draw.circle(self.screen, (173, 58, 75), (x2,y2), 15)
			# Redraw piece on "from" square so line comes from underneath it (but covers other pieces, potentially)
			y = 8-int(self.requestedMove[1])
			x = files.find(self.requestedMove[0])
			piece = self.chess.getBoard()[y][x]
			self.screen.blit(self.pieces[piece],(boardOffsetX+x*square_size, boardOffsetY+y*square_size))

		# Bottom heading
		if self.bottomHeading is not None:
			self.screen.blit(self.bottomHeading, (1105, 84 + 140 + 165 + 403))

		# Render chess moves
		color = (255, 255, 255)
		x = 1105
		startY = 84 + 140 + 165
		y = startY
		font = self.getFont(20)
		allMoves = self.chess.getAllTextMoves(ChessBoard.LAN)
		if allMoves is not None:
			whiteMoves = allMoves[0::2]
			blackMoves = allMoves[1::2]
			num = 1
			for move in whiteMoves:
				txt = "%d.  %s" % (num, move)
				if num < 10:
					txt = " " + txt
				fs = font.render(txt, True, color)
				self.screen.blit(fs, (x, y))
				y += 25
				num = num + 1
				if y > startY + 403:
					break
			x += 200
			y = startY
			for move in blackMoves:
				fs = font.render(move, True, color)
				self.screen.blit(fs, (x, y))
				y += 25
				if y > startY + 403:
					break


		pygame.display.flip()

				
	def cvThread(self, cv):
		while True:
			try:
				if self.state == UserInterface.STATE_WAITING_FOR_BOARD_CHANGE or self.state == UserInterface.STATE_WAITING_FOR_START_POS:
					if self.cv.continuous == True or self.cv.snapshot == True:
						self.cv.snapshot = False
						sys.stdout.write('.')
						sys.stdout.flush()
						board = self.cv.current_board()
						if board is not None:
							self.boardscan = np.rot90(board, UserInterface.ROTATIONS_RIGHT)
			except Exception, e:
				print e
			time.sleep(0.25)