def sacrifice_shield(country: Country, area: Area, item): old_gold = country.gold #old_pop = country.pop if country.shields <= 1: raise BuyException("not_enough_shields") # you can't buy city tile # if item in ('city','river',''): # raise BuyException("bad_conf") # hack: set infinite resources, buy item, then reset country.gold = 999 #country.pop = 99 try: return buy_item(area, country, item) except BuyException as e: raise e finally: # restore original resources country.gold = old_gold #country.pop = old_pop # remove 1 shield country.shields -= 1
def test_pay_tribute(self): country1 = Country(iso='FR', gold=100) country2 = Country(iso='UK', gold=100) amount = 30 economy.give_tribute(country1, country2, amount) self.assertEqual(country1.gold, 70) self.assertEqual(country2.gold, 130)
def test_occupied_fail(self): country = Country(iso='UK', gold=20, pop=1) area = Area(iso='UK', tile='city', unit='inf') with self.assertRaises(BuyException) as context: service.buy_item(area, country, 'inf') self.assertEqual(context.exception.reason, 'item_exists')
def test_money_fail(self): country = Country(iso='UK', gold=19, pop=1) area = Area(iso='UK', tile='city') with self.assertRaises(BuyException) as context: service.buy_item(area, country, 'inf') self.assertEqual(context.exception.reason, 'not_enough_gold') self.assertIsNone(area.unit)
def test_not_city_fail(self): country = Country(iso='UK', gold=20, pop=1) area = Area(iso='UK') with self.assertRaises(BuyException) as context: service.buy_item(area, country, 'inf') self.assertEqual(context.exception.reason, 'missing_city') self.assertIsNone(area.unit)
def test_pesto_sacrifice(self): country = Country(iso='UK', gold=20, pop=0, shields=2) area = Area(iso='UK', tile='city') economy.sacrifice_shield(country, area, 'cav') self.assertEqual(country.gold, 20) self.assertEqual(country.pop, 0) self.assertEqual(area.unit, 'cav')
def test_pesto_notcity_fail(self): country = Country(iso='UK', gold=0, pop=0, shields=2) area = Area(iso='UK') with self.assertRaises(BuyException) as context: economy.sacrifice_shield(country, area, 'art') self.assertEqual(context.exception.reason, 'missing_city') self.assertIsNone(area.unit)
def test_buy_pass(self): country = Country(iso='UK', gold=20 + 70 + 120, pop=3) try: area = Area(iso='UK', tile='city') service.buy_item(area, country, 'inf') self.assertEqual(area.unit, 'inf') self.assertEqual(country.gold, 70 + 120) self.assertEqual(country.pop, 2) except BuyException as e: self.fail( "test_occupied_fail raised BuyException({}) unexpectedly!". format(e.reason)) try: area = Area(iso='UK', tile='city') service.buy_item(area, country, 'cav') self.assertEqual(area.unit, 'cav') self.assertEqual(country.gold, 120) self.assertEqual(country.pop, 1) except BuyException as e: self.fail( "test_occupied_fail raised BuyException({}) unexpectedly!". format(e.reason)) try: area = Area(iso='UK', tile='city') service.buy_item(area, country, 'art') self.assertEqual(area.unit, 'art') self.assertEqual(country.gold, 0) self.assertEqual(country.pop, 0) except BuyException as e: self.fail( "test_occupied_fail raised BuyException({}) unexpectedly!". format(e.reason))
def load_gtml(filename, skip=None): if skip is None: skip = [] l_countries = [] l_areas = [] l_calls = [] l_options = {} f_countries = [] area_pattern = re.compile(r"(?P<id>\w+)\((?P<iso>\w*),?(?P<buildtile>\w*),?(?P<unit>\w*)\)") with open(filename) as fh: status = None for line in fh: if not line or line[0] == '#' or line[0] == '\n': continue if line[0] == '>': status = line[1:-1] if status == 'STOP_TEST': l_calls.append((status,None)) break elif status[:9] == 'COUNTRIES': f_countries = status[10:].split() status = 'COUNTRIES' continue if status in skip: continue if status == 'COUNTRIES': attrs = line.split() cc = Country() for val,attr in zip(attrs, f_countries): if attr in ('iso', 'name', 'color'): if attr == 'name': val = val.replace('_', ' ') setattr(cc, attr, val) elif attr in ('emperor', 'ai'): setattr(cc, attr, val == 'true') else: setattr(cc, attr, int(val)) l_countries.append(cc) elif status == 'AREAS': match = area_pattern.findall(line) for (aid, iso, btile, unit) in match: area = Area(id=aid) if iso: area.iso = iso if btile in ('barr','house','cita'): area.build = btile area.tile = 'city' else: area.tile = btile if unit: area.unit = unit l_areas.append(area) elif status == 'OPTIONS': k,v = line.split() l_options[k] = v elif status == 'TEST_AREAS': ff = [] sareas = line.split() for sarea in sareas: sarea = sarea.split(',') area = Area(iso=sarea[0]) if len(sarea) > 1 and sarea[1]: tile = sarea[1] if tile in ('barr','house','cita'): area.tile = 'city' area.build = tile else: area.tile = tile if len(sarea) > 2: area.unit = sarea[2] ff.append(area) l_areas.append(ff) elif status == 'TEST_CALLS': method,params,iso,exps = line.split() params = params.split(',') try: exp_js = list(map(json.loads, exps.split('|'))) except: raise Exception("Failed to parse call: {}".format(exps)) if method == 'BUY': call = ('Game:buy', {'area_id': params[0], 'item_id': params[1]}, iso) elif method == 'MOVE': call = ('Game:move', {'area_id': params[0], 'to_id': params[1]}, iso) elif method == 'END': call = ('Game:end_turn', {}, iso) else: continue l_calls.append((call, exp_js)) if len(l_calls) == 0 and len(l_options) != 0: l_calls = l_options return l_countries, l_areas, l_calls