Example #1
0
def set (key, value):
    try:
        configParser.set (section, key, str(value))
        configParser.set (section+"_Types", key, typeEncode[type(value)])
    except Exception, e:
        log.error("Unable to save configuration '%s'='%s' because of error: %s %s"%
                (repr(key), repr(value), e.__class__.__name__, ", ".join(str(a) for a in e.args)))
Example #2
0
 def save(self, *args):
     try:
         with open(self.jsonpath, "w") as f:
             json.dump(self._engines, f, indent=1, sort_keys=True)
     except IOError as e:
         log.error("Saving engines.json raised exception: %s" % \
                   ", ".join(str(a) for a in e.args))
Example #3
0
 def save(self, *args):
     try:
         with open(self.jsonpath, "w") as f:
             json.dump(self._engines, f, indent=1, sort_keys=True)
     except IOError as e:
         log.error("Saving engines.json raised exception: %s" % \
                   ", ".join(str(a) for a in e.args))
 def cb(self_, *args):
     try:
         with open(self.xmlpath, "w") as f:
             self.dom.write(f)
     except IOError, e:
         log.error("Saving enginexml raised exception: %s\n" % \
                   ", ".join(str(a) for a in e.args))
Example #5
0
 def getBoardAtPly(self, ply):
     try:
         return self.boards[self._plyToIndex(ply)]
     except:
         log.error("%d\t%d\t%d\t%d\n" %
                   (self.lowply, ply, self.ply, len(self.boards)))
         raise
Example #6
0
 def load_from_xml(self):
     if os.path.isfile(self.dockLocation):
         try:
             self.dock.loadFromXML(self.dockLocation, self.docks)
         except Exception as e:
             # We don't send error message when error caused by no more existing SwitcherPanel
             if e.args[0] != "SwitcherPanel" and "unittest" not in sys.modules.keys():
                 stringio = StringIO()
                 traceback.print_exc(file=stringio)
                 error = stringio.getvalue()
                 log.error("Dock loading error: %s\n%s" % (e, error))
                 msg_dia = Gtk.MessageDialog(mainwindow(),
                                             type=Gtk.MessageType.ERROR,
                                             buttons=Gtk.ButtonsType.CLOSE)
                 msg_dia.set_markup(_(
                     "<b><big>PyChess was unable to load your panel settings</big></b>"))
                 msg_dia.format_secondary_text(_(
                     "Your panel settings have been reset. If this problem repeats, \
                     you should report it to the developers"))
                 msg_dia.run()
                 msg_dia.hide()
             os.remove(self.dockLocation)
             for title, panel, menu_item in self.docks.values():
                 title.unparent()
                 panel.unparent()
Example #7
0
 def _get_waitingplayer(self):
     try:
         return self.players[1 - self.getBoardAtPly(self.ply).color]
     except IndexError:
         log.error("%s %s" %
                   (self.players, 1 - self.getBoardAtPly(self.ply).color))
         raise
Example #8
0
 def save(self, *args):
     try:
         with open(self.jsonpath, "w") as file_handle:
             json.dump(self.engines, file_handle, indent=1, sort_keys=True)
     except IOError as err:
         log.error("Saving engines.json raised exception: %s" %
                   ", ".join(str(a) for a in err.args))
Example #9
0
 def page_reordered (widget, child, new_num, headbook):
     old_num = notebooks["board"].page_num(key2gmwidg[child].boardvbox)
     if old_num == -1:
         log.error('Games and labels are out of sync!')
     else:
         for notebook in notebooks.values():
             notebook.reorder_child(notebook.get_nth_page(old_num), new_num)
Example #10
0
 def cb(self_, *args):
     try:
         with open(self.xmlpath, "w") as f:
             self.dom.write(f)
     except IOError, e:
         log.error("Saving enginexml raised exception: %s\n" % \
                   ", ".join(str(a) for a in e.args))
Example #11
0
 def _get_curplayer(self):
     try:
         return self.players[self.getBoardAtPly(self.ply).color]
     except IndexError:
         log.error("%s %s\n" %
                   (self.players, self.getBoardAtPly(self.ply).color))
         raise
Example #12
0
 def getBoardAtPly(self, ply, variation=0):
     try:
         return self.variations[variation][self._plyToIndex(ply)]
     except IndexError:
         log.error("%d\t%d\t%d\t%d\t%d" % (self.lowply, ply, self.ply,
                                           variation, len(self.variations)))
         raise
Example #13
0
 def getMoveAtPly(self, ply):
     try:
         return self.moves[self._plyToIndex(ply)]
     except IndexError:
         log.error("%d\t%d\t%d\t%d\n" %
                   (self.lowply, ply, self.ply, len(self.moves)))
         raise
Example #14
0
 def getBoardAtPly(self, ply, variation=0):
     try:
         return self.variations[variation][self._plyToIndex(ply)]
     except IndexError:
         log.error("%d\t%d\t%d\t%d\t%d" % (self.lowply, ply, self.ply,
                                           variation, len(self.variations)))
         raise
Example #15
0
 def page_reordered (widget, child, new_num, headbook):
     old_num = notebooks["board"].page_num(key2gmwidg[child].boardvbox)
     if old_num == -1:
         log.error('Games and labels are out of sync!')
     else:
         for notebook in notebooks.values():
             notebook.reorder_child(notebook.get_nth_page(old_num), new_num)
Example #16
0
 def load_from_xml(self):
     if os.path.isfile(self.dockLocation):
         try:
             self.dock.loadFromXML(self.dockLocation, self.docks)
         except Exception as e:
             # We don't send error message when error caused by no more existing SwitcherPanel
             if e.args[0] != "SwitcherPanel" and "unittest" not in sys.modules.keys():
                 stringio = StringIO()
                 traceback.print_exc(file=stringio)
                 error = stringio.getvalue()
                 log.error("Dock loading error: %s\n%s" % (e, error))
                 msg_dia = Gtk.MessageDialog(mainwindow(),
                                             type=Gtk.MessageType.ERROR,
                                             buttons=Gtk.ButtonsType.CLOSE)
                 msg_dia.set_markup(_(
                     "<b><big>PyChess was unable to load your panel settings</big></b>"))
                 msg_dia.format_secondary_text(_(
                     "Your panel settings have been reset. If this problem repeats, \
                     you should report it to the developers"))
                 msg_dia.run()
                 msg_dia.hide()
             os.remove(self.dockLocation)
             for title, panel, menu_item in self.docks.values():
                 title.unparent()
                 panel.unparent()
Example #17
0
 def _get_waitingplayer(self):
     try:
         return self.players[1 - self.getBoardAtPly(self.ply).color]
     except IndexError:
         log.error("%s %s" %
                   (self.players, 1 - self.getBoardAtPly(self.ply).color))
         raise
Example #18
0
 def play(self, uri):
     try:
         winsound.PlaySound(None, 0)
         winsound.PlaySound(url2pathname(uri[5:]),
                            winsound.SND_FILENAME | winsound.SND_ASYNC)
     except RuntimeError:
         log.error("ERROR: RuntimeError while playing %s." %
                   url2pathname(uri[5:]))
Example #19
0
 def getMoveAtPly(self, ply, variation=0):
     try:
         return Move(self.variations[variation][self._plyToIndex(ply) +
                                                1].board.lastMove)
     except IndexError:
         log.error("%d\t%d\t%d\t%d\t%d" % (self.lowply, ply, self.ply,
                                           variation, len(self.variations)))
         raise
Example #20
0
 def getMoveAtPly(self, ply, variation=0):
     try:
         return Move(self.variations[variation][self._plyToIndex(ply) +
                                                1].board.lastMove)
     except IndexError:
         log.error("%d\t%d\t%d\t%d\t%d" % (self.lowply, ply, self.ply,
                                           variation, len(self.variations)))
         raise
Example #21
0
 def getBoardAtPly (self, ply, variation=0):
     # Losing on time in FICS game will undo our last move if it was taken too late
     if variation == 0 and ply > self.ply:
         ply = self.ply
     try:
         return self.variations[variation][self._plyToIndex(ply)]
     except IndexError:
         log.error("%d\t%d\t%d\t%d\t%d" % (self.lowply, ply, self.ply, variation, len(self.variations)))
         raise
Example #22
0
def set (key, value):
    try:
        configParser.set (section, key, str(value))
    except Exception as e:
        log.error("Unable to save configuration '%s'='%s' because of error: %s %s"%
                (repr(key), repr(value), e.__class__.__name__, ", ".join(str(a) for a in e.args)))
    for key_, func, args in idkeyfuncs.values():
        if key_ == key:
            func (None, *args)
Example #23
0
 def getBoardAtPly(self, ply, variation=0):
     # Losing on time in FICS game will undo our last move if it was taken too late
     if variation == 0 and ply > self.ply:
         ply = self.ply
     try:
         return self.variations[variation][self._plyToIndex(ply)]
     except IndexError:
         log.error("%d\t%d\t%d\t%d\t%d" % (self.lowply, ply, self.ply,
                                           variation, len(self.variations)))
         raise
Example #24
0
def set(key, value):
    try:
        configParser.set(section, key, str(value))
    except Exception as e:
        log.error(
            "Unable to save configuration '%s'='%s' because of error: %s %s" %
            (repr(key), repr(value), e.__class__.__name__, ", ".join(
                str(a) for a in e.args)))
    for key_, func, args in idkeyfuncs.values():
        if key_ == key:
            func(None, *args)
Example #25
0
def set(key, value, section=section):
    try:
        configParser.set(section, key, str(value))
        configParser.write(open(path, "w"))
    except Exception as err:
        log.error(
            "Unable to save configuration '%s'='%s' because of error: %s %s" %
            (repr(key), repr(value), err.__class__.__name__, ", ".join(
                str(a) for a in err.args)))
    for key_, func, args, section_ in idkeyfuncs.values():
        if key_ == key and section_ == section:
            func(None, *args)
Example #26
0
    def onOfferAdd(self, match):
        log.debug("OfferManager.onOfferAdd: match.string=%s\n" % match.string)
        tofrom, index, offertype, parameters = match.groups()
        if tofrom == "t":
            # ICGameModel keeps track of the offers we've sent ourselves, so we
            # don't need this
            return
        if offertype not in strToOfferType:
            log.error("OfferManager.onOfferAdd: Declining unknown offer type: " + \
                "offertype=%s parameters=%s index=%s\n" % (offertype, parameters, index))
            print >> self.connection.client, "decline", index
        offertype = strToOfferType[offertype]
        if offertype == TAKEBACK_OFFER:
            offer = Offer(offertype, param=int(parameters), index=int(index))
        else:
            offer = Offer(offertype, index=int(index))
        self.offers[offer.index] = offer

        if offer.type == MATCH_OFFER:
            if matchreUntimed.match(parameters) != None:
                fname, frating, col, tname, trating, rated, type = \
                    matchreUntimed.match(parameters).groups()
                mins = "0"
                incr = "0"
            else:
                fname, frating, col, tname, trating, rated, type_short, mins, incr, type = \
                    matchre.match(parameters).groups()
                if not type or "adjourned" in type:
                    type = type_short

            if type.split()[-1] in unsupportedtypes:
                self.decline(offer)
            else:
                rating = frating.strip()
                rating = rating.isdigit() and rating or "0"
                rated = rated == "unrated" and "u" or "r"
                match = {
                    "tp": convertName(type),
                    "w": fname,
                    "rt": rating,
                    "r": rated,
                    "t": mins,
                    "i": incr
                }
                self.emit("onChallengeAdd", index, match)

        else:
            log.debug("OfferManager.onOfferAdd: emitting onOfferAdd: %s\n" %
                      offer)
            self.emit("onOfferAdd", offer)
Example #27
0
    def run(self):
        # Avoid racecondition when self.start is called while we are in self.end
        if self.status != WAITING_TO_START:
            return
        self.status = RUNNING

        for player in self.players + self.spectactors.values():
            player.start()

        self.emit("game_started")

        while self.status in (PAUSED, RUNNING, DRAW, WHITEWON, BLACKWON):
            curColor = self.boards[-1].color
            curPlayer = self.players[curColor]

            if self.timemodel:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: updating %s's time\n" % \
                    (id(self), str(self.players), str(self.ply), str(curPlayer)))
                curPlayer.updateTime(
                    self.timemodel.getPlayerTime(curColor),
                    self.timemodel.getPlayerTime(1 - curColor))

            try:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: calling %s.makeMove()\n" % \
                    (id(self), str(self.players), self.ply, str(curPlayer)))
                if self.ply > self.lowply:
                    move = curPlayer.makeMove(self.boards[-1], self.moves[-1],
                                              self.boards[-2])
                else:
                    move = curPlayer.makeMove(self.boards[-1], None, None)
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from %s\n" % \
                    (id(self), str(self.players), self.ply, move, str(curPlayer)))
            except PlayerIsDead, e:
                if self.status in (WAITING_TO_START, PAUSED, RUNNING):
                    stringio = cStringIO.StringIO()
                    traceback.print_exc(file=stringio)
                    error = stringio.getvalue()
                    log.error(
                        "GameModel.run: A Player died: player=%s error=%s\n%s"
                        % (curPlayer, error, e))
                    if curColor == WHITE:
                        self.kill(WHITE_ENGINE_DIED)
                    else:
                        self.kill(BLACK_ENGINE_DIED)
                break
            except TurnInterrupt:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: TurnInterrupt\n" % \
                    (id(self), str(self.players), self.ply))
                continue
    def savePosition(window, *event):

        width = window.get_allocation().width
        height = window.get_allocation().height
        x, y = window.get_position()

        if width <= 0:
            log.error("Setting width = '%d' for %s to conf" % (width, key))
        if height <= 0:
            log.error("Setting height = '%d' for %s to conf" % (height, key))

        conf.set(key + "_width", width)
        conf.set(key + "_height", height)
        conf.set(key + "_x", x)
        conf.set(key + "_y", y)
Example #29
0
 def savePosition (window, *event):
     
     width = window.get_allocation().width
     height = window.get_allocation().height
     x, y = window.get_position()
     
     if width <= 0:
         log.error("Setting width = '%d' for %s to conf" % (width,key))
     if height <= 0:
         log.error("Setting height = '%d' for %s to conf" % (height,key))
     
     conf.set(key+"_width",  width)
     conf.set(key+"_height", height)
     conf.set(key+"_x", x)
     conf.set(key+"_y", y)
 def run (self):
     # Avoid racecondition when self.start is called while we are in self.end
     if self.status != WAITING_TO_START:
         return
     self.status = RUNNING
     
     for player in self.players + self.spectactors.values():
         player.start()
     
     self.emit("game_started")
     
     while self.status in (PAUSED, RUNNING, DRAW, WHITEWON, BLACKWON):
         curColor = self.boards[-1].color
         curPlayer = self.players[curColor]
         
         if self.timemodel:
             log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: updating %s's time\n" % \
                 (id(self), str(self.players), str(self.ply), str(curPlayer)))
             curPlayer.updateTime(self.timemodel.getPlayerTime(curColor),
                                  self.timemodel.getPlayerTime(1-curColor))
         
         try:
             log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: calling %s.makeMove()\n" % \
                 (id(self), str(self.players), self.ply, str(curPlayer)))
             if self.ply > self.lowply:
                 move = curPlayer.makeMove(self.boards[-1],
                                           self.moves[-1],
                                           self.boards[-2])
             else: move = curPlayer.makeMove(self.boards[-1], None, None)
             log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from %s\n" % \
                 (id(self), str(self.players), self.ply, move, str(curPlayer)))
         except PlayerIsDead, e:
             if self.status in (WAITING_TO_START, PAUSED, RUNNING):
                 stringio = cStringIO.StringIO()
                 traceback.print_exc(file=stringio)
                 error = stringio.getvalue()
                 log.error("GameModel.run: A Player died: player=%s error=%s\n%s" % (curPlayer, error, e))
                 if curColor == WHITE:
                     self.kill(WHITE_ENGINE_DIED)
                 else: self.kill(BLACK_ENGINE_DIED)
             break
         except TurnInterrupt:
             log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: TurnInterrupt\n" % \
                 (id(self), str(self.players), self.ply))
             continue
 def onOfferAdd (self, match):
     log.debug("OfferManager.onOfferAdd: match.string=%s\n" % match.string)
     tofrom, index, offertype, parameters = match.groups()
     if tofrom == "t":
         # ICGameModel keeps track of the offers we've sent ourselves, so we
         # don't need this
         return
     if offertype not in strToOfferType:
         log.error("OfferManager.onOfferAdd: Declining unknown offer type: " + \
             "offertype=%s parameters=%s index=%s\n" % (offertype, parameters, index))
         print >> self.connection.client, "decline", index
     offertype = strToOfferType[offertype]
     if offertype == TAKEBACK_OFFER:
         offer = Offer(offertype, param=int(parameters), index=int(index))
     else:
         offer = Offer(offertype, index=int(index))
     self.offers[offer.index] = offer
     
     if offer.type == MATCH_OFFER:
         if matchreUntimed.match(parameters) != None:
             fname, frating, col, tname, trating, rated, type = \
                 matchreUntimed.match(parameters).groups()
             mins = "0"
             incr = "0"
         else:
             fname, frating, col, tname, trating, rated, type_short, mins, incr, type = \
                 matchre.match(parameters).groups()
             if not type or "adjourned" in type:
                 type = type_short
         
         if type.split()[-1] in unsupportedtypes:
             self.decline(offer)
         else:
             rating = frating.strip()
             rating = rating.isdigit() and rating or "0"
             rated = rated == "unrated" and "u" or "r"
             match = {"tp": convertName(type), "w": fname, "rt": rating,
                      "r": rated, "t": mins, "i": incr}
             self.emit("onChallengeAdd", index, match)
     
     else:
         log.debug("OfferManager.onOfferAdd: emitting onOfferAdd: %s\n" % offer)
         self.emit("onOfferAdd", offer)
Example #32
0
    def savePosition(window, *event):
        log.debug("keepWindowSize.savePosition: %s" % window.get_title())
        width = window.get_allocation().width
        height = window.get_allocation().height
        x, y = window.get_position()

        if width <= 0:
            log.error("Setting width = '%d' for %s to conf" % (width, key))
        if height <= 0:
            log.error("Setting height = '%d' for %s to conf" % (height, key))

        log.debug("Saving window position width=%s height=%s x=%s y=%s" %
                  (width, height, x, y))
        conf.set(key + "_width", width)
        conf.set(key + "_height", height)
        conf.set(key + "_x", x)
        conf.set(key + "_y", y)

        return False
Example #33
0
    def savePosition(window, *event):
        log.debug("keepWindowSize.savePosition: %s" % window.get_title())
        width = window.get_allocation().width
        height = window.get_allocation().height
        x_loc, y_loc = window.get_position()

        if width <= 0:
            log.error("Setting width = '%d' for %s to conf" % (width, key))
        if height <= 0:
            log.error("Setting height = '%d' for %s to conf" % (height, key))

        log.debug("Saving window position width=%s height=%s x=%s y=%s" %
                  (width, height, x_loc, y_loc))
        conf.set(key + "_width", width)
        conf.set(key + "_height", height)
        conf.set(key + "_x", x_loc)
        conf.set(key + "_y", y_loc)

        return False
Example #34
0
        def __init__(self):
            PYTHONBIN = sys.executable.split("/")[-1]
            try:
                if getattr(sys, 'frozen', False):
                    gst_player = os.path.join(
                        os.path.abspath(os.path.dirname(sys.executable)),
                        "gst_player.py")
                else:
                    gst_player = os.path.join(
                        os.path.abspath(os.path.dirname(__file__)),
                        "gst_player.py")
                self.player = subprocess.Popen([PYTHONBIN, gst_player],
                                               stdin=subprocess.PIPE)

                self.stdin = io.TextIOWrapper(self.player.stdin,
                                              encoding='utf-8',
                                              line_buffering=True)
                self.ready = True
            except Exception:
                self.player = None
                log.error('ERROR: starting gst_player failed')
                raise
 def _get_curplayer (self):
     try:
         return self.players[self.getBoardAtPly(self.ply).color]
     except IndexError:
         log.error("%s %s\n" % (self.players, self.getBoardAtPly(self.ply).color))
         raise
Example #36
0
            def coro():
                persp = perspective_manager.get_perspective("games")
                gmwidg = persp.cur_gmwidg()
                gamemodel = gmwidg.gamemodel

                old_check_value = conf.get("analyzer_check")
                conf.set("analyzer_check", True)
                if HINT not in gamemodel.spectators:
                    try:
                        yield from asyncio.wait_for(gamemodel.start_analyzer(HINT), 5.0)
                    except asyncio.TimeoutError:
                        log.error("Got timeout error while starting hint analyzer")
                        return
                    except Exception:
                        log.error("Unknown error while starting hint analyzer")
                        return
                analyzer = gamemodel.spectators[HINT]
                gmwidg.menuitems["hint_mode"].active = True
                threat_PV = conf.get("ThreatPV")
                if threat_PV:
                    old_inv_check_value = conf.get("inv_analyzer_check")
                    conf.set("inv_analyzer_check", True)
                    if SPY not in gamemodel.spectators:
                        try:
                            yield from asyncio.wait_for(gamemodel.start_analyzer(SPY), 5.0)
                        except asyncio.TimeoutError:
                            log.error("Got timeout error while starting spy analyzer")
                            return
                        except Exception:
                            log.error("Unknown error while starting spy analyzer")
                            return
                    inv_analyzer = gamemodel.spectators[SPY]
                    gmwidg.menuitems["spy_mode"].active = True

                title = _("Game analyzing in progress...")
                text = _("Do you want to abort it?")
                content = InfoBar.get_message_content(title, text, Gtk.STOCK_DIALOG_QUESTION)

                def response_cb(infobar, response, message):
                    conf.set("analyzer_check", old_check_value)
                    if threat_PV:
                        conf.set("inv_analyzer_check", old_inv_check_value)
                    message.dismiss()
                    abort()
                message = InfoBarMessage(Gtk.MessageType.QUESTION, content, response_cb)
                message.add_button(InfoBarMessageButton(_("Abort"), Gtk.ResponseType.CANCEL))
                gmwidg.replaceMessages(message)

                @asyncio.coroutine
                def analyse_moves():
                    should_black = conf.get("shouldBlack")
                    should_white = conf.get("shouldWhite")
                    from_current = conf.get("fromCurrent")
                    start_ply = gmwidg.board.view.shown if from_current else 0
                    move_time = int(conf.get("max_analysis_spin"))
                    threshold = int(conf.get("variation_threshold_spin"))
                    for board in gamemodel.boards[start_ply:]:
                        if self.stop_event.is_set():
                            break

                        gmwidg.board.view.setShownBoard(board)
                        analyzer.setBoard(board)
                        if threat_PV:
                            inv_analyzer.setBoard(board)
                        yield from asyncio.sleep(move_time + 0.1)

                        ply = board.ply - gamemodel.lowply
                        color = (ply - 1) % 2
                        if ply - 1 in gamemodel.scores and ply in gamemodel.scores and (
                                (color == BLACK and should_black) or (color == WHITE and should_white)):
                            oldmoves, oldscore, olddepth = gamemodel.scores[ply - 1]
                            oldscore = oldscore * -1 if color == BLACK else oldscore
                            score_str = prettyPrintScore(oldscore, olddepth)
                            moves, score, depth = gamemodel.scores[ply]
                            score = score * -1 if color == WHITE else score
                            diff = score - oldscore
                            if ((diff > threshold and color == BLACK) or (diff < -1 * threshold and color == WHITE)) and (
                               gamemodel.moves[ply - 1] != parseAny(gamemodel.boards[ply - 1], oldmoves[0])):
                                if threat_PV:
                                    try:
                                        if ply - 1 in gamemodel.spy_scores:
                                            oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[ply - 1]
                                            score_str0 = prettyPrintScore(oldscore0, olddepth0)
                                            pv0 = listToMoves(gamemodel.boards[ply - 1], ["--"] + oldmoves0, validate=True)
                                            if len(pv0) > 2:
                                                gamemodel.add_variation(gamemodel.boards[ply - 1], pv0,
                                                                        comment="Threatening", score=score_str0, emit=False)
                                    except ParsingError as e:
                                        # ParsingErrors may happen when parsing "old" lines from
                                        # analyzing engines, which haven't yet noticed their new tasks
                                        log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" %
                                                  (' '.join(oldmoves), e))
                                try:
                                    pv = listToMoves(gamemodel.boards[ply - 1], oldmoves, validate=True)
                                    gamemodel.add_variation(gamemodel.boards[ply - 1], pv,
                                                            comment="Better is", score=score_str, emit=False)
                                except ParsingError as e:
                                    # ParsingErrors may happen when parsing "old" lines from
                                    # analyzing engines, which haven't yet noticed their new tasks
                                    log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" %
                                              (' '.join(oldmoves), e))

                    self.widgets["analyze_game"].hide()
                    self.widgets["analyze_ok_button"].set_sensitive(True)
                    conf.set("analyzer_check", old_check_value)
                    if threat_PV:
                        conf.set("inv_analyzer_check", old_inv_check_value)
                    message.dismiss()

                    gamemodel.emit("analysis_finished")

                create_task(analyse_moves())
                hide_window(None)

                return True
 def getBoardAtPly (self, ply):
     try:
         return self.boards[self._plyToIndex(ply)]
     except:
         log.error("%d\t%d\t%d\t%d\n" % (self.lowply, ply, self.ply, len(self.boards)))
         raise
 def getMoveAtPly (self, ply):
     try:
         return self.moves[self._plyToIndex(ply)]
     except IndexError:
         log.error("%d\t%d\t%d\t%d\n" % (self.lowply, ply, self.ply, len(self.moves)))
         raise
Example #39
0
    def __parseLine (self, line):
        if not self.connected: return
        parts = line.split()
        if not parts: return
        
        #---------------------------------------------------------- Initializing
        if parts[0] == "id":
            self.ids[parts[1]] = " ".join(parts[2:])
            if parts[1] == "name":
                self.setName(self.ids["name"])
            return
        
        if parts[0] == "uciok":
            self.emit("readyForOptions")
            return
        
        if parts[0] == "readyok":
            self.emit("readyForMoves")
            return
        
        #------------------------------------------------------- Options parsing
        if parts[0] == "option":
            dic = {}
            last = 1
            varlist = []
            for i in range (2, len(parts)+1):
                if i == len(parts) or parts[i] in OPTKEYS:
                    key = parts[last]
                    value = " ".join(parts[last+1:i])
                    if "type" in dic and dic["type"] in TYPEDIC:
                        value = TYPEDIC[dic["type"]](value)
                        
                    if key == "var":
                        varlist.append(value)
                    elif key == "type" and value == "string":
                        dic[key] = "text"
                    else:
                        dic[key] = value
                        
                    last = i
            if varlist:
                dic["choices"] = varlist
            
            self.options[dic["name"]] = dic
            return
        
        #---------------------------------------------------------------- A Move
        if self.mode == NORMAL and parts[0] == "bestmove":
            with self.moveLock:
                self.needBestmove = False
                self.__sendQueuedGo()
                
                if self.ignoreNext:
                    log.debug("__parseLine: line='%s' self.ignoreNext==True, returning" % \
                        line.strip(), extra={"task":self.defname})
                    self.ignoreNext = False
                    self.readyForStop = True
                    return
                
                if not self.waitingForMove:
                    log.warning("__parseLine: self.waitingForMove==False, ignoring move=%s" % \
                        parts[1], extra={"task":self.defname})
                    self.pondermove = None
                    return
                self.waitingForMove = False

                try:
                    move = parseAny(self.board, parts[1])
                except ParsingError as e:
                    self.end(WHITEWON if self.board.color == BLACK else BLACKWON, WON_ADJUDICATION)
                    return
                
                if not validate(self.board, move):
                    # This is critical. To avoid game stalls, we need to resign on
                    # behalf of the engine.
                    log.error("__parseLine: move=%s didn't validate, putting 'del' in returnQueue. self.board=%s" % \
                        (repr(move), self.board), extra={"task":self.defname})
                    self.end(WHITEWON if self.board.color == BLACK else BLACKWON, WON_ADJUDICATION)
                    return
                
                self._recordMove(self.board.move(move), move, self.board)
                log.debug("__parseLine: applied move=%s to self.board=%s" % \
                    (move, self.board), extra={"task":self.defname})
                
                if self.ponderOn:
                    self.pondermove = None
                    # An engine may send an empty ponder line, simply to clear.
                    if len(parts) == 4:
                        # Engines don't always check for everything in their
                        # ponders. Hence we need to validate.
                        # But in some cases, what they send may not even be
                        # correct AN - specially in the case of promotion.
                        try:
                            pondermove = parseAny(self.board, parts[3])
                        except ParsingError:
                            pass
                        else:
                            if validate(self.board, pondermove):
                                self.pondermove = pondermove
                                self._startPonder()
                
                self.returnQueue.put(move)
                log.debug("__parseLine: put move=%s into self.returnQueue=%s" % \
                    (move, self.returnQueue.queue), extra={"task":self.defname})
                return
        
        #----------------------------------------------------------- An Analysis
        if self.mode != NORMAL and parts[0] == "info" and "pv" in parts:
            multipv = 1
            if "multipv" in parts:
                multipv = int(parts[parts.index("multipv")+1])
            scoretype = parts[parts.index("score")+1]
            if scoretype in ('lowerbound', 'upperbound'):
                score = None
            else:
                score = int(parts[parts.index("score")+2])
                if scoretype == 'mate':
#                    print >> self.engine, "stop"
                    if score != 0:
                        sign = score/abs(score)
                        score = sign*MATE_VALUE
            
            movstrs = parts[parts.index("pv")+1:]
            try:
                moves = listToMoves (self.board, movstrs, AN, validate=True, ignoreErrors=False)
            except ParsingError as e:
                # ParsingErrors may happen when parsing "old" lines from
                # analyzing engines, which haven't yet noticed their new tasks
                log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s" % \
                    (' '.join(movstrs),e), extra={"task":self.defname})
                return

            if "depth" in parts:
                depth = parts[parts.index("depth")+1]
            else:
                depth = ""
                
            if multipv <= len(self.analysis):
                self.analysis[multipv - 1] = (moves, score, depth)

            self.emit("analyze", self.analysis)
            return
        
        #-----------------------------------------------  An Analyzer bestmove
        if self.mode != NORMAL and parts[0] == "bestmove":
            with self.moveLock:
                log.debug("__parseLine: processing analyzer bestmove='%s'" % \
                    line.strip(), extra={"task":self.defname})
                self.needBestmove = False
                self.__sendQueuedGo(sendlast=True)
                return
        
        #  Stockfish complaining it received a 'stop' without a corresponding 'position..go'
        if line.strip() == "Unknown command: stop":
            with self.moveLock:
                log.debug("__parseLine: processing '%s'" % line.strip(), extra={"task":self.defname})
                self.ignoreNext = False
                self.needBestmove = False
                self.readyForStop = False
                self.__sendQueuedGo()
                return
Example #40
0
def _ensureReadForGameWidgets():
    mainvbox = widgets["mainvbox"]
    if len(mainvbox.get_children()) == 3:
        return
    global background, notebooks
    notebooks = get_clean_notebooks(mainvbox)
    background = widgets["mainvbox"].get_children()[1]
    mainvbox.remove(background)

    # Initing headbook

    align = createAlignment(4, 4, 0, 4)
    align.set_property("yscale", 0)
    headbook = Gtk.Notebook()
    headbook.set_scrollable(True)
    align.add(headbook)
    mainvbox.pack_start(align, False, True, 0)
    show_tabs(not conf.get("hideTabs", False))

    # Initing center

    centerVBox = Gtk.VBox()

    # The dock

    global dock, dockAlign
    dock = PyDockTop("main")
    dockAlign = createAlignment(4, 4, 0, 4)
    dockAlign.add(dock)
    centerVBox.pack_start(dockAlign, True, True, 0)
    dockAlign.show()
    dock.show()

    for panel in sidePanels:
        hbox = Gtk.HBox()
        pixbuf = get_pixbuf(panel.__icon__, 16)
        icon = Gtk.Image.new_from_pixbuf(pixbuf)
        label = Gtk.Label(label=panel.__title__)
        label.set_size_request(0, 0)
        label.set_alignment(0, 1)
        hbox.pack_start(icon, False, False, 0)
        hbox.pack_start(label, True, True, 0)
        hbox.set_spacing(2)
        hbox.show_all()

        def cb(widget, x, y, keyboard_mode, tooltip, title, desc, filename):
            table = Gtk.Table(2, 2)
            table.set_row_spacings(2)
            table.set_col_spacings(6)
            table.set_border_width(4)
            pixbuf = get_pixbuf(filename, 56)
            image = Gtk.Image.new_from_pixbuf(pixbuf)
            image.set_alignment(0, 0)
            table.attach(image, 0, 1, 0, 2)
            titleLabel = Gtk.Label()
            titleLabel.set_markup("<b>%s</b>" % title)
            titleLabel.set_alignment(0, 0)
            table.attach(titleLabel, 1, 2, 0, 1)
            descLabel = Gtk.Label(label=desc)
            descLabel.props.wrap = True
            table.attach(descLabel, 1, 2, 1, 2)
            tooltip.set_custom(table)
            table.show_all()
            return True

        hbox.props.has_tooltip = True
        hbox.connect("query-tooltip", cb, panel.__title__, panel.__desc__,
                     panel.__icon__)

        docks[panel.__name__] = (hbox, notebooks[panel.__name__])

    if os.path.isfile(dockLocation):
        try:
            dock.loadFromXML(dockLocation, docks)
        except Exception as e:
            stringio = StringIO()
            traceback.print_exc(file=stringio)
            error = stringio.getvalue()
            log.error("Dock loading error: %s\n%s" % (e, error))
            msg_dia = Gtk.MessageDialog(widgets["window1"],
                                        type=Gtk.MessageType.ERROR,
                                        buttons=Gtk.ButtonsType.CLOSE)
            msg_dia.set_markup(
                _("<b><big>PyChess was unable to load your panel settings</big></b>"
                  ))
            msg_dia.format_secondary_text(
                _("Your panel settings have been reset. If this problem repeats, \
                you should report it to the developers"))
            msg_dia.run()
            msg_dia.hide()
            os.remove(dockLocation)
            for title, panel in docks.values():
                title.unparent()
                panel.unparent()

    if not os.path.isfile(dockLocation):
        leaf = dock.dock(docks["board"][1], CENTER,
                         Gtk.Label(label=docks["board"][0]), "board")
        docks["board"][1].show_all()
        leaf.setDockable(False)

        # S
        epanel = leaf.dock(docks["bookPanel"][1], SOUTH, docks["bookPanel"][0],
                           "bookPanel")
        epanel.default_item_height = 45
        epanel = epanel.dock(docks["engineOutputPanel"][1], CENTER,
                             docks["engineOutputPanel"][0],
                             "engineOutputPanel")

        # NE
        leaf = leaf.dock(docks["annotationPanel"][1], EAST,
                         docks["annotationPanel"][0], "annotationPanel")
        leaf = leaf.dock(docks["historyPanel"][1], CENTER,
                         docks["historyPanel"][0], "historyPanel")
        leaf = leaf.dock(docks["scorePanel"][1], CENTER,
                         docks["scorePanel"][0], "scorePanel")

        # SE
        leaf = leaf.dock(docks["chatPanel"][1], SOUTH, docks["chatPanel"][0],
                         "chatPanel")
        leaf = leaf.dock(docks["commentPanel"][1], CENTER,
                         docks["commentPanel"][0], "commentPanel")

    def unrealize(dock, notebooks):
        # unhide the panel before saving so its configuration is saved correctly
        notebooks["board"].get_parent().get_parent().zoomDown()
        dock.saveToXML(dockLocation)
        dock._del()

    dock.connect("unrealize", unrealize, notebooks)

    hbox = Gtk.HBox()

    # Buttons
    notebooks["buttons"].set_border_width(4)
    hbox.pack_start(notebooks["buttons"], False, True, 0)

    # The message area
    # TODO: If you try to fix this first read issue #958 and 1018
    align = createAlignment(0, 0, 0, 0)
    # sw = Gtk.ScrolledWindow()
    # port = Gtk.Viewport()
    # port.add(notebooks["messageArea"])
    # sw.add(port)
    # align.add(sw)
    align.add(notebooks["messageArea"])
    hbox.pack_start(align, True, True, 0)

    def ma_switch_page(notebook, gpointer, page_num):
        notebook.props.visible = notebook.get_nth_page(page_num).\
            get_child().props.visible

    notebooks["messageArea"].connect("switch-page", ma_switch_page)
    centerVBox.pack_start(hbox, False, True, 0)

    mainvbox.pack_start(centerVBox, True, True, 0)
    centerVBox.show_all()
    mainvbox.show()

    # Connecting headbook to other notebooks

    def hb_switch_page(notebook, gpointer, page_num):
        for notebook in notebooks.values():
            notebook.set_current_page(page_num)


#        log.debug("HB_switch ficsgame no. %s , %s " % (key2gmwidg[getheadbook().\
#           get_nth_page(page_num)].gamemodel.ficsgame.gameno,str(page_num)))
        gmwidg = key2gmwidg[getheadbook().get_nth_page(page_num)]
        if isinstance(gmwidg.gamemodel, ICGameModel):
            primary = "primary " + str(gmwidg.gamemodel.ficsgame.gameno)
            gmwidg.gamemodel.connection.client.run_command(primary)

    headbook.connect("switch-page", hb_switch_page)

    if hasattr(headbook, "set_tab_reorderable"):

        def page_reordered(widget, child, new_num, headbook):
            old_num = notebooks["board"].page_num(key2gmwidg[child].boardvbox)
            if old_num == -1:
                log.error('Games and labels are out of sync!')
            else:
                for notebook in notebooks.values():
                    notebook.reorder_child(notebook.get_nth_page(old_num),
                                           new_num)

        headbook.connect("page-reordered", page_reordered, headbook)
Example #41
0
 def save(self, *args):
     try:
         with open(self.jsonpath, "w") as file_handle:
             json.dump(self.engines, file_handle, indent=1, sort_keys=True)
     except IOError as err:
         log.error("Saving engines.json raised exception: %s" % ", ".join(str(a) for a in err.args))
Example #42
0
    def init_layout(self):
        perspective_widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        perspective_manager.set_perspective_widget("games", perspective_widget)

        self.notebooks = {"board": cleanNotebook("board"),
                          "buttons": cleanNotebook("buttons"),
                          "messageArea": cleanNotebook("messageArea")}
        for panel in sidePanels:
            self.notebooks[panel.__name__] = cleanNotebook(panel.__name__)

        # Initing headbook

        align = gamewidget.createAlignment(4, 4, 0, 4)
        align.set_property("yscale", 0)

        headbook = Gtk.Notebook()
        headbook.set_name("headbook")
        headbook.set_scrollable(True)
        align.add(headbook)
        perspective_widget.pack_start(align, False, True, 0)
        self.show_tabs(not conf.get("hideTabs", False))

        # Initing center

        centerVBox = Gtk.VBox()

        # The dock

        self.dock = PyDockTop("main", self)
        self.dockAlign = gamewidget.createAlignment(4, 4, 0, 4)
        self.dockAlign.add(self.dock)
        centerVBox.pack_start(self.dockAlign, True, True, 0)
        self.dockAlign.show()
        self.dock.show()

        self.docks = {"board": (Gtk.Label(label="Board"), self.notebooks["board"])}
        for panel in sidePanels:
            box = dock_panel_tab(panel.__title__, panel.__desc__, panel.__icon__)
            self.docks[panel.__name__] = (box, self.notebooks[panel.__name__])

        if os.path.isfile(dockLocation):
            try:
                self.dock.loadFromXML(dockLocation, self.docks)
            except Exception as e:
                stringio = StringIO()
                traceback.print_exc(file=stringio)
                error = stringio.getvalue()
                log.error("Dock loading error: %s\n%s" % (e, error))
                widgets = gamewidget.getWidgets()
                msg_dia = Gtk.MessageDialog(widgets["main_window"],
                                            type=Gtk.MessageType.ERROR,
                                            buttons=Gtk.ButtonsType.CLOSE)
                msg_dia.set_markup(_(
                    "<b><big>PyChess was unable to load your panel settings</big></b>"))
                msg_dia.format_secondary_text(_(
                    "Your panel settings have been reset. If this problem repeats, \
                    you should report it to the developers"))
                msg_dia.run()
                msg_dia.hide()
                os.remove(dockLocation)
                for title, panel in self.docks.values():
                    title.unparent()
                    panel.unparent()

        if not os.path.isfile(dockLocation):
            leaf = self.dock.dock(self.docks["board"][1],
                                  CENTER,
                                  Gtk.Label(label=self.docks["board"][0]),
                                  "board")
            self.docks["board"][1].show_all()
            leaf.setDockable(False)

            # S
            epanel = leaf.dock(self.docks["bookPanel"][1], SOUTH, self.docks["bookPanel"][0],
                               "bookPanel")
            epanel.default_item_height = 45
            epanel = epanel.dock(self.docks["engineOutputPanel"][1], CENTER,
                                 self.docks["engineOutputPanel"][0],
                                 "engineOutputPanel")

            # NE
            leaf = leaf.dock(self.docks["annotationPanel"][1], EAST,
                             self.docks["annotationPanel"][0], "annotationPanel")
            leaf = leaf.dock(self.docks["historyPanel"][1], CENTER,
                             self.docks["historyPanel"][0], "historyPanel")
            leaf = leaf.dock(self.docks["scorePanel"][1], CENTER,
                             self.docks["scorePanel"][0], "scorePanel")

            # SE
            leaf = leaf.dock(self.docks["chatPanel"][1], SOUTH, self.docks["chatPanel"][0],
                             "chatPanel")
            leaf = leaf.dock(self.docks["commentPanel"][1], CENTER,
                             self.docks["commentPanel"][0], "commentPanel")

        def unrealize(dock, notebooks):
            # unhide the panel before saving so its configuration is saved correctly
            self.notebooks["board"].get_parent().get_parent().zoomDown()
            dock.saveToXML(dockLocation)
            dock._del()

        self.dock.connect("unrealize", unrealize, self.notebooks)

        hbox = Gtk.HBox()

        # Buttons
        self.notebooks["buttons"].set_border_width(4)
        hbox.pack_start(self.notebooks["buttons"], False, True, 0)

        # The message area
        # TODO: If you try to fix this first read issue #958 and 1018
        align = gamewidget.createAlignment(0, 0, 0, 0)
        # sw = Gtk.ScrolledWindow()
        # port = Gtk.Viewport()
        # port.add(self.notebooks["messageArea"])
        # sw.add(port)
        # align.add(sw)
        align.add(self.notebooks["messageArea"])
        hbox.pack_start(align, True, True, 0)

        def ma_switch_page(notebook, gpointer, page_num):
            notebook.props.visible = notebook.get_nth_page(page_num).\
                get_child().props.visible

        self.notebooks["messageArea"].connect("switch-page", ma_switch_page)
        centerVBox.pack_start(hbox, False, True, 0)

        perspective_widget.pack_start(centerVBox, True, True, 0)
        centerVBox.show_all()
        perspective_widget.show_all()

        conf.notify_add("hideTabs", self.tabsCallback)

        # Connecting headbook to other notebooks

        def hb_switch_page(notebook, gpointer, page_num):
            for notebook in self.notebooks.values():
                notebook.set_current_page(page_num)

            gmwidg = self.key2gmwidg[self.getheadbook().get_nth_page(page_num)]
            if isinstance(gmwidg.gamemodel, ICGameModel):
                primary = "primary " + str(gmwidg.gamemodel.ficsgame.gameno)
                gmwidg.gamemodel.connection.client.run_command(primary)

        headbook.connect("switch-page", hb_switch_page)

        if hasattr(headbook, "set_tab_reorderable"):

            def page_reordered(widget, child, new_num, headbook):
                old_num = self.notebooks["board"].page_num(self.key2gmwidg[child].boardvbox)
                if old_num == -1:
                    log.error('Games and labels are out of sync!')
                else:
                    for notebook in self.notebooks.values():
                        notebook.reorder_child(
                            notebook.get_nth_page(old_num), new_num)

            headbook.connect("page-reordered", page_reordered, headbook)
Example #43
0
    def open_lounge(self, connection, helperconn, host):
        if self.first_run:
            self.init_layout()

        self.connection = connection
        self.helperconn = helperconn
        self.host = host

        self.finger_sent = False
        self.messages = []
        self.players = []
        self.game_cids = {}

        self.widgets = uistuff.GladeWidgets("fics_lounge.glade")
        self.widgets["fics_lounge"].hide()

        fics_home = self.widgets["fics_home"]
        self.widgets["fics_lounge_content_hbox"].remove(fics_home)

        self.archive_list = self.widgets["archiveListContent"]
        self.widgets["fics_panels_notebook"].remove(self.archive_list)

        self.games_list = self.widgets["gamesListContent"]
        self.widgets["fics_panels_notebook"].remove(self.games_list)

        self.news_list = self.widgets["news"]
        self.widgets["fics_home"].remove(self.news_list)

        self.players_list = self.widgets["playersListContent"]
        self.widgets["fics_panels_notebook"].remove(self.players_list)

        self.seek_graph = self.widgets["seekGraphContent"]
        self.widgets["fics_panels_notebook"].remove(self.seek_graph)

        self.seek_list = self.widgets["seekListContent"]
        self.widgets["fics_panels_notebook"].remove(self.seek_list)

        self.seek_challenge = SeekChallengeSection(self)

        def on_autoLogout(alm):
            self.emit("autoLogout")
            self.close()

        self.connection.alm.connect("logOut", on_autoLogout)
        self.connection.connect("disconnected",
                                lambda connection: self.close())
        self.connection.connect("error", self.on_connection_error)
        if self.connection.isRegistred():
            numtimes = conf.get("numberOfTimesLoggedInAsRegisteredUser", 0) + 1
            conf.set("numberOfTimesLoggedInAsRegisteredUser", numtimes)
        self.connection.em.connect(
            "onCommandNotFound", lambda em, cmd: log.error(
                "Fics answered '%s': Command not found" % cmd))
        self.connection.bm.connect("playGameCreated", self.onPlayGameCreated)
        self.connection.bm.connect("obsGameCreated", self.onObserveGameCreated)
        self.connection.bm.connect("exGameCreated", self.onObserveGameCreated)
        self.connection.fm.connect("fingeringFinished", self.onFinger)
        # the rest of these relay server messages to the lounge infobar
        self.connection.bm.connect("tooManySeeks", self.tooManySeeks)
        self.connection.bm.connect("nonoWhileExamine", self.nonoWhileExamine)
        self.connection.bm.connect("matchDeclined", self.matchDeclined)
        self.connection.bm.connect("player_on_censor", self.player_on_censor)
        self.connection.bm.connect("player_on_noplay", self.player_on_noplay)
        self.connection.bm.connect("req_not_fit_formula",
                                   self.req_not_fit_formula)
        self.connection.glm.connect("seek-updated", self.on_seek_updated)
        self.connection.glm.connect("our-seeks-removed",
                                    self.our_seeks_removed)
        self.connection.cm.connect("arrivalNotification",
                                   self.onArrivalNotification)
        self.connection.cm.connect("departedNotification",
                                   self.onDepartedNotification)

        def get_top_games():
            if perspective_manager.current_perspective == self:
                self.connection.client.run_command("games *19")
            return True

        if self.connection.ICC:
            self.event_id = GLib.timeout_add_seconds(5, get_top_games)

        for user in self.connection.notify_users:
            user = self.connection.players.get(user)
            self.user_from_notify_list_is_present(user)

        self.userinfo = UserInfoSection(self.widgets, self.connection,
                                        self.host, self)
        if not self.first_run:
            self.notebooks["ficshome"].remove_page(-1)
        self.notebooks["ficshome"].append_page(fics_home)

        self.panels = [
            panel.Sidepanel().load(self.widgets, self.connection, self)
            for panel in self.sidePanels
        ]

        for panel, instance in zip(self.sidePanels, self.panels):
            if not self.first_run:
                self.notebooks[panel.__name__].remove_page(-1)
            self.notebooks[panel.__name__].append_page(instance)
            instance.show()

        tool_buttons = [
            self.logoff_button,
        ]
        self.quick_seek_buttons = []
        if self.connection.ICC:
            self.quick_seek_buttons = [
                self.minute_1_button, self.minute_3_button,
                self.minute_5_button, self.minute_15_button,
                self.minute_25_button, self.chess960_button
            ]
            tool_buttons += self.quick_seek_buttons
        perspective_manager.set_perspective_toolbuttons("fics", tool_buttons)

        if self.first_run:
            self.first_run = False

        # After all panel is set up we can push initial messages out
        self.connection.com.onConsoleMessage("", self.connection.ini_messages)
def _ensureReadForGameWidgets():
    mainvbox = widgets["mainvbox"]
    if len(mainvbox.get_children()) == 3:
        return

    global background
    background = widgets["mainvbox"].get_children()[1]
    mainvbox.remove(background)

    # Initing headbook

    align = createAlignment(4, 4, 0, 4)
    align.set_property("yscale", 0)
    headbook = gtk.Notebook()
    headbook.set_scrollable(True)
    headbook.props.tab_vborder = 0
    align.add(headbook)
    mainvbox.pack_start(align, expand=False)
    show_tabs(not conf.get("hideTabs", False))

    # Initing center

    centerVBox = gtk.VBox()

    # The message area

    centerVBox.pack_start(notebooks["messageArea"], expand=False)

    def callback(notebook, gpointer, page_num):
        notebook.props.visible = notebook.get_nth_page(page_num).child.props.visible

    notebooks["messageArea"].connect("switch-page", callback)

    # The dock

    global dock, dockAlign
    dock = PyDockTop("main")
    dockAlign = createAlignment(4, 4, 0, 4)
    dockAlign.add(dock)
    centerVBox.pack_start(dockAlign)
    dockAlign.show()
    dock.show()

    dockLocation = addUserConfigPrefix("pydock.xml")
    for panel in sidePanels:
        hbox = gtk.HBox()
        pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(panel.__icon__, 16, 16)
        icon = gtk.image_new_from_pixbuf(pixbuf)
        label = gtk.Label(panel.__title__)
        label.set_size_request(0, 0)
        label.set_alignment(0, 1)
        hbox.pack_start(icon, expand=False, fill=False)
        hbox.pack_start(label, expand=True, fill=True)
        hbox.set_spacing(2)
        hbox.show_all()

        def cb(widget, x, y, keyboard_mode, tooltip, title, desc, filename):
            table = gtk.Table(2, 2)
            table.set_row_spacings(2)
            table.set_col_spacings(6)
            table.set_border_width(4)
            pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 56, 56)
            image = gtk.image_new_from_pixbuf(pixbuf)
            image.set_alignment(0, 0)
            table.attach(image, 0, 1, 0, 2)
            titleLabel = gtk.Label()
            titleLabel.set_markup("<b>%s</b>" % title)
            titleLabel.set_alignment(0, 0)
            table.attach(titleLabel, 1, 2, 0, 1)
            descLabel = gtk.Label(desc)
            descLabel.props.wrap = True
            table.attach(descLabel, 1, 2, 1, 2)
            tooltip.set_custom(table)
            table.show_all()
            return True

        hbox.props.has_tooltip = True
        hbox.connect("query-tooltip", cb, panel.__title__, panel.__desc__, panel.__icon__)

        docks[panel.__name__] = (hbox, notebooks[panel.__name__])

    if os.path.isfile(dockLocation):
        try:
            dock.loadFromXML(dockLocation, docks)
        except Exception, e:
            stringio = cStringIO.StringIO()
            traceback.print_exc(file=stringio)
            error = stringio.getvalue()
            log.error("Dock loading error: %s\n%s" % (e, error))
            md = gtk.MessageDialog(widgets["window1"], type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_CLOSE)
            md.set_markup(_("<b><big>PyChess was unable to load your panel settings</big></b>"))
            md.format_secondary_text(
                _(
                    "Your panel settings have been reset. If this problem repeats, you should report it to the developers"
                )
            )
            md.run()
            md.hide()
            os.remove(dockLocation)
            for title, panel in docks.values():
                title.unparent()
                panel.unparent()
Example #45
0
    def parseLine(self, proc):
        while True:
            line = yield from wait_signal(proc, 'line')
            if not line:
                break
            else:
                line = line[1]
                parts = line.split()
                if not parts:
                    continue
                # Initializing
                if parts[0] == "id":
                    if parts[1] == "name":
                        self.ids[parts[1]] = " ".join(parts[2:])
                        self.setName(self.ids["name"])
                    continue

                if parts[0] == "uciok":
                    self.emit("readyForOptions")
                    continue

                if parts[0] == "readyok":
                    self.emit("readyForMoves")
                    continue

                # Options parsing
                if parts[0] == "option":
                    dic = {}
                    last = 1
                    varlist = []
                    for i in range(2, len(parts) + 1):
                        if i == len(parts) or parts[i] in OPTKEYS:
                            key = parts[last]
                            value = " ".join(parts[last + 1:i])
                            if "type" in dic and dic["type"] in TYPEDIC:
                                value = TYPEDIC[dic["type"]](value)

                            if key == "var":
                                varlist.append(value)
                            elif key == "type" and value == "string":
                                dic[key] = "text"
                            else:
                                dic[key] = value

                            last = i
                    if varlist:
                        dic["choices"] = varlist

                    if "name" in dic:
                        self.options[dic["name"]] = dic
                    continue

                # A Move
                if self.mode == NORMAL and parts[0] == "bestmove":
                    self.needBestmove = False
                    self.bestmove_event.set()
                    self.__sendQueuedGo()

                    if self.ignoreNext:
                        log.debug(
                            "__parseLine: line='%s' self.ignoreNext==True, returning"
                            % line.strip(),
                            extra={"task": self.defname})
                        self.ignoreNext = False
                        self.readyForStop = True
                        continue

                    movestr = parts[1]
                    if not self.waitingForMove:
                        log.warning(
                            "__parseLine: self.waitingForMove==False, ignoring move=%s"
                            % movestr,
                            extra={"task": self.defname})
                        self.pondermove = None
                        continue
                    self.waitingForMove = False

                    try:
                        move = parseAny(self.board, movestr)
                    except ParsingError:
                        self.invalid_move = movestr
                        log.info(
                            "__parseLine: ParsingError engine move: %s %s" %
                            (movestr, self.board),
                            extra={"task": self.defname})
                        self.end(
                            WHITEWON if self.board.color == BLACK else
                            BLACKWON, WON_ADJUDICATION)
                        continue

                    if not validate(self.board, move):
                        # This is critical. To avoid game stalls, we need to resign on
                        # behalf of the engine.
                        log.error(
                            "__parseLine: move=%s didn't validate, putting 'del' \
                                  in returnQueue. self.board=%s" %
                            (repr(move), self.board),
                            extra={"task": self.defname})
                        self.invalid_move = movestr
                        self.end(
                            WHITEWON if self.board.color == BLACK else
                            BLACKWON, WON_ADJUDICATION)
                        continue

                    self._recordMove(self.board.move(move), move, self.board)
                    log.debug("__parseLine: applied move=%s to self.board=%s" %
                              (move, self.board),
                              extra={"task": self.defname})

                    if self.ponderOn:
                        self.pondermove = None
                        # An engine may send an empty ponder line, simply to clear.
                        if len(parts) == 4:
                            # Engines don't always check for everything in their
                            # ponders. Hence we need to validate.
                            # But in some cases, what they send may not even be
                            # correct AN - specially in the case of promotion.
                            try:
                                pondermove = parseAny(self.board, parts[3])
                            except ParsingError:
                                pass
                            else:
                                if validate(self.board, pondermove):
                                    self.pondermove = pondermove
                                    self._startPonder()

                    self.queue.put_nowait(move)
                    log.debug("__parseLine: put move=%s into self.queue=%s" %
                              (move, self.queue),
                              extra={"task": self.defname})
                    continue

                # An Analysis
                if self.mode != NORMAL and parts[0] == "info" and "pv" in parts:
                    multipv = 1
                    if "multipv" in parts:
                        multipv = int(parts[parts.index("multipv") + 1])
                    scoretype = parts[parts.index("score") + 1]
                    if scoretype in ('lowerbound', 'upperbound'):
                        score = None
                    else:
                        score = int(parts[parts.index("score") + 2])
                        if scoretype == 'mate':
                            #                    print >> self.engine, "stop"
                            if score != 0:
                                sign = score / abs(score)
                                score = sign * (MATE_VALUE - abs(score))

                    movstrs = parts[parts.index("pv") + 1:]

                    if "depth" in parts:
                        depth = parts[parts.index("depth") + 1]
                    else:
                        depth = ""

                    if "nps" in parts:
                        nps = parts[parts.index("nps") + 1]
                    else:
                        nps = ""

                    if multipv <= len(self.analysis):
                        self.analysis[multipv - 1] = (self.board.ply, movstrs,
                                                      score, depth, nps)
                    self.emit("analyze", self.analysis)
                    continue

                # An Analyzer bestmove
                if self.mode != NORMAL and parts[0] == "bestmove":
                    log.debug(
                        "__parseLine: processing analyzer bestmove='%s'" %
                        line.strip(),
                        extra={"task": self.defname})
                    self.needBestmove = False
                    self.bestmove_event.set()
                    if parts[1] == "(none)":
                        self.emit("analyze", [])
                    else:
                        self.__sendQueuedGo(sendlast=True)
                    continue

                # Stockfish complaining it received a 'stop' without a corresponding 'position..go'
                if line.strip() == "Unknown command: stop":
                    log.debug("__parseLine: processing '%s'" % line.strip(),
                              extra={"task": self.defname})
                    self.ignoreNext = False
                    self.needBestmove = False
                    self.readyForStop = False
                    self.__sendQueuedGo()
                    continue
Example #46
0
    def init_layout(self):
        perspective_widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        perspective_manager.set_perspective_widget("database", perspective_widget)

        self.switcher_panel = SwitcherPanel(self)
        self.notebooks["gamelist"] = new_notebook()
        self.notebooks["opening_tree"] = new_notebook()
        self.notebooks["filter"] = new_notebook()
        self.notebooks["preview"] = new_notebook()

        self.spinner = Gtk.Spinner()
        self.spinner.set_size_request(50, 50)
        self.progressbar0 = Gtk.ProgressBar(show_text=True)
        self.progressbar1 = Gtk.ProgressBar(show_text=True)

        mainwindow = gamewidget.getWidgets()["main_window"]
        self.progress_dialog = Gtk.Dialog("", mainwindow, 0, (
            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL))
        self.progress_dialog.get_content_area().pack_start(self.spinner, True, True, 0)
        self.progress_dialog.get_content_area().pack_start(self.progressbar0, True, True, 0)
        self.progress_dialog.get_content_area().pack_start(self.progressbar1, True, True, 0)
        self.progress_dialog.get_content_area().show_all()

        self.dock = PyDockTop("database", self)
        align = Gtk.Alignment()
        align.show()
        align.add(self.dock)
        self.dock.show()
        perspective_widget.pack_start(align, True, True, 0)

        dockLocation = addUserConfigPrefix("pydock-database.xml")

        docks = {
            "gamelist": (Gtk.Label(label="gamelist"), self.notebooks["gamelist"]),
            "switcher": (dock_panel_tab(_("Databases"), "", addDataPrefix("glade/panel_database.svg")), self.switcher_panel.alignment),
            "openingtree": (dock_panel_tab(_("Openings"), "", addDataPrefix("glade/panel_book.svg")), self.notebooks["opening_tree"]),
            "filter": (dock_panel_tab(_("Filters"), "", addDataPrefix("glade/panel_filter.svg")), self.notebooks["filter"]),
            "preview": (dock_panel_tab(_("Preview"), "", addDataPrefix("glade/panel_games.svg")), self.notebooks["preview"]),
        }

        if os.path.isfile(dockLocation):
            try:
                self.dock.loadFromXML(dockLocation, docks)
            except Exception as e:
                stringio = StringIO()
                traceback.print_exc(file=stringio)
                error = stringio.getvalue()
                log.error("Dock loading error: %s\n%s" % (e, error))
                msg_dia = Gtk.MessageDialog(None,
                                            type=Gtk.MessageType.ERROR,
                                            buttons=Gtk.ButtonsType.CLOSE)
                msg_dia.set_markup(_(
                    "<b><big>PyChess was unable to load your panel settings</big></b>"))
                msg_dia.format_secondary_text(_(
                    "Your panel settings have been reset. If this problem repeats, \
                    you should report it to the developers"))
                msg_dia.run()
                msg_dia.hide()
                os.remove(dockLocation)
                for title, panel in docks.values():
                    title.unparent()
                    panel.unparent()

        if not os.path.isfile(dockLocation):
            leaf = self.dock.dock(docks["gamelist"][1], CENTER, docks["gamelist"][0], "gamelist")
            leaf.setDockable(False)

            leaf.dock(docks["switcher"][1], NORTH, docks["switcher"][0], "switcher")
            leaf = leaf.dock(docks["openingtree"][1], EAST, docks["openingtree"][0], "openingtree")
            leaf = leaf.dock(docks["filter"][1], CENTER, docks["filter"][0], "filter")
            leaf.dock(docks["preview"][1], SOUTH, docks["preview"][0], "preview")

        def unrealize(dock):
            dock.saveToXML(dockLocation)
            dock._del()

        self.dock.connect("unrealize", unrealize)

        self.dock.show_all()
        perspective_widget.show_all()

        perspective_manager.set_perspective_toolbuttons("database", [self.import_button, self.close_button])

        self.switcher_panel.connect("chessfile_switched", self.on_chessfile_switched)
Example #47
0
    def run(self):
        log.debug("GameModel.run: Starting. self=%s" % self)
        # Avoid racecondition when self.start is called while we are in
        # self.end
        if self.status != WAITING_TO_START:
            return

        if not self.isLocalGame():
            self.timemodel.handle_gain = False

        self.status = RUNNING

        for player in self.players + list(self.spectators.values()):
            player.start()

        log.debug("GameModel.run: emitting 'game_started' self=%s" % self)
        self.emit("game_started")

        # Let GameModel end() itself on games started with loadAndStart()
        self.checkStatus()

        self.curColor = self.boards[-1].color

        while self.status in (PAUSED, RUNNING, DRAW, WHITEWON, BLACKWON):
            curPlayer = self.players[self.curColor]

            if self.timed:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: updating %s's time" % (
                    id(self), str(self.players), str(self.ply), str(curPlayer)))
                curPlayer.updateTime(
                    self.timemodel.getPlayerTime(self.curColor),
                    self.timemodel.getPlayerTime(1 - self.curColor))

            try:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: calling %s.makeMove()" % (
                    id(self), str(self.players), self.ply, str(curPlayer)))
                if self.ply > self.lowply:
                    move = curPlayer.makeMove(self.boards[-1], self.moves[-1],
                                              self.boards[-2])
                else:
                    move = curPlayer.makeMove(self.boards[-1], None, None)
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from %s" % (
                    id(self), str(self.players), self.ply, move, str(curPlayer)))
            except PlayerIsDead as e:
                if self.status in (WAITING_TO_START, PAUSED, RUNNING):
                    stringio = StringIO()
                    traceback.print_exc(file=stringio)
                    error = stringio.getvalue()
                    log.error(
                        "GameModel.run: A Player died: player=%s error=%s\n%s"
                        % (curPlayer, error, e))
                    if self.curColor == WHITE:
                        self.kill(WHITE_ENGINE_DIED)
                    else:
                        self.kill(BLACK_ENGINE_DIED)
                break
            except InvalidMove as e:
                if self.curColor == WHITE:
                    self.end(BLACKWON, WON_ADJUDICATION)
                else:
                    self.end(WHITEWON, WON_ADJUDICATION)
                break
            except TurnInterrupt:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: TurnInterrupt" % (
                    id(self), str(self.players), self.ply))
                self.curColor = self.boards[-1].color
                continue

            log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: acquiring self.applyingMoveLock" % (
                id(self), str(self.players), self.ply))
            assert isinstance(move, Move), "%s" % repr(move)

            self.applyingMoveLock.acquire()
            try:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: applying move=%s" % (
                    id(self), str(self.players), self.ply, str(move)))
                self.needsSave = True
                newBoard = self.boards[-1].move(move)
                newBoard.board.prev = self.boards[-1].board

                # Variation on next move can exist from the hint panel...
                if self.boards[-1].board.next is not None:
                    newBoard.board.children = self.boards[
                        -1].board.next.children

                self.boards = self.variations[0]
                self.boards[-1].board.next = newBoard.board
                self.boards.append(newBoard)
                self.moves.append(move)

                if self.timed:
                    self.timemodel.tap()

                if not self.terminated:
                    self.emit("game_changed", self.ply)

                for spectator in self.spectators.values():
                    if spectator.board == self.boards[-2]:
                        spectator.putMove(self.boards[-1], self.moves[-1],
                                          self.boards[-2])

                self.setOpening()

                self.checkStatus()
                self.curColor = 1 - self.curColor

            finally:
                log.debug("GameModel.run: releasing self.applyingMoveLock")
                self.applyingMoveLock.release()
Example #48
0
    def parseGame (self, matchlist, gameclass, in_progress=False, gameno=None):
        """ 
        Parses the header and movelist for an observed or stored game from its
        matchlist (an re.match object) into a gameclass (FICSGame or subclass
        of) object.
        
        in_progress - should be True for an observed game matchlist, and False
        for stored/adjourned games
        """
        #################   observed game movelist example:
        #        Movelist for game 64:
        #        
        #        Ajido (2281) vs. IMgooeyjim (2068) --- Thu Oct 14, 20:36 PDT 2010
        #        Rated standard match, initial time: 15 minutes, increment: 3 seconds.
        #        
        #        Move  Ajido                   IMgooeyjim         
        #        ----  ---------------------   ---------------------
        #          1.  d4      (0:00.000)      Nf6     (0:00.000)   
        #          2.  c4      (0:04.061)      g6      (0:00.969)   
        #          3.  Nc3     (0:13.280)      Bg7     (0:06.422)   
        #              {Still in progress} *
        #
        ##################   stored game example:
        #        BwanaSlei (1137) vs. mgatto (1336) --- Wed Nov  5, 20:56 PST 2008
        #        Rated blitz match, initial time: 5 minutes, increment: 0 seconds.
        #
        #        Move  BwanaSlei               mgatto
        #        ----  ---------------------   ---------------------
        #        1.  e4      (0:00.000)      c5      (0:00.000)
        #        2.  d4      (0:05.750)      cxd4    (0:03.020)
        #        ...
        #        23.  Qxf3    (1:05.500)
        #             {White lost connection; game adjourned} *
        #
        ################## stored wild/3 game with style12:
        #        kurushi (1626) vs. mgatto (1627) --- Thu Nov  4, 10:33 PDT 2010
        #        Rated wild/3 match, initial time: 3 minutes, increment: 0 seconds.
        #        
        #        <12> nqbrknrn pppppppp -------- -------- -------- -------- PPPPPPPP NQBRKNRN W -1 0 0 0 0 0 17 kurushi mgatto -4 3 0 39 39 169403 45227 1 none (0:00.000) none 0 1 0
        #        
        #        Move  kurushi                 mgatto             
        #        ----  ---------------------   ---------------------
        #          1.  Nb3     (0:00.000)      d5      (0:00.000)   
        #          2.  Nhg3    (0:00.386)      e5      (0:03.672)   
        #         ...
        #         28.  Rxd5    (0:00.412)   
        #              {Black lost connection; game adjourned} *
        #                
        ##################  stored game movelist following stored game(s):
        #        Stored games for mgatto:
        #        C Opponent       On Type          Str  M    ECO Date
        #        1: W BabyLurking     Y [ br  5   0] 29-13 W27  D37 Fri Nov  5, 04:41 PDT 2010
        #        2: W gbtami          N [ wr  5   0] 32-34 W14  --- Thu Oct 21, 00:14 PDT 2010
        #        
        #        mgatto (1233) vs. BabyLurking (1455) --- Fri Nov  5, 04:33 PDT 2010
        #        Rated blitz match, initial time: 5 minutes, increment: 0 seconds.
        #        
        #        Move  mgatto             BabyLurking
        #        ----  ----------------   ----------------
        #        1.  Nf3     (0:00)     d5      (0:00)
        #        2.  d4      (0:03)     Nf6     (0:00)
        #        3.  c4      (0:03)     e6      (0:00)
        #        {White lost connection; game adjourned} *
        #
        ################### stored game movelist following stored game(s):
        ###   Note: A wild stored game in this format won't be parseable into a board because
        ###   it doesn't come with a style12 that has the start position, so we warn and return
        ###################
        #        Stored games for mgatto:
        #        C Opponent       On Type          Str  M    ECO Date
        #        1: W gbtami          N [ wr  5   0] 32-34 W14  --- Thu Oct 21, 00:14 PDT 2010
        #        
        #        mgatto (1627) vs. gbtami (1881) --- Thu Oct 21, 00:10 PDT 2010
        #        Rated wild/fr match, initial time: 5 minutes, increment: 0 seconds.
        #        
        #        Move  mgatto             gbtami
        #        ----  ----------------   ----------------
        #        1.  d4      (0:00)     b6      (0:00)
        #        2.  b3      (0:06)     d5      (0:03)
        #        3.  c4      (0:08)     e6      (0:03)
        #        4.  e3      (0:04)     dxc4    (0:02)
        #        5.  bxc4    (0:02)     g6      (0:09)
        #        6.  Nd3     (0:12)     Bg7     (0:02)
        #        7.  Nc3     (0:10)     Ne7     (0:03)
        #        8.  Be2     (0:08)     c5      (0:05)
        #        9.  a4      (0:07)     cxd4    (0:38)
        #        10.  exd4    (0:06)     Bxd4    (0:03)
        #        11.  O-O     (0:10)     Qc6     (0:06)
        #        12.  Bf3     (0:16)     Qxc4    (0:04)
        #        13.  Bxa8    (0:03)     Rxa8    (0:14)
        #        {White lost connection; game adjourned} *
        #
        ##################   other reasons the game could be stored/adjourned:
        #        Game courtesyadjourned by (Black|White)
        #        Still in progress                    # This one must be a FICS bug
        #        Game adjourned by mutual agreement
        #        (White|Black) lost connection; game adjourned
        #        Game adjourned by ((server shutdown)|(adjudication)|(simul holder))
        
        index = 0
        if in_progress:
            gameno = int(matchlist[index].groups()[0])
            index += 2
        header1 = matchlist[index] if isinstance(matchlist[index], str) \
            else matchlist[index].group()

        matches = moveListHeader1.match(header1).groups()
        wname, wrating, bname, brating = matches[:4]
        if self.connection.FatICS:
            year, month, day, hour, minute, timezone =  matches[11:]
        else:
            weekday, month, day, hour, minute, timezone, year = matches[4:11]
            month = months.index(month)+1

        wrating = self.parseRating(wrating)
        brating = self.parseRating(brating)
        rated, game_type, minutes, increment = \
            moveListHeader2.match(matchlist[index+1]).groups()
        minutes = int(minutes)
        increment = int(increment)
        game_type = GAME_TYPES[game_type]

        reason = matchlist[-1].group().lower()
        if in_progress:
            result = None
            result_str = "*"
        elif "1-0" in reason:
            result = WHITEWON
            result_str = "1-0"
        elif "0-1" in reason:
            result = BLACKWON
            result_str = "0-1"
        elif "1/2-1/2" in reason:
            result = DRAW
            result_str = "1/2-1/2"
        else:
            result = ADJOURNED
            result_str = "*"
        result, reason = parse_reason(result, reason, wname=wname)

        index += 3
        if matchlist[index].startswith("<12>"):
            style12 = matchlist[index][5:]
            castleSigns = self.generateCastleSigns(style12, game_type)
            gameno, relation, curcol, ply, wname, bname, wms, bms, gain, lastmove, \
                fen = self.parseStyle12(style12, castleSigns)
            initialfen = fen
            movesstart = index + 4
        else:
            if game_type.rating_type == TYPE_WILD:
                # we need a style12 start position to correctly parse a wild/* board
                log.error("BoardManager.parseGame: no style12 for %s board." % game_type.fics_name)
                return None
            castleSigns = ("k", "q")
            initialfen = None
            movesstart = index + 2
        
        if in_progress:
            self.castleSigns[gameno] = castleSigns
        
        moves = {}
        times = {}
        wms = bms = minutes * 60 * 1000
        for line in matchlist[movesstart:-1]:
            if not moveListMoves.match(line):
                log.error("BoardManager.parseGame: unmatched line: \"%s\"" % \
                          repr(line))
                raise Exception("BoardManager.parseGame: unmatched line: \"%s\"" % \
                          repr(line))
            moveno, wmove, whour, wmin, wsec, wmsec, bmove, bhour, bmin, bsec, bmsec = \
                moveListMoves.match(line).groups()
            whour = 0 if whour is None else int(whour[0])
            bhour = 0 if bhour is None else int(bhour[0])
            ply = int(moveno)*2-2
            if wmove:
                moves[ply] = wmove
                wms -= (int(whour) * 60 * 60 * 1000) + (int(wmin) * 60 * 1000) + (int(wsec) * 1000)
                if wmsec is not None:
                    wms -= int(wmsec)
                else:
                    wmsec = 0
                if int(moveno) > 1 and increment > 0:
                    wms += (increment * 1000)
                times[ply] = "%01d:%02d:%02d.%03d" % (int(whour), int(wmin), int(wsec), int(wmsec))
            if bmove:
                moves[ply+1] = bmove
                bms -= (int(bhour) * 60 * 60 * 1000) + (int(bmin) * 60 * 1000) + (int(bsec) * 1000)
                if bmsec is not None:
                    bms -= int(bmsec)
                else:
                    bmsec = 0
                if int(moveno) > 1 and increment > 0:
                    bms += (increment * 1000)
                times[ply+1] = "%01d:%02d:%02d.%03d" % (int(bhour), int(bmin), int(bsec), int(bmsec))
        
        if in_progress and gameno in self.queuedStyle12s:
            # Apply queued board updates
            for style12 in self.queuedStyle12s[gameno]:
                gameno, relation, curcol, ply, wname, bname, wms, bms, gain, lastmove, fen = \
                        self.parseStyle12(style12, castleSigns)
                if lastmove == None: continue
                moves[ply-1] = lastmove
                # Updated the queuedMoves in case there has been a takeback
                for moveply in list(moves.keys()):
                    if moveply > ply-1:
                        del moves[moveply]
            del self.queuedStyle12s[gameno]
        
        pgnHead = [
            ("Event", "FICS %s %s game" % (rated.lower(), game_type.fics_name)),
            ("Site", "freechess.org"),
            ("White", wname),
            ("Black", bname),
            ("TimeControl", "%d+%d" % (minutes * 60, increment)),
            ("Result", result_str),
            ("WhiteClock", msToClockTimeTag(wms)),
            ("BlackClock", msToClockTimeTag(bms)),
        ]
        if wrating != 0:
            pgnHead += [ ("WhiteElo", wrating) ]
        if brating != 0:
            pgnHead += [ ("BlackElo", brating) ]
        if year and month and day and hour and minute:
            pgnHead += [
                ("Date", "%04d.%02d.%02d" % (int(year), int(month), int(day))),
                ("Time", "%02d:%02d:00" % (int(hour), int(minute))),
            ]
        if initialfen:
            pgnHead += [
                ("SetUp", "1"),
                ("FEN", initialfen)
            ]
        if game_type.variant_type == FISCHERRANDOMCHESS:
            pgnHead += [ ("Variant", "Fischerandom") ]
            # FR is the only variant used in this tag by the PGN generator @
            # ficsgames.org. They put all the other wild/* stuff only in the
            # "Event" header.
        elif game_type.variant_type == CRAZYHOUSECHESS:
            pgnHead += [ ("Variant", "Crazyhouse") ]
        elif game_type.variant_type in (WILDCASTLECHESS, WILDCASTLESHUFFLECHESS):
            pgnHead += [ ("Variant", "Wildcastle") ]
        elif game_type.variant_type == ATOMICCHESS:
            pgnHead += [ ("Variant", "Atomic") ]
        elif game_type.variant_type == LOSERSCHESS:
            pgnHead += [ ("Variant", "Losers") ]
        elif game_type.variant_type == SUICIDECHESS:
            pgnHead += [ ("Variant", "Suicide") ]
        pgn = "\n".join(['[%s "%s"]' % line for line in pgnHead]) + "\n"
        
        moves = sorted(moves.items())
        for ply, move in moves:
            if ply % 2 == 0:
                pgn += "%d. " % (ply//2+1)
            time = times[ply]
            pgn += "%s {[%%emt %s]} " % (move, time)
        pgn += "*\n"
        
        wplayer = self.connection.players.get(FICSPlayer(wname))
        bplayer = self.connection.players.get(FICSPlayer(bname))
        for player, rating in ((wplayer, wrating), (bplayer, brating)):
            if game_type.rating_type in player.ratings and \
                    player.ratings[game_type.rating_type].elo != rating:
                player.ratings[game_type.rating_type].elo = rating
            player.keep_after_logout = True
        game = gameclass(wplayer, bplayer, game_type=game_type, result=result,
            rated=(rated.lower() == "rated"), minutes=minutes, inc=increment,
            board=FICSBoard(wms, bms, pgn=pgn))
        if in_progress:
            game.gameno = gameno
        else:
            if gameno is not None:
                game.gameno = gameno
            game.reason = reason
        game = self.connection.games.get(game, emit=False)
        
        return game
Example #49
0
    def open_lounge(self, connection, helperconn, host):
        if self.first_run:
            self.init_layout()

        self.connection = connection
        self.helperconn = helperconn
        self.host = host

        self.finger_sent = False
        self.messages = []
        self.players = []
        self.game_cids = {}

        self.widgets = uistuff.GladeWidgets("fics_lounge.glade")
        self.widgets["fics_lounge"].hide()

        fics_home = self.widgets["fics_home"]
        self.widgets["fics_lounge_content_hbox"].remove(fics_home)

        self.archive_list = self.widgets["archiveListContent"]
        self.widgets["fics_panels_notebook"].remove(self.archive_list)

        self.games_list = self.widgets["gamesListContent"]
        self.widgets["fics_panels_notebook"].remove(self.games_list)

        self.news_list = self.widgets["news"]
        self.widgets["fics_home"].remove(self.news_list)

        self.players_list = self.widgets["playersListContent"]
        self.widgets["fics_panels_notebook"].remove(self.players_list)

        self.seek_graph = self.widgets["seekGraphContent"]
        self.widgets["fics_panels_notebook"].remove(self.seek_graph)

        self.seek_list = self.widgets["seekListContent"]
        self.widgets["fics_panels_notebook"].remove(self.seek_list)

        self.seek_challenge = SeekChallengeSection(self)

        def on_autoLogout(alm):
            self.emit("autoLogout")
            self.close()

        self.connection.alm.connect("logOut", on_autoLogout)
        self.connection.connect("disconnected", lambda connection: self.close())
        self.connection.connect("error", self.on_connection_error)
        if self.connection.isRegistred():
            numtimes = conf.get("numberOfTimesLoggedInAsRegisteredUser") + 1
            conf.set("numberOfTimesLoggedInAsRegisteredUser", numtimes)
        self.connection.em.connect("onCommandNotFound", lambda em, cmd: log.error(
            "Fics answered '%s': Command not found" % cmd))
        self.connection.bm.connect("playGameCreated", self.onPlayGameCreated)
        self.connection.bm.connect("obsGameCreated", self.onObserveGameCreated)
        self.connection.bm.connect("exGameCreated", self.onObserveGameCreated)
        self.connection.fm.connect("fingeringFinished", self.onFinger)
        # the rest of these relay server messages to the lounge infobar
        self.connection.bm.connect("tooManySeeks", self.tooManySeeks)
        self.connection.bm.connect("nonoWhileExamine", self.nonoWhileExamine)
        self.connection.bm.connect("matchDeclined", self.matchDeclined)
        self.connection.bm.connect("player_on_censor", self.player_on_censor)
        self.connection.bm.connect("player_on_noplay", self.player_on_noplay)
        self.connection.bm.connect("req_not_fit_formula", self.req_not_fit_formula)
        self.connection.glm.connect("seek-updated", self.on_seek_updated)
        self.connection.glm.connect("our-seeks-removed", self.our_seeks_removed)
        self.connection.cm.connect("arrivalNotification", self.onArrivalNotification)
        self.connection.cm.connect("departedNotification", self.onDepartedNotification)

        def get_top_games():
            if perspective_manager.current_perspective == self:
                self.connection.client.run_command("games *19")
            return True

        if self.connection.ICC:
            self.event_id = GLib.timeout_add_seconds(5, get_top_games)

        for user in self.connection.notify_users:
            user = self.connection.players.get(user)
            self.user_from_notify_list_is_present(user)

        self.userinfo = UserInfoSection(self.widgets, self.connection, self.host, self)
        if not self.first_run:
            self.notebooks["ficshome"].remove_page(-1)
        self.notebooks["ficshome"].append_page(fics_home)

        self.panels = [panel.Sidepanel().load(self.widgets, self.connection, self) for panel in self.sidePanels]

        for panel, instance in zip(self.sidePanels, self.panels):
            if not self.first_run:
                self.notebooks[panel_name(panel.__name__)].remove_page(-1)
            self.notebooks[panel_name(panel.__name__)].append_page(instance)
            instance.show()

        tool_buttons = [self.logoff_button, ]
        self.quick_seek_buttons = []
        if self.connection.ICC:
            self.quick_seek_buttons = [self.minute_1_button, self.minute_3_button, self.minute_5_button,
                                       self.minute_15_button, self.minute_25_button, self.chess960_button]
            tool_buttons += self.quick_seek_buttons
        perspective_manager.set_perspective_toolbuttons("fics", tool_buttons)

        if self.first_run:
            self.first_run = False

        # After all panel is set up we can push initial messages out
        self.connection.com.onConsoleMessage("", self.connection.ini_messages)
Example #50
0
            def coro():
                persp = perspective_manager.get_perspective("games")
                gmwidg = persp.cur_gmwidg()
                gamemodel = gmwidg.gamemodel

                old_check_value = conf.get("analyzer_check")
                conf.set("analyzer_check", True)
                if HINT not in gamemodel.spectators:
                    try:
                        yield from asyncio.wait_for(
                            gamemodel.start_analyzer(HINT), 5.0)
                    except asyncio.TimeoutError:
                        log.error(
                            "Got timeout error while starting hint analyzer")
                        return
                    except Exception:
                        log.error("Unknown error while starting hint analyzer")
                        return
                self.analyzer = gamemodel.spectators[HINT]
                gmwidg.menuitems["hint_mode"].active = True
                self.threat_PV = conf.get("ThreatPV")
                if self.threat_PV:
                    old_inv_check_value = conf.get("inv_analyzer_check")
                    conf.set("inv_analyzer_check", True)
                    if SPY not in gamemodel.spectators:
                        try:
                            yield from asyncio.wait_for(
                                gamemodel.start_analyzer(SPY), 5.0)
                        except asyncio.TimeoutError:
                            log.error(
                                "Got timeout error while starting spy analyzer"
                            )
                            return
                        except Exception:
                            log.error(
                                "Unknown error while starting spy analyzer")
                            return
                    inv_analyzer = gamemodel.spectators[SPY]
                    gmwidg.menuitems["spy_mode"].active = True

                title = _("Game analyzing in progress...")
                text = _("Do you want to abort it?")
                content = InfoBar.get_message_content(
                    title, text, Gtk.STOCK_DIALOG_QUESTION)

                def response_cb(infobar, response, message):
                    conf.set("analyzer_check", old_check_value)
                    if self.threat_PV:
                        conf.set("inv_analyzer_check", old_inv_check_value)
                    message.dismiss()
                    abort()

                message = InfoBarMessage(Gtk.MessageType.QUESTION, content,
                                         response_cb)
                message.add_button(
                    InfoBarMessageButton(_("Abort"), Gtk.ResponseType.CANCEL))
                gmwidg.replaceMessages(message)

                @asyncio.coroutine
                def analyse_moves():
                    should_black = conf.get("shouldBlack")
                    should_white = conf.get("shouldWhite")
                    from_current = conf.get("fromCurrent")
                    start_ply = gmwidg.board.view.shown if from_current else 0
                    move_time = int(conf.get("max_analysis_spin"))
                    threshold = int(conf.get("variation_threshold_spin"))
                    for board in gamemodel.boards[start_ply:]:
                        if self.stop_event.is_set():
                            break

                        gmwidg.board.view.setShownBoard(board)
                        self.analyzer.setBoard(board)
                        if self.threat_PV:
                            inv_analyzer.setBoard(board)
                        yield from asyncio.sleep(move_time + 0.1)

                        ply = board.ply - gamemodel.lowply
                        color = (ply - 1) % 2
                        if ply - 1 in gamemodel.scores and ply in gamemodel.scores and (
                            (color == BLACK and should_black) or
                            (color == WHITE and should_white)):
                            oldmoves, oldscore, olddepth = gamemodel.scores[ply
                                                                            -
                                                                            1]
                            oldscore = oldscore * -1 if color == BLACK else oldscore
                            score_str = prettyPrintScore(oldscore, olddepth)
                            moves, score, depth = gamemodel.scores[ply]
                            score = score * -1 if color == WHITE else score
                            diff = score - oldscore
                            if ((diff > threshold and color == BLACK) or
                                (diff < -1 * threshold and color == WHITE)
                                ) and (gamemodel.moves[ply - 1] != parseAny(
                                    gamemodel.boards[ply - 1], oldmoves[0])):
                                if self.threat_PV:
                                    try:
                                        if ply - 1 in gamemodel.spy_scores:
                                            oldmoves0, oldscore0, olddepth0 = gamemodel.spy_scores[
                                                ply - 1]
                                            score_str0 = prettyPrintScore(
                                                oldscore0, olddepth0)
                                            pv0 = listToMoves(
                                                gamemodel.boards[ply - 1],
                                                ["--"] + oldmoves0,
                                                validate=True)
                                            if len(pv0) > 2:
                                                gamemodel.add_variation(
                                                    gamemodel.boards[ply - 1],
                                                    pv0,
                                                    comment="Threatening",
                                                    score=score_str0,
                                                    emit=False)
                                    except ParsingError as e:
                                        # ParsingErrors may happen when parsing "old" lines from
                                        # analyzing engines, which haven't yet noticed their new tasks
                                        log.debug(
                                            "__parseLine: Ignored (%s) from analyzer: ParsingError%s"
                                            % (' '.join(oldmoves), e))
                                try:
                                    pv = listToMoves(gamemodel.boards[ply - 1],
                                                     oldmoves,
                                                     validate=True)
                                    gamemodel.add_variation(
                                        gamemodel.boards[ply - 1],
                                        pv,
                                        comment="Better is",
                                        score=score_str,
                                        emit=False)
                                except ParsingError as e:
                                    # ParsingErrors may happen when parsing "old" lines from
                                    # analyzing engines, which haven't yet noticed their new tasks
                                    log.debug(
                                        "__parseLine: Ignored (%s) from analyzer: ParsingError%s"
                                        % (' '.join(oldmoves), e))

                    self.widgets["analyze_game"].hide()
                    self.widgets["analyze_ok_button"].set_sensitive(True)
                    conf.set("analyzer_check", old_check_value)
                    if self.threat_PV:
                        conf.set("inv_analyzer_check", old_inv_check_value)
                    message.dismiss()

                    gamemodel.emit("analysis_finished")

                create_task(analyse_moves())
                hide_window(None)

                return True
Example #51
0
def _ensureReadForGameWidgets():
    if len(key2gmwidg) > 0:
        return
    global notebooks
    perspective_widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
    perspective_manager.set_perspective_widget("games", perspective_widget)
    perspective = perspective_manager.get_perspective("games")
    notebooks = get_clean_notebooks(perspective.widget)

    # Initing headbook

    align = createAlignment(4, 4, 0, 4)
    align.set_property("yscale", 0)

    headbook = Gtk.Notebook()
    headbook.set_name("headbook")
    headbook.set_scrollable(True)
    align.add(headbook)
    perspective_widget.pack_start(align, False, True, 0)
    show_tabs(not conf.get("hideTabs", False))

    # Initing center

    centerVBox = Gtk.VBox()

    # The dock

    global dock, dockAlign
    dock = PyDockTop("main", perspective)
    dockAlign = createAlignment(4, 4, 0, 4)
    dockAlign.add(dock)
    centerVBox.pack_start(dockAlign, True, True, 0)
    dockAlign.show()
    dock.show()

    for panel in sidePanels:
        box = dock_panel_tab(panel.__title__, panel.__desc__, panel.__icon__)
        docks[panel.__name__] = (box, notebooks[panel.__name__])

    if os.path.isfile(dockLocation):
        try:
            dock.loadFromXML(dockLocation, docks)
        except Exception as e:
            stringio = StringIO()
            traceback.print_exc(file=stringio)
            error = stringio.getvalue()
            log.error("Dock loading error: %s\n%s" % (e, error))
            msg_dia = Gtk.MessageDialog(widgets["main_window"],
                                        type=Gtk.MessageType.ERROR,
                                        buttons=Gtk.ButtonsType.CLOSE)
            msg_dia.set_markup(
                _("<b><big>PyChess was unable to load your panel settings</big></b>"
                  ))
            msg_dia.format_secondary_text(
                _("Your panel settings have been reset. If this problem repeats, \
                you should report it to the developers"))
            msg_dia.run()
            msg_dia.hide()
            os.remove(dockLocation)
            for title, panel in docks.values():
                title.unparent()
                panel.unparent()

    if not os.path.isfile(dockLocation):
        leaf = dock.dock(docks["board"][1], CENTER,
                         Gtk.Label(label=docks["board"][0]), "board")
        docks["board"][1].show_all()
        leaf.setDockable(False)

        # S
        epanel = leaf.dock(docks["bookPanel"][1], SOUTH, docks["bookPanel"][0],
                           "bookPanel")
        epanel.default_item_height = 45
        epanel = epanel.dock(docks["engineOutputPanel"][1], CENTER,
                             docks["engineOutputPanel"][0],
                             "engineOutputPanel")

        # NE
        leaf = leaf.dock(docks["annotationPanel"][1], EAST,
                         docks["annotationPanel"][0], "annotationPanel")
        leaf = leaf.dock(docks["historyPanel"][1], CENTER,
                         docks["historyPanel"][0], "historyPanel")
        leaf = leaf.dock(docks["scorePanel"][1], CENTER,
                         docks["scorePanel"][0], "scorePanel")

        # SE
        leaf = leaf.dock(docks["chatPanel"][1], SOUTH, docks["chatPanel"][0],
                         "chatPanel")
        leaf = leaf.dock(docks["commentPanel"][1], CENTER,
                         docks["commentPanel"][0], "commentPanel")

    def unrealize(dock, notebooks):
        # unhide the panel before saving so its configuration is saved correctly
        notebooks["board"].get_parent().get_parent().zoomDown()
        dock.saveToXML(dockLocation)
        dock._del()

    dock.connect("unrealize", unrealize, notebooks)

    hbox = Gtk.HBox()

    # Buttons
    notebooks["buttons"].set_border_width(4)
    hbox.pack_start(notebooks["buttons"], False, True, 0)

    # The message area
    # TODO: If you try to fix this first read issue #958 and 1018
    align = createAlignment(0, 0, 0, 0)
    # sw = Gtk.ScrolledWindow()
    # port = Gtk.Viewport()
    # port.add(notebooks["messageArea"])
    # sw.add(port)
    # align.add(sw)
    align.add(notebooks["messageArea"])
    hbox.pack_start(align, True, True, 0)

    def ma_switch_page(notebook, gpointer, page_num):
        notebook.props.visible = notebook.get_nth_page(page_num).\
            get_child().props.visible

    notebooks["messageArea"].connect("switch-page", ma_switch_page)
    centerVBox.pack_start(hbox, False, True, 0)

    perspective_widget.pack_start(centerVBox, True, True, 0)
    centerVBox.show_all()
    perspective_widget.show_all()

    # Connecting headbook to other notebooks

    def hb_switch_page(notebook, gpointer, page_num):
        for notebook in notebooks.values():
            notebook.set_current_page(page_num)

        gmwidg = key2gmwidg[getheadbook().get_nth_page(page_num)]
        if isinstance(gmwidg.gamemodel, ICGameModel):
            primary = "primary " + str(gmwidg.gamemodel.ficsgame.gameno)
            gmwidg.gamemodel.connection.client.run_command(primary)

    headbook.connect("switch-page", hb_switch_page)

    if hasattr(headbook, "set_tab_reorderable"):

        def page_reordered(widget, child, new_num, headbook):
            old_num = notebooks["board"].page_num(key2gmwidg[child].boardvbox)
            if old_num == -1:
                log.error('Games and labels are out of sync!')
            else:
                for notebook in notebooks.values():
                    notebook.reorder_child(notebook.get_nth_page(old_num),
                                           new_num)

        headbook.connect("page-reordered", page_reordered, headbook)
Example #52
0
        def coro():
            log.debug("GameModel.run: Starting. self=%s" % self)
            # Avoid racecondition when self.start is called while we are in
            # self.end
            if self.status != WAITING_TO_START:
                return

            if not self.isLocalGame():
                self.timemodel.handle_gain = False

            self.status = RUNNING

            for player in self.players + list(self.spectators.values()):
                event = asyncio.Event()
                is_dead = set()
                player.start(event, is_dead)

                yield from event.wait()

                if is_dead:
                    if player in self.players[WHITE]:
                        self.kill(WHITE_ENGINE_DIED)
                        break
                    elif player in self.players[BLACK]:
                        self.kill(BLACK_ENGINE_DIED)
                        break

            log.debug("GameModel.run: emitting 'game_started' self=%s" % self)
            self.emit("game_started")

            # Let GameModel end() itself on games started with loadAndStart()
            if not self.lesson_game:
                self.checkStatus()

            if self.isEngine2EngineGame() and self.timed:
                self.timemodel.start()
                self.timemodel.started = True

            self.curColor = self.boards[-1].color

            book_depth_max = conf.get("book_depth_max")

            while self.status in (PAUSED, RUNNING, DRAW, WHITEWON, BLACKWON):
                curPlayer = self.players[self.curColor]

                if self.timed:
                    log.debug(
                        "GameModel.run: id=%s, players=%s, self.ply=%s: updating %s's time"
                        % (id(self), str(self.players), str(
                            self.ply), str(curPlayer)))
                    curPlayer.updateTime(
                        self.timemodel.getPlayerTime(self.curColor),
                        self.timemodel.getPlayerTime(1 - self.curColor))
                try:
                    log.debug(
                        "GameModel.run: id=%s, players=%s, self.ply=%s: calling %s.makeMove()"
                        % (id(self), str(
                            self.players), self.ply, str(curPlayer)))

                    move = None
                    # if the current player is a bot
                    if curPlayer.__type__ == ARTIFICIAL and book_depth_max > 0 and self.ply <= book_depth_max:
                        move = self.get_book_move()
                        log.debug(
                            "GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from book"
                            % (id(self), str(self.players), self.ply, move))
                        if move is not None:
                            curPlayer.set_board(self.boards[-1].move(move))
                    # if the current player is not a bot
                    if move is None:

                        if self.ply > self.lowply:
                            move = yield from curPlayer.makeMove(
                                self.boards[-1], self.moves[-1],
                                self.boards[-2])
                        else:
                            move = yield from curPlayer.makeMove(
                                self.boards[-1], None, None)
                        log.debug(
                            "GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from %s"
                            % (id(self), str(
                                self.players), self.ply, move, str(curPlayer)))
                except PlayerIsDead as e:
                    if self.status in (WAITING_TO_START, PAUSED, RUNNING):
                        stringio = StringIO()
                        traceback.print_exc(file=stringio)
                        error = stringio.getvalue()
                        log.error(
                            "GameModel.run: A Player died: player=%s error=%s\n%s"
                            % (curPlayer, error, e))
                        if self.curColor == WHITE:
                            self.kill(WHITE_ENGINE_DIED)
                        else:
                            self.kill(BLACK_ENGINE_DIED)
                    break
                except InvalidMove as e:
                    stringio = StringIO()
                    traceback.print_exc(file=stringio)
                    error = stringio.getvalue()
                    log.error(
                        "GameModel.run: InvalidMove by player=%s error=%s\n%s"
                        % (curPlayer, error, e))
                    if self.curColor == WHITE:
                        self.end(BLACKWON, WON_ADJUDICATION)
                    else:
                        self.end(WHITEWON, WON_ADJUDICATION)
                    break
                except PassInterrupt:
                    log.debug(
                        "GameModel.run: id=%s, players=%s, self.ply=%s: PassInterrupt"
                        % (id(self), str(self.players), self.ply))
                    continue
                except TurnInterrupt:
                    log.debug(
                        "GameModel.run: id=%s, players=%s, self.ply=%s: TurnInterrupt"
                        % (id(self), str(self.players), self.ply))
                    self.curColor = self.boards[-1].color
                    continue
                except GameEnded:
                    log.debug("GameModel.run: got GameEnded exception")
                    break

                assert isinstance(move, Move), "%s" % repr(move)
                log.debug(
                    "GameModel.run: id=%s, players=%s, self.ply=%s: applying move=%s"
                    % (id(self), str(self.players), self.ply, str(move)))
                self.needsSave = True
                newBoard = self.boards[-1].move(move)
                newBoard.board.prev = self.boards[-1].board

                # newBoard.printPieces()
                # Variation on next move can exist from the hint panel...
                if self.boards[-1].board.next is not None:
                    newBoard.board.children = self.boards[
                        -1].board.next.children

                self.boards = self.variations[0]
                self.boards[-1].board.next = newBoard.board
                self.boards.append(newBoard)
                self.moves.append(move)

                if self.timed:
                    self.timemodel.tap()

                if not self.terminated:
                    self.emit("game_changed", self.ply)

                for spectator in self.spectators.values():
                    if spectator.board == self.boards[-2]:
                        spectator.putMove(self.boards[-1], self.moves[-1],
                                          self.boards[-2])

                if self.puzzle_game and len(self.moves) % 2 == 1:
                    status, reason = getStatus(self.boards[-1])
                    self.failed_playing_best = self.check_failed_playing_best(
                        status)
                    if self.failed_playing_best:
                        # print("failed_playing_best() == True -> yield from asyncio.sleep(1.5) ")
                        # It may happen that analysis had no time to fill hints with best moves
                        # so we give him another chance with some additional time to think on it
                        self.spectators[HINT].setBoard(self.boards[-2])
                        # TODO: wait for an event (analyzer PV reaching 18 ply)
                        # instead of hard coded sleep time
                        yield from asyncio.sleep(1.5)
                        self.failed_playing_best = self.check_failed_playing_best(
                            status)

                self.checkStatus()

                self.setOpening()

                self.curColor = 1 - self.curColor

            self.checkStatus()
Example #53
0
    def run(self):
        log.debug("GameModel.run: Starting. self=%s" % self)
        # Avoid racecondition when self.start is called while we are in
        # self.end
        if self.status != WAITING_TO_START:
            return

        if not self.isLocalGame():
            self.timemodel.handle_gain = False

        self.status = RUNNING

        for player in self.players + list(self.spectators.values()):
            player.start()

        log.debug("GameModel.run: emitting 'game_started' self=%s" % self)
        self.emit("game_started")

        # Let GameModel end() itself on games started with loadAndStart()
        self.checkStatus()

        self.curColor = self.boards[-1].color

        while self.status in (PAUSED, RUNNING, DRAW, WHITEWON, BLACKWON):
            curPlayer = self.players[self.curColor]

            if self.timed:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: updating %s's time" % (
                    id(self), str(self.players), str(self.ply), str(curPlayer)))
                curPlayer.updateTime(
                    self.timemodel.getPlayerTime(self.curColor),
                    self.timemodel.getPlayerTime(1 - self.curColor))

            try:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: calling %s.makeMove()" % (
                    id(self), str(self.players), self.ply, str(curPlayer)))
                if self.ply > self.lowply:
                    move = curPlayer.makeMove(self.boards[-1], self.moves[-1],
                                              self.boards[-2])
                else:
                    move = curPlayer.makeMove(self.boards[-1], None, None)
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from %s" % (
                    id(self), str(self.players), self.ply, move, str(curPlayer)))
            except PlayerIsDead as e:
                if self.status in (WAITING_TO_START, PAUSED, RUNNING):
                    stringio = StringIO()
                    traceback.print_exc(file=stringio)
                    error = stringio.getvalue()
                    log.error(
                        "GameModel.run: A Player died: player=%s error=%s\n%s"
                        % (curPlayer, error, e))
                    if self.curColor == WHITE:
                        self.kill(WHITE_ENGINE_DIED)
                    else:
                        self.kill(BLACK_ENGINE_DIED)
                break
            except InvalidMove as e:
                if self.curColor == WHITE:
                    self.end(BLACKWON, WON_ADJUDICATION)
                else:
                    self.end(WHITEWON, WON_ADJUDICATION)
                break
            except TurnInterrupt:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: TurnInterrupt" % (
                    id(self), str(self.players), self.ply))
                self.curColor = self.boards[-1].color
                continue

            log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: acquiring self.applyingMoveLock" % (
                id(self), str(self.players), self.ply))
            assert isinstance(move, Move), "%s" % repr(move)

            self.applyingMoveLock.acquire()
            try:
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: applying move=%s" % (
                    id(self), str(self.players), self.ply, str(move)))
                self.needsSave = True
                newBoard = self.boards[-1].move(move)
                newBoard.board.prev = self.boards[-1].board

                # Variation on next move can exist from the hint panel...
                if self.boards[-1].board.next is not None:
                    newBoard.board.children = self.boards[
                        -1].board.next.children

                self.boards = self.variations[0]
                self.boards[-1].board.next = newBoard.board
                self.boards.append(newBoard)
                self.moves.append(move)

                if self.timed:
                    self.timemodel.tap()

                if not self.terminated:
                    self.emit("game_changed", self.ply)

                for spectator in self.spectators.values():
                    if spectator.board == self.boards[-2]:
                        spectator.putMove(self.boards[-1], self.moves[-1],
                                          self.boards[-2])

                self.setOpening()

                self.checkStatus()
                self.curColor = 1 - self.curColor

            finally:
                log.debug("GameModel.run: releasing self.applyingMoveLock")
                self.applyingMoveLock.release()
Example #54
0
    def parseGame(self, matchlist, gameclass, in_progress=False, gameno=None):
        """
        Parses the header and movelist for an observed or stored game from its
        matchlist (an re.match object) into a gameclass (FICSGame or subclass
        of) object.

        in_progress - should be True for an observed game matchlist, and False
        for stored/adjourned games
        """
        # ################   observed game movelist example:
        #        Movelist for game 64:
        #
        #        Ajido (2281) vs. IMgooeyjim (2068) --- Thu Oct 14, 20:36 PDT 2010
        #        Rated standard match, initial time: 15 minutes, increment: 3 seconds.
        #
        #        Move  Ajido                   IMgooeyjim
        #        ----  ---------------------   ---------------------
        #          1.  d4      (0:00.000)      Nf6     (0:00.000)
        #          2.  c4      (0:04.061)      g6      (0:00.969)
        #          3.  Nc3     (0:13.280)      Bg7     (0:06.422)
        #              {Still in progress} *
        #
        # #################   stored game example:
        #        BwanaSlei (1137) vs. mgatto (1336) --- Wed Nov  5, 20:56 PST 2008
        #        Rated blitz match, initial time: 5 minutes, increment: 0 seconds.
        #
        #        Move  BwanaSlei               mgatto
        #        ----  ---------------------   ---------------------
        #        1.  e4      (0:00.000)      c5      (0:00.000)
        #        2.  d4      (0:05.750)      cxd4    (0:03.020)
        #        ...
        #        23.  Qxf3    (1:05.500)
        #             {White lost connection; game adjourned} *
        #
        # ################# stored wild/3 game with style12:
        #        kurushi (1626) vs. mgatto (1627) --- Thu Nov  4, 10:33 PDT 2010
        #        Rated wild/3 match, initial time: 3 minutes, increment: 0 seconds.
        #
        #        <12> nqbrknrn pppppppp -------- -------- -------- -------- PPPPPPPP NQBRKNRN W -1 0 0 0 0 0 17 kurushi mgatto -4 3 0 39 39 169403 45227 1 none (0:00.000) none 0 1 0
        #
        #        Move  kurushi                 mgatto
        #        ----  ---------------------   ---------------------
        #          1.  Nb3     (0:00.000)      d5      (0:00.000)
        #          2.  Nhg3    (0:00.386)      e5      (0:03.672)
        #         ...
        #         28.  Rxd5    (0:00.412)
        #              {Black lost connection; game adjourned} *
        #
        # #################  stored game movelist following stored game(s):
        #        Stored games for mgatto:
        #        C Opponent       On Type          Str  M    ECO Date
        #        1: W BabyLurking     Y [ br  5   0] 29-13 W27  D37 Fri Nov  5, 04:41 PDT 2010
        #        2: W gbtami          N [ wr  5   0] 32-34 W14  --- Thu Oct 21, 00:14 PDT 2010
        #
        #        mgatto (1233) vs. BabyLurking (1455) --- Fri Nov  5, 04:33 PDT 2010
        #        Rated blitz match, initial time: 5 minutes, increment: 0 seconds.
        #
        #        Move  mgatto             BabyLurking
        #        ----  ----------------   ----------------
        #        1.  Nf3     (0:00)     d5      (0:00)
        #        2.  d4      (0:03)     Nf6     (0:00)
        #        3.  c4      (0:03)     e6      (0:00)
        #        {White lost connection; game adjourned} *
        #
        # ################## stored game movelist following stored game(s):
        # ##   Note: A wild stored game in this format won't be parseable into a board because
        # ##   it doesn't come with a style12 that has the start position, so we warn and return
        # ##################
        #        Stored games for mgatto:
        #        C Opponent       On Type          Str  M    ECO Date
        #        1: W gbtami          N [ wr  5   0] 32-34 W14  --- Thu Oct 21, 00:14 PDT 2010
        #
        #        mgatto (1627) vs. gbtami (1881) --- Thu Oct 21, 00:10 PDT 2010
        #        Rated wild/fr match, initial time: 5 minutes, increment: 0 seconds.
        #
        #        Move  mgatto             gbtami
        #        ----  ----------------   ----------------
        #        1.  d4      (0:00)     b6      (0:00)
        #        2.  b3      (0:06)     d5      (0:03)
        #        3.  c4      (0:08)     e6      (0:03)
        #        4.  e3      (0:04)     dxc4    (0:02)
        #        5.  bxc4    (0:02)     g6      (0:09)
        #        6.  Nd3     (0:12)     Bg7     (0:02)
        #        7.  Nc3     (0:10)     Ne7     (0:03)
        #        8.  Be2     (0:08)     c5      (0:05)
        #        9.  a4      (0:07)     cxd4    (0:38)
        #        10.  exd4    (0:06)     Bxd4    (0:03)
        #        11.  O-O     (0:10)     Qc6     (0:06)
        #        12.  Bf3     (0:16)     Qxc4    (0:04)
        #        13.  Bxa8    (0:03)     Rxa8    (0:14)
        #        {White lost connection; game adjourned} *
        #
        # #################   other reasons the game could be stored/adjourned:
        #        Game courtesyadjourned by (Black|White)
        #        Still in progress                    # This one must be a FICS bug
        #        Game adjourned by mutual agreement
        #        (White|Black) lost connection; game adjourned
        #        Game adjourned by ((server shutdown)|(adjudication)|(simul holder))

        index = 0
        if in_progress:
            gameno = int(matchlist[index].groups()[0])
            index += 2
        header1 = matchlist[index] if isinstance(matchlist[index], str) \
            else matchlist[index].group()

        matches = moveListHeader1.match(header1).groups()
        wname, wrating, bname, brating = matches[:4]
        if self.connection.FatICS:
            year, month, day, hour, minute, timezone = matches[11:]
        else:
            weekday, month, day, hour, minute, timezone, year = matches[4:11]
            month = months.index(month) + 1

        wrating = parseRating(wrating)
        brating = parseRating(brating)
        rated, game_type, minutes, increment = \
            moveListHeader2.match(matchlist[index + 1]).groups()
        minutes = int(minutes)
        increment = int(increment)
        game_type = GAME_TYPES[game_type]

        reason = matchlist[-1].group().lower()
        if in_progress:
            result = None
            result_str = "*"
        elif "1-0" in reason:
            result = WHITEWON
            result_str = "1-0"
        elif "0-1" in reason:
            result = BLACKWON
            result_str = "0-1"
        elif "1/2-1/2" in reason:
            result = DRAW
            result_str = "1/2-1/2"
        else:
            result = ADJOURNED
            result_str = "*"
        result, reason = parse_reason(result, reason, wname=wname)

        index += 3
        if matchlist[index].startswith("<12>"):
            style12 = matchlist[index][5:]
            castleSigns = self.generateCastleSigns(style12, game_type)
            gameno, relation, curcol, ply, wname, bname, wms, bms, gain, lastmove, \
                fen = self.parseStyle12(style12, castleSigns)
            initialfen = fen
            movesstart = index + 4
        else:
            if game_type.rating_type == TYPE_WILD:
                # we need a style12 start position to correctly parse a wild/* board
                log.error("BoardManager.parseGame: no style12 for %s board." %
                          game_type.fics_name)
                return None
            castleSigns = ("k", "q")
            initialfen = None
            movesstart = index + 2

        if in_progress:
            self.castleSigns[gameno] = castleSigns

        moves = {}
        times = {}
        wms = bms = minutes * 60 * 1000

        for line in matchlist[movesstart:-1]:
            if not moveListMoves.match(line):
                log.error("BoardManager.parseGame: unmatched line: \"%s\"" %
                          repr(line))
                raise Exception(
                    "BoardManager.parseGame: unmatched line: \"%s\"" %
                    repr(line))
            moveno, wmove, whour, wmin, wsec, wmsec, bmove, bhour, bmin, bsec, bmsec = \
                moveListMoves.match(line).groups()
            whour = 0 if whour is None else int(whour[0])
            bhour = 0 if bhour is None else int(bhour[0])
            ply = int(moveno) * 2 - 2
            if wmove:
                moves[ply] = wmove
                wms -= (int(whour) * 60 * 60 *
                        1000) + (int(wmin) * 60 * 1000) + (int(wsec) * 1000)
                if wmsec is not None:
                    wms -= int(wmsec)
                else:
                    wmsec = 0
                if increment > 0:
                    wms += (increment * 1000)
                times[ply] = "%01d:%02d:%02d.%03d" % (int(whour), int(wmin),
                                                      int(wsec), int(wmsec))
            if bmove:
                moves[ply + 1] = bmove
                bms -= (int(bhour) * 60 * 60 *
                        1000) + (int(bmin) * 60 * 1000) + (int(bsec) * 1000)
                if bmsec is not None:
                    bms -= int(bmsec)
                else:
                    bmsec = 0
                if increment > 0:
                    bms += (increment * 1000)
                times[ply +
                      1] = "%01d:%02d:%02d.%03d" % (int(bhour), int(bmin),
                                                    int(bsec), int(bmsec))

        if in_progress and gameno in self.queuedStyle12s:
            # Apply queued board updates
            for style12 in self.queuedStyle12s[gameno]:
                gameno, relation, curcol, ply, wname, bname, wms, bms, gain, lastmove, fen = \
                    self.parseStyle12(style12, castleSigns)
                if lastmove is None:
                    continue
                moves[ply - 1] = lastmove
                # Updated the queuedMoves in case there has been a takeback
                for moveply in list(moves.keys()):
                    if moveply > ply - 1:
                        del moves[moveply]
            del self.queuedStyle12s[gameno]

        pgnHead = [
            ("Event",
             "FICS %s %s game" % (rated.lower(), game_type.fics_name)),
            ("Site", "freechess.org"),
            ("White", wname),
            ("Black", bname),
            ("TimeControl", "%d+%d" % (minutes * 60, increment)),
            ("Result", result_str),
            ("WhiteClock", msToClockTimeTag(wms)),
            ("BlackClock", msToClockTimeTag(bms)),
        ]
        if wrating != 0:
            pgnHead += [("WhiteElo", wrating)]
        if brating != 0:
            pgnHead += [("BlackElo", brating)]
        if year and month and day and hour and minute:
            pgnHead += [
                ("Date", "%04d.%02d.%02d" % (int(year), int(month), int(day))),
                ("Time", "%02d:%02d:00" % (int(hour), int(minute))),
            ]
        if initialfen:
            pgnHead += [("SetUp", "1"), ("FEN", initialfen)]
        if game_type.variant_type == FISCHERRANDOMCHESS:
            pgnHead += [("Variant", "Fischerandom")]
            # FR is the only variant used in this tag by the PGN generator @
            # ficsgames.org. They put all the other wild/* stuff only in the
            # "Event" header.
        elif game_type.variant_type == CRAZYHOUSECHESS:
            pgnHead += [("Variant", "Crazyhouse")]
        elif game_type.variant_type in (WILDCASTLECHESS,
                                        WILDCASTLESHUFFLECHESS):
            pgnHead += [("Variant", "Wildcastle")]
        elif game_type.variant_type == ATOMICCHESS:
            pgnHead += [("Variant", "Atomic")]
        elif game_type.variant_type == LOSERSCHESS:
            pgnHead += [("Variant", "Losers")]
        elif game_type.variant_type == SUICIDECHESS:
            pgnHead += [("Variant", "Suicide")]
        pgn = "\n".join(['[%s "%s"]' % line for line in pgnHead]) + "\n"

        moves = sorted(moves.items())
        for ply, move in moves:
            if ply % 2 == 0:
                pgn += "%d. " % (ply // 2 + 1)
            time = times[ply]
            pgn += "%s {[%%emt %s]} " % (move, time)
        pgn += "*\n"

        wplayer = self.connection.players.get(wname)
        bplayer = self.connection.players.get(bname)
        for player, rating in ((wplayer, wrating), (bplayer, brating)):
            if game_type.rating_type in player.ratings and \
                    player.ratings[game_type.rating_type] != rating:
                player.ratings[game_type.rating_type] = rating
                player.emit("ratings_changed", game_type.rating_type, player)
        game = gameclass(wplayer,
                         bplayer,
                         game_type=game_type,
                         result=result,
                         rated=(rated.lower() == "rated"),
                         minutes=minutes,
                         inc=increment,
                         board=FICSBoard(wms, bms, pgn=pgn))

        if in_progress:
            game.gameno = gameno
        else:
            if gameno is not None:
                game.gameno = gameno
            game.reason = reason
        game = self.connection.games.get(game, emit=False)

        return game
Example #55
0
        def coro():
            log.debug("GameModel.run: Starting. self=%s" % self)
            # Avoid racecondition when self.start is called while we are in
            # self.end
            if self.status != WAITING_TO_START:
                return

            if not self.isLocalGame():
                self.timemodel.handle_gain = False

            self.status = RUNNING

            for player in self.players + list(self.spectators.values()):
                event = asyncio.Event()
                is_dead = set()
                player.start(event, is_dead)

                yield from event.wait()

                if is_dead:
                    if player in self.players[WHITE]:
                        self.kill(WHITE_ENGINE_DIED)
                        break
                    elif player in self.players[BLACK]:
                        self.kill(BLACK_ENGINE_DIED)
                        break

            log.debug("GameModel.run: emitting 'game_started' self=%s" % self)
            self.emit("game_started")

            # Let GameModel end() itself on games started with loadAndStart()
            if not self.lesson_game:
                self.checkStatus()

            if self.isEngine2EngineGame() and self.timed:
                self.timemodel.start()
                self.timemodel.started = True

            self.curColor = self.boards[-1].color

            while self.status in (PAUSED, RUNNING, DRAW, WHITEWON, BLACKWON):
                curPlayer = self.players[self.curColor]
                if self.timed:
                    log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: updating %s's time" % (
                        id(self), str(self.players), str(self.ply), str(curPlayer)))
                    curPlayer.updateTime(
                        self.timemodel.getPlayerTime(self.curColor),
                        self.timemodel.getPlayerTime(1 - self.curColor))
                try:
                    log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: calling %s.makeMove()" % (
                        id(self), str(self.players), self.ply, str(curPlayer)))
                    if self.ply > self.lowply:
                        move = yield from curPlayer.makeMove(self.boards[-1], self.moves[-1], self.boards[-2])
                    else:
                        move = yield from curPlayer.makeMove(self.boards[-1], None, None)
                    log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: got move=%s from %s" % (
                        id(self), str(self.players), self.ply, move, str(curPlayer)))
                except PlayerIsDead as e:
                    if self.status in (WAITING_TO_START, PAUSED, RUNNING):
                        stringio = StringIO()
                        traceback.print_exc(file=stringio)
                        error = stringio.getvalue()
                        log.error(
                            "GameModel.run: A Player died: player=%s error=%s\n%s"
                            % (curPlayer, error, e))
                        if self.curColor == WHITE:
                            self.kill(WHITE_ENGINE_DIED)
                        else:
                            self.kill(BLACK_ENGINE_DIED)
                    break
                except InvalidMove as e:
                    stringio = StringIO()
                    traceback.print_exc(file=stringio)
                    error = stringio.getvalue()
                    log.error(
                        "GameModel.run: InvalidMove by player=%s error=%s\n%s"
                        % (curPlayer, error, e))
                    if self.curColor == WHITE:
                        self.end(BLACKWON, WON_ADJUDICATION)
                    else:
                        self.end(WHITEWON, WON_ADJUDICATION)
                    break
                except PassInterrupt:
                    log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: PassInterrupt" % (
                        id(self), str(self.players), self.ply))
                    continue
                except TurnInterrupt:
                    log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: TurnInterrupt" % (
                        id(self), str(self.players), self.ply))
                    self.curColor = self.boards[-1].color
                    continue
                except GameEnded:
                    log.debug("GameModel.run: got GameEnded exception")
                    break

                assert isinstance(move, Move), "%s" % repr(move)
                log.debug("GameModel.run: id=%s, players=%s, self.ply=%s: applying move=%s" % (
                    id(self), str(self.players), self.ply, str(move)))
                self.needsSave = True
                newBoard = self.boards[-1].move(move)
                newBoard.board.prev = self.boards[-1].board

                # Variation on next move can exist from the hint panel...
                if self.boards[-1].board.next is not None:
                    newBoard.board.children = self.boards[
                        -1].board.next.children

                self.boards = self.variations[0]
                self.boards[-1].board.next = newBoard.board
                self.boards.append(newBoard)
                self.moves.append(move)

                if self.timed:
                    self.timemodel.tap()

                if not self.terminated:
                    self.emit("game_changed", self.ply)

                for spectator in self.spectators.values():
                    if spectator.board == self.boards[-2]:
                        spectator.putMove(self.boards[-1], self.moves[-1],
                                          self.boards[-2])

                if self.puzzle_game and len(self.moves) % 2 == 1:
                    status, reason = getStatus(self.boards[-1])
                    self.failed_playing_best = self.check_failed_playing_best(status)
                    if self.failed_playing_best:
                        # print("failed_playing_best() == True -> yield from asyncio.sleep(1.5) ")
                        # It may happen that analysis had no time to fill hints with best moves
                        # so we give him another chance with some additional time to think on it
                        self.spectators[HINT].setBoard(self.boards[-2])
                        # TODO: wait for an event (analyzer PV reaching 18 ply)
                        # instead of hard coded sleep time
                        yield from asyncio.sleep(1.5)
                        self.failed_playing_best = self.check_failed_playing_best(status)

                self.checkStatus()

                self.setOpening()

                self.curColor = 1 - self.curColor

            self.checkStatus()
Example #56
0
def _ensureReadForGameWidgets():
    mainvbox = widgets["mainvbox"]
    if len(mainvbox.get_children()) == 3:
        return

    global background
    background = widgets["mainvbox"].get_children()[1]
    mainvbox.remove(background)

    # Initing headbook

    align = createAlignment(4, 4, 0, 4)
    align.set_property("yscale", 0)
    headbook = Gtk.Notebook()
    headbook.set_scrollable(True)
    align.add(headbook)
    mainvbox.pack_start(align, False, True, 0)
    show_tabs(not conf.get("hideTabs", False))

    # Initing center

    centerVBox = Gtk.VBox()

    # The dock

    global dock, dockAlign
    dock = PyDockTop("main")
    dockAlign = createAlignment(4, 4, 0, 4)
    dockAlign.add(dock)
    centerVBox.pack_start(dockAlign, True, True, 0)
    dockAlign.show()
    dock.show()

    for panel in sidePanels:
        hbox = Gtk.HBox()
        pixbuf = get_pixbuf(panel.__icon__, 16)
        icon = Gtk.Image.new_from_pixbuf(pixbuf)
        label = Gtk.Label(label=panel.__title__)
        label.set_size_request(0, 0)
        label.set_alignment(0, 1)
        hbox.pack_start(icon, False, False, 0)
        hbox.pack_start(label, True, True, 0)
        hbox.set_spacing(2)
        hbox.show_all()

        def cb(widget, x, y, keyboard_mode, tooltip, title, desc, filename):
            table = Gtk.Table(2, 2)
            table.set_row_spacings(2)
            table.set_col_spacings(6)
            table.set_border_width(4)
            pixbuf = get_pixbuf(filename, 56)
            image = Gtk.Image.new_from_pixbuf(pixbuf)
            image.set_alignment(0, 0)
            table.attach(image, 0, 1, 0, 2)
            titleLabel = Gtk.Label()
            titleLabel.set_markup("<b>%s</b>" % title)
            titleLabel.set_alignment(0, 0)
            table.attach(titleLabel, 1, 2, 0, 1)
            descLabel = Gtk.Label(label=desc)
            descLabel.props.wrap = True
            table.attach(descLabel, 1, 2, 1, 2)
            tooltip.set_custom(table)
            table.show_all()
            return True

        hbox.props.has_tooltip = True
        hbox.connect("query-tooltip", cb, panel.__title__, panel.__desc__,
                     panel.__icon__)

        docks[panel.__name__] = (hbox, notebooks[panel.__name__])

    if os.path.isfile(dockLocation):
        try:
            dock.loadFromXML(dockLocation, docks)
        except Exception as e:
            stringio = StringIO()
            traceback.print_exc(file=stringio)
            error = stringio.getvalue()
            log.error("Dock loading error: %s\n%s" % (e, error))
            msg_dia = Gtk.MessageDialog(widgets["window1"],
                                        type=Gtk.MessageType.ERROR,
                                        buttons=Gtk.ButtonsType.CLOSE)
            msg_dia.set_markup(_(
                "<b><big>PyChess was unable to load your panel settings</big></b>"))
            msg_dia.format_secondary_text(_(
                "Your panel settings have been reset. If this problem repeats, \
                you should report it to the developers"))
            msg_dia.run()
            msg_dia.hide()
            os.remove(dockLocation)
            for title, panel in docks.values():
                title.unparent()
                panel.unparent()

    if not os.path.isfile(dockLocation):
        leaf = dock.dock(docks["board"][1],
                         CENTER,
                         Gtk.Label(label=docks["board"][0]),
                         "board")
        docks["board"][1].show_all()
        leaf.setDockable(False)

        # S
        epanel = leaf.dock(docks["bookPanel"][1], SOUTH, docks["bookPanel"][0],
                           "bookPanel")
        epanel.default_item_height = 45
        epanel = epanel.dock(docks["engineOutputPanel"][1], CENTER,
                             docks["engineOutputPanel"][0],
                             "engineOutputPanel")

        # NE
        leaf = leaf.dock(docks["annotationPanel"][1], EAST,
                         docks["annotationPanel"][0], "annotationPanel")
        leaf = leaf.dock(docks["historyPanel"][1], CENTER,
                         docks["historyPanel"][0], "historyPanel")
        leaf = leaf.dock(docks["scorePanel"][1], CENTER,
                         docks["scorePanel"][0], "scorePanel")

        # SE
        leaf = leaf.dock(docks["chatPanel"][1], SOUTH, docks["chatPanel"][0],
                         "chatPanel")
        leaf = leaf.dock(docks["commentPanel"][1], CENTER,
                         docks["commentPanel"][0], "commentPanel")

    def unrealize(dock):
        # unhide the panel before saving so its configuration is saved correctly
        notebooks["board"].get_parent().get_parent().zoomDown()
        dock.saveToXML(dockLocation)
        dock._del()

    dock.connect("unrealize", unrealize)

    hbox = Gtk.HBox()

    # The status bar
    notebooks["statusbar"].set_border_width(4)
    hbox.pack_start(notebooks["statusbar"], False, True, 0)

    # The message area
    # TODO: If you try to fix this first read issue #958 and 1018
    align = createAlignment(0, 0, 0, 0)
    # sw = Gtk.ScrolledWindow()
    # port = Gtk.Viewport()
    # port.add(notebooks["messageArea"])
    # sw.add(port)
    # align.add(sw)
    align.add(notebooks["messageArea"])
    hbox.pack_start(align, True, True, 0)

    def ma_switch_page(notebook, gpointer, page_num):
        notebook.props.visible = notebook.get_nth_page(page_num).\
            get_child().props.visible

    notebooks["messageArea"].connect("switch-page", ma_switch_page)
    centerVBox.pack_start(hbox, False, True, 0)

    mainvbox.pack_start(centerVBox, True, True, 0)
    centerVBox.show_all()
    mainvbox.show()

    # Connecting headbook to other notebooks

    def hb_switch_page(notebook, gpointer, page_num):
        for notebook in notebooks.values():
            notebook.set_current_page(page_num)

#        log.debug("HB_switch ficsgame no. %s , %s " % (key2gmwidg[getheadbook().\
#           get_nth_page(page_num)].gamemodel.ficsgame.gameno,str(page_num)))
        gmwidg = key2gmwidg[getheadbook().get_nth_page(page_num)]
        if isinstance(gmwidg.gamemodel, ICGameModel):
            primary = "primary " + str(gmwidg.gamemodel.ficsgame.gameno)
            gmwidg.gamemodel.connection.client.run_command(primary)

    headbook.connect("switch-page", hb_switch_page)

    if hasattr(headbook, "set_tab_reorderable"):

        def page_reordered(widget, child, new_num, headbook):
            old_num = notebooks["board"].page_num(key2gmwidg[child].boardvbox)
            if old_num == -1:
                log.error('Games and labels are out of sync!')
            else:
                for notebook in notebooks.values():
                    notebook.reorder_child(
                        notebook.get_nth_page(old_num), new_num)

        headbook.connect("page-reordered", page_reordered, headbook)
Example #57
0
    def init_layout(self):
        perspective_widget = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        perspective_manager.set_perspective_widget("database", perspective_widget)

        self.gamelist = GameList(database.load(None))
        self.switcher_panel = SwitcherPanel(self.gamelist)
        self.opening_tree_panel = OpeningTreePanel(self.gamelist)
        self.filter_panel = FilterPanel(self.gamelist)
        self.preview_panel = PreviewPanel(self.gamelist)

        self.progressbar0 = Gtk.ProgressBar(show_text=True)
        self.progressbar = Gtk.ProgressBar(show_text=True)
        self.progress_dialog = Gtk.Dialog("Import", None, 0, (
            Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL))
        self.progress_dialog.get_content_area().pack_start(self.progressbar0, True, True, 0)
        self.progress_dialog.get_content_area().pack_start(self.progressbar, True, True, 0)
        self.progress_dialog.get_content_area().show_all()

        perspective = perspective_manager.get_perspective("database")

        self.dock = PyDockTop("database", perspective)
        align = Gtk.Alignment()
        align.show()
        align.add(self.dock)
        self.dock.show()
        perspective_widget.pack_start(align, True, True, 0)

        dockLocation = addUserConfigPrefix("pydock-database.xml")

        docks = {
            "gamelist": (Gtk.Label(label="gamelist"), self.gamelist.box),
            "switcher": (dock_panel_tab(_("Database switcher"), "", addDataPrefix("glade/panel_docker.svg")), self.switcher_panel.alignment),
            "openingtree": (dock_panel_tab(_("Opening tree"), "", addDataPrefix("glade/panel_docker.svg")), self.opening_tree_panel.box),
            "filter": (dock_panel_tab(_("Filter"), "", addDataPrefix("glade/panel_docker.svg")), self.filter_panel.box),
            "preview": (dock_panel_tab(_("Preview"), "", addDataPrefix("glade/panel_docker.svg")), self.preview_panel.box),
        }

        if os.path.isfile(dockLocation):
            try:
                self.dock.loadFromXML(dockLocation, docks)
            except Exception as e:
                stringio = StringIO()
                traceback.print_exc(file=stringio)
                error = stringio.getvalue()
                log.error("Dock loading error: %s\n%s" % (e, error))
                msg_dia = Gtk.MessageDialog(None,
                                            type=Gtk.MessageType.ERROR,
                                            buttons=Gtk.ButtonsType.CLOSE)
                msg_dia.set_markup(_(
                    "<b><big>PyChess was unable to load your panel settings</big></b>"))
                msg_dia.format_secondary_text(_(
                    "Your panel settings have been reset. If this problem repeats, \
                    you should report it to the developers"))
                msg_dia.run()
                msg_dia.hide()
                os.remove(dockLocation)
                for title, panel in docks.values():
                    title.unparent()
                    panel.unparent()

        if not os.path.isfile(dockLocation):
            leaf = self.dock.dock(docks["gamelist"][1], CENTER, docks["gamelist"][0], "gamelist")
            leaf.setDockable(False)

            leaf.dock(docks["switcher"][1], NORTH, docks["switcher"][0], "switcher")
            leaf = leaf.dock(docks["filter"][1], EAST, docks["filter"][0], "filter")
            leaf = leaf.dock(docks["openingtree"][1], SOUTH, docks["openingtree"][0], "openingtree")
            leaf.dock(docks["preview"][1], SOUTH, docks["preview"][0], "preview")

        def unrealize(dock):
            dock.saveToXML(dockLocation)
            dock._del()

        self.dock.connect("unrealize", unrealize)

        self.dock.show_all()
        perspective_widget.show_all()

        perspective_manager.set_perspective_toolbuttons("database", [self.import_button, self.close_button])

        self.switcher_panel.connect("chessfile_switched", self.on_chessfile_switched)
    def __parseLine (self, line):
        if not self.connected: return
        parts = line.split()
        if not parts: return
        
        #---------------------------------------------------------- Initializing
        if parts[0] == "id":
            self.ids[parts[1]] = " ".join(parts[2:])
            return
        
        if parts[0] == "uciok":
            self.emit("readyForOptions")
            return
        
        if parts[0] == "readyok":
            self.emit("readyForMoves")
            return
        
        #------------------------------------------------------- Options parsing
        if parts[0] == "option":
            dic = {}
            last = 1
            varlist = []
            for i in xrange (2, len(parts)+1):
                if i == len(parts) or parts[i] in OPTKEYS:
                    key = parts[last]
                    value = " ".join(parts[last+1:i])
                    if "type" in dic and dic["type"] in TYPEDIC:
                        value = TYPEDIC[dic["type"]](value)
                        
                    if key == "var":
                        varlist.append(value)
                    else:
                        dic[key] = value
                        
                    last = i
            if varlist:
                dic["vars"] = varlist
            
            name = dic["name"]
            del dic["name"]
            self.options[name] = dic
            return
        
        #---------------------------------------------------------------- A Move
        if self.mode == NORMAL and parts[0] == "bestmove":
            with self.moveLock:
                self.needBestmove = False
                self.__sendQueuedGo()
                
                if self.ignoreNext:
                    log.debug("__parseLine: line='%s' self.ignoreNext==True, returning\n" % \
                        line.strip(), self.defname)
                    self.ignoreNext = False
                    self.readyForStop = True
                    return
                
                if not self.waitingForMove:
                    log.warn("__parseLine: self.waitingForMove==False, ignoring move=%s\n" % \
                        parts[1], self.defname)
                    self.pondermove = None
                    return
                self.waitingForMove = False
                
                move = parseAN(self.board, parts[1])
                
                if not validate(self.board, move):
                    # This is critical. To avoid game stalls, we need to resign on
                    # behalf of the engine.
                    log.error("__parseLine: move=%s didn't validate, putting 'del' in returnQueue. self.board=%s\n" % \
                        (repr(move), self.board), self.defname)
                    self.returnQueue.put('del')
                    return
                
                self.board = self.board.move(move)
                log.debug("__parseLine: applied move=%s to self.board=%s\n" % \
                    (move, self.board), self.defname)
                
                if self.getOption('Ponder'):
                    self.pondermove = None
                    # An engine may send an empty ponder line, simply to clear.
                    if len(parts) == 4 and self.board:
                        # Engines don't always check for everything in their
                        # ponders. Hence we need to validate.
                        # But in some cases, what they send may not even be
                        # correct AN - specially in the case of promotion.
                        try:
                            pondermove = parseAN(self.board, parts[3])
                        except ParsingError:
                            pass
                        else:
                            if validate(self.board, pondermove):
                                self.pondermove = pondermove
                                self._startPonder()
                
                self.returnQueue.put(move)
                log.debug("__parseLine: put move=%s into self.returnQueue=%s\n" % \
                    (move, self.returnQueue.queue), self.defname)
                return
        
        #----------------------------------------------------------- An Analysis
        if self.mode != NORMAL and parts[0] == "info" and "pv" in parts:
            scoretype = parts[parts.index("score")+1]
            if scoretype in ('lowerbound', 'upperbound'):
                score = None
            else:
                score = int(parts[parts.index("score")+2])
                if scoretype == 'mate':
#                    print >> self.engine, "stop"
                    sign = score/abs(score)
                    score = sign * (MATE_VALUE-abs(score))
            
            movstrs = parts[parts.index("pv")+1:]
            try:
                moves = listToMoves (self.board, movstrs, AN, validate=True, ignoreErrors=False)
            except ParsingError, e:
                # ParsingErrors may happen when parsing "old" lines from
                # analyzing engines, which haven't yet noticed their new tasks
                log.debug("__parseLine: Ignored (%s) from analyzer: ParsingError%s\n" % \
                    (' '.join(movstrs),e), self.defname)
                return
            
            self.emit("analyze", moves, score)
            return