Пример #1
0
    def __init__(self, gamemodel, actionMenuItems):
        gtk.EventBox.__init__(self)
        self.promotionDialog = PromotionDialog()
        self.view = BoardView(gamemodel)
        self.add(self.view)

        self.actionMenuItems = actionMenuItems
        self.connections = {}
        for key, menuitem in self.actionMenuItems.iteritems():
            if menuitem == None: print key
            self.connections[menuitem] = menuitem.connect(
                "activate", self.actionActivate, key)

        self.view.connect("shown_changed", self.shown_changed)
        gamemodel.connect("moves_undoing", self.moves_undone)
        self.connect("button_press_event", self.button_press)
        self.connect("button_release_event", self.button_release)
        self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK
                        | gtk.gdk.POINTER_MOTION_MASK)
        self.connect("motion_notify_event", self.motion_notify)
        self.connect("leave_notify_event", self.leave_notify)

        self.selected_last = None
        self.stateLock = threading.Lock()
        self.normalState = NormalState(self)
        self.selectedState = SelectedState(self)
        self.activeState = ActiveState(self)
        self.lockedState = LockedState(self)
        self.lockedSelectedState = LockedSelectedState(self)
        self.lockedActiveState = LockedActiveState(self)
        self.currentState = self.lockedState

        self.lockedPly = self.view.shown
        self.possibleBoards = {
            self.lockedPly: self._genPossibleBoards(self.lockedPly)
        }

        self.allowPremove = False

        def onGameStart(gamemodel):
            for player in gamemodel.players:
                if player.__type__ == LOCAL:
                    self.allowPremove = True

        gamemodel.connect("game_started", onGameStart)
Пример #2
0
    def makeMove(self, firstCell, secondCell):
        if self.gameStarted is False:
            return

        firstCellCoords = firstCell.getCoordinates()
        secondCellCoords = secondCell.getCoordinates()

        firstSquare = chess.square(*firstCellCoords)
        secondSquare = chess.square(*secondCellCoords)

        promotion = None

        if self.board.piece_at(firstSquare).piece_type == chess.PAWN:
            if secondCellCoords[1] == 0 or secondCellCoords[1] == 7:
                promotion = chess.QUEEN

        move = chess.Move(firstSquare, secondSquare, promotion=promotion)

        if move in self.board.legal_moves:
            if promotion is not None:
                self.promotionDialog = PromotionDialog(self.parent(),
                                                       self.board.turn)
                choosen = self.promotionDialog.exec()

                if choosen == 0:
                    return

                move.promotion = self.promotionDialog.getPromotion()

            self.board.push(move)

            self.moveMade.emit(move)

            result = self.board.result()
            if result != '*':
                self.gameStarted = False
                self.gameEnded.emit(result)
        self.updateBoard()
Пример #3
0
    def __init__(self, gamemodel, actionMenuItems):
        gtk.EventBox.__init__(self)
        self.promotionDialog = PromotionDialog()
        self.view = BoardView(gamemodel)
        self.add(self.view)
        self.variant = gamemodel.variant

        self.RANKS = gamemodel.boards[0].RANKS
        self.FILES = gamemodel.boards[0].FILES
        
        self.actionMenuItems = actionMenuItems
        self.connections = {}
        for key, menuitem in self.actionMenuItems.iteritems():
            if menuitem == None: print key
            self.connections[menuitem] = menuitem.connect("activate", self.actionActivate, key)
        
        self.view.connect("shown_changed", self.shown_changed)
        gamemodel.connect("moves_undoing", self.moves_undone)
        self.connect("button_press_event", self.button_press)
        self.connect("button_release_event", self.button_release)
        self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK|gtk.gdk.POINTER_MOTION_MASK)
        self.connect("motion_notify_event", self.motion_notify)
        self.connect("leave_notify_event", self.leave_notify)
        
        self.selected_last = None
        self.stateLock = threading.Lock()
        self.normalState = NormalState(self)
        self.selectedState = SelectedState(self)
        self.activeState = ActiveState(self)
        self.lockedNormalState = LockedNormalState(self)
        self.lockedSelectedState = LockedSelectedState(self)
        self.lockedActiveState = LockedActiveState(self)
        self.currentState = self.normalState
        
        self.lockedPly = self.view.shown
        self.possibleBoards = {
            self.lockedPly : self._genPossibleBoards(self.lockedPly) }
        
        self.allowPremove = False
        def onGameStart (gamemodel):
            for player in gamemodel.players:
                if player.__type__ == LOCAL:
                    self.allowPremove = True
        gamemodel.connect("game_started", onGameStart)
        self.keybuffer = ""
Пример #4
0
class BoardWidget(QtWidgets.QWidget):
    gameEnded = QtCore.pyqtSignal(str)
    moveMade = QtCore.pyqtSignal(chess.Move)

    def __init__(self, parent=None):
        super().__init__(parent)

        self.initUi()

        self.gameStarted = False

    def initUi(self):
        self.resize(FIELD_SIZE, FIELD_SIZE)
        self.cellsLayout = QtWidgets.QGridLayout(self)
        self.initBoard()

    def initBoard(self):
        self.board = chess.Board()

        for row in range(8):
            for col in range(8):
                cell = Cell(self, col, row, CELL_SIZE, CELL_SIZE)
                cell.moveMade.connect(self.makeMove)

                if (row + col) % 2 == 0:
                    cell.setColor(BLACK_CELL_COLOR)
                else:
                    cell.setColor(WHITE_CELL_COLOR)

                self.cellsLayout.addWidget(cell, 7 - row, col)

    def updateBoard(self):
        for row in range(8):
            for col in range(8):
                cell = self.cellsLayout.itemAtPosition(7 - row, col).widget()
                square = chess.square(col, row)
                piece = self.board.piece_at(square)
                cell.setPiece(piece)

    def startGame(self):
        self.board.reset()
        self.updateBoard()
        self.gameStarted = True

    def makeMove(self, firstCell, secondCell):
        if self.gameStarted is False:
            return

        firstCellCoords = firstCell.getCoordinates()
        secondCellCoords = secondCell.getCoordinates()

        firstSquare = chess.square(*firstCellCoords)
        secondSquare = chess.square(*secondCellCoords)

        promotion = None

        if self.board.piece_at(firstSquare).piece_type == chess.PAWN:
            if secondCellCoords[1] == 0 or secondCellCoords[1] == 7:
                promotion = chess.QUEEN

        move = chess.Move(firstSquare, secondSquare, promotion=promotion)

        if move in self.board.legal_moves:
            if promotion is not None:
                self.promotionDialog = PromotionDialog(self.parent(),
                                                       self.board.turn)
                choosen = self.promotionDialog.exec()

                if choosen == 0:
                    return

                move.promotion = self.promotionDialog.getPromotion()

            self.board.push(move)

            self.moveMade.emit(move)

            result = self.board.result()
            if result != '*':
                self.gameStarted = False
                self.gameEnded.emit(result)
        self.updateBoard()

    def getCurrentTurn(self):
        return self.board.turn

    def isGameStarted(self):
        return self.gameStarted

    def forceLose(self, loser):
        self.gameStarted = False

        if loser == chess.WHITE:
            self.gameEnded.emit("0-1")
        else:
            self.gameEnded.emit("1-0")

    def hasInsufficientMaterial(self, color):
        return self.board.has_insufficient_material(color)

    def isDrawPossibleWithoutOpponentApproval(self):
        return self.board.can_claim_draw()

    def draw(self):
        self.gameStarted = False
        self.gameEnded.emit("1/2-1/2")

    def getMovesQuantity(self):
        return len(self.board.move_stack)

    def getGame(self):
        return chess.pgn.Game.from_board(self.board)
Пример #5
0
class BoardControl(gtk.EventBox):

    __gsignals__ = {
        'piece_moved': (SIGNAL_RUN_FIRST, TYPE_NONE, (object, int)),
        'action': (SIGNAL_RUN_FIRST, TYPE_NONE, (str, object))
    }

    def __init__(self, gamemodel, actionMenuItems):
        gtk.EventBox.__init__(self)
        self.promotionDialog = PromotionDialog()
        self.view = BoardView(gamemodel)
        self.add(self.view)

        self.actionMenuItems = actionMenuItems
        self.connections = {}
        for key, menuitem in self.actionMenuItems.iteritems():
            if menuitem == None: print key
            self.connections[menuitem] = menuitem.connect(
                "activate", self.actionActivate, key)

        self.view.connect("shown_changed", self.shown_changed)
        gamemodel.connect("moves_undoing", self.moves_undone)
        self.connect("button_press_event", self.button_press)
        self.connect("button_release_event", self.button_release)
        self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK
                        | gtk.gdk.POINTER_MOTION_MASK)
        self.connect("motion_notify_event", self.motion_notify)
        self.connect("leave_notify_event", self.leave_notify)

        self.selected_last = None
        self.stateLock = threading.Lock()
        self.normalState = NormalState(self)
        self.selectedState = SelectedState(self)
        self.activeState = ActiveState(self)
        self.lockedState = LockedState(self)
        self.lockedSelectedState = LockedSelectedState(self)
        self.lockedActiveState = LockedActiveState(self)
        self.currentState = self.lockedState

        self.lockedPly = self.view.shown
        self.possibleBoards = {
            self.lockedPly: self._genPossibleBoards(self.lockedPly)
        }

        self.allowPremove = False

        def onGameStart(gamemodel):
            for player in gamemodel.players:
                if player.__type__ == LOCAL:
                    self.allowPremove = True

        gamemodel.connect("game_started", onGameStart)

    def __del__(self):
        for menu, conid in self.connections.iteritems():
            menu.disconnect(conid)
        self.connections = {}

    def emit_move_signal(self, cord0, cord1):
        color = self.view.model.boards[-1].color
        board = self.view.model.getBoardAtPly(self.view.shown)

        # Ask player for which piece to promote into. If this move does not
        # include a promotion, QUEEN will be sent as a dummy value, but not used
        promotion = QUEEN
        if board[cord0].sign == PAWN and cord1.y in (0, 7):
            res = self.promotionDialog.runAndHide(color)
            if res != gtk.RESPONSE_DELETE_EVENT:
                promotion = res
            else:
                # Put back pawn moved be d'n'd
                self.view.runAnimation(redrawMisc=False)
                return

        move = Move(cord0, cord1, self.view.model.boards[-1], promotion)
        self.emit("piece_moved", move, color)

    def actionActivate(self, widget, key):
        """ Put actions from a menu or similar """
        if key == "call_flag":
            self.emit("action", FLAG_CALL, None)
        elif key == "abort":
            self.emit("action", ABORT_OFFER, None)
        elif key == "adjourn":
            self.emit("action", ADJOURN_OFFER, None)
        elif key == "draw":
            self.emit("action", DRAW_OFFER, None)
        elif key == "resign":
            self.emit("action", RESIGNATION, None)
        elif key == "ask_to_move":
            self.emit("action", HURRY_ACTION, None)
        elif key == "undo1":
            if self.view.model.curplayer.__type__ == LOCAL \
               and self.view.model.ply > 1:
                self.emit("action", TAKEBACK_OFFER, self.view.model.ply - 2)
            else:
                self.emit("action", TAKEBACK_OFFER, self.view.model.ply - 1)
        elif key == "pause1":
            self.emit("action", PAUSE_OFFER, None)
        elif key == "resume1":
            self.emit("action", RESUME_OFFER, None)

    def shown_changed(self, view, shown):
        self.lockedPly = self.view.shown
        self.possibleBoards[self.lockedPly] = self._genPossibleBoards(
            self.lockedPly)
        if self.view.shown - 2 in self.possibleBoards:
            del self.possibleBoards[self.view.shown - 2]

    def moves_undone(self, gamemodel, moves):
        self.stateLock.acquire()
        try:
            self.view.selected = None
            self.view.active = None
            self.view.hover = None
            self.view.draggedPiece = None
            self.view.startAnimation()
            self.currentState = self.lockedState
        finally:
            self.stateLock.release()

    def setLocked(self, locked):
        self.stateLock.acquire()
        try:
            if locked:
                if self.view.model.status != RUNNING:
                    self.view.selected = None
                    self.view.active = None
                    self.view.hover = None
                    self.view.draggedPiece = None
                    self.view.startAnimation()
                self.currentState = self.lockedState
            else:
                if self.currentState == self.lockedSelectedState:
                    self.currentState = self.selectedState
                elif self.currentState == self.lockedActiveState:
                    self.currentState = self.activeState
                else:
                    self.currentState = self.normalState
        finally:
            self.stateLock.release()

    def setStateSelected(self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedState,
                                     self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedSelectedState
            else:
                self.currentState = self.selectedState
        finally:
            self.stateLock.release()

    def setStateActive(self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedState,
                                     self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedActiveState
            else:
                self.currentState = self.activeState
        finally:
            self.stateLock.release()

    def setStateNormal(self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedState,
                                     self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedState
            else:
                self.currentState = self.normalState
        finally:
            self.stateLock.release()

    def button_press(self, widget, event):
        return self.currentState.press(event.x, event.y)

    def button_release(self, widget, event):
        return self.currentState.release(event.x, event.y)

    def motion_notify(self, widget, event):
        return self.currentState.motion(event.x, event.y)

    def leave_notify(self, widget, event):
        return self.currentState.leave(event.x, event.y)

    def _genPossibleBoards(self, ply):
        possibleBoards = []
        curboard = self.view.model.getBoardAtPly(ply)
        for lmove in lmovegen.genAllMoves(curboard.board):
            move = Move(lmove)
            board = curboard.move(move)
            possibleBoards.append(board)
        return possibleBoards
class BoardControl (gtk.EventBox):
    
    __gsignals__ = {
        'piece_moved' : (SIGNAL_RUN_FIRST, TYPE_NONE, (object, int)),
        'action' : (SIGNAL_RUN_FIRST, TYPE_NONE, (str, object))
    }
    
    def __init__(self, gamemodel, actionMenuItems):
        gtk.EventBox.__init__(self)
        self.promotionDialog = PromotionDialog()
        self.view = BoardView(gamemodel)
        self.add(self.view)
        
        self.actionMenuItems = actionMenuItems
        self.connections = {}
        for key, menuitem in self.actionMenuItems.iteritems():
            if menuitem == None: print key
            self.connections[menuitem] = menuitem.connect("activate", self.actionActivate, key)
        
        self.view.connect("shown_changed", self.shown_changed)
        gamemodel.connect("moves_undoing", self.moves_undone)
        self.connect("button_press_event", self.button_press)
        self.connect("button_release_event", self.button_release)
        self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK|gtk.gdk.POINTER_MOTION_MASK)
        self.connect("motion_notify_event", self.motion_notify)
        self.connect("leave_notify_event", self.leave_notify)
        
        self.selected_last = None
        self.stateLock = threading.Lock()
        self.normalState = NormalState(self)
        self.selectedState = SelectedState(self)
        self.activeState = ActiveState(self)
        self.lockedState = LockedState(self)
        self.lockedSelectedState = LockedSelectedState(self)
        self.lockedActiveState = LockedActiveState(self)
        self.currentState = self.lockedState
        
        self.lockedPly = self.view.shown
        self.possibleBoards = {
            self.lockedPly : self._genPossibleBoards(self.lockedPly) }
        
        self.allowPremove = False
        def onGameStart (gamemodel):
            for player in gamemodel.players:
                if player.__type__ == LOCAL:
                    self.allowPremove = True
        gamemodel.connect("game_started", onGameStart)
        
    def __del__ (self):
        for menu, conid in self.connections.iteritems():
            menu.disconnect(conid)
        self.connections = {}
        
    def emit_move_signal (self, cord0, cord1):
        color = self.view.model.boards[-1].color
        board = self.view.model.getBoardAtPly(self.view.shown)
        
        # Ask player for which piece to promote into. If this move does not
        # include a promotion, QUEEN will be sent as a dummy value, but not used
        promotion = QUEEN
        if board[cord0].sign == PAWN and cord1.y in (0,7):
            res = self.promotionDialog.runAndHide(color)
            if res != gtk.RESPONSE_DELETE_EVENT:
                promotion = res
            else:
                # Put back pawn moved be d'n'd
                self.view.runAnimation(redrawMisc = False)
                return
        
        move = Move(cord0, cord1, self.view.model.boards[-1], promotion)
        self.emit("piece_moved", move, color)
    
    def actionActivate (self, widget, key):
        """ Put actions from a menu or similar """
        if key == "call_flag":
            self.emit("action", FLAG_CALL, None)
        elif key == "abort":
            self.emit("action", ABORT_OFFER, None)
        elif key == "adjourn":
            self.emit("action", ADJOURN_OFFER, None)
        elif key == "draw":
            self.emit("action", DRAW_OFFER, None)
        elif key == "resign":
            self.emit("action", RESIGNATION, None)
        elif key == "ask_to_move":
            self.emit("action", HURRY_ACTION, None)
        elif key == "undo1":
            if self.view.model.curplayer.__type__ == LOCAL \
               and self.view.model.ply > 1:
                self.emit("action", TAKEBACK_OFFER, self.view.model.ply-2)
            else: self.emit("action", TAKEBACK_OFFER, self.view.model.ply-1)
        elif key == "pause1":
            self.emit("action", PAUSE_OFFER, None)
        elif key == "resume1":
            self.emit("action", RESUME_OFFER, None)
    
    def shown_changed (self, view, shown):
        self.lockedPly = self.view.shown
        self.possibleBoards[self.lockedPly] = self._genPossibleBoards(self.lockedPly)
        if self.view.shown-2 in self.possibleBoards:
            del self.possibleBoards[self.view.shown-2]
    
    def moves_undone (self, gamemodel, moves):
        self.stateLock.acquire()
        try:
            self.view.selected = None
            self.view.active = None
            self.view.hover = None
            self.view.draggedPiece = None
            self.view.startAnimation()
            self.currentState = self.lockedState
        finally:
            self.stateLock.release()
    
    def setLocked (self, locked):
        self.stateLock.acquire()
        try:
            if locked:
                if self.view.model.status != RUNNING:
                    self.view.selected = None
                    self.view.active = None
                    self.view.hover = None
                    self.view.draggedPiece = None
                    self.view.startAnimation()
                self.currentState = self.lockedState
            else:
                if self.currentState == self.lockedSelectedState:
                    self.currentState = self.selectedState
                elif self.currentState == self.lockedActiveState:
                    self.currentState = self.activeState
                else:
                    self.currentState = self.normalState
        finally:
            self.stateLock.release()
    
    def setStateSelected (self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedState, self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedSelectedState
            else:
                self.currentState = self.selectedState
        finally:
            self.stateLock.release()
    
    def setStateActive (self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedState, self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedActiveState
            else:
                self.currentState = self.activeState
        finally:
            self.stateLock.release()
    
    def setStateNormal (self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedState, self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedState
            else:
                self.currentState = self.normalState
        finally:
            self.stateLock.release()
    
    def button_press (self, widget, event):
        return self.currentState.press(event.x, event.y)
    
    def button_release (self, widget, event):
        return self.currentState.release(event.x, event.y)
    
    def motion_notify (self, widget, event):
        return self.currentState.motion(event.x, event.y)
    
    def leave_notify (self, widget, event):
        return self.currentState.leave(event.x, event.y)
    
    def _genPossibleBoards(self, ply):
        possibleBoards = []
        curboard = self.view.model.getBoardAtPly(ply)
        for lmove in lmovegen.genAllMoves(curboard.board):
            move = Move(lmove)
            board = curboard.move(move)
            possibleBoards.append(board)        
        return possibleBoards
Пример #7
0
class BoardControl (gtk.EventBox):
    
    __gsignals__ = {
        'piece_moved' : (SIGNAL_RUN_FIRST, TYPE_NONE, (object, int)),
        'action' : (SIGNAL_RUN_FIRST, TYPE_NONE, (str, object))
    }
    
    def __init__(self, gamemodel, actionMenuItems):
        gtk.EventBox.__init__(self)
        self.promotionDialog = PromotionDialog()
        self.view = BoardView(gamemodel)
        self.add(self.view)
        self.variant = gamemodel.variant

        self.RANKS = gamemodel.boards[0].RANKS
        self.FILES = gamemodel.boards[0].FILES
        
        self.actionMenuItems = actionMenuItems
        self.connections = {}
        for key, menuitem in self.actionMenuItems.iteritems():
            if menuitem == None: print key
            self.connections[menuitem] = menuitem.connect("activate", self.actionActivate, key)
        
        self.view.connect("shown_changed", self.shown_changed)
        gamemodel.connect("moves_undoing", self.moves_undone)
        self.connect("button_press_event", self.button_press)
        self.connect("button_release_event", self.button_release)
        self.add_events(gtk.gdk.LEAVE_NOTIFY_MASK|gtk.gdk.POINTER_MOTION_MASK)
        self.connect("motion_notify_event", self.motion_notify)
        self.connect("leave_notify_event", self.leave_notify)
        
        self.selected_last = None
        self.stateLock = threading.Lock()
        self.normalState = NormalState(self)
        self.selectedState = SelectedState(self)
        self.activeState = ActiveState(self)
        self.lockedNormalState = LockedNormalState(self)
        self.lockedSelectedState = LockedSelectedState(self)
        self.lockedActiveState = LockedActiveState(self)
        self.currentState = self.normalState
        
        self.lockedPly = self.view.shown
        self.possibleBoards = {
            self.lockedPly : self._genPossibleBoards(self.lockedPly) }
        
        self.allowPremove = False
        def onGameStart (gamemodel):
            for player in gamemodel.players:
                if player.__type__ == LOCAL:
                    self.allowPremove = True
        gamemodel.connect("game_started", onGameStart)
        self.keybuffer = ""
        
    def __del__ (self):
        for menu, conid in self.connections.iteritems():
            menu.disconnect(conid)
        self.connections = {}
        self.view.save_board_size()

    def getPromotion(self):
        color = self.view.model.boards[-1].color
        variant = self.view.model.boards[-1].variant
        promotion = None
        glock.acquire()
        try:
            promotion = self.promotionDialog.runAndHide(color, variant)
        finally:
            glock.release()
        return promotion
        
    def emit_move_signal (self, cord0, cord1, promotion=None):
        color = self.view.model.boards[-1].color
        board = self.view.model.getBoardAtPly(self.view.shown, self.view.shownVariationIdx)
        # Ask player for which piece to promote into. If this move does not
        # include a promotion, QUEEN will be sent as a dummy value, but not used
        
        if promotion is None and board[cord0].sign == PAWN and cord1.y in (0, self.RANKS-1):
            promotion = self.getPromotion()
            if promotion is None:
                # Put back pawn moved be d'n'd
                self.view.runAnimation(redrawMisc = False)
                return
        
        if cord0.x < 0 or cord0.x > self.FILES-1:
            move = Move(lmovegen.newMove(board[cord0].piece, cord1.cord, DROP))
        else:
            move = Move(cord0, cord1, board, promotion)
        
        if self.view.model.curplayer.__type__ == LOCAL and self.view.shownIsMainLine() and \
           board.board.next is None and self.view.model.status == RUNNING:
            #self.emit("piece_moved", move, color)
        else:
            if board.board.next is None and not self.view.shownIsMainLine():
                self.view.model.add_move2variation(board, move, self.view.shownVariationIdx)
                self.view.shown += 1
            else:
                new_vari = self.view.model.add_variation(board, (move,))
                self.view.setShownBoard(new_vari[-1])
    
    def actionActivate (self, widget, key):
        """ Put actions from a menu or similar """
        if key == "call_flag":
            #self.emit("action", FLAG_CALL, None)
        elif key == "abort":
            #self.emit("action", ABORT_OFFER, None)
        elif key == "adjourn":
            #self.emit("action", ADJOURN_OFFER, None)
        elif key == "draw":
            #self.emit("action", DRAW_OFFER, None)
        elif key == "resign":
            #self.emit("action", RESIGNATION, None)
        elif key == "ask_to_move":
            #self.emit("action", HURRY_ACTION, None)
        elif key == "undo1":
            curColor = self.view.model.variations[0][-1].color
            curPlayer = self.view.model.players[curColor]
            if curPlayer.__type__ == LOCAL and self.view.model.ply > 1:
                #self.emit("action", TAKEBACK_OFFER, self.view.model.ply-2)
            else:
                #self.emit("action", TAKEBACK_OFFER, self.view.model.ply-1)
        elif key == "pause1":
            #self.emit("action", PAUSE_OFFER, None)
        elif key == "resume1":
            #self.emit("action", RESUME_OFFER, None)
    
    def shown_changed (self, view, shown):
        self.lockedPly = self.view.shown
        self.possibleBoards[self.lockedPly] = self._genPossibleBoards(self.lockedPly)
        if self.view.shown-2 in self.possibleBoards:
            del self.possibleBoards[self.view.shown-2]
    
    def moves_undone (self, gamemodel, moves):
        self.stateLock.acquire()
        try:
            self.view.selected = None
            self.view.active = None
            self.view.hover = None
            self.view.draggedPiece = None
            self.view.startAnimation()
            self.currentState = self.lockedNormalState
        finally:
            self.stateLock.release()

    def getBoard (self):
        return self.view.model.getBoardAtPly(self.view.shown, self.view.shownVariationIdx)

    def isLastPlayed(self, board):
        return board == self.view.model.boards[-1]
    
    def setLocked (self, locked):
        self.stateLock.acquire()
        try:
            if locked and self.isLastPlayed(self.getBoard()) and self.view.model.status == RUNNING:
                if self.view.model.status != RUNNING:
                    self.view.selected = None
                    self.view.active = None
                    self.view.hover = None
                    self.view.draggedPiece = None
                    self.view.startAnimation()

                if self.currentState == self.selectedState:
                    self.currentState = self.lockedSelectedState
                elif self.currentState == self.activeState:
                    self.currentState = self.lockedActiveState
                else:
                    self.currentState = self.lockedNormalState
            else:
                if self.currentState == self.lockedSelectedState:
                    self.currentState = self.selectedState
                elif self.currentState == self.lockedActiveState:
                    self.currentState = self.activeState
                else:
                    self.currentState = self.normalState
        finally:
            self.stateLock.release()
    
    def setStateSelected (self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedNormalState, self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedSelectedState
            else:
                self.view.setPremove(None, None, None, None)
                self.currentState = self.selectedState
        finally:
            self.stateLock.release()
    
    def setStateActive (self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedNormalState, self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedActiveState
            else:
                self.view.setPremove(None, None, None, None)
                self.currentState = self.activeState
        finally:
            self.stateLock.release()
    
    def setStateNormal (self):
        self.stateLock.acquire()
        try:
            if self.currentState in (self.lockedNormalState, self.lockedSelectedState,
                                     self.lockedActiveState):
                self.currentState = self.lockedNormalState
            else:
                self.view.setPremove(None, None, None, None)
                self.currentState = self.normalState
        finally:
            self.stateLock.release()
    
    def button_press (self, widget, event):
        return self.currentState.press(event.x, event.y, event.button)
    
    def button_release (self, widget, event):
        return self.currentState.release(event.x, event.y)
    
    def motion_notify (self, widget, event):
        return self.currentState.motion(event.x, event.y)
    
    def leave_notify (self, widget, event):
        return self.currentState.leave(event.x, event.y)

    def key_pressed (self, keyname):
        if keyname in "PNBRQKOox12345678abcdefgh":
            self.keybuffer += keyname
        elif keyname == "minus":
            self.keybuffer += "-"
        elif keyname == "at":
            self.keybuffer += "@"
        elif keyname == "Return":
            color = self.view.model.boards[-1].color
            board = self.view.model.getBoardAtPly(self.view.shown, self.view.shownVariationIdx)
            try:
                move = parseAny(board, self.keybuffer)
            except:
                self.keybuffer = ""
                return
            if validate(board, move):
                if self.view.shownIsMainLine() and board.board.next is None:
                    #self.emit("piece_moved", move, color)
                else:
                    if board.board.next is None:
                        self.view.model.add_move2variation(board, move, self.view.shownVariationIdx)
                        self.view.shown += 1
                    else:
                        new_vari = self.view.model.add_variation(board, (move,))
                        self.view.setShownBoard(new_vari[-1])
            self.keybuffer = ""
        elif keyname == "BackSpace":
            self.keybuffer = self.keybuffer[:-1] if self.keybuffer else ""

    def _genPossibleBoards(self, ply):
        possibleBoards = []
        curboard = self.view.model.getBoardAtPly(ply, self.view.shownVariationIdx)
        for lmove in lmovegen.genAllMoves(curboard.board):
            move = Move(lmove)
            board = curboard.move(move)
            possibleBoards.append(board)
        return possibleBoards