Esempio n. 1
0
    def run(self, args, conn):
        if args[0] is None:
            g_ = True
            p_ = True
            u_ = True
        else:
            g_ = False
            p_ = False
            u_ = False
            for c in args[0]:
                if c == 'g':
                    g_ = True
                elif c == 'p':
                    p_ = True
                elif c == 'u':
                    u_ = True
                else:
                    raise BadCommandError

        if g_:
            # bughouse games
            conn.write(_('Bughouse games in progress\n'))
            count = 0
            for g in global_.games.values():
                if g.variant.name == 'bughouse':
                    # XXX
                    conn.write('TODO\n')
                    count += 1
            conn.write(ngettext(' %d game displayed.\n',
                ' %d games displayed.\n', count) % count)
        if p_:
            conn.write(_('Partnerships not playing bughouse\n'))
            for p in global_.partners:
                [p1, p2] = sorted(list(p), key=lambda p: p.name)
                conn.write('%s %s / %s %s\n' %
                    (p1.get_rating(speed_variant.from_names('blitz',
                        'bughouse')), p1.get_display_name(),
                        p2.get_rating(speed_variant.from_names('blitz',
                        'bughouse')), p2.get_display_name()))
            count = len(global_.partners)
            conn.write(ngettext(' %d partnership displayed.\n',
                '  %d partnerships displayed.\n', count) % count)

        if u_:
            conn.write(_('Unpartnered players with bugopen on\n'))
            ulist = sorted([u for u in global_.online if u.vars_['bugopen'] and
                not u.session.partner], key=lambda u: u.name)
            for u in ulist:
                conn.write('%s %s\n' %
                    (u.get_rating(speed_variant.from_names('blitz',
                        'bughouse')), u.get_display_name()))
            total = len(global_.online)
            count = len(ulist)
            conn.write(ngettext(' %(count)d player displayed (of %(total)d).\n',
                '  %(count)d players displayed (of %(total)d).\n', count)
                % {'count': count, 'total': total})
Esempio n. 2
0
    def __init__(self, user, hist_game=None):
        self.gtype = EXAMINED
        self.players = set([user])
        super(ExaminedGame, self).__init__()

        self.white_time = 0
        self.black_time = 0
        self.white_rating = 0  # XXX
        self.black_rating = 0  # XXX
        self.clock = clock.UntimedClock()
        self.inc = 0
        self.rated_str = 'unrated'
        self.info_str = '%s (0) %s (0) unrated untimed 0 0' % (user, user)
        assert (user.session.game is None)
        user.session.game = self
        self.when_started = datetime.datetime.utcnow()

        if hist_game is None:
            self.speed_variant = speed_variant.from_names('untimed', 'chess')
            self.variant = speed_variant.variant_class[
                self.speed_variant.variant.name](self)
            self.moves = []
            #self.white_name = list(self.players)[0].name
            #self.black_name = self.white_name
            self.white_name = 'White'
            self.black_name = 'Black'
            self.result_code = None
        else:
            self.idn = hist_game['idn']
            variant_name = speed_variant.variant_abbrevs[hist_game['flags']
                                                         [1]].name
            # XXX use the speed from history
            self.speed_variant = speed_variant.from_names(
                'untimed', variant_name)
            self.variant = speed_variant.variant_class[
                self.speed_variant.variant.name](self)
            self.moves = hist_game['movetext'].split(' ')
            self.white_name = hist_game['white_name']
            self.black_name = hist_game['black_name']
            self.result_code = hist_game['result']
            self.result_reason = hist_game['result_reason']

        for uf in user.session.followed_by:
            uf.write_(
                '\n%s, whom you are following, has started examining a game.\n',
                user)
            self.observe(uf)

        self.send_boards()
Esempio n. 3
0
    def __init__(self, user, hist_game=None):
        self.gtype = EXAMINED
        self.players = set([user])
        super(ExaminedGame, self).__init__()

        self.white_time = 0
        self.black_time = 0
        self.white_rating = 0  # XXX
        self.black_rating = 0  # XXX
        self.clock = clock.UntimedClock()
        self.inc = 0
        self.rated_str = 'unrated'
        self.info_str = '%s (0) %s (0) unrated untimed 0 0' % (user, user)
        assert (user.session.game is None)
        user.session.game = self
        self.when_started = datetime.datetime.utcnow()

        if hist_game is None:
            # TODO: examining variants
            self.speed_variant = speed_variant.from_names('untimed', 'chess')
            self.variant = global_.variant_class[
                self.speed_variant.variant.name](self)
            self.moves = []
            #self.white_name = list(self.players)[0].name
            #self.black_name = self.white_name
            self.white_name = 'White'
            self.black_name = 'Black'
            self.result_code = None
        else:
            self.idn = hist_game['idn']
            variant_name = speed_variant.variant_abbrevs[hist_game['flags']
                                                         [1]].name
            # XXX use the speed from history
            self.speed_variant = speed_variant.from_names(
                'untimed', variant_name)
            self.variant = global_.variant_class[
                self.speed_variant.variant.name](self)
            # idn will be set by caller for chess960
            self.moves = hist_game['movetext'].split(' ')
            self.white_name = hist_game['white_name']
            self.black_name = hist_game['black_name']
            self.result_code = hist_game['result']
            self.result_reason = hist_game['result_reason']

        self.gameinfo_str = '\n<g1> %d p=%d t=%s r=%d u=%d,%d it=%d,%d i=%d,%d pt=0 rt=%s,%s ts=%d,%d m=%d n=%d\n' % (
            self.number, self.private, self.speed_variant.legacy_str(),
            0, user.is_guest, user.is_guest, 0, 0, 0, 0, 0, 0,
            user.has_timeseal(), user.has_timeseal(), 0, 0)
Esempio n. 4
0
    def run(self, args, conn):
        if args[0] not in [None, 'g', 'p', 'u']:
            raise BadCommandError
        if args[0] is None or args[0] == 'g':
            # bughouse games
            conn.write(_('Bughouse games in progress\n'))
            count = 0
            for g in game.games.values():
                if game.variant.name == 'bughouse':
                    count += 1
            conn.write(
                ngettext(' %d game displayed.\n', ' %d games displayed.\n',
                         count) % count)
        if args[0] is None or args[0] == 'p':
            conn.write(_('Partnerships not playing bughouse\n'))
            for p in partner.partners:
                [p1, p2] = sorted(list(p), key=lambda p: p.name)
                conn.write('%s %s / %s %s\n' % (
                    p1.get_rating(speed_variant.from_names(
                        'blitz', 'bughouse')), p1.get_display_name(),
                    p2.get_rating(speed_variant.from_names(
                        'blitz', 'bughouse')), p2.get_display_name()))
            count = len(partner.partners)
            conn.write(
                ngettext(' %d partnership displayed.\n',
                         '  %d partnerships displayed.\n', count) % count)

        if args[0] is None or args[0] == 'u':
            conn.write(_('Unpartnered players with bugopen on\n'))
            ulist = sorted([
                u for u in online.online
                if u.vars['bugopen'] and not u.session.partner
            ],
                           key=lambda u: u.name)
            for u in ulist:
                conn.write(
                    '%s %s\n' %
                    (u.get_rating(speed_variant.from_names(
                        'blitz', 'bughouse')), u.get_display_name()))
            total = len(online.online)
            count = len(ulist)
            conn.write(
                ngettext(' %(count)d player displayed (of %(total)d).\n',
                         '  %(count)d players displayed (of %(total)d).\n',
                         count) % {
                             'count': count,
                             'total': total
                         })
Esempio n. 5
0
    def __init__(self, user, hist_game=None):
        self.gtype = EXAMINED
        self.players = set([user])
        super(ExaminedGame, self).__init__()

        self.white_time = 0
        self.black_time = 0
        self.white_rating = 0 # XXX
        self.black_rating = 0 # XXX
        self.clock = clock.UntimedClock()
        self.inc = 0
        self.rated_str = 'unrated'
        self.info_str = '%s (0) %s (0) unrated untimed 0 0' % (
            user, user)
        assert(user.session.game is None)
        user.session.game = self
        self.when_started = datetime.datetime.utcnow()

        if hist_game is None:
            self.speed_variant = speed_variant.from_names('untimed', 'chess')
            self.variant = speed_variant.variant_class[self.speed_variant.variant.name](self)
            self.moves = []
            #self.white_name = list(self.players)[0].name
            #self.black_name = self.white_name
            self.white_name = 'White'
            self.black_name = 'Black'
            self.result_code = None
        else:
            self.idn = hist_game['idn']
            variant_name = speed_variant.variant_abbrevs[hist_game['flags'][1]].name
            # XXX use the speed from history
            self.speed_variant = speed_variant.from_names('untimed',
                variant_name)
            self.variant = speed_variant.variant_class[self.speed_variant.variant.name](self)
            self.moves = hist_game['movetext'].split(' ')
            self.white_name = hist_game['white_name']
            self.black_name = hist_game['black_name']
            self.result_code = hist_game['result']
            self.result_reason = hist_game['result_reason']

        for uf in user.session.followed_by:
            uf.write_('\n%s, whom you are following, has started examining a game.\n', user)
            self.observe(uf)

        self.send_boards()
Esempio n. 6
0
    def run(self, args, conn):
        if args[0] not in [None, 'g', 'p', 'u']:
            raise BadCommandError
        if args[0] is None or args[0] == 'g':
            # bughouse games
            conn.write(_('Bughouse games in progress\n'))
            count = 0
            for g in game.games.values():
                if game.variant.name == 'bughouse':
                    count += 1
            conn.write(ngettext(' %d game displayed.\n',
                ' %d games displayed.\n', count) % count)
        if args[0] is None or args[0] == 'p':
            conn.write(_('Partnerships not playing bughouse\n'))
            for p in partner.partners:
                [p1, p2] = sorted(list(p), key=lambda p: p.name)
                conn.write('%s %s / %s %s\n' %
                    (p1.get_rating(speed_variant.from_names('blitz',
                        'bughouse')), p1.get_display_name(),
                        p2.get_rating(speed_variant.from_names('blitz',
                        'bughouse')), p2.get_display_name()))
            count = len(partner.partners)
            conn.write(ngettext(' %d partnership displayed.\n',
                '  %d partnerships displayed.\n', count) % count)

        if args[0] is None or args[0] == 'u':
            conn.write(_('Unpartnered players with bugopen on\n'))
            ulist = sorted([u for u in online.online if u.vars['bugopen'] and
                not u.session.partner], key=lambda u: u.name)
            for u in ulist:
                conn.write('%s %s\n' %
                    (u.get_rating(speed_variant.from_names('blitz',
                        'bughouse')), u.get_display_name()))
            total = len(online.online)
            count = len(ulist)
            conn.write(ngettext(' %(count)d player displayed (of %(total)d).\n',
                '  %(count)d players displayed (of %(total)d).\n', count)
                % {'count': count, 'total': total})
Esempio n. 7
0
    def __init__(self, user, args):
        """ Create a new seek.  Raises a MatchError if given an invalid
        match string. """
        self.a = user
        self.b = None
        self.expired = False
        self.adjourned = None

        # may raise MatchError
        self._parse_args(args)

        assert (self.time is not None and self.inc is not None)
        assert (self.rated is not None)
        assert (self.variant_name is not None)
        assert (self.clock_name is not None)
        assert (self.side in [None, WHITE, BLACK])

        self.tags = {
            'rated': self.rated,
            'speed_name': self.speed_name,
            'variant_name': self.variant_name,
            'clock_name': self.clock_name,
            'time': self.time,
            'inc': self.inc,
            'idn': self.idn,
        }

        # defaults
        if self.manual is None:
            self.manual = False
        if self.clock_name is None:
            self.clock_name = 'fischer'
        if self.formula is None:
            self.formula = False
        if self.manual is None:
            self.manual = False
        assert (self.manual in [True, False])

        self.speed_variant = speed_variant.from_names(self.speed_name,
                                                      self.variant_name)

        variant_str = '' if self.variant_name == 'chess' else (
            ' %s' % self.variant_name)
        clock_str = '' if self.clock_name == 'fischer' else (' %s' %
                                                             self.clock_name)
Esempio n. 8
0
    def __init__(self, user, args):
        """ Create a new seek.  Raises a MatchError if given an invalid
        match string. """
        self.a = user
        self.b = None
        self.expired = False
        self.adjourned = None

        # may raise MatchError
        self._parse_args(args)

        assert(self.time is not None and self.inc is not None)
        assert(self.rated is not None)
        assert(self.variant_name is not None)
        assert(self.clock_name is not None)
        assert(self.side in [None, WHITE, BLACK])

        self.tags = {
            'rated': self.rated,
            'speed_name': self.speed_name,
            'variant_name': self.variant_name,
            'clock_name': self.clock_name,
            'time': self.time,
            'inc': self.inc,
            'idn': self.idn,
        }

        # defaults
        if self.manual is None:
            self.manual = False
        if self.clock_name is None:
            self.clock_name = 'fischer'
        if self.formula is None:
            self.formula = False
        if self.manual is None:
            self.manual = False
        assert(self.manual in [True, False])

        self.speed_variant = speed_variant.from_names(self.speed_name,
            self.variant_name)

        variant_str = '' if self.variant_name == 'chess' else (
            ' %s' % self.variant_name)
        clock_str = '' if self.clock_name == 'fischer' else (
            ' %s' % self.clock_name)
Esempio n. 9
0
    def _resume(self, adj, a, b):
        """ Resume an adjourned game. """
        if adj['white_user_id'] == a.id:
            assert(adj['black_user_id'] == b.id)
            self.white = a
            self.black = b
        else:
            assert(adj['white_user_id'] == b.id)
            assert(adj['black_user_id'] == a.id)
            self.white = b
            self.black = a
        self.white_name = self.white.name
        self.black_name = self.black.name

        self.speed_variant = speed_variant.from_names(adj['speed_name'],
            adj['variant_name'])
        self.white_time = adj['time']
        self.black_time = adj['time']
        # XXX is this correct, or should we use the actual time
        # remaining for the gameinfo string?
        if self.white_time == 0:
            self.initial_secs = 10.0
        else:
            self.initial_secs = 60.0 * self.white_time
        # XXX use a stored rating?
        self.white_rating = self.white.get_rating(self.speed_variant)
        self.black_rating = self.black.get_rating(self.speed_variant)
        self.inc = adj['inc']
        self.rated = adj['rated']
        self.tags = {
            'time': adj['time'],
            'inc': adj['inc']
        }
        self.clock_name = adj['clock_name']
        self.clock = clock.clock_names[self.clock_name](self,
            adj['white_clock'], adj['black_clock'])
        self.idn = adj['idn'] # for chess960
        if self.clock_name == 'overtime':
            self.overtime_move_num = adj['overtime_move_num']
            self.overtime_bonus = adj['overtime_bonus']
        self.when_started = adj['when_started']

        # clear the game in the database
        db.delete_adjourned(adj['adjourn_id'])
Esempio n. 10
0
 def run(self, args, conn):
     (name, speed_name, variant_name, urating, rd, volatility, win,
         loss, draw) = args
     u = user.find_by_prefix_for_user(name, conn)
     if not u:
         return
     if u.is_guest:
         conn.write(A_('You cannot set the rating of an unregistered player.\n'))
         return
     try:
         sv = speed_variant.from_names(speed_name, variant_name)
     except KeyError:
         conn.write(A_('Unknown speed and variant "%s %s".\n') %
             (speed_name, variant_name))
         return
     if urating == 0:
         u.del_rating(sv)
         conn.write(A_('Cleared %s %s rating for %s.\n' %
             (speed_name, variant_name, u.name)))
     else:
         u.set_rating(sv, urating, rd, volatility, win, loss, draw,
             datetime.datetime.utcnow())
         conn.write(A_('Set %s %s rating for %s.\n' %
             (speed_name, variant_name, u.name)))
Esempio n. 11
0
    def run(self, args, conn):
        users = [u for u in online.online]

        sort_order = 'b'
        fmt = 't'
        if args[0]:
            param = args[0]
            i = 0
            while i < len(param):
                if param[i] == 'o':
                    users = [u for u in users if u.vars['open']]
                # r for rated not implemented (it's obsolete)
                elif param[i] == 'f':
                    users = [u for u in users if not u.session.game]
                elif param[i] == 'a':
                    users = [
                        u for u in users
                        if u.vars['open'] and not u.session.game
                    ]
                elif param[i] == 'R':
                    users = [u for u in users if not u.is_guest]
                elif param[i] == 'U':
                    users = [u for u in users if u.is_guest]
                elif param[i] in ['s', 'b', 'w', 'z', 'L', 'S', 'B', 'A', 'l']:
                    if sort_order != 'b' and sort_order != param[i]:
                        # conflicting sort orders given
                        raise BadCommandError
                    sort_order = param[i]
                elif param[i] in ['t', 'v', 'n', 'I']:
                    # what does n do?
                    if fmt != 't' and fmt != param[i]:
                        # conflicting formats given
                        raise BadCommandError
                    fmt = param[i]
                elif param[i].isdigit():
                    if i + 1 >= len(param) or not param[i + 1].isdigit():
                        # only one digit given; default to 3 parts
                        page = int(param[i])
                        if page < 1 or page > 3:
                            raise BadCommandError
                        divs = 3
                    else:
                        page = int(param[i])
                        divs = int(param[i + 1])
                else:
                    raise BadCommandError

                i += 1

        #standard = speed_variant.from_names('standard', 'chess')
        #blitz = speed_variant.from_names('blitz', 'chess')
        #lightning = speed_variant.from_names('lightning', 'chess')
        #zh = speed_variant.from_names('blitz', 'crazyhouse')
        #fr = speed_variant.from_names('blitz', 'chess960')
        #suicide = speed_variant.from_names('blitz', 'chess960')
        bughouse = speed_variant.from_names('blitz', 'bughouse')
        if sort_order == 's':
            compare = lambda p: int(p.get_rating(speed_variant.standard_chess))
        elif sort_order == 'b':
            compare = lambda p: int(p.get_rating(speed_variant.blitz_chess))
        elif sort_order == 'L':
            compare = lambda p: int(p.get_rating(speed_variant.lightning_chess)
                                    )
        elif sort_order == 'z':
            compare = lambda p: int(
                p.get_rating(speed_variant.blitz_crazyhouse))
        elif sort_order == 'w':
            # hack: in original fics this means wild, but it now means chess960
            compare = lambda p: int(p.get_rating(speed_variant.blitz_chess960))
        elif sort_order == 'S':
            # XXX suicide
            assert (False)
        elif sort_order == 'B':
            compare = lambda p: int(p.get_rating(speed_variant.blitz_bughouse))
        elif sort_order == 'A':
            compare = lambda p: p.name
        elif sort_order == 'l':
            compare = lambda p: p.name
        else:
            assert (False)
        users.sort(key=compare)

        if fmt == 't':
            count = 0
            conn.write('\n')
            for u in users:
                if sort_order == 'A':
                    conn.write('     ')
                elif sort_order == 'l':
                    conn.write('%4d ' %
                               u.get_rating(speed_variant.blitz_chess))
                else:
                    conn.write('%4d ' % compare(u))
                conn.write(u.get_display_name() + '\n')
                count = count + 1
            conn.write('\n')

            conn.write(
                ngettext('%d player displayed.\n\n',
                         '%d players displayed.\n\n', count) % count)
        else:
            conn.write('TODO: unsupposted format\n')
Esempio n. 12
0
    def run(self, args, conn):
        users = [u for u in online.online]

        sort_order = 'b'
        fmt = 't'
        if args[0]:
            param = args[0]
            i = 0
            while i < len(param):
                if param[i] ==  'o':
                    users = [u for u in users if u.vars['open']]
                # r for rated not implemented (it's obsolete)
                elif param[i] ==  'f':
                    users = [u for u in users if not u.session.game]
                elif param[i] ==  'a':
                    users = [u for u in users if u.vars['open'] and not u.session.game]
                elif param[i] == 'R':
                    users = [u for u in users if not u.is_guest]
                elif param[i] == 'U':
                    users = [u for u in users if u.is_guest]
                elif param[i] in ['s', 'b', 'w', 'z', 'L', 'S', 'B', 'A', 'l']:
                    if sort_order != 'b' and sort_order != param[i]:
                        # conflicting sort orders given
                        raise BadCommandError
                    sort_order = param[i]
                elif param[i] in ['t', 'v', 'n', 'I']:
                    # what does n do?
                    if fmt != 't' and fmt != param[i]:
                        # conflicting formats given
                        raise BadCommandError
                    fmt = param[i]
                elif param[i].isdigit():
                    if i + 1 >= len(param) or not param[i + 1].isdigit():
                        # only one digit given; default to 3 parts
                        page = int(param[i])
                        if page < 1 or page > 3:
                            raise BadCommandError
                        divs = 3
                    else:
                        page = int(param[i])
                        divs = int(param[i + 1])
                else:
                    raise BadCommandError

                i += 1

        #standard = speed_variant.from_names('standard', 'chess')
        #blitz = speed_variant.from_names('blitz', 'chess')
        #lightning = speed_variant.from_names('lightning', 'chess')
        #zh = speed_variant.from_names('blitz', 'crazyhouse')
        #fr = speed_variant.from_names('blitz', 'chess960')
        #suicide = speed_variant.from_names('blitz', 'chess960')
        bughouse = speed_variant.from_names('blitz', 'bughouse')
        if sort_order == 's':
            compare = lambda p: int(p.get_rating(speed_variant.standard_chess))
        elif sort_order == 'b':
            compare = lambda p: int(p.get_rating(speed_variant.blitz_chess))
        elif sort_order == 'L':
            compare = lambda p: int(p.get_rating(speed_variant.lightning_chess))
        elif sort_order == 'z':
            compare = lambda p: int(p.get_rating(speed_variant.blitz_crazyhouse))
        elif sort_order == 'w':
            # hack: in original fics this means wild, but it now means chess960
            compare = lambda p: int(p.get_rating(speed_variant.blitz_chess960))
        elif sort_order == 'S':
            # XXX suicide
            assert(False)
        elif sort_order == 'B':
            compare = lambda p: int(p.get_rating(speed_variant.blitz_bughouse))
        elif sort_order == 'A':
            compare = lambda p: p.name
        elif sort_order == 'l':
            compare = lambda p: p.name
        else:
            assert(False)
        users.sort(key=compare)

        if fmt == 't':
            count = 0
            conn.write('\n')
            for u in users:
                if sort_order == 'A':
                    conn.write('     ')
                elif sort_order == 'l':
                    conn.write('%4d ' % u.get_rating(speed_variant.blitz_chess))
                else:
                    conn.write('%4d ' % compare(u))
                conn.write(u.get_display_name() + '\n')
                count = count + 1
            conn.write('\n')

            conn.write(ngettext('%d player displayed.\n\n', '%d players displayed.\n\n', count) % count)
        else:
            conn.write('TODO: unsupposted format\n')
Esempio n. 13
0
    def finish_init(self, a, b, args=None, tags=None):
        """ Initiate a new offer.  "a" is the player issuing the offer;
        "b" receives the request """
        self.a = a
        self.b = b

        if a.is_guest or b.is_guest:
            self.adjourned = None
        else:
            self.adjourned = yield a.get_adjourned_with(b)
        if self.adjourned:
            if tags or args:
                a.write(
                    _('You have an adjourned game with %s.  You cannot start a new game until you finish it.\n'
                      ) % b.name)
                return
            tags = self.adjourned.copy()
            tags.update({'side': None})
        else:
            if not check_censor_noplay(a, b):
                return

        if tags:
            # copy match parameters
            self.side = tags['side']
            self.rated = tags['is_rated']
            self.speed_name = tags['speed_name']
            self.variant_name = tags['variant_name']
            self.clock_name = tags['clock_name']
            self.time = tags['time']
            self.inc = tags['inc']
            self.idn = tags['idn']
            self.speed_variant = speed_variant.from_names(
                self.speed_name, self.variant_name)
            self.a_rating = a.get_rating(self.speed_variant)
            self.b_rating = b.get_rating(self.speed_variant)
            # TODO: overtime move number, bonus
        else:
            # get match parameters from a string or use defaults
            try:
                self._check_open()
                self._parse_args(args, a, b)
            except MatchError as e:
                a.write(e.args[0])
                return

        a_sent = a.session.offers_sent
        b_sent = b.session.offers_sent
        a_received = a.session.offers_received
        b_received = b.session.offers_received

        # look for a matching offer from player b
        o = next((o for o in a_received
                  if o.name == self.name and o.equivalent_to(self)), None)
        if o:
            # a already received an identical offer, so just accept it
            a.write(
                _("Your challenge intercepts %s's challenge.\n") %
                (o.a.name, ))
            b.write_("%s's challenge intercepts your challenge.\n", (a.name, ))
            # XXX don't send "Accepting" and "USER accepts" messages?
            o.accept()
            return

        # build the "Challenge:" string
        if self.side is not None:
            side_str = ' [%s]' % side_to_str(self.side)
        else:
            side_str = ''

        rated_str = "rated" if self.rated else "unrated"

        if self.clock_name == 'untimed':
            time_str = ''
        else:
            time_str = ' %d %d' % (self.time, self.inc)

        # example: GuestABCD (++++) [white] hans (----) unrated blitz 5 0.
        challenge_str = '%s (%s)%s %s (%s) %s %s%s' % (
            self.a.name, self.a_rating, side_str, self.b.name, self.b_rating,
            rated_str, self.speed_variant, time_str)
        if self.idn is not None:
            challenge_str = '%s idn=%d' % (challenge_str, self.idn)
        if self.clock_name not in ['fischer', 'untimed']:
            challenge_str = '%s %s' % (challenge_str, self.clock_name)
        if self.clock_name == 'overtime':
            challenge_str = '%s %d/%d,SD/%d+%d' % (
                challenge_str, self.overtime_move_num, self.time,
                self.overtime_bonus, self.inc)
        if self.adjourned:
            challenge_str = '%s (adjourned)' % challenge_str
        #if self.board is not None:
        #    challenge_str = 'Loaded from a board'

        if self in a_sent:
            a.write_('You are already offering an identical match to %s.\n',
                     (b.name, ))
            return

        if not formula.check_formula(self, b.vars_['formula']):
            a.write_('Match request does not meet formula for %s:\n', b.name)
            b.write_('Ignoring (formula): %s\n', challenge_str)
            return

        if self.variant_name == 'bughouse':
            # build the challenge string for the other game
            apart = a.session.partner
            bpart = b.session.partner
            challenge_str2 = '%s (%s) %s (%s) %s %s%s' % (
                apart.name, apart.get_rating(self.speed_variant), bpart.name,
                bpart.get_rating(self.speed_variant), rated_str,
                self.speed_variant, time_str)
            if self.idn is not None:
                challenge_str2 = '%s idn=%d' % (challenge_str2, self.idn)
            if self.clock_name not in ['fischer', 'untimed']:
                challenge_str2 = '%s %s' % (challenge_str2, self.clock_name)
            if self.clock_name == 'overtime':
                challenge_str2 = '%s %d/%d,SD/%d+%d' % (
                    challenge_str2, self.overtime_move_num, self.time,
                    self.overtime_bonus, self.inc)
            if self.adjourned:
                challenge_str2 = '%s (adjourned)' % challenge_str2

            # inform the other two players about the challenge
            apart.write_('Your bughouse partner issues: %s\n', challenge_str)
            apart.write_('Your game will be: %s\n', challenge_str2)
            bpart.write_('Your bughouse partner was challenged: %s\n',
                         challenge_str)
            bpart.write_('Your game will be: %s\n', challenge_str2)

        o = next((o for o in b_sent if o.name == self.name and o.b == a), None)
        if o:
            a.write_(
                'Declining the offer from %s and proposing a counteroffer.\n',
                (b.name, ))
            b.write_('%s declines your offer and proposes a counteroffer.\n',
                     (a.name, ))
            o.decline(notify=False)

        o = next((o for o in a_sent if o.name == self.name and o.b == b), None)
        if o:
            a.write_('Updating the offer already made to %s.\n', (b.name, ))
            b.write_('%s updates the offer.\n', (a.name, ))
            a_sent.remove(o)
            b_received.remove(o)

        self._register()

        a.write_nowrap('Issuing: %s.\n' % challenge_str)
        b.write_nowrap('Challenge: %s.\n' % challenge_str)
        if a.has_title('abuser'):
            b.write_('--** %s is an abuser **--\n', (a.name, ))
        if b.has_title('abuser'):
            a.write_('--** %s is an abuser **--\n', (b.name, ))
        if a.has_title('computer'):
            b.write_('--** %s is a computer **--\n', (a.name, ))
        if b.has_title('computer'):
            a.write_('--** %s is a computer **--\n', (b.name, ))
        b.write_(
            'You can "accept", "decline", or propose different parameters.\n')
        self.pendinfo('match', challenge_str)
Esempio n. 14
0
    def _parse_args_common(self, args, u):
        """ Do the parsing of a match string that is common to both match
        commands and seek commands. Raises MatchError on invalid syntax
        or disallowed combinations of options. """
        self.variant_name = None
        self.clock_name = None

        self.time = None
        self.inc = None
        self.rated = None
        self.side = None  # the side requested, if any
        self.idn = None
        # seeks only
        self.manual = None
        self.formula = None

        if args is None:
            words = []
        else:
            assert (args == args.lower())
            words = re.split(r'\s+', args)

        times = []
        for w in words:
            if w in shortcuts:
                w = shortcuts[w]

            try:
                times.append(int(w))
                continue
            except ValueError:
                pass

            if w == 'unrated':
                self._set_rated(False)
            elif w == 'rated':
                self._set_rated(True)
            elif w == 'white':
                self._set_side(WHITE)
            elif w == 'black':
                self._set_side(BLACK)

            elif w == 'manual':
                self._set_manual(True)
            elif w == 'auto':
                self._set_manual(False)
            elif w == 'formula':
                self._set_formula(True)
            # currently there no way to explicitly specify the default of
            # no formula

            elif w in speed_variant.variant_names:
                self._set_variant_name(w)

            elif w in clock.clock_names:
                self._set_clock_name(w)

            else:
                m = re.match(self._idn_re, w)
                if m:
                    # TODO: self._set_idn
                    if self.idn is not None:
                        raise parser.BadCommandError
                    self.idn = int(m.group(1))
                    if self.idn < -1 or self.idn > 959:
                        raise MatchError(
                            _('An idn must be between 0 and 959.\n'))
                    continue

                m = re.match(self._plus_re, w)
                if m:
                    self._set_time(int(m.group(1)))
                    self._set_inc(int(m.group(2)))
                    continue

                m = re.match(self._overtime_re, w)
                if m:
                    self._set_clock_name('overtime')
                    # e.g. 40/90,sd/30+30
                    self.overtime_move_num = int(m.group(1))
                    self._set_time(int(m.group(2)))
                    self.overtime_bonus = int(int(m.group(3)))
                    if m.group(4) is not None:
                        self._set_inc(int(m.group(4)))
                    else:
                        self._set_inc(0)
                    continue

                #print('got unknown keyword "%s"' % w)
                raise parser.BadCommandError

        if len(times) > 2:
            # time odds not supported
            raise parser.BadCommandError
        elif len(times) == 2:
            self._set_time(times[0])
            self._set_inc(times[1])
        elif len(times) == 1:
            self._set_time(times[0])

        # validate the match parameters
        if self.rated and self.clock_name in ['hourglass', 'untimed']:
            raise MatchError(
                _('This clock type cannot be used in rated games.\n'))

        if self.clock_name == 'untimed':
            if self.time != 0:
                self._set_time(0)
            if self.inc != 0:
                self._set_inc(0)

        if self.inc is None:
            if self.time is None:
                # use user-defined defaults
                self.time = u.vars_['time']
                self.inc = u.vars_['inc']
            else:
                # original FICS set the increment to 0 when only an
                # initial time is given
                self.inc = 0

        if self.clock_name == 'bronstein' and not self.inc:
            raise MatchError(
                _('Games using a Bronstein clock must have an increment.\n'))
        if self.clock_name == 'hourglass' and self.inc:
            raise MatchError(
                _('Games using an hourglass clock may not have an increment.\n'
                  ))
        if self.clock_name == 'overtime':
            if self.time < 1:
                raise MatchError(
                    _('Games using an overtime clock must have a positive initial time.\n'
                      ))
            if self.overtime_bonus < 1:
                raise MatchError(
                    _('Games using an overtime clock must have a positive overtime bonus.\n'
                      ))
            # I would make the limit higher, but the test depends on it
            # being low....
            if self.overtime_move_num < 3:
                raise MatchError(
                    _('Invalid number of moves before overtime bonus.\n'))

        if self.time == 0 and self.inc == 0:
            if self.clock_name != 'untimed':
                self._set_clock_name('untimed')

        # defaults
        if self.variant_name is None:
            self.variant_name = 'chess'

        if self.clock_name is None:
            self.clock_name = 'fischer'

        if self.idn is not None and (self.variant_name != 'chess960'
                                     or self.rated):
            raise MatchError(
                _('You may only specify an idn for unrated chess960 games.\n'))

        if self.clock_name == 'untimed':
            self.speed_name = 'untimed'
        else:
            expected_duration = self.time + self.inc * float(2) / 3
            if self.clock_name == 'overtime':
                expected_duration += self.overtime_bonus
            elif self.clock_name == 'hourglass':
                # ???
                expected_duration *= 3
            assert (expected_duration > 0)
            if expected_duration < 3.0:
                self.speed_name = 'lightning'
            elif expected_duration < 15.0:
                self.speed_name = 'blitz'
            elif expected_duration < 75.0:
                self.speed_name = 'standard'
            else:
                self.speed_name = 'slow'

        self.speed_variant = speed_variant.from_names(self.speed_name,
                                                      self.variant_name)
Esempio n. 15
0
    def __init__(self, a, b, args=None, tags=None):
        """ Initiate a new offer.  "a" is the player issuing the offer;
        "b" receives the request """
        Offer.__init__(self, 'match offer')

        self.a = a
        self.b = b

        if a.is_guest or b.is_guest:
            self.adjourned = None
        else:
            self.adjourned = db.get_adjourned_between(a.id, b.id)
        if self.adjourned:
            if tags or args:
                a.write_('You have an adjourned game with %s.  You cannot start a new game until you finish it.\n', b.name)
                return
            tags = self.adjourned.copy()
            tags.update({
                'side': None
            })
        else:
            if not check_censor_noplay(a, b):
                return

        if tags:
            # copy match parameters
            self.side = tags['side']
            self.rated = tags['rated']
            self.speed_name = tags['speed_name']
            self.variant_name = tags['variant_name']
            self.clock_name = tags['clock_name']
            self.time = tags['time']
            self.inc = tags['inc']
            self.idn = tags['idn']
            self.speed_variant = speed_variant.from_names(self.speed_name,
                self.variant_name)
            self.a_rating = a.get_rating(self.speed_variant)
            self.b_rating = b.get_rating(self.speed_variant)
            # TODO: overtime move number, bonus
        else:
            # get match parameters from a string or use defaults
            try:
                self._check_open()
                self._parse_args(args, a, b)
            except MatchError as e:
                a.write(e[0])
                return

        # look for a matching offer from player b
        o = next((o for o in a.session.offers_received if
            o.name == self.name and o.equivalent_to(self)), None)
        if o:
            # a already received an identical offer, so just accept it
            a.write_("Your challenge intercepts %s's challenge.\n", (o.a.name,))
            b.write_("%s's challenge intercepts your challenge.\n", (a.name,))
            # XXX don't send "Accepting" and "USER accepts" messages?
            o.accept()
            return

        # build the "Challenge:" string
        if self.side is not None:
            side_str = ' [%s]' % game.side_to_str(self.side)
        else:
            side_str = ''

        rated_str = "rated" if self.rated else "unrated"

        if self.clock_name == 'untimed':
            time_str = ''
        else:
            time_str = ' %d %d' % (self.time, self.inc)

        # example: GuestABCD (++++) [white] hans (----) unrated blitz 5 0.
        challenge_str = '%s (%s)%s %s (%s) %s %s%s' % (self.a.name,
            self.a_rating, side_str, self.b.name, self.b_rating, rated_str,
            self.speed_variant, time_str)
        if self.idn is not None:
            challenge_str = '%s idn=%d' % (challenge_str, self.idn)
        if self.clock_name not in ['fischer', 'untimed']:
            challenge_str = '%s %s' % (challenge_str, self.clock_name)
        if self.clock_name == 'overtime':
            challenge_str = '%s %d/%d,SD/%d+%d' % (challenge_str,
                self.overtime_move_num, self.time, self.overtime_bonus,
                self.inc)
        if self.adjourned:
            challenge_str = '%s (adjourned)' % challenge_str
        #if self.board is not None:
        #    challenge_str = 'Loaded from a board'

        a_sent = a.session.offers_sent
        b_sent = b.session.offers_sent
        a_received = a.session.offers_received
        b_received = b.session.offers_received

        if self in a_sent:
            a.write_('You are already offering an identical match to %s.\n',
                (b.name,))
            return

        if not formula.check_formula(self, b.vars['formula']):
            a.write_('Match request does not meet formula for %s:\n', b.name)
            b.write_('Ignoring (formula): %s\n', challenge_str)
            return

        if self.variant_name == 'bughouse':
            # build the challenge string for the other game
            apart = a.session.partner
            bpart = b.session.partner
            challenge_str2 = '%s (%s) %s (%s) %s %s%s' % (apart.name,
                apart.get_rating(self.speed_variant),
                bpart.name, bpart.get_rating(self.speed_variant), rated_str,
                self.speed_variant, time_str)
            if self.idn is not None:
                challenge_str2 = '%s idn=%d' % (challenge_str2, self.idn)
            if self.clock_name not in ['fischer', 'untimed']:
                challenge_str2 = '%s %s' % (challenge_str2, self.clock_name)
            if self.clock_name == 'overtime':
                challenge_str2 = '%s %d/%d,SD/%d+%d' % (challenge_str2,
                    self.overtime_move_num, self.time, self.overtime_bonus,
                    self.inc)
            if self.adjourned:
                challenge_str2 = '%s (adjourned)' % challenge_str2

            # inform the other two players about the challenge
            apart.write_('Your bughouse partner issues: %s\n', challenge_str)
            apart.write_('Your game will be: %s\n', challenge_str2)
            bpart.write_('Your bughouse partner was challenged: %s\n',
                challenge_str)
            bpart.write_('Your game will be: %s\n', challenge_str2)


        o = next((o for o in b_sent if o.name == self.name and
            o.b == a), None)
        if o:
            a.write_('Declining the offer from %s and proposing a counteroffer.\n', (b.name,))
            b.write_('%s declines your offer and proposes a counteroffer.\n', (a.name,))
            o.decline(notify=False)

        o = next((o for o in a_sent if o.name == self.name and
            o.b == b), None)
        if o:
            a.write_('Updating the offer already made to %s.\n', (b.name,))
            b.write_('%s updates the offer.\n', (a.name,))
            a_sent.remove(o)
            b_received.remove(o)

        self._register()

        a.write_nowrap('Issuing: %s.\n' % challenge_str)
        b.write_nowrap('Challenge: %s.\n' % challenge_str)
        if a.has_title('abuser'):
            b.write_('--** %s is an abuser **--\n', (a.name,))
        if b.has_title('abuser'):
            a.write_('--** %s is an abuser **--\n', (b.name,))
        if a.has_title('computer'):
            b.write_('--** %s is a computer **--\n', (a.name,))
        if b.has_title('computer'):
            a.write_('--** %s is a computer **--\n', (b.name,))
        b.write_('You can "accept", "decline", or propose different parameters.\n')
Esempio n. 16
0
    def _parse_args_common(self, args, u):
        """ Do the parsing of a match string that is common to both match
        commands and seek commands. Raises MatchError on invalid syntax
        or disallowed combinations of options. """
        self.variant_name = None
        self.clock_name = None

        self.time = None
        self.inc = None
        self.rated = None
        self.side = None # the side requested, if any
        self.idn = None
        # seeks only
        self.manual = None
        self.formula = None

        if args is None:
            words = []
        else:
            assert(args == args.lower())
            words = re.split(r'\s+', args)

        times = []
        for w in words:
            if w in shortcuts:
                w = shortcuts[w]

            try:
                times.append(int(w))
                continue
            except ValueError:
                pass

            if w == 'unrated':
                self._set_rated(False)
            elif w == 'rated':
                self._set_rated(True)
            elif w == 'white':
                self._set_side(WHITE)
            elif w == 'black':
                self._set_side(BLACK)

            elif w == 'manual':
                self._set_manual(True)
            elif w == 'auto':
                self._set_manual(False)
            elif w == 'formula':
                self._set_formula(True)
            # currently there no way to explicitly specify the default of
            # no formula

            elif w in speed_variant.variant_names:
                self._set_variant_name(w)

            elif w in clock.clock_names:
                self._set_clock_name(w)

            else:
                m = re.match(self._idn_re, w)
                if m:
                    # TODO: self._set_idn
                    if self.idn is not None:
                        raise command_parser.BadCommandError
                    self.idn = int(m.group(1))
                    if self.idn < -1 or self.idn > 959:
                        raise MatchError(_('An idn must be between 0 and 959.\n'))
                    continue

                m = re.match(self._plus_re, w)
                if m:
                    self._set_time(int(m.group(1)))
                    self._set_inc(int(m.group(2)))
                    continue

                m = re.match(self._overtime_re, w)
                if m:
                    self._set_clock_name('overtime')
                    # e.g. 40/90,sd/30+30
                    self.overtime_move_num = int(m.group(1))
                    self._set_time(int(m.group(2)))
                    self.overtime_bonus = int(int(m.group(3)))
                    if m.group(4) is not None:
                        self._set_inc(int(m.group(4)))
                    else:
                        self._set_inc(0)
                    continue

                #print('got unknown keyword "%s"' % w)
                raise command_parser.BadCommandError

        if len(times) > 2:
            # time odds not supported
            raise command_parser.BadCommandError
        elif len(times) == 2:
            self._set_time(times[0])
            self._set_inc(times[1])
        elif len(times) == 1:
            self._set_time(times[0])

        # validate the match parameters
        if self.rated and self.clock_name in ['hourglass', 'untimed']:
            raise MatchError(_('This clock type cannot be used in rated games.\n'))

        if self.clock_name == 'untimed':
            if self.time != 0:
                self._set_time(0)
            if self.inc != 0:
                self._set_inc(0)

        if self.inc is None:
            if self.time is None:
                # use user-defined defaults
                self.time = u.vars['time']
                self.inc = u.vars['inc']
            else:
                # original FICS set the increment to 0 when only an
                # initial time is given
                self.inc = 0

        if self.clock_name == 'bronstein' and not self.inc:
            raise MatchError(_('Games using a Bronstein clock must have an increment.\n'))
        if self.clock_name == 'hourglass' and self.inc:
            raise MatchError(_('Games using an hourglass clock may not have an increment.\n'))
        if self.clock_name == 'overtime':
            if self.time < 1:
                raise MatchError(_('Games using an overtime clock must have a positive initial time.\n'))
            if self.overtime_bonus < 1:
                raise MatchError(_('Games using an overtime clock must have a positive overtime bonus.\n'))
            # I would make the limit higher, but the test depends on it
            # being low....
            if self.overtime_move_num < 3:
                raise MatchError(_('Invalid number of moves before overtime bonus.\n'))

        if self.time == 0 and self.inc == 0:
            if self.clock_name != 'untimed':
                self._set_clock_name('untimed')

        # defaults
        if self.variant_name is None:
            self.variant_name = 'chess'

        if self.clock_name is None:
            self.clock_name = 'fischer'

        if self.idn is not None and (self.variant_name != 'chess960'
                or self.rated):
            raise MatchError(_('You may only specify an idn for unrated chess960 games.\n'))

        if self.clock_name == 'untimed':
            self.speed_name = 'untimed'
        else:
            expected_duration = self.time + self.inc * float(2) / 3
            if self.clock_name == 'overtime':
                expected_duration += self.overtime_bonus
            elif self.clock_name == 'hourglass':
                # ???
                expected_duration *= 3
            assert(expected_duration > 0)
            if expected_duration < 3.0:
                self.speed_name = 'lightning'
            elif expected_duration < 15.0:
                self.speed_name = 'blitz'
            elif expected_duration < 75.0:
                self.speed_name = 'standard'
            else:
                self.speed_name = 'slow'

        self.speed_variant = speed_variant.from_names(self.speed_name,
            self.variant_name)