Exemple #1
0
    def on_icc_my_game_result(self, data):
        # gamenumber become-examined game_result_code score_string2 description-string ECO
        # 1242 1 Res 1-0 {Black resigns} {D89}
        parts = data.split(" ", 4)
        gameno, ex, result_code, result, rest = parts
        gameno = int(gameno)
        comment, rest = rest[2:].split("}", 1)

        try:
            game = self.connection.games.get_game_by_gameno(gameno)
        except KeyError:
            return
        wname = game.wplayer.name
        bname = game.bplayer.name

        result, reason = parse_reason(
            reprResult.index(result),
            comment,
            wname=wname)

        try:
            wplayer = self.connection.players.get(wname)
            wplayer.restore_previous_status()
            # no status update will be sent by
            # FICS if the player doesn't become available, so we restore
            # previous status first (not necessarily true, but the best guess)
        except KeyError:
            print("%s not in self.connections.players - creating" % wname)
            wplayer = FICSPlayer(wname)

        try:
            bplayer = self.connection.players.get(bname)
            bplayer.restore_previous_status()
        except KeyError:
            print("%s not in self.connections.players - creating" % bname)
            bplayer = FICSPlayer(bname)

        game = FICSGame(wplayer,
                        bplayer,
                        gameno=int(gameno),
                        result=result,
                        reason=reason)
        if wplayer.game is not None:
            game.rated = wplayer.game.rated
        game = self.connection.games.get(game, emit=False)
        self.connection.games.game_ended(game)
        # Do this last to give anybody connected to the game's signals a chance
        # to disconnect from them first
        wplayer.game = None
        bplayer.game = None
    def on_game_remove(self, match):
        gameno, wname, bname, comment, result = match.groups()
        result, reason = parse_reason(
            reprResult.index(result),
            comment,
            wname=wname)

        try:
            wplayer = self.connection.players.get(wname)
            wplayer.restore_previous_status()
            # no status update will be sent by
            # FICS if the player doesn't become available, so we restore
            # previous status first (not necessarily true, but the best guess)
        except KeyError:
            print("%s not in self.connections.players - creating" % wname)
            wplayer = FICSPlayer(wname)

        try:
            bplayer = self.connection.players.get(bname)
            bplayer.restore_previous_status()
        except KeyError:
            print("%s not in self.connections.players - creating" % bname)
            bplayer = FICSPlayer(bname)

        game = FICSGame(wplayer,
                        bplayer,
                        gameno=int(gameno),
                        result=result,
                        reason=reason)
        if wplayer.game is not None:
            game.rated = wplayer.game.rated
        game = self.connection.games.get(game, emit=False)

        # Our played/observed game ends are handled in main connection to prevent
        # removing them by helper connection before latest move(style12) comes from server
        if game == self.connection.bm.theGameImPlaying or \
           game in self.connection.bm.gamesImObserving:
            return

        self.connection.games.game_ended(game)
        # Do this last to give anybody connected to the game's signals a chance
        # to disconnect from them first
        wplayer.game = None
        bplayer.game = None
    def onRatingCenterSliderChanged(self, slider):
        center = int(self.widgets["ratingCenterSlider"].get_value(
        )) * RATING_SLIDER_STEP
        pixbuf = FICSPlayer.getIconByRating(center)
        self.widgets["ratingCenterLabel"].set_label("%d" % (center))
        self.widgets["ratingCenterImage"].set_from_pixbuf(pixbuf)
        self.__updateRatingRangeBox()

        rating = self.__getRating(self.__getGameType().rating_type)
        if rating is None:
            return
        rating = self.__clamp(rating)
        self.lastdifference = rating - center
Exemple #4
0
    def on_game_remove(self, match):
        gameno, wname, bname, comment, result = match.groups()
        result, reason = parse_reason(
            reprResult.index(result),
            comment,
            wname=wname)

        try:
            wplayer = self.connection.players.get(wname)
            wplayer.restore_previous_status()
            # no status update will be sent by
            # FICS if the player doesn't become available, so we restore
            # previous status first (not necessarily true, but the best guess)
        except KeyError:
            print("%s not in self.connections.players - creating" % wname)
            wplayer = FICSPlayer(wname)

        try:
            bplayer = self.connection.players.get(bname)
            bplayer.restore_previous_status()
        except KeyError:
            print("%s not in self.connections.players - creating" % bname)
            bplayer = FICSPlayer(bname)

        game = FICSGame(wplayer,
                        bplayer,
                        gameno=int(gameno),
                        result=result,
                        reason=reason)
        if wplayer.game is not None:
            game.rated = wplayer.game.rated
        game = self.connection.games.get(game, emit=False)
        self.connection.games.game_ended(game)
        # Do this last to give anybody connected to the game's signals a chance
        # to disconnect from them first
        wplayer.game = None
        bplayer.game = None
    def __updateRatingRangeBox(self):
        center = int(self.widgets["ratingCenterSlider"].get_value(
        )) * RATING_SLIDER_STEP
        tolerance = int(self.widgets["toleranceSlider"].get_value(
        )) * RATING_SLIDER_STEP
        min_rating = center - tolerance
        min_rating = min_rating > 0 and min_rating or 0
        max_rating = center + tolerance
        max_rating = max_rating >= 3000 and 9999 or max_rating

        self.widgets["ratingRangeMinLabel"].set_label("%d" % min_rating)
        self.widgets["ratingRangeMaxLabel"].set_label("%d" % max_rating)

        for widgetName, rating in (("ratingRangeMinImage", min_rating),
                                   ("ratingRangeMaxImage", max_rating)):
            pixbuf = FICSPlayer.getIconByRating(rating)
            self.widgets[widgetName].set_from_pixbuf(pixbuf)

        self.widgets["ratingRangeMinImage"].show()
        self.widgets["ratingRangeMinLabel"].show()
        self.widgets["dashLabel"].show()
        self.widgets["ratingRangeMaxImage"].show()
        self.widgets["ratingRangeMaxLabel"].show()
        if min_rating == 0:
            self.widgets["ratingRangeMinImage"].hide()
            self.widgets["ratingRangeMinLabel"].hide()
            self.widgets["dashLabel"].hide()
            self.widgets["ratingRangeMaxLabel"].set_label("%d↓" % max_rating)
        if max_rating == 9999:
            self.widgets["ratingRangeMaxImage"].hide()
            self.widgets["ratingRangeMaxLabel"].hide()
            self.widgets["dashLabel"].hide()
            self.widgets["ratingRangeMinLabel"].set_label("%d↑" % min_rating)
        if min_rating == 0 and max_rating == 9999:
            self.widgets["ratingRangeMinLabel"].set_label(_("Any strength"))
            self.widgets["ratingRangeMinLabel"].show()
Exemple #6
0
    def __updateRatingRangeBox(self):
        center = int(self.widgets["ratingCenterSlider"].get_value()
                     ) * RATING_SLIDER_STEP
        tolerance = int(
            self.widgets["toleranceSlider"].get_value()) * RATING_SLIDER_STEP
        min_rating = center - tolerance
        min_rating = min_rating > 0 and min_rating or 0
        max_rating = center + tolerance
        max_rating = max_rating >= 3000 and 9999 or max_rating

        self.widgets["ratingRangeMinLabel"].set_label("%d" % min_rating)
        self.widgets["ratingRangeMaxLabel"].set_label("%d" % max_rating)

        for widgetName, rating in (("ratingRangeMinImage", min_rating),
                                   ("ratingRangeMaxImage", max_rating)):
            pixbuf = FICSPlayer.getIconByRating(rating)
            self.widgets[widgetName].set_from_pixbuf(pixbuf)

        self.widgets["ratingRangeMinImage"].show()
        self.widgets["ratingRangeMinLabel"].show()
        self.widgets["dashLabel"].show()
        self.widgets["ratingRangeMaxImage"].show()
        self.widgets["ratingRangeMaxLabel"].show()
        if min_rating == 0:
            self.widgets["ratingRangeMinImage"].hide()
            self.widgets["ratingRangeMinLabel"].hide()
            self.widgets["dashLabel"].hide()
            self.widgets["ratingRangeMaxLabel"].set_label("%d↓" % max_rating)
        if max_rating == 9999:
            self.widgets["ratingRangeMaxImage"].hide()
            self.widgets["ratingRangeMaxLabel"].hide()
            self.widgets["dashLabel"].hide()
            self.widgets["ratingRangeMinLabel"].set_label("%d↑" % min_rating)
        if min_rating == 0 and max_rating == 9999:
            self.widgets["ratingRangeMinLabel"].set_label(_("Any strength"))
            self.widgets["ratingRangeMinLabel"].show()
    def __updateYourRatingHBox(self):
        gametype = self.__getGameType()
        self.widgets["yourRatingNameLabel"].set_label(
            "(" + gametype.display_text + ")")
        rating = self.__getRating(gametype.rating_type)
        if rating is None:
            self.widgets["yourRatingImage"].clear()
            self.widgets["yourRatingLabel"].set_label(_("Unrated"))
            return
        pixbuf = FICSPlayer.getIconByRating(rating)
        self.widgets["yourRatingImage"].set_from_pixbuf(pixbuf)
        self.widgets["yourRatingLabel"].set_label(str(rating))

        center = int(self.widgets["ratingCenterSlider"].get_value(
        )) * RATING_SLIDER_STEP
        rating = self.__clamp(rating)
        difference = rating - center
        if self.loading_seek_editor is False and self.chainbox.active and \
                difference != self.lastdifference:
            newcenter = rating - self.lastdifference
            self.widgets["ratingCenterSlider"].set_value(newcenter //
                                                         RATING_SLIDER_STEP)
        else:
            self.lastdifference = difference
    def on_game_remove(self, match):
        gameno, wname, bname, comment, result = match.groups()
        result, reason = parse_reason(reprResult.index(result),
                                      comment,
                                      wname=wname)

        try:
            wplayer = self.connection.players.get(wname)
            wplayer.restore_previous_status()
            # no status update will be sent by
            # FICS if the player doesn't become available, so we restore
            # previous status first (not necessarily true, but the best guess)
        except KeyError:
            print("%s not in self.connections.players - creating" % wname)
            wplayer = FICSPlayer(wname)

        try:
            bplayer = self.connection.players.get(bname)
            bplayer.restore_previous_status()
        except KeyError:
            print("%s not in self.connections.players - creating" % bname)
            bplayer = FICSPlayer(bname)

        game = FICSGame(wplayer,
                        bplayer,
                        gameno=int(gameno),
                        result=result,
                        reason=reason)
        if wplayer.game is not None:
            game.rated = wplayer.game.rated
        game = self.connection.games.get(game, emit=False)

        # Our played/observed game ends are handled in main connection to prevent
        # removing them by helper connection before latest move(style12) comes from server
        if (game == self.connection.bm.theGameImPlaying
                or game in self.connection.bm.gamesImObserving):
            return

        self.connection.games.game_ended(game)
        # Do this last to give anybody connected to the game's signals a chance
        # to disconnect from them first
        wplayer.game = None
        bplayer.game = None
Exemple #9
0
    def on_game_remove(self, match):
        gameno, wname, bname, comment, result = match.groups()
        result, reason = parse_reason(
            reprResult.index(result),
            comment,
            wname=wname)

        try:
            wplayer = self.connection.players.get(wname)
            wplayer.restore_previous_status()
            # no status update will be sent by
            # FICS if the player doesn't become available, so we restore
            # previous status first (not necessarily true, but the best guess)
        except KeyError:
            print("%s not in self.connections.players - creating" % wname)
            wplayer = FICSPlayer(wname)

        try:
            bplayer = self.connection.players.get(bname)
            bplayer.restore_previous_status()
        except KeyError:
            print("%s not in self.connections.players - creating" % bname)
            bplayer = FICSPlayer(bname)

        game = FICSGame(wplayer,
                        bplayer,
                        gameno=int(gameno),
                        result=result,
                        reason=reason)
        if wplayer.game is not None:
            game.rated = wplayer.game.rated
        game = self.connection.games.get(game, emit=False)
        self.connection.games.game_ended(game)
        # Do this last to give anybody connected to the game's signals a chance
        # to disconnect from them first
        wplayer.game = None
        bplayer.game = None
Exemple #10
0
 def player_lagged(self, match):
     gameno, player, num_seconds = match.groups()
     player = self.connection.players.get(FICSPlayer(player))
     self.emit("player_lagged", player)
Exemple #11
0
    def test2(self):
        """ Test manual examine lecturebot lec2 """

        lines = [
            # examine
            BLOCK_START + '62' + BLOCK_SEPARATOR + '36' + BLOCK_SEPARATOR,
            'Starting a game in examine (scratch) mode.',
            '',
            '<12> rnbqkbnr pppppppp -------- -------- -------- -------- PPPPPPPP RNBQKBNR W -1 1 1 1 1 0 77 gbtami gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
        ]

        signal = 'exGameCreated'

        game = FICSGame(
            FICSPlayer("gbtami"),
            FICSPlayer("gbtami"),
            gameno=77)
        game = self.connection.games.get(game)
        expectedResults = (game, )
        self.runAndAssertEquals(signal, lines, expectedResults)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            # bsetup
            BLOCK_START + '63' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            "Entering setup mode.",
            'fics% ',
            BLOCK_END,
            # bsetup fen r1bq2k1/2p2p1p/p1pp2pB/2n4r/8/2N2Q2/PPP2PPP/4RRK1
            BLOCK_START + '64' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 1 1 1 1 0 77 gbtami gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bsetup wcastle none
            BLOCK_START + '65' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 0 0 1 1 0 77 gbtami gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bsetup bcastle none
            BLOCK_START + '66' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 0 0 0 0 0 77 gbtami gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # tomove white
            BLOCK_START + '67' + BLOCK_SEPARATOR + '134' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 0 0 0 0 0 77 gbtami gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bsetup done
            BLOCK_START + '68' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            'Game is validated - entering examine mode.',
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 0 0 0 0 0 77 gbtami gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # wname Honfi
            BLOCK_START + '69' + BLOCK_SEPARATOR + '148' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 0 0 0 0 0 77 Honfi gbtami 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bname Sebestyen
            BLOCK_START + '70' + BLOCK_SEPARATOR + '19' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp--pB --n----r -------- --N--Q-- PPP--PPP ----RRK- W -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # f3f6
            BLOCK_START + '71' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> r-bq--k- --p--p-p p-pp-QpB --n----r -------- --N----- PPP--PPP ----RRK- B -1 0 0 0 0 1 77 Honfi Sebestyen 2 0 0 39 39 0 0 1 Q/f3-f6 (0:00.000) Qf6 0 0 0',
            'Game 77: gbtami moves: Qf6',
            'fics% ',
            BLOCK_END,
            # d8f6
            BLOCK_START + '72' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> r-b---k- --p--p-p p-pp-qpB --n----r -------- --N----- PPP--PPP ----RRK- W -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 30 39 0 0 2 Q/d8-f6 (0:00.000) Qxf6 0 0 0',
            'Game 119: gbtami moves: Qxf6',
            'fics% ',
            BLOCK_END,
            # e1e8
            BLOCK_START + '73' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> r-b-R-k- --p--p-p p-pp-qpB --n----r -------- --N----- PPP--PPP -----RK- B -1 0 0 0 0 1 77 Honfi Sebestyen 2 0 0 30 39 0 0 2 R/e1-e8 (0:00.000) Re8# 0 0 0',
            'Game 119: gbtami moves: Re8#',
            'Game 119: Black checkmated 1-0',
            'fics% ',
            BLOCK_END,
        ]

        async def coro():
            await self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 3)

        lines = [
            # kibitz Example 2:...
            BLOCK_START + '74' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            'gbtami(1719)[77] kibitzes: Example 2: Dementyev vs Karpov, Riga 1971',
            BLOCK_END,
            # bsetup
            BLOCK_START + '75' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            "Entering setup mode.",
            'fics% ',
            BLOCK_END,
            # bsetup fen q3r1k1/4Rp1p/6p1/2Q1B3/P2P4/1r1b3P/5PP1/4R1K1
            BLOCK_START + '76' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- B -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bsetup wcastle none
            BLOCK_START + '77' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- B -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bsetup bcastle none
            BLOCK_START + '78' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- B -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # tomove white
            BLOCK_START + '79' + BLOCK_SEPARATOR + '134' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- W -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bsetup done
            BLOCK_START + '80' + BLOCK_SEPARATOR + '21' + BLOCK_SEPARATOR,
            'Game is validated - entering examine mode.',
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- W -1 0 0 0 0 0 77 Honfi Sebestyen 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # wname Dementyev
            BLOCK_START + '81' + BLOCK_SEPARATOR + '148' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- W -1 0 0 0 0 0 77 Dementyev Sebestyen 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # bname Karpov
            BLOCK_START + '82' + BLOCK_SEPARATOR + '19' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- --Q-B--- P--P---- -r-b---P -----PP- ----R-K- W -1 0 0 0 0 0 77 Dementyev Karpov 2 0 0 30 39 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            BLOCK_END,
            # c5d5
            BLOCK_START + '83' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> q---r-k- ----Rp-p ------p- ---QB--- P--P---- -r-b---P -----PP- ----R-K- B -1 0 0 0 0 1 77 Dementyev Karpov 2 0 0 30 39 0 0 1 Q/c5-d5 (0:00.000) Qd5 0 0 0',
            'Game 119: gbtami moves: Qd5',
            'fics% ',
            BLOCK_END,
        ]

        async def coro():
            await self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 1)
Exemple #12
0
    def __onHistoryResponseYES(self, matchlist):
        #History for User:
        #Opponent      Type         ECO End Date
        #66: - 1735 B    0 GuestHKZX     [ bu  3   0] B23 Res Sun Dec  6, 15:50 EST 2015
        #67: - 1703 B    0 GuestQWML     [ lu  1   0] B07 Fla Sun Dec  6, 15:53 EST 2015
        history = []
        self.connection.history_owner = matchlist[0].groups()[0]
        for match in matchlist[2:]:
            #print(match.groups())
            history_no = match.groups()[0]
            result = match.groups()[1]
            owner_rating = match.groups()[2]
            owner_color = match.groups()[3]
            opp_rating = match.groups()[4]
            if result == "+":
                result = WHITEWON if owner_color == "W" else BLACKWON
            elif result == "-":
                result = WHITEWON if owner_color == "B" else BLACKWON
            else:
                result = DRAW
            opponent_name = match.groups()[5]
            if owner_color == "W":
                white = self.connection.history_owner
                black = opponent_name
                wrating = owner_rating
                brating = opp_rating
            else:
                white = opponent_name
                black = self.connection.history_owner
                brating = owner_rating
                wrating = opp_rating
            game_type = match.groups()[6]
            minutes, gain = match.groups()[7:9]
            eco = match.groups()[9]
            reason = reasons_dict[match.groups()[10]]
            week, month, day, hour, minute, timezone, year = match.groups(
            )[11:18]
            gametime = datetime.datetime(int(year),
                                         months.index(month) + 1, int(day),
                                         int(hour), int(minute))
            private = game_type[0] == "p"
            rated = game_type[2] == "r"
            gametype = GAME_TYPES_BY_SHORT_FICS_NAME[game_type[1]]
            owner_color = owner_color == "B" and BLACK or WHITE
            minutes = int(minutes)
            gain = int(gain)

            wplayer = self.connection.players.get(
                FICSPlayer(white, status=IC_STATUS_OFFLINE))
            bplayer = self.connection.players.get(
                FICSPlayer(black, status=IC_STATUS_OFFLINE))
            game = FICSHistoryGame(wplayer,
                                   bplayer,
                                   game_type=gametype,
                                   rated=rated,
                                   minutes=minutes,
                                   inc=gain,
                                   private=private,
                                   wrating=wrating,
                                   brating=brating,
                                   time=gametime,
                                   reason=reason,
                                   history_no=history_no,
                                   result=result)

            if game not in self.connection.games:
                game = self.connection.games.get(game, emit=False)
                self.emit("historyGameAdded", game)
            history.append(game)

        self.emit("onHistoryList", history)
Exemple #13
0
 def matchDeclined(self, match):
     decliner, = match.groups()
     decliner = self.connection.players.get(FICSPlayer(decliner),
                                            create=False)
     self.emit("matchDeclined", decliner)
Exemple #14
0
    def test2(self):
        """ Test observing lecturebot """

        # ♜ ♛ . . ♚ . ♞ ♜
        # ♟ ♟ . ♝ . ♟ ♟ ♟
        # . . . ♝ ♟ . . .
        # . . . ♘ . . . .
        # . . . . . . ♕ .
        # . . . ♗ . . . .
        # ♙ ♙ . . . ♙ ♙ .
        # ♖ . ♗ . ♖ . . ♔

        lines = [
            BLOCK_START + '53' + BLOCK_SEPARATOR + '80' + BLOCK_SEPARATOR,
            'You are now observing game 1.',
            'Game 1: LectureBot (0) LectureBot (0) unrated untimed 0 0',
            '',
            '<12> rq--k-nr pp-b-ppp ---bp--- ---N---- ------Q- ---B---- PP---PP- R-B-R--K W -1 0 0 1 1 2 1 LectureBot LectureBot -2 0 0 32 34 0 0 15 B/h2-d6 (0:00.000) Bd6 0 0 0',
            BLOCK_END
        ]

        signal = 'obsGameCreated'

        game = FICSGame(
            FICSPlayer("LectureBot"),
            FICSPlayer("LectureBot"),
            gameno=1)
        game = self.connection.games.get(game)
        expectedResults = (game, )
        self.runAndAssertEquals(signal, lines, expectedResults)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            "<12> rq--k-nr pp-b-pQp ---bp--- ---N---- -------- ---B---- PP---PP- R-B-R--K B -1 0 0 1 1 0 1 LectureBot LectureBot -2 0 0 32 33 0 0 15 Q/g4-g7 (0:00.000) Qxg7 0 0 0",
            "fics% ",
            "Game 1: LectureBot moves: Qxg7",
            "nfics% ",
            "LectureBot(TD)(----)[1] kibitzes: Black is now going to drop a rook.  Therefore, Black must find an alternate to 13...Bxh2+.",
            "fics% ",
            "LectureBot(TD)(----)[1] kibitzes: Let\'s back up and find the right 13th move.",
            "fics% "
        ]

        def coro():
            yield from self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 29)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            "Game 1: LectureBot backs up 4 moves.",
            "<12> rq--k-nr pp-b-ppp ---bp--- ---N---- ------Q- ---B---- PP---PPP R-B-R-K- B -1 0 0 1 1 2 1 LectureBot LectureBot -2 0 0 33 34 0 0 13 Q/d1-g4 (0:00.000) Qg4 0 0 0",
            "fics% ",
            "LectureBot(TD)(----)[1] kibitzes: Can you find Black\'s best move?",
            "fics% "
        ]

        def coro():
            yield from self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 25)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            "<12> rq---knr pp-b-ppp ---bp--- ---N---- ------Q- ---B---- PP---PPP R-B-R-K- W -1 0 0 0 0 3 1 LectureBot LectureBot -2 0 0 33 34 0 0 14 K/e8-f8 (0:00.000) Kf8 0 0 0",
            "fics% ",
            "Game 1: LectureBot moves: Kf8",
            "fics% ",
            "LectureBot(TD)(----)[1] kibitzes: Black needs to guard the g-pawn.  This also gets the king out of the pin.",
            "fics% ",
            "<12> rq---knr pp-b-ppp ---bp--- ---N---- ------Q- ---B---- PP-B-PPP R---R-K- B -1 0 0 0 0 4 1 LectureBot LectureBot -2 0 0 33 34 0 0 14 B/c1-d2 (0:00.000) Bd2 0 0 0",
            "fics% ",
            "Game 1: LectureBot moves: Bd2",
            "fics% ",
            "LectureBot(TD)(----)[1] kibitzes: White doesn\'t have to move the attacked knight because if 14. exd5, 15. Qxd7 is a trade.",
            "fics% ",
            "LectureBot(TD)(----)[1] kibitzes: Not to mention, it would be a trade favorable to White.",
            "fics% ",
            "<12> rq---knr pp-b-pp- ---bp--- ---N---p ------Q- ---B---- PP-B-PPP R---R-K- W 7 0 0 0 0 0 1 LectureBot LectureBot -2 0 0 33 34 0 0 15 P/h7-h5 (0:00.000) h5 0 0 0",
            "fics% ",
            "Game 1: LectureBot moves: h5",
            "fics% ",
            "LectureBot(TD)(----)[1] kibitzes: Here, Black attacks White\'s queen, and will try to open the h-file for his rook.",
            "fics% "
        ]

        def coro():
            yield from self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 28)

        print(self.games_persp.cur_gmwidg().gamemodel)
Exemple #15
0
    def test1(self):
        """ Test observing game """

        lines = [
            "{Game 463 (schachbjm vs. Maras) Creating rated standard match.}",
            BLOCK_START + '34' + BLOCK_SEPARATOR + '80' + BLOCK_SEPARATOR,
            'You are now observing game 463.',
            'Game 463: schachbjm (2243) Maras (2158E) rated standard 45 45',
            '',
            '<12> -r------ --k----- ----p--- n-ppPb-p -----P-P -PP-K-P- PR------ --R----- W -1 0 0 0 0 11 463 schachbjm Maras 0 45 45 17 15 557871 274070 37 R/f8-b8 (0:10.025) Rb8 0 1 0',
            BLOCK_END
        ]

        def coro():
            yield from self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(self.connection.client.commands[-1], "moves 463")

        signal = 'obsGameCreated'
        lines = [
            'Movelist for game 463:',
            '',
            'schachbjm (2243) vs. Maras (2158) --- Sat Jan 23, 14:34 EST 2016',
            'Rated standard match, initial time: 45 minutes, increment: 45 seconds.',
            '',
            'Move  schachbjm               Maras',
            '----  ---------------------   ---------------------',
            '1.  e4      (0:00.000)      e6      (0:00.000)',
            '2.  d4      (0:01.617)      d5      (0:02.220)',
            '3.  Nc3     (0:00.442)      Nc6     (0:54.807)',
            '4.  e5      (0:40.427)      Nge7    (0:28.205)',
            '5.  Nf3     (0:21.570)      Nf5     (0:28.818)',
            '6.  h4      (1:17.369)      h5      (4:58.315)',
            '7.  Bg5     (0:55.946)      Be7     (4:01.555)',
            '8.  Qd2     (0:02.434)      b6      (5:12.110)',
            '9.  O-O-O   (0:59.124)      Bb7     (0:08.796)',
            '10.  Kb1     (0:01.900)      Qd7     (4:39.500)',
            '11.  Bxe7    (19:59.514)     Qxe7    (2:42.462)',
            '12.  g3      (0:58.847)      O-O-O   (0:36.468)',
            '13.  Bh3     (0:12.284)      Nh6     (4:06.076)',
            '14.  Ne2     (0:02.387)      g6      (5:02.695)',
            '15.  Nf4     (0:02.976)      Kb8     (5:26.776)',
            '16.  Rhe1    (2:33.781)      Na5     (2:23.956)',
            '17.  b3      (0:28.817)      Rc8     (1:09.281)',
            '18.  Ng5     (8:15.515)      c5      (5:17.139)',
            '19.  Bxe6    (12:26.052)     fxe6    (1:14.670)',
            '20.  Nxg6    (0:02.168)      Qd7     (1:23.832)',
            '21.  Nxh8    (0:02.249)      Rxh8    (0:04.212)',
            '22.  dxc5    (0:14.456)      Nf5     (0:24.046)',
            '23.  cxb6    (0:07.092)      axb6    (0:03.296)',
            '24.  Qb4     (0:42.800)      Qc6     (2:48.991)',
            '25.  Nf7     (2:09.657)      Rc8     (0:37.030)',
            '26.  Rd2     (0:01.602)      Qc5     (5:03.082)',
            '27.  Qxc5    (0:09.672)      bxc5    (0:00.100)',
            '28.  Nd6     (0:00.849)      Rf8     (0:04.101)',
            '29.  c3      (0:57.437)      Kc7     (3:05.263)',
            '30.  Nxf5    (1:51.872)      Rxf5    (0:00.100)',
            '31.  f4      (0:00.603)      Bc6     (1:06.696)',
            '32.  Kc2     (0:01.613)      Be8     (0:07.670)',
            '33.  Kd3     (1:39.823)      Rf8     (1:28.227)',
            '34.  Ke3     (0:06.207)      Bg6     (0:08.648)',
            '35.  Rc1     (3:24.100)      Bf5     (1:11.762)',
            '36.  Rb2     (0:13.173)      Rb8     (0:10.025)',
            '{Still in progress} *',
        ]

        game = FICSGame(
            FICSPlayer("schachbjm"),
            FICSPlayer("Maras"),
            gameno=463)
        game = self.connection.games.get(game)
        expectedResults = (game, )
        self.runAndAssertEquals(signal, lines, expectedResults)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            '<12> -r------ --k----- ----p--- n-ppPb-p -----P-P -PP-K-P- PR------ ------R- B -1 0 0 0 0 11 463 schachbjm Maras 0 45 45 17 15 557871 274070 37 R/b2-g2 (0:10.025) Rg2 0 1 0',
            '<12> ------r- --k----- ----p--- n-ppPb-p -----P-P -PP-K-P- PR------ ------R- W -1 0 0 0 0 11 463 schachbjm Maras 0 45 45 17 15 557871 274070 38 R/b8-g8 (0:10.025) Rg8 0 1 0',
        ]

        def coro():
            yield from self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 74)

        print(self.games_persp.cur_gmwidg().gamemodel)
Exemple #16
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 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(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
Exemple #17
0
    def onStyle12(self, match):
        style12 = match.groups()[0]
        gameno = int(style12.split()[15])
        if gameno in self.queuedStyle12s:
            self.queuedStyle12s[gameno].append(style12)
            return

        try:
            self.gamemodelStartedEvents[gameno].wait()
        except KeyError:
            pass

        if gameno in self.castleSigns:
            castleSigns = self.castleSigns[gameno]
        else:
            castleSigns = ("k", "q")
        gameno, relation, curcol, ply, wname, bname, wms, bms, gain, lastmove, fen = \
            self.parseStyle12(style12, castleSigns)

        # examine starts with a <12> line only
        if lastmove is None and relation == IC_POS_EXAMINATING:
            pgnHead = [("Event", "FICS examined game"),
                       ("Site", "freechess.org"), ("White", wname),
                       ("Black", bname), ("Result", "*"), ("SetUp", "1"),
                       ("FEN", fen)]
            pgn = "\n".join(['[%s "%s"]' % line for line in pgnHead]) + "\n*\n"
            wplayer = self.connection.players.get(FICSPlayer(wname))
            bplayer = self.connection.players.get(FICSPlayer(bname))

            # examine from console or got mexamine in observed game
            if self.connection.examined_game is None:
                no_smoves = True
                game = FICSGame(wplayer,
                                bplayer,
                                gameno=int(gameno),
                                game_type=GAME_TYPES["examined"],
                                minutes=0,
                                inc=0,
                                board=FICSBoard(0, 0, pgn=pgn),
                                relation=relation)
                self.connection.examined_game = game
            else:
                # examine an archived game from GUI
                no_smoves = False
                game = self.connection.examined_game
                game.gameno = int(gameno)
                game.relation = relation
                # game.game_type = GAME_TYPES["examined"]
            game = self.connection.games.get(game)

            # don't start new game in puzzlebot/endgamebot when they just reuse gameno
            if game.relation == IC_POS_OBSERVING_EXAMINATION or \
                    (game.board is not None and game.board.pgn == pgn):
                self.emit("boardUpdate", gameno, ply, curcol, lastmove, fen,
                          wname, bname, wms, bms)
                return

            game.relation = relation
            game.board = FICSBoard(0, 0, pgn=pgn)
            self.gamesImObserving[game] = None

            # start a new game now or after smoves
            self.gamemodelStartedEvents[game.gameno] = threading.Event()
            if no_smoves:
                self.emit("exGameCreated", game)
                self.gamemodelStartedEvents[game.gameno].wait()
            else:
                if isinstance(game, FICSHistoryGame):
                    self.connection.client.run_command(
                        "smoves %s %s" %
                        (self.connection.history_owner, game.history_no))
                elif isinstance(game, FICSJournalGame):
                    self.connection.client.run_command(
                        "smoves %s %%%s" %
                        (self.connection.journal_owner, game.journal_no))
                elif isinstance(game, FICSAdjournedGame):
                    self.connection.client.run_command(
                        "smoves %s %s" %
                        (self.connection.stored_owner, game.opponent.name))
                self.connection.client.run_command("forward 999")
        else:
            self.emit("boardUpdate", gameno, ply, curcol, lastmove, fen, wname,
                      bname, wms, bms)
Exemple #18
0
    def test1(self):
        """ Test following lecturebot starting new lecture after finishing previous one """

        lines = [
            'LectureBot(TD)(----)[1] kibitzes: That concludes this lecture. If this lecture inspired you to write your own lecture, "finger LectureBot" and read note 8. toddmf would really like to hear from you about LectureBot. Please send him comments! Hope to see you all again soon!',
            'fics% ',
            'LectureBot stopped examining game 1.',
            '',
            'Game 1 (which you were observing) has no examiners.',
            'Removing game 1 from observation list.',
            'fics% ',
            'LectureBot, whom you are following, has started examining a game.',
            'You are now observing game 1.',
            'Game 1: LectureBot (0) LectureBot (0) unrated untimed 0 0',
            '',
            '<12> rnbqkbnr pppppppp -------- -------- -------- -------- PPPPPPPP RNBQKBNR W -1 1 1 1 1 0 1 LectureBot LectureBot -2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
        ]

        signal = 'obsGameCreated'

        game = FICSGame(
            FICSPlayer("LectureBot"),
            FICSPlayer("LectureBot"),
            gameno=1)
        game = self.connection.games.get(game)
        expectedResults = (game, )
        self.runAndAssertEquals(signal, lines, expectedResults)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            '<12> rnbqkbnr pppppppp -------- -------- -------- -------- PPPPPPPP RNBQKBNR W -1 1 1 1 1 0 1 Henley LectureBot -2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            '<12> rnbqkbnr pppppppp -------- -------- -------- -------- PPPPPPPP RNBQKBNR W -1 1 1 1 1 0 1 Henley Browne -2 0 0 39 39 0 0 1 none (0:00.000) none 0 0 0',
            '<12> rnbqkbnr pppppppp -------- -------- -------- -----N-- PPPPPPPP RNBQKB-R B -1 1 1 1 1 1 1 Henley Browne -2 0 0 39 39 0 0 1 N/g1-f3 (0:00.000) Nf3 0 0 0',
            'fics% ',
            'Game 1: LectureBot moves: Nf3',
        ]

        async def coro():
            await self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 1)

        lines = [
            '<12> rnbqkbnr pp-ppppp -------- --p----- -------- -----N-- PPPPPPPP RNBQKB-R W 2 1 1 1 1 0 1 Henley Browne -2 0 0 39 39 0 0 2 P/c7-c5 (0:00.000) c5 0 0 0',
            'fics% ',
            'Game 1: LectureBot moves: c5',
            '<12> rnbqkbnr pp-ppppp -------- --p----- -------- -----NP- PPPPPP-P RNBQKB-R B -1 1 1 1 1 0 1 Henley Browne -2 0 0 39 39 0 0 2 P/g2-g3 (0:00.000) g3 0 0 0',
            'fics% '
            'Game 1: LectureBot moves: g3',
            '<12> rnbqkbnr p--ppppp -p------ --p----- -------- -----NP- PPPPPP-P RNBQKB-R W -1 1 1 1 1 0 1 Henley Browne -2 0 0 39 39 0 0 3 P/b7-b6 (0:00.000) b6 0 0 0',
            'fics% '
            'Game 1: LectureBot moves: b6',
        ]

        async def coro():
            await self.connection.process_lines(lines)
        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 4)
Exemple #19
0
 def req_not_fit_formula(self, matchlist):
     player, formula = matchlist[1].groups()
     player = self.connection.players.get(FICSPlayer(player))
     self.emit("req_not_fit_formula", player, formula)
Exemple #20
0
 def on_player_disconnect(self, match):
     name = match.groups()[0]
     self.connection.players.player_disconnected(FICSPlayer(name))
Exemple #21
0
 def on_player_connect(self, match):
     name = match.groups()[0]
     player = self.connection.players.get(FICSPlayer(name))
     self.players.append(player)
     player.online = True
Exemple #22
0
    def onObserveGameCreated(self, matchlist):
        log.debug("'%s'" % (matchlist[1].string),
                  extra={
                      "task":
                      (self.connection.username, "BM.onObserveGameCreated")
                  })
        if self.connection.USCN:
            # TODO? is this ok?
            game_type = GAME_TYPES["blitz"]
            castleSigns = ("k", "q")
        else:
            gameno, wname, wrating, bname, brating, rated, gametype, minutes, inc = matchlist[
                1].groups()
            wrating = self.parseRating(wrating)
            brating = self.parseRating(brating)
            game_type = GAME_TYPES[gametype]

        style12 = matchlist[-1].groups()[0]

        castleSigns = self.generateCastleSigns(style12, game_type)
        gameno, relation, curcol, ply, wname, bname, wms, bms, gain, lastmove, fen = \
            self.parseStyle12(style12, castleSigns)
        gameno = int(gameno)
        self.castleSigns[gameno] = castleSigns

        wplayer = self.connection.players.get(FICSPlayer(wname))
        bplayer = self.connection.players.get(FICSPlayer(bname))

        if relation == IC_POS_OBSERVING_EXAMINATION:
            pgnHead = [("Event",
                        "FICS %s %s game" % (rated, game_type.fics_name)),
                       ("Site", "freechess.org"), ("White", wname),
                       ("Black", bname), ("Result", "*"), ("SetUp", "1"),
                       ("FEN", fen)]
            pgn = "\n".join(['[%s "%s"]' % line for line in pgnHead]) + "\n*\n"
            game = FICSGame(wplayer,
                            bplayer,
                            gameno=gameno,
                            rated=rated == "rated",
                            game_type=game_type,
                            minutes=int(minutes),
                            inc=int(inc),
                            board=FICSBoard(wms, bms, pgn=pgn),
                            relation=relation)
            game = self.connection.games.get(game)
            self.gamesImObserving[game] = None

            self.gamemodelStartedEvents[game.gameno] = threading.Event()
            self.emit("obsGameCreated", game)
            self.gamemodelStartedEvents[game.gameno].wait()
        else:
            game = FICSGame(wplayer,
                            bplayer,
                            gameno=gameno,
                            rated=rated == "rated",
                            game_type=game_type,
                            minutes=int(minutes),
                            inc=int(inc),
                            relation=relation)
            game = self.connection.games.get(game, emit=False)

            if not game.supported:
                log.warning("Trying to follow an unsupported type game %s" %
                            game.game_type)
                return

            if game.gameno in self.gamemodelStartedEvents:
                log.warning("%s already in gamemodelstartedevents" %
                            game.gameno)
                return

            self.gamesImObserving[game] = None
            self.queuedStyle12s[game.gameno] = []
            self.queuedEmits[game.gameno] = []
            self.gamemodelStartedEvents[game.gameno] = threading.Event()

            # FICS doesn't send the move list after 'observe' and 'follow' commands
            self.connection.client.run_command("moves %d" % game.gameno)
Exemple #23
0
    def onOfferAdd(self, match):
        log.debug("OfferManager.onOfferAdd: match.string=%s" % match.string)

        tofrom, index, offertype, parameters = match.groups()
        index = int(index)

        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.warning(
                "OfferManager.onOfferAdd: Declining unknown offer type: " +
                "offertype=%s parameters=%s index=%d" %
                (offertype, parameters, index))
            self.connection.client.run_command("decline %d" % index)
            return
        offertype = strToOfferType[offertype]
        if offertype == TAKEBACK_OFFER:
            offer = Offer(offertype, param=int(parameters), index=index)
        else:
            offer = Offer(offertype, index=index)
        self.offers[offer.index] = offer

        if offer.type == MATCH_OFFER:
            is_adjourned = False
            if matchreUntimed.match(parameters) is not None:
                fname, frating, col, tname, trating, rated, type = \
                    matchreUntimed.match(parameters).groups()
                mins = 0
                incr = 0
                gametype = GAME_TYPES["untimed"]
            else:
                fname, frating, col, tname, trating, rated, gametype, mins, \
                    incr, wildtype, adjourned = matchre.match(parameters).groups()
                if (wildtype and "adjourned" in wildtype) or \
                        (adjourned and "adjourned" in adjourned):
                    is_adjourned = True
                if wildtype and "wild" in wildtype:
                    gametype = wildtype

                try:
                    gametype = GAME_TYPES[gametype]
                except KeyError:
                    log.warning("OfferManager.onOfferAdd: auto-declining " +
                                "unknown offer type: '%s'\n" % gametype)
                    self.decline(offer)
                    del self.offers[offer.index]
                    return

            player = self.connection.players.get(FICSPlayer(fname))
            rating = frating.strip()
            rating = int(rating) if rating.isdigit() else 0
            if gametype.rating_type in player.ratings and \
                    player.ratings[gametype.rating_type].elo != rating:
                player.ratings[gametype.rating_type].elo = rating
            rated = rated != "unrated"
            challenge = FICSChallenge(index,
                                      player,
                                      int(mins),
                                      int(incr),
                                      rated,
                                      col,
                                      gametype,
                                      adjourned=is_adjourned)
            self.emit("onChallengeAdd", challenge)

        else:
            log.debug("OfferManager.onOfferAdd: emitting onOfferAdd: %s" %
                      offer)
            self.emit("onOfferAdd", offer)
Exemple #24
0
    def test1(self):
        """ Test puzzlebot starting a new mate in 2 puzzle """

        # tell puzzlebot gm2
        lines = [
            BLOCK_START + '92' + BLOCK_SEPARATOR + '132' + BLOCK_SEPARATOR,
            '(told puzzlebot, who is examining a game)',
            BLOCK_END,
            'fics% ',
            BLOCK_POSE_START + '\n' + BLOCK_START + '0' + BLOCK_SEPARATOR +
            '80' + BLOCK_SEPARATOR,
            'You are now observing game 127.',
            'Game 127: gbtami (0) puzzlebot (0) unrated untimed 0 0',
            '',
            '<12> --kr---r pp--bppp ----bn-- -Npp---q -----B-Q ---B---- PPP--PPP -K-R---R W -1 0 0 0 0 0 127 gbtami puzzlebot -2 0 0 0 0 0 0 1 none (0:00.000) none 0 0 0',
            BLOCK_END,
            'fics% ',
            BLOCK_POSE_END,
        ]

        signal = 'obsGameCreated'

        game = FICSGame(FICSPlayer("gbtami"),
                        FICSPlayer("puzzlebot"),
                        gameno=127,
                        relation=IC_POS_OBSERVING_EXAMINATION)
        game = self.connection.games.get(game)
        expectedResults = (game, )
        self.runAndAssertEquals(signal, lines, expectedResults)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            'Removing game 127 from observation list.'
            '',
            'puzzlebot has made you an examiner of game 127.',
            '',
            '<12> --kr---r pp--bppp ----bn-- -Npp---q -----B-Q ---B---- PPP--PPP -K-R---R W -1 0 0 0 0 0 127 gbtami puzzlebot 2 0 0 0 0 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: This is mate problem number [00655]',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: White moves and mates in 2 moves.',
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        # check that our relation has changed as expected
        self.assertEqual(game.relation, IC_POS_EXAMINATING)

        # try with a wrong move first: h4h5
        lines = [
            'puzzlebot stopped examining game 127.',
            'fics% ',
            BLOCK_START + '109' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> --kr---r pp--bppp ----bn-- -Npp---Q -----B-- ---B---- PPP--PPP -K-R---R B -1 0 0 0 0 0 127 gbtami puzzlebot 2 0 0 0 247 0 0 1 Q/h4-h5 (0:00.000) Qxh5 0 0 0',
            '',
            'Game 127: gbtami moves: Qxh5',
            BLOCK_END,
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        game = self.connection.games.get(game)
        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 1)

        # puzzlebot just backs up our move and sends the puzzle starting position again
        lines = [
            BLOCK_POSE_START + '\n' + BLOCK_START + '0' + BLOCK_SEPARATOR +
            '80' + BLOCK_SEPARATOR,
            'puzzlebot is now an examiner of game 127.',
            BLOCK_END,
            'fics% ',
            BLOCK_POSE_END,
            'Game 127: puzzlebot backs up 1 move.',
            '',
            '<12> --kr---r pp--bppp ----bn-- -Npp---q -----B-Q ---B---- PPP--PPP -K-R---R W -1 0 0 0 0 0 127 gbtami puzzlebot 2 0 0 34 35 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            'Game 127: Still in progress *',
            '',
            'puzzlebot(TD)(----)[127] kibitzes: There is a better move.',
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 0)

        # now we take the good move: b5a7
        lines = [
            'puzzlebot stopped examining game 127.',
            'fics% ',
            BLOCK_START + '114' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> --kr---r Np--bppp ----bn-- --pp---q -----B-Q ---B---- PPP--PPP -K-R---R B -1 0 0 0 0 0 127 gbtami puzzlebot 2 0 0 34 34 0 0 1 N/b5-a7 (0:00.000) Nxa7+ 0 0 0',
            '',
            'Game 127: gbtami moves: Nxa7+',
            BLOCK_END,
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 1)

        # puzzlebot moves
        lines = [
            BLOCK_POSE_START + '\n' + BLOCK_START + '0' + BLOCK_SEPARATOR +
            '75' + BLOCK_SEPARATOR,
            'puzzlebot is now an examiner of game 127.', BLOCK_END, 'fics% ',
            BLOCK_POSE_END,
            '<12> ---r---r Np-kbppp ----bn-- --pp---q -----B-Q ---B---- PPP--PPP -K-R---R W -1 0 0 0 0 1 127 gbtami puzzlebot 2 0 0 34 34 0 0 2 K/c8-d7 (0:00.000) Kd7 0 0 0',
            'fics% ', 'Game 127: puzzlebot moves: Kd7', 'fics% '
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])
        print(self.games_persp.cur_gmwidg().gamemodel.moves)

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 2)

        # we make the mating move: d3b5
        lines = [
            'puzzlebot stopped examining game 127.',
            'fics% ',
            BLOCK_START + '117' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> ---r---r Np-kbppp ----bn-- -Bpp---q -----B-Q -------- PPP--PPP -K-R---R B -1 0 0 0 0 2 127 gbtami puzzlebot 2 0 0 34 34 0 0 2 B/d3-b5 (0:00.000) Bb5# 0 0 0',
            ''
            'Game 127: gbtami moves: Bb5#',
            '',
            'Game 127: Black checkmated 1-0',
            BLOCK_END,
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: You solved problem number [00655] in 02m01s',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: You made 1 wrong moves and needed 0 hints',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: To solve the next problem type "tell puzzlebot next". To solve the previous problem type "tell puzzlebot previous" To automatically load problems type "tell puzzlebot auto" Or type "tell puzzlebot getmate" or "tell puzzlebot gettactics" or "tell puzzlebot getstudy"',
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 3)

        ########################################################################
        # now start another mate in 2 puzzle
        # tell puzzlebot next
        lines = [
            BLOCK_START + '125' + BLOCK_SEPARATOR + '132' + BLOCK_SEPARATOR,
            '(told puzzlebot, who is examining a game)',
            BLOCK_END,
            'fics% ',
            BLOCK_POSE_START + '\n' + BLOCK_START + '0' + BLOCK_SEPARATOR +
            '80' + BLOCK_SEPARATOR,
            'You are now observing game 127.',
            'Game 127: gbtami (0) puzzlebot (0) unrated untimed 0 0',
            '',
            '<12> -----k-- -R------ --p--n-- -------- P-P--pr- -P---RNK -----PP- ----r--- B -1 0 0 0 0 0 127 puzzlebot gbtami -2 0 0 0 0 0 0 1 none (0:00.000) none 0 0 0',
        ]

        signal = 'obsGameCreated'

        game = FICSGame(FICSPlayer("puzzlebot"),
                        FICSPlayer("gbtami"),
                        gameno=127,
                        relation=IC_POS_OBSERVING_EXAMINATION)
        game = self.connection.games.get(game)
        expectedResults = (game, )
        self.runAndAssertEquals(signal, lines, expectedResults)

        print(self.games_persp.cur_gmwidg().gamemodel)

        lines = [
            'Removing game 127 from observation list.'
            '',
            'puzzlebot has made you an examiner of game 127.',
            '',
            '<12> -----k-- -R------ --p--n-- -------- P-P--pr- -P---RNK -----PP- ----r--- B -1 0 0 0 0 0 127 puzzlebot gbtami 2 0 0 0 0 0 0 1 none (0:00.000) none 0 0 0',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: This is mate problem number [00656]',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: Black moves and mates in 2 moves.',
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        # check that our relation has changed as expected
        self.assertEqual(game.relation, IC_POS_EXAMINATING)

        # g4g3
        lines = [
            'puzzlebot stopped examining game 127.',
            'fics% ',
            BLOCK_START + '147' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> -----k-- -R------ --p--n-- -------- P-P--p-- -P---RrK -----PP- ----r--- W -1 0 0 0 0 0 127 puzzlebot gbtami 2 0 0 253 0 0 0 2 R/g4-g3 (0:00.000) Rxg3+ 0 0 0',
            '',
            'Game 127: gbtami moves: Rxg3+',
            BLOCK_END,
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 2)

        # puzzlebot moves
        lines = [
            BLOCK_POSE_START + '\n' + BLOCK_START + '0' + BLOCK_SEPARATOR +
            '75' + BLOCK_SEPARATOR,
            'puzzlebot is now an examiner of game 127.', BLOCK_END, 'fics% ',
            BLOCK_POSE_END, 'fics% ',
            '<12> -----k-- -R------ --p--n-- -------- P-P--p-- -P---RPK ------P- ----r--- B -1 0 0 0 0 0 127 puzzlebot gbtami 2 0 0 253 251 0 0 2 P/f2-g3 (0:00.000) fxg3 0 0 0',
            'Game 127: puzzlebot moves: fxg3', 'fics% '
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 3)

        # we make the mating move: e1h1
        lines = [
            'puzzlebot stopped examining game 127.',
            'fics% ',
            BLOCK_START + '150' + BLOCK_SEPARATOR + '1' + BLOCK_SEPARATOR,
            '<12> -----k-- -R------ --p--n-- -------- P-P--p-- -P---RPK ------P- -------r W -1 0 0 0 0 1 127 puzzlebot gbtami 2 0 0 253 251 0 0 3 R/e1-h1 (0:00.000) Rh1# 0 0 0',
            ''
            'Game 127: gbtami moves: Rh1#',
            '',
            'Game 127: White checkmated 0-1',
            BLOCK_END,
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: You solved problem number [00656] in 00m45s',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: You made 1 wrong moves and needed 0 hints',
            'fics% ',
            'puzzlebot(TD)(----)[127] kibitzes: To solve the next problem type "tell puzzlebot next". To solve the previous problem type "tell puzzlebot previous" To automatically load problems type "tell puzzlebot auto" Or type "tell puzzlebot getmate" or "tell puzzlebot gettactics" or "tell puzzlebot getstudy"',
            'fics% ',
        ]

        async def coro():
            await self.connection.process_lines(lines)

        self.loop.run_until_complete(coro())

        self.assertEqual(game.move_queue.qsize(), 0)

        print(self.games_persp.cur_gmwidg().gamemodel.boards[-1])

        self.assertEqual(self.games_persp.cur_gmwidg().gamemodel.ply, 4)
Exemple #25
0
    def on_seek_add(self, match):
        # The <s> message looks like:
        # <s> index w=name_from ti=titles rt=rating t=time i=increment
        #     r=rated('r')/unrated('u') tp=type("wild/fr", "wild/4","blitz")
        #     c=color rr=rating_range(lower-upper) a=automatic?('t'/'f')
        #     f=formula_checked('t'/f')
        parts = match.groups()[0].split(" ")
        seek = {}
        for key, value in [p.split("=") for p in parts[1:] if p]:
            seek[key] = value

        try:
            index = int(parts[0])
            player = self.connection.players.get(FICSPlayer(seek['w']))
            player.titles |= parse_title_hex(seek['ti'])
            rated = seek['r'] == 'r'
            minutes = int(seek['t'])
            increment = int(seek['i'])
            rmin, rmax = [int(r) for r in seek['rr'].split("-")]
            rating = seek['rt']
            if rating[-1] in (" ", "P", "E"):
                deviation = DEVIATION[rating[-1]]
                rating = rating[:-1]
            rating = int(rating)
            deviation = None
            automatic = seek['a'] == 't'
            color = None
            if seek['c'] == "W":
                color = "white"
            elif seek['c'] == "B":
                color = "black"
        except KeyError as e:
            log.warning("on_seek_add: KeyError: %s %s" % (repr(e), repr(seek)))
            return

        try:
            gametype = GAME_TYPES[seek["tp"]]
        except KeyError:
            if self.connection.FatICS and seek["tp"] == "chess":
                # TODO: remove when fixed in FatICS
                expected_time = minutes + increment * 2 / 3
                if expected_time == 0:
                    gametype = "untimed"
                elif expected_time < 3:
                    gametype = "lightning"
                elif expected_time < 15:
                    gametype = "blitz"
                else:
                    gametype = "standard"
                gametype = GAME_TYPES[gametype]
            else:
                return
        if gametype.variant_type in UNSUPPORTED:
            return
        try:
            ratingobj = player.ratings[gametype.rating_type]
            if ratingobj.elo != rating:
                ratingobj.elo = rating
            ratingobj.deviation = deviation
        except KeyError:
            pass

        seek = FICSSeek(index,
                        player,
                        minutes,
                        increment,
                        rated,
                        color,
                        gametype,
                        rmin=rmin,
                        rmax=rmax,
                        automatic=automatic)
        self.emit("addSeek", seek)
Exemple #26
0
 def player_on_noplay(self, match):
     player, = match.groups()
     player = self.connection.players.get(FICSPlayer(player))
     self.emit("player_on_noplay", player)