def __init__(self): Race.__init__(self) self.intelligence = 1 self.charisma = 2 self.languages = ['Common', 'Infernal'] self.features = ['Darkvision', 'Hellish Resistance', 'Infernal Legacy'] self.cantrips = ['Thaumaturgy']
def main(): """The main entry point for the turtle game""" race_meet = RaceMeet() print("Race name: {}".format(race_meet.name)) print("Race length: {} metres".format(race_meet.length)) print("Number of competitors: {}\n".format( race_meet.number_of_competitors)) competitors = generate_competitor_list(race_meet.number_of_competitors) race = Race() competitor_times = {} for i in range(0, len(competitors)): try: total_time_for_competitor = (race.get_total_time_for_turtle( competitors[i].speed, competitors[i].stamina, race_meet.length)) except TurtleHasNoEnergyError: print(("Competitor {}: {} didn't have the energy to complete the " "race...").format(i + 1, competitors[i].name)) continue competitor_times[competitors[i].name] = total_time_for_competitor print(("Competitor {}: " "{} ran the race in {} seconds").format( i + 1, competitors[i].name, total_time_for_competitor))
class Character: ''' This class should hold information about each character made using the generator ''' def __init__(self, name_in): self.name = name_in self.stats = { "str": 0, "dex": 0, "con": 0, "wis": 0, "int": 0, "cha": 0 } self.species = Race() print("Creating character: ", self.name) def roll_stats(self): '''Function to generate random stats''' keys = list(self.stats) for i in range(6): # Roll 4d6, drop the lowest dice = [] for j in range(4): dice.append(random.randint(1, 6)) dice.remove(min(dice)) self.stats[keys[i]] = sum(dice) print("Random Stats = ", self.stats) def generate(self): ''' Function to generate a full character ''' self.roll_stats() self.species.generate()
def start(self, champ_name, champ_races): championship = Championship(champ_name, int(champ_races)) race = Race(self.__drivers(), round(random.uniform(1.00, 1.60), 2)) print(championship) print(race) print(championship.start(race.start_race())) self.__store_results(championship.total)
def __init__(self): with open("conf/filepaths.yaml") as filepath_config: self.conf = yaml.safe_load(filepath_config) self.sheet_stuff = utils.load_json(self.conf["CHARACTER_STATS_PATH"]) self.all_items = utils.load_json(self.conf["ITEM_PATH"]) self.clss = PlayerClass( self.sheet_stuff["saving_throws"], utils.load_json(self.conf["ITEM_PATH"]), *utils.select_random_from_json(self.conf["PLAYER_CLASS_PATH"]), ) self.stats = sheet_maths.generate_stats() self.race = Race( *utils.select_random_from_json(self.conf["RACES_PATH"])) self.finalise_stats() self.mods = sheet_maths.generate_mods(self.stats) self.saves = sheet_maths.generate_saves(self.mods, self.clss.saves, self.clss.proficiency_bonus) self.weapons = self.finalise_weapons() self.bg = Background( *utils.select_random_from_json(self.conf["BACKGROUND_PATH"])) self.final_languages = self.select_languages() self.final_profs = self.select_profs() self.final_skills = self.select_skills() self.ac = self.finalise_ac() if "Perception" in self.final_skills: self.pp = self.mods["WISmod"] + self.clss.proficiency_bonus + 10 else: self.pp = self.mods["WISmod"] + 10
def begin_new_race(self): self.cancelling_racers = [] self.before_races = False self.race = Race(self, RaceRoom.get_new_raceinfo()) yield from self.race.initialize() self.recorded_race = False for racer in self.match.racers: racer_as_member = self._cm.necrobot.find_member_with_id(racer.discord_id) if racer_as_member: yield from self.race.enter_racer(racer_as_member) else: yield from self.write('Error: Couldn\'t find the racer {0}. Please contact CoNDOR Staff (`.staff`).'.format(racer.escaped_twitch_name)) yield from self.update_leaderboard() race_number = int(self._cm.condordb.number_of_finished_races(self.match) + 1) race_str = '{}th'.format(race_number) if race_number == int(1): race_str = 'first' elif race_number == int(2): race_str = 'second' elif race_number == int(3): race_str = 'third' yield from self.write('Please input the seed ({1}) and type `.ready` when you are ready for the {0} race. '\ 'When both racers `.ready`, the race will begin.'.format(race_str, self.race.race_info.seed))
def __init__(self, name): self.name = name self.class_name = self.chooseClass() self.race = Race() self.rolls = [] self.scores = { 'Strength': 0, 'Dexterity': 0, 'Constitution': 0, 'Intelligence': 0, 'Wisdom': 0, 'Charisma': 0, } self.rollStats() self.assignScores() self.modifiers = { 'Strength': 0, 'Dexterity': 0, 'Constitution': 0, 'Intelligence': 0, 'Wisdom': 0, 'Charisma': 0, } self.getMods() self.printStats()
def __init__(self, ancestry): Race.__init__(self) self.strength = 2 self.charisma = 1 self.languages = ['Common', 'Draconic'] self.features = [ 'Draconic Ancestry: ' + ancestry, 'Breath Weapon', 'Damage Resistance(' + ancestry + ')' ]
def __init__(self): Race.__init__(self) self.strength = 2 self.constitution = 1 self.languages = ['Common', 'Orc'] self.features = [ 'Darkvision', 'Relentless Endurance', 'Savage Attacks' ] self.proficiencies = ['Intimidation']
def __init__(self, language): Race.__init__(self) self.strength = 1 self.dexterity = 1 self.constitution = 1 self.intelligence = 1 self.wisdom = 1 self.charisma = 1 self.languages = ['Common', language]
def testRaceStartingNow(self): # create a race race = Race(name='Brass Monkey Race 2 Large Handicap') # set it's start time to be in three minutes race.startTime = datetime.datetime.now() + datetime.timedelta(seconds = START_SECONDS-1) # check that it's running but not started self.assertTrue(race.isRunning()) self.assertFalse(race.isStarted()) # check its status self.assertEqual(race.status(),"Starting")
def __init__(self, subrace): Race.__init__(self) self.intelligence = 2 self.speed = 25 self.languages = ['Common', 'Gnomish'] self.features = ['Darkvision', 'Gnome Cunning'] self.subrace = subrace if self.subrace == 'Forest Gnome': self._forest_gnome() if self.subrace == 'Rock Gnome': self._rock_gnome()
def test_TheOneWhoDNFsStandsLower(self): participant1 = 7 participant2 = 9 sut = Race(laps=3, bibs=[participant1, participant2]) sut.start('12:00:00') sut.split(participant2, '12:10:00') sut.split(participant1, '12:12:00') sut.split(participant2, '12:15:00') sut.dnf(participant2) standings = [result.bib for result in sut.results] self.assertSequenceEqual([participant1, participant2], standings)
def test_DoesNotAcceptDnfIfBibHasAlreadyFinished(self): some_participant = 7 sut = Race(laps=3, bibs=[some_participant]) sut.start('12:00:00') sut.split(some_participant, '12:10:10') sut.split(some_participant, '12:15:20') sut.split(some_participant, '12:20:00') with self.assertRaises(BibHasAlreadyFinished): sut.dnf(some_participant)
def setUp(self): self.driver1 = Driver('Ivo', Car('Opel', 'Astra', 240)) self.driver2 = Driver('Rado', Car('Peugeot', '107', 180)) self.driver3 = Driver('Slavqna', Car('Opel', 'Meriva', 300)) self.driver4 = Driver('Pavlin', Car('AUDI', 'R8', 380)) self.driver5 = Driver('Roni', Car('Golf', '5', 200)) self.driver6 = Driver('Ceco', Car('AUDI', 'Q5', 310)) self.race = Race([ self.driver1, self.driver2, self.driver3, self.driver4, self.driver5, self.driver6 ], 0.2)
def __init__(self, r, headings, filename): super().__init__(r, len(headings)) self.onFocusGainedText = "" self.headings = headings self.setColumnWidth(0, 70) self.setColumnWidth(1, 200) self.setColumnWidth(2, 200) self.setColumnWidth(3, 200) self.setColumnWidth(4, 70) self.setColumnWidth(5, 70) self.setColumnWidth(6, 70) self.setHorizontalHeaderLabels(headings) self.check_change = True self.cellChanged.connect(self.c_current) QEsFile = r"2020_Feb_QE.txt" handicapsFile = r"2020.csv" self.filename = filename handicaps = [] self.PYdict = {} self.dinghyLst = [] self.cols = dict() for h in headings: self.cols[h] = [] for line in open(handicapsFile, "r").readlines(): tokens = line.split(",") if tokens[0] != "" and len(tokens) > 3: self.dinghyLst.append(tokens[0]) handicaps.append(tokens[0] + "," + tokens[1] + "," + tokens[2]) self.PYdict[tokens[0]] = int(tokens[1]) QEs = [] for line in open(QEsFile, "r").readlines(): QEs.append(QE(line, self.PYdict)) self.race = Race([], QEs) self.race.handicaps = handicaps self.completerLsts = {"QE": [], "Class": [], "Code": []} for qe in QEs: self.completerLsts["QE"].append(qe.QE) for c in self.PYdict.keys(): self.completerLsts["Class"].append(c) self.completerLsts["Code"] = ["DNF", "OCS", "DNC"] self.completers = dict() for k in self.completerLsts.keys(): self.completers[k] = QCompleter(self.completerLsts[k]) self.completers[k].setCaseSensitivity(QtCore.Qt.CaseInsensitive) people = set() for Q in QEs: people.add(Q.helm) people.add(Q.crew) self.peopleLst = list(people) self.show()
def __init__(self, subrace): Race.__init__(self) self.dexterity = 2 self.speed = 25 self.languages = ['Common', 'Halfling'] self.features = ['Lucky', 'Brave', 'Halfling Nimbleness'] self.subrace = subrace if self.subrace is 'Lightfoot Halfling': self._lightfoot() if self.subrace is 'Stout Halfling': self._stout()
def __init__(self, hardware, *args, **kwargs): self.lock = threading.Lock() self.on_update = None self.hardware = hardware Race.__init__(self, [1, 1]) threading.Thread.__init__(self) self._stop = False self.start()
def testDeltaToStartTime(self): # create a race race = Race(name='Brass Monkey Race 2 Large Handicap') # set it's start time to be in ten minutes race.startTime = datetime.datetime.now() + datetime.timedelta(minutes = -10) # test that the delta is ten minutes # note this may fail if the clock moves on during execution self.assertEqual(race.deltaToStartTime(), datetime.datetime.now() - race.startTime)
def test_LappedRiderRidesLess(self): leader = 7 lapped = 9 sut = Race(laps=3, bibs=[leader, lapped]) sut.start('12:00:00') sut.split(leader, '12:05:00') sut.split(leader, '12:10:00') sut.split(lapped, '12:10:00') sut.split(leader, '12:15:00') sut.split(lapped, '12:20:00') lapped_state = sut.results[1].state self.assertEqual(ParticipantState.FINISHED, lapped_state)
def __init__(self, name_in): self.name = name_in self.stats = { "str": 0, "dex": 0, "con": 0, "wis": 0, "int": 0, "cha": 0 } self.species = Race() print("Creating character: ", self.name)
def test_DoesNotAcceptSplitIfBibHasAlreadyFinished(self): some_participant = 7 sut = Race(laps=3, bibs=[some_participant]) sut.start('12:00:00') sut.split(some_participant, '12:10:10') sut.split(some_participant, '12:15:20') sut.split(some_participant, '12:20:00') with self.assertRaises(BibHasAlreadyFinished): excessive_split = '12:25:00' sut.split(some_participant, excessive_split)
async def open(self, ctx, start_time_str): """ usage: !kiite open TIMESTRING TIMESTRING: A string indicates a start time of the race. The string must be following the format "hh:mm" or "yyyy/mm/dd hh:mm". """ start_time = self.__parse_timestamp(start_time_str) race = Race(ctx.message.id, ctx.channel.id, start_time) self.races[race.hash()] = race await ctx.channel.send(race.template())
def __init__(self, subrace, cantrip=None, language=None): Race.__init__(self) self.dexterity = 2 self.languages = ['Common', 'Elvish'] self.features = ['Darkvision', 'Fey Ancestry', 'Trance'] self.subrace = subrace self.proficiencies = ['Perception'] if self.subrace == 'High Elf': self._high_elf(cantrip, language) if self.subrace == 'Wood Elf': self._wood_elf() if self.subrace == 'Dark Elf (Drow)': self._dark_elf()
def __init__(self, player): self.races = {} self.races["Elders"] = Race("Elders", None, "E", colorama.Fore.LIGHTWHITE_EX) self.races["Humans"] = Race("Human", None, "H", colorama.Fore.WHITE) self.races["Rindhalu"] = Race("Rindhalu", None, "R", colorama.Fore.GREEN) self.races["Jeraptha"] = Race("Jeraptha", self.races["Rindhalu"], "J", colorama.Fore.BLUE) self.races["Ruhar"] = Race("Ruhar", self.races["Jeraptha"], "R", colorama.Fore.LIGHTCYAN_EX) self.races["Maxolhx"] = Race("Maxolhx", None, "M", colorama.Fore.LIGHTMAGENTA_EX) self.races["Thuranin"] = Race("Thuranin", self.races["Maxolhx"], "T", colorama.Fore.MAGENTA) self.races["Kristang"] = Race("Kristang", self.races["Thuranin"], "K", colorama.Fore.YELLOW) self.races["Bosphuraq"] = Race("Bosphuraq", self.races["Maxolhx"], "B", colorama.Fore.RED) self.races["Wurgalan"] = Race("Wurgalan", self.races["Bosphuraq"], "W", colorama.Fore.LIGHTYELLOW_EX) self.news = {} self.news["global"] = [] self._star_names = StarNamesStack() self.stars = [] for n in range(len(self._star_names.names)): star = Star(random.randrange(config.world_width), random.randrange(config.world_height), self._star_names.pop(), self.get_random_owner_race()) self.stars.append(star) self.news[star.name] = [] self._scatter_stars() self._scatter_stars() sol = Sol(self, player.world_x, player.world_y) self.stars.append(sol) player.star = sol for b in sol.bodies: if b.name == 'Planet Earth (Medium Terran)': player.system_x = b.body_x player.system_y = b.body_y player.body = b break self.fleets = [] self.spawn_fleets() self.spawn_investigator_fleet()
def testDeltaToStartTimeException(self): # create a race race = Race(name='Brass Monkey Race 2 Large Handicap') # check that we get an exception if we ask for a start time try: delta = race.deltaToStartTime() except RaceException: pass except: e = sys.exc_info()[0] self.fail('Unexpected exception thrown:',e) else: self.fail('RaceException not thrown')
def __init__(self, subrace, tool): Race.__init__(self) self.constitution = 2 self.speed = 25 self.languages = ['Common', 'Dwarvish'] self.features = ['Darkvision', 'Dwarven Resillience', 'Stone Cunning'] self.other = [ 'Battleaxe', 'Handaxe', 'Throwing Hammer', 'Warhammer', tool ] self.subrace = subrace if self.subrace == 'Hill Dwarf': self._hill_dwarf() if self.subrace == 'Mountain Dwarf': self._mountain_dwarf()
def __init__(self, name): super().__init__(name) self.name = name self.race = Race() self.scores = { 'Strength': 0, 'Dexterity': 0, 'Constitution': 0, 'Intelligence': 0, 'Wisdom': 0, 'Charisma': 0, } self.scores['Strength'] = self.getRoll() self.scores['Dexterity'] = self.getRoll() self.scores['Constitution'] = self.getRoll() self.scores['Intelligence'] = self.getRoll() self.scores['Wisdom'] = self.getRoll() self.scores['Charisma'] = self.getRoll() self.getClass() self.modifiers = { 'Strength': 0, 'Dexterity': 0, 'Constitution': 0, 'Intelligence': 0, 'Wisdom': 0, 'Charisma': 0, } self.getMods()
def get_race(self, key): with dbapi2.connect(self.app.config['dsn']) as connection: cursor = connection.cursor() query = "SELECT TITLE, RACE_TYPE, FOUNDERID, PARTICIPANT_COUNT, TIME, CYCROUTEID FROM RACE WHERE (ID = %s)" cursor.execute(query, (key,)) title, race_type, founder, participant_count, time, place = cursor.fetchone() return Race(title, race_type, founder, participant_count, time, place)
def begin_new_race(self): self.cancelling_racers = [] self.before_races = False self.race = Race(self, RaceRoom.get_new_raceinfo(), self._cm.condordb) yield from self.race.initialize() self.recorded_race = False for racer in self.match.racers: racer_as_member = self._cm.necrobot.find_member_with_id(racer.discord_id) if racer_as_member: yield from self.race.enter_racer(racer_as_member) else: yield from self.write('Error: Couldn\'t find the racer {0}. Please contact CoNDOR Staff (`.staff`).'.format(racer.escaped_twitch_name)) yield from self.update_leaderboard() race_number = int(self._cm.condordb.number_of_finished_races(self.match) + 1) race_str = '{}th'.format(race_number) if race_number == int(1): race_str = 'first' elif race_number == int(2): race_str = 'second' elif race_number == int(3): race_str = 'third' yield from self.write('Please input the seed ({1}) and type `.ready` when you are ready for the {0} race. '\ 'When both racers `.ready`, the race will begin.'.format(race_str, self.race.race_info.seed))
def load_track(self, dt, *args, **kwargs): if not self.images_loaded: self.track.load_images() self.label.text = self.text + '5%' self.total = len(self.track.partition_list) self.images_loaded = True elif not self.overlay_loaded: self.track.load_overlay() self.label.text = self.text + '25%' self.overlay_loaded = True else: partitions_left = self.track.load_partitions() percent = 25 + int( ((self.total - partitions_left) * 1.0 / self.total) * 75) self.label.text = self.text + str(percent) + '%' if partitions_left == 0: # load the music last self.track.load_music() # hack to prevent circular imports from race import Race race = Race(self.track, [ state.profile.car, ComputerCar.get_default(), ComputerCar.get_default() ]) director.replace(race)
def start(self, championship_name): print('Starting a new championship called {} with {} races.'.format( self.name, self.races_count)) print('Running {} races...'.format(self.races_count)) print('') for i in range(self.races_count): crash_chance = randint(0, 100) / 100.0 r = Race(self.load_drivers(), crash_chance) print('Race #{}'.format(i + 1)) r.start(championship_name, i + 1) print('') with open('result.json', 'r') as f: data = json.load(f) Championship.total_ranking(data, self.name)
def make_rematch(self): if not self._rematch_made: yield from self.race.record() new_race_info = self.race.race_info.copy() self.race = Race(self, new_race_info) asyncio.ensure_future(self.race.initialize()) self._rematch_made = True yield from self.write('Rematch created!')
def get_races(self): with dbapi2.connect(self.app.config['dsn']) as connection: cursor = connection.cursor() query = "SELECT * FROM RACE ORDER BY ID" cursor.execute(query) races = [(key, Race(title, race_type, founder, participant_count, time, place)) for key, title, race_type, founder, participant_count, time, place in cursor] return races
def test_TheOneWhoRidesMoreLapsStandsHigher_2(self): participant1 = 7 participant2 = 9 sut = Race(laps=3, bibs=[participant1, participant2]) sut.start('12:00:00') sut.split(participant2, '12:14:00') sut.split(participant1, '12:15:00') sut.split(participant1, '12:20:00') standings = [result.bib for result in sut.results] self.assertSequenceEqual([participant1, participant2], standings)
def test_OrderOfSplitsMatters(self): some_participant = 7 other_participant = 9 sut = Race(laps=3, bibs=[some_participant, other_participant]) sut.start('12:00:00') shuffled_splits = ['12:15:20', '12:10:10'] sut.split(some_participant, shuffled_splits[0]) with self.assertRaises(SplitsAreOutOfOrder): sut.split(other_participant, shuffled_splits[1])
def __init__(self, race_module, race_channel, race_info): self.channel = race_channel #The channel in which this race is taking place self.creator = None #Can store a user that created this room. Not used internally. self.is_closed = False #True if room has been closed self.race = Race(self, race_info) #The current race self.admin_ready = True self._rm = race_module self._rematch_made = False #True once a rematch of this has been made (prevents duplicates) self._mention_on_rematch = [] #A list of users that should be @mentioned when a rematch is created self.mentioned_users = [] #A list of users that were @mentioned when this race started self._nopoke = False self.command_types = [command.DefaultHelp(self), Enter(self), Unenter(self), Ready(self), Unready(self), Done(self), Undone(self), Forfeit(self), Unforfeit(self), Comment(self), Death(self), Igt(self), Rematch(self), DelayRecord(self), Notify(self), Time(self), Missing(self), Shame(self), Poke(self), ForceCancel(self), ForceClose(self), ForceForfeit(self), ForceForfeitAll(self), ForceRecord(self), Kick(self)]
from horse import Horse from race import Race name_horse1 = input("Nombre del primer caballo: ") name_horse2 = input("Nombre del segundo caballo: ") horse1 = Horse(name_horse1) horse2 = Horse(name_horse2) race = Race(horse1, horse2) race.start()
def test_race(self): slug = Slug("Mickey") race = Race() race.slugs.append(slug) winner = race.do_race() self.assertTrue(winner is not None)
class TestRace(unittest.TestCase): def setUp(self): self.test_race = Race('Dwarf') self.expected_effect = Effect() self.expected_description = 'Dwarves are a hearty breed, and make excellent warriors due to their high strength and toughness.' def tearDown(self): self.test_race = None self.expected_effect = None self.expected_description = None def test_total_hp(self): self.assertEqual(0, self.test_race.total_hp()) def test_total_strength(self): self.assertEqual(5, self.test_race.total_strength()) def test_total_intelligence(self): self.assertEqual(0, self.test_race.total_intelligence()) def test_total_agility(self): self.assertEqual(0, self.test_race.total_agility()) def test_total_attack(self): self.assertEqual(Damage(0,0), self.test_race.total_attack()) def test_total_defense(self): self.assertEqual(Damage(20,30), self.test_race.total_defense()) def test_valid_name(self): self.assertFalse(self.test_race.valid_name('INVALID')) def test_valid_name2(self): self.assertTrue(self.test_race.valid_name('DWARF')) def test_valid_name3(self): self.assertTrue(self.test_race.valid_name('dwarf')) def test_race_effect(self): self.assertEqual(self.expected_effect, self.test_race.race_effect("Dwarf")) def test_race_description(self): self.assertEqual(self.expected_description, self.test_race.race_description("Dwarf")) def test_race_description2(self): self.assertEqual(self.expected_description, self.test_race.race_description("dwarf")) def test_race_description3(self): self.assertEqual(self.expected_description, self.test_race.race_description("DWARF"))
def resilience_defense(self): """docstring for resilience_defense""" return 10 + self.ability.bonus(self.ability.constitution) #+ misc def movemnet_speed(self): """docstring for movemnet_speed""" return 5 + self.ability.modifier(self.ability.dexterity) #+ misc if __name__ == '__main__': from level import Level from ability import Ability from class_ import Class from race import Race level = Level() race = Race() ability = Ability(level) ability.generate() ability.wisdom = 22 class_ = Class() statistics = Statistics(ability, level, class_) def yell(): """docstring for debug""" print "hp:%s ap:%s mb:%s rb:%s mab:%s ad:%s ed:%s md:%s rd:%s spd:%s at level: %s" % ( statistics.max_health_points(), statistics.max_anima_points(), statistics.melee_bonus(), statistics.ranged_bonus(), statistics.magic_bonus(), statistics.armor_defense(10), statistics.evasion_defense(),
def setUp(self): self.test_race = Race('Dwarf') self.expected_effect = Effect() self.expected_description = 'Dwarves are a hearty breed, and make excellent warriors due to their high strength and toughness.'
class RacePrivateRoom(raceroom.RaceRoom): def __init__(self, race_module, race_channel, race_private_info): raceroom.RaceRoom.__init__(self, race_module, race_channel, race_private_info.race_info) self._match_info = race_private_info.match_info self.permission_info = permissioninfo.get_permission_info(race_module.server, race_private_info) self.command_types = [command.DefaultHelp(self), raceroom.Enter(self), raceroom.Unenter(self), raceroom.Ready(self), raceroom.Unready(self), raceroom.Done(self), raceroom.Undone(self), raceroom.Forfeit(self), raceroom.Unforfeit(self), raceroom.Comment(self), raceroom.Igt(self), raceroom.Death(self), raceroom.Rematch(self), raceroom.DelayRecord(self), raceroom.Notify(self), raceroom.Time(self), raceroom.ForceCancel(self), raceroom.ForceClose(self), raceroom.ForceForfeit(self), raceroom.ForceForfeitAll(self), raceroom.Kick(self), Add(self), Admins(self), Remove(self), ChangeRules(self), MakeAdmin(self), Reseed(self), ForceReset(self), Pause(self), Unpause(self)] @property def infostr(self): return 'Private race' # Sets up the leaderboard for the race # Overrides @asyncio.coroutine def initialize(self): yield from self._set_permissions() yield from raceroom.RaceRoom.initialize(self) # Makes a rematch of this race in this room, if one has not already been made # Overrides @asyncio.coroutine def make_rematch(self): if not self._rematch_made: yield from self.race.record() new_race_info = self.race.race_info.copy() self.race = Race(self, new_race_info) asyncio.ensure_future(self.race.initialize()) self._rematch_made = True yield from self.write('Rematch created!') # Begins the race if ready. (Writes a message if all racers are ready but an admin is not.) # Overrides @asyncio.coroutine def begin_if_ready(self): success = yield from raceroom.RaceRoom.begin_if_ready(self) if success: self._rematch_made = False return success # Find all members with the given username def find_members(self, username): return self._rm.necrobot.find_members(username) # True if the user has admin permissions for this race # Overrides def is_race_admin(self, member): return self.permission_info.is_admin(member) or raceroom.RaceRoom.is_race_admin(self, member) # A string to add to the race details ("Private") # Overrides def format_rider(self): return '(private)' # Allow the member to see the channel @asyncio.coroutine def allow(self, member): read_permit = discord.PermissionOverwrite() read_permit.read_messages = True yield from self.client.edit_channel_permissions(self.channel, member, read_permit) #Restrict the member from seeing the channel @asyncio.coroutine def deny(self, member): read_deny = discord.PermissionOverwrite() read_deny.read_messages = False yield from self.client.edit_channel_permissions(self.channel, member, read_deny) # Make room private to all but admins and racers in permission_info @asyncio.coroutine def _set_permissions(self): read_permit = discord.Permissions.none() read_permit.read_messages = True #deny access to @everyone yield from self.deny(self._rm.server.default_role) #allow access for self yield from self.allow(self._rm.necrobot.get_as_member(self.client.user)) #give admin roles permission for role in self.permission_info.admin_roles: yield from self.allow(role) #give admins permission for member in self.permission_info.admins: yield from self.allow(member) #give racers permission for member in self.permission_info.racers: yield from self.allow(member)
if not sigma: sigma = 1. threshold = float(a) elif o == '-g': ghosts = a.split(',') elif o == '-a': ais = True elif o == '-c': shape = a elif o == '--filter': density = 0.01 sigma = 1. threshold = 5. else: assert False, 'unhandled option' race = Race(n, shape, length, width) for name in ghosts: race.add_ghost(name) if ais: add_ai(race) if density: race.circuit.add_obstacles(density) if threshold or sigma: race.circuit.filter_obstacles(threshold, sigma) # , True) race.run() ask(race) def ask(race): while 1: tmp = raw_input('R for replay, '+ 'M for one more (just one..), '+
class RaceRoom(command.Module): def get_new_raceinfo(): to_return = RaceInfo() to_return.seed_fixed = False to_return.seeded = True to_return.character = 'Cadence' to_return.descriptor = 'Condor Race' to_return.sudden_death = False to_return.flagplant = False to_return.seed = seedgen.get_new_seed() return to_return def __init__(self, condor_module, condor_match, race_channel): self.channel = race_channel #The channel in which this race is taking place self.is_closed = False #True if room has been closed self.match = condor_match self.events = Events() self.race = None #The current race self.recorded_race = False #Whether the current race has been recorded self.entered_racers = [] #Racers that have typed .here in this channel self.before_races = True self.cancelling_racers = [] #Racers that have typed .cancel self._cm = condor_module self.command_types = [command.DefaultHelp(self), Here(self), Ready(self), Unready(self), Done(self), Undone(self), Cancel(self), #Forfeit(self), #Unforfeit(self), #Comment(self), #Igt(self), Time(self), Contest(self), ForceCancel(self), ForceChangeWinner(self), #ForceClose(self), ForceForfeit(self), #ForceForfeitAll(self), ForceRecordRace(self), ForceNewRace(self), ForceCancelRace(self), ForceRecordMatch(self), #Kick(self), ] @property def infostr(self): return 'Race' @property def client(self): return self._cm.necrobot.client @property def necrobot(self): return self._cm.necrobot @property def condordb(self): return self._cm.condordb #True if the user has admin permissions for this race def is_race_admin(self, member): admin_roles = self._cm.necrobot.admin_roles for role in member.roles: if role in admin_roles: return True return False # Set up the leaderboard etc. Should be called after creation; code not put into __init__ b/c coroutine @asyncio.coroutine def initialize(self, users_to_mention=[]): yield from self.update_leaderboard() asyncio.ensure_future(self.countdown_to_match_start()) # Write text to the raceroom. Return a Message for the text written @asyncio.coroutine def write(self, text): return self.client.send_message(self.channel, text) # Write text to the bot_notifications channel. @asyncio.coroutine def alert_staff(self, text): return self.client.send_message(self._cm.necrobot.notifications_channel, text) # Register a racer as wanting to cancel @asyncio.coroutine def wants_to_cancel(self, member): for racer in self.match.racers: if int(racer.discord_id) == int(member.id) and not racer in self.cancelling_racers: self.cancelling_racers.append(racer) if len(self.cancelling_racers) == 2: yield from self.cancel_race() return True else: return False # Cancel the race @asyncio.coroutine def cancel_race(self): if self.race and not self.race.is_before_race: self.cancelling_racers = [] yield from self.race.cancel() yield from self.record_race(cancelled=True) yield from self.write('The current race was cancelled.') else: self.cancelling_racers = [] race_number = int(self._cm.condordb.largest_recorded_race_number(self.match)) if race_number > 0: self.condordb.cancel_race(self.match, race_number) yield from self.write('The previous race was cancelled.'.format(race_number)) yield from self.update_leaderboard() #Updates the leaderboard @asyncio.coroutine def update_leaderboard(self): if self.race or self.match.time_until_match.total_seconds() < 0: topic = '``` \n' topic += 'Necrodancer World Cup Match (Cadence Seeded)\n' max_name_len = 0 for racer in self.match.racers: max_name_len = max(max_name_len, len(racer.discord_name)) for racer in self.match.racers: wins = self._cm.condordb.number_of_wins(self.match, racer, count_draws=True) topic += ' ' + racer.discord_name + (' ' * (max_name_len - len(racer.discord_name))) + ' --- Wins: {0}\n'.format(str(round(wins,1) if wins % 1 else int(wins))) race_number = self._cm.condordb.number_of_finished_races(self.match) + 1 if race_number > config.RACE_NUMBER_OF_RACES: topic += 'Match complete. \n' else: topic += 'Current race: #{}\n'.format(race_number) if self.race: topic += self.race.leaderboard topic += '\n ```' asyncio.ensure_future(self.client.edit_channel(self.channel, topic=topic)) else: topic_str = '``` \n' minutes_until_match = int( (self.match.time_until_match.total_seconds() + 30) // 60 ) topic_str += 'The race is scheduled to begin in {0} minutes! Please let the bot know you\'re here by typing .here. \n\n'.format(minutes_until_match) waiting_str = '' if self.match.racer_1 not in self.entered_racers: waiting_str += self.match.racer_1.twitch_name + ', ' if self.match.racer_2 not in self.entered_racers: waiting_str += self.match.racer_2.twitch_name + ', ' topic_str += 'Still waiting for .here from: {0} \n'.format(waiting_str[:-2]) if waiting_str else 'Both racers are here!\n' topic_str += '```' asyncio.ensure_future(self.client.edit_channel(self.channel, topic=topic_str)) @asyncio.coroutine def alert_racers(self, send_pm=False): member_1 = self._cm.necrobot.find_member_with_id(self.match.racer_1.discord_id) member_2 = self._cm.necrobot.find_member_with_id(self.match.racer_2.discord_id) alert_str = '' if member_1: alert_str += member_1.mention + ', ' if member_2: alert_str += member_2.mention + ', ' minutes_until_match = int( (self.match.time_until_match.total_seconds() + 30) // 60 ) if alert_str: yield from self.write('{0}: The match is scheduled to begin in {1} minutes.'.format(alert_str[:-2], minutes_until_match)) if send_pm: if member_1: yield from self.client.send_message(member_1, '{0}: Your match with {1} is scheduled to begin in {2} minutes.'.format(member_1.mention, self.match.racer_2.escaped_twitch_name, minutes_until_match)) if member_2: yield from self.client.send_message(member_2, '{0}: Your match with {1} is scheduled to begin in {2} minutes.'.format(member_2.mention, self.match.racer_1.escaped_twitch_name, minutes_until_match)) @asyncio.coroutine def countdown_to_match_start(self): time_until_match = self.match.time_until_match asyncio.ensure_future(self.constantly_update_leaderboard()) if time_until_match < datetime.timedelta(seconds=0): if not self.played_all_races: yield from self.write('I believe that I was just restarted; an error may have occurred. I am beginning a new race and attempting to pick up this ' \ 'match where we left off. If this is an error, or if there are unrecorded races, please contact CoNDOR Staff (`.staff`).') yield from self.begin_new_race() else: pm_warning = datetime.timedelta(minutes=30) first_warning = datetime.timedelta(minutes=15) alert_staff_warning = datetime.timedelta(minutes=5) if time_until_match > pm_warning: yield from asyncio.sleep( (time_until_match - pm_warning).total_seconds() ) if not self.race: yield from self.alert_racers(send_pm=True) time_until_match = self.match.time_until_match if time_until_match > first_warning: yield from asyncio.sleep( (time_until_match - first_warning).total_seconds() ) if not self.race: yield from self.alert_racers() time_until_match = self.match.time_until_match if time_until_match > alert_staff_warning: yield from asyncio.sleep( (time_until_match - alert_staff_warning).total_seconds() ) # this is done at the alert_staff_warning, unless this function was called after the alert_staff_warning, in which case do it immediately if not self.race: yield from self.alert_racers() for racer in self.match.racers: if racer not in self.entered_racers: discord_name = '' if racer.discord_name: discord_name = ' (Discord name: {0})'.format(racer.discord_name) minutes_until_race = int( (self.match.time_until_match.total_seconds() + 30) // 60) yield from self.alert_staff('Alert: {0}{1} has not yet shown up for their match, which is scheduled in {2} minutes.'.format(racer.escaped_twitch_name, discord_name, minutes_until_race)) yield from self._cm.post_match_alert(self.match) yield from asyncio.sleep(self.match.time_until_match.total_seconds()) if not self.race: yield from self.begin_new_race() @asyncio.coroutine def constantly_update_leaderboard(self): while self.match.time_until_match.total_seconds() > 0: asyncio.ensure_future(self.update_leaderboard()) yield from asyncio.sleep(30) @asyncio.coroutine def begin_new_race(self): self.cancelling_racers = [] self.before_races = False self.race = Race(self, RaceRoom.get_new_raceinfo(), self._cm.condordb) yield from self.race.initialize() self.recorded_race = False for racer in self.match.racers: racer_as_member = self._cm.necrobot.find_member_with_id(racer.discord_id) if racer_as_member: yield from self.race.enter_racer(racer_as_member) else: yield from self.write('Error: Couldn\'t find the racer {0}. Please contact CoNDOR Staff (`.staff`).'.format(racer.escaped_twitch_name)) yield from self.update_leaderboard() race_number = int(self._cm.condordb.number_of_finished_races(self.match) + 1) race_str = '{}th'.format(race_number) if race_number == int(1): race_str = 'first' elif race_number == int(2): race_str = 'second' elif race_number == int(3): race_str = 'third' yield from self.write('Please input the seed ({1}) and type `.ready` when you are ready for the {0} race. '\ 'When both racers `.ready`, the race will begin.'.format(race_str, self.race.race_info.seed)) # Returns true if all racers are ready @property def all_racers_ready(self): return self.race and self.race.num_not_ready == 0 @property def played_all_races(self): if self.match.is_best_of: return self._cm.condordb.number_of_wins_of_leader(self.match) >= (self.match.number_of_races//2 + 1) else: return self._cm.condordb.number_of_finished_races(self.match) >= self.match.number_of_races @property def race_to_contest(self): if not self.race: return 0 if self.race.is_before_race: return self.race_number - 1 else: return self.race_number # Begins the race if ready. (Writes a message if all racers are ready but an admin is not.) # Returns true on success @asyncio.coroutine def begin_if_ready(self): if self.race and self.all_racers_ready: yield from self.race.begin_race_countdown() return True @asyncio.coroutine def enter_racer(self, member): for racer in self.match.racers: if int(racer.discord_id) == int(member.id): if racer in self.entered_racers: yield from self.write('{0} is already here.'.format(member.mention)) return self.entered_racers.append(racer) yield from self.write('{0} is here for the race.'.format(member.mention)) yield from self.update_leaderboard() return yield from self.write('{0}: I do not recognize you as one of the racers in this match. Contact CoNDOR Staff (`.staff`) if this is in error.'.format(member.mention)) @asyncio.coroutine def record_race(self, cancelled=False): if self.race and self.race.start_time: self.recorded_race = True racer_1_time = -1 racer_2_time = -1 racer_1_finished = False racer_2_finished = False for racer in self.race.racer_list: if int(racer.id) == int(self.match.racer_1.discord_id): if racer.is_finished: racer_1_time = racer.time racer_1_finished = True elif int(racer.id) == int(self.match.racer_2.discord_id): if racer.is_finished: racer_2_time = racer.time racer_2_finished = True winner = 0 if racer_1_finished and not racer_2_finished: winner = 1 elif not racer_1_finished and racer_2_finished: winner = 2 elif racer_1_finished and racer_2_finished: if racer_1_time < racer_2_time: winner = 1 elif racer_2_time < racer_1_time: winner = 2 if abs(racer_1_time - racer_2_time) <= (config.RACE_NOTIFY_IF_TIMES_WITHIN_SEC*100): race_number = self._cm.condordb.number_of_finished_races(self.match) + 1 yield from self.client.send_message(self.necrobot.notifications_channel, 'Race number {0} has finished within {1} seconds in channel {2}. ({3} -- {4}, {5} -- {6})'.format( race_number, config.RACE_NOTIFY_IF_TIMES_WITHIN_SEC, self.channel.mention, self.match.racer_1.escaped_twitch_name, racetime.to_str(racer_1_time), self.match.racer_2.escaped_twitch_name, racetime.to_str(racer_2_time))) self._cm.condordb.record_race(self.match, racer_1_time, racer_2_time, winner, self.race.race_info.seed, self.race.start_time.timestamp(), cancelled) if not cancelled: racer_1_member = self.necrobot.find_member_with_id(self.match.racer_1.discord_id) racer_2_member = self.necrobot.find_member_with_id(self.match.racer_2.discord_id) racer_1_mention = racer_1_member.mention if racer_1_member else '' racer_2_mention = racer_2_member.mention if racer_2_member else '' write_str = '{0}, {1}: The race is over, and has been recorded.'.format(racer_1_mention, racer_2_mention) else: write_str = 'Race cancelled.' yield from self.write(write_str) yield from self.write('If you wish to contest the previous race\'s result, use the `.contest` command. This marks the race as contested; CoNDOR Staff will be alerted, and will ' 'look into your race.') if self.played_all_races: #Send match ending event if all races have been played self.events.matchend(self.match.racer_1.twitch_name, self.match.racer_2.twitch_name) yield from self.record_match() else: yield from self.begin_new_race() @asyncio.coroutine def record_match(self): self._cm.condordb.record_match(self.match) yield from self._cm.condorsheet.record_match(self.match) yield from self.write('Match results recorded.') yield from self.update_leaderboard()
class RaceRoom(command.Module): def __init__(self, race_module, race_channel, race_info): self.channel = race_channel #The channel in which this race is taking place self.creator = None #Can store a user that created this room. Not used internally. self.is_closed = False #True if room has been closed self.race = Race(self, race_info) #The current race self.admin_ready = True self._rm = race_module self._rematch_made = False #True once a rematch of this has been made (prevents duplicates) self._mention_on_rematch = [] #A list of users that should be @mentioned when a rematch is created self.mentioned_users = [] #A list of users that were @mentioned when this race started self._nopoke = False self.command_types = [command.DefaultHelp(self), Enter(self), Unenter(self), Ready(self), Unready(self), Done(self), Undone(self), Forfeit(self), Unforfeit(self), Comment(self), Death(self), Igt(self), Rematch(self), DelayRecord(self), Notify(self), Time(self), Missing(self), Shame(self), Poke(self), ForceCancel(self), ForceClose(self), ForceForfeit(self), ForceForfeitAll(self), ForceRecord(self), Kick(self)] @property def infostr(self): return 'Race' @property def client(self): return self._rm.client # Notifies the given user on a rematch def notify(self, user): if not user in self._mention_on_rematch: self._mention_on_rematch.append(user) # Removes notifications for the given user on rematch def dont_notify(self, user): self._mention_on_rematch = [u for u in self._mention_on_rematch if u != user] # Set up the leaderboard etc. Should be called after creation; code not put into __init__ b/c coroutine @asyncio.coroutine def initialize(self, users_to_mention=[]): asyncio.ensure_future(self.race.initialize()) asyncio.ensure_future(self.client.edit_channel(self.channel, topic=self.race.leaderboard)) asyncio.ensure_future(self._monitor_for_cleanup()) #send @mention message mention_text = '' for user in users_to_mention: mention_text += user.mention + ' ' self.mentioned_users.append(user) if mention_text: asyncio.ensure_future(self.client.send_message(self.channel, 'Alerting users: ' + mention_text)) #put seed in chat if self.race.race_info.seeded: asyncio.ensure_future(self.client.send_message(self.channel, 'The seed for this race is {0}.'.format(self.race.race_info.seed))) # Write text to the raceroom. Return a Message for the text written @asyncio.coroutine def write(self, text): return self.client.send_message(self.channel, text) # A string to add to the race details (used for private races; empty in base class) def format_rider(self): return '' #Updates the leaderboard @asyncio.coroutine def update_leaderboard(self): asyncio.ensure_future(self.client.edit_channel(self.channel, topic=self.race.leaderboard)) # Close the channel. @asyncio.coroutine def close(self): self.is_closed = True yield from self.client.delete_channel(self.channel) # Returns true if all racers are ready @property def all_racers_ready(self): return self.race.num_not_ready == 0 and (not config.REQUIRE_AT_LEAST_TWO_FOR_RACE or len(self.race.racers) > 1) # Begins the race if ready. (Writes a message if all racers are ready but an admin is not.) # Returns true on success @asyncio.coroutine def begin_if_ready(self): if self.all_racers_ready: if self.admin_ready: yield from self.race.begin_race_countdown() return True else: yield from self.write('Waiting on an admin to type `.ready`.') return False # Makes a rematch of this race in a new room, if one has not already been made @asyncio.coroutine def make_rematch(self): if not self._rematch_made: self._rematch_made = True new_race_info = self.race.race_info.copy() new_race_channel = yield from self._rm.make_race(new_race_info, mention=self._mention_on_rematch, suppress_alerts=True) if new_race_channel: yield from self.write('Rematch created in {}!'.format(new_race_channel.mention)) ## yield from self._rm.client.send_message(self._rm.main_channel, 'A new race has been started:\nFormat: {1}\nChannel: {0}'.format(new_race_channel.mention, new_race_info.format_str())) else: self._rematch_made = False #True if the user has admin permissions for this race def is_race_admin(self, member): admin_roles = self._rm.necrobot.admin_roles for role in member.roles: if role in admin_roles: return True return False # Checks to see whether the room should be cleaned. @asyncio.coroutine def _monitor_for_cleanup(self): # Pre-race cleanup loop while not self.is_closed: yield from asyncio.sleep(30) #Wait between check times # Pre-race if self.race.is_before_race: if (not self.race.racers) and self.race.no_entrants_time: #if there are no entrants (and we've stored the last time this was not the case) if time.monotonic() - self.race.no_entrants_time > config.NO_ENTRANTS_CLEANUP_WARNING_SEC: time_remaining = config.NO_ENTRANTS_CLEANUP_SEC - config.NO_ENTRANTS_CLEANUP_WARNING_SEC yield from self.write('Warning: Race has had zero entrants for some time and will be closed in {} seconds.'.format(time_remaining)) yield from asyncio.sleep(time_remaining) if not self.race.racers: yield from self.close() return # Post-race elif self.race.complete: msg_list = yield from self.client.logs_from(self.channel, 1) for msg in msg_list: if (datetime.datetime.utcnow() - msg.timestamp).total_seconds() > config.CLEANUP_TIME_SEC: yield from self.close() return ## TODO: more intelligent result posting @asyncio.coroutine def post_result(self, text): asyncio.ensure_future(self.client.send_message(self._rm.results_channel, text)) # Alerts unready users @asyncio.coroutine def poke(self): if self._nopoke: return ready_racers = [] unready_racers = [] for racer in self.race.racers.values(): if racer.is_ready: ready_racers.append(racer) else: unready_racers.append(racer) num_unready = len(unready_racers) quorum = (num_unready == 1) or (3*num_unready <= len(ready_racers)) if ready_racers and quorum: self._nopoke = True asyncio.ensure_future(self.run_nopoke_delay()) alert_string = '' for racer in unready_racers: alert_string += racer.member.mention + ', ' yield from self.write('Poking {0}.'.format(alert_string[:-2])) # Implements a delay before pokes can happen again @asyncio.coroutine def run_nopoke_delay(self): yield from asyncio.sleep(config.RACE_POKE_DELAY) self._nopoke = False