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})
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()
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)
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 })
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()
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})
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)
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)
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'])
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)))
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')
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')
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)
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)
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')
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)