Beispiel #1
0
def execute_buys(w, city_dict):
    # city_dict = w.live_cities()

    for city_id, the_city in cli_f.progressbar(city_dict.items(), "Executing buys: ", 60, True):
        # for city_id, the_city in city_dict.items():
        for s in the_city.sells:
            s.execute()
Beispiel #2
0
def check_operative_locations(cursor, verbose):
	"""Finds operatives in dead cities and relocates them"""
	teams_dict			= team_q.get_all_teams(cursor)
	operatives_dict		= operative_q.get_all_operatives(cursor)
	city_dict			= city_q.get_all_cities(cursor)
	
	# Get a list of the dead cities
	dead_city_list = []
	for c_id, the_city in city_dict.items():
		if the_city.dead > 0 or not teams_dict[the_city.team].active:
			dead_city_list.append(str(c_id))
	
	# Find operatives in those cities
	query = """SELECT id FROM operatives WHERE city in (%s) and died < 1""" % ",".join(dead_city_list)
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	move_op_list = {}
	for row in cursor:
		o = row['id']
		t = operatives_dict[o].team
		
		if not teams_dict[t].active: continue
		
		if t not in move_op_list:
			move_op_list[t] = []
		
		move_op_list[t].append(str(o))
	
	# Find out which teams we need to get a city for
	teams_cities = {}
	for t in move_op_list.keys():
		teams_cities[t] = -1
	
	# Find cities for those teams
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "ops_check.check_operative_locations: ", 40, with_eta = True)
	else:
		it = city_dict.items()
	
	for c_id, the_city in it:
		if the_city.team in teams_cities and not teams_dict[the_city.team].dead:
			teams_cities[the_city.team] = c_id
	
	# Now run the queries
	queries = []
	for t, c in teams_cities.items():
		query = "UPDATE operatives SET city = %d, arrival = %d WHERE id in (%s)" % (
			c,
			common.current_turn(),
			",".join(move_op_list[t]),
		)
	
		try: cursor.execute(query)
		except Exception as e:
			raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
Beispiel #3
0
def execute_buys(w, city_dict, verbose=True):
	# city_dict = w.live_cities()
	
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "Executing buys: ", 60, True)
	else:
		it = city_dict.items()
	
	for city_id, the_city in it:
		for s in the_city.sells:
			_execute(w, city_dict, s)
Beispiel #4
0
def build_unit_equipment_strings(cursor, verbose):
	# Does what it says on the tin
	the_world = world.World(cursor)
	# the_world.units()
	unit_dict = unit_q.get_all_live_units(cursor)
	
	if verbose:
		it = cli_f.progressbar(unit_dict.items(), "military_check.build_unit_equipment_strings: ", 40, with_eta = True)
	else:
		it = unit_dict.items()
	
	for unit_id, the_unit in it:
		unit_f.rebuild_equipment_string(cursor, unit_id, the_world)
Beispiel #5
0
def get_happiness(cursor, verbose):
	w = world.World(cursor)
	
	if verbose:
		it = cli_f.progressbar(w.live_cities().items(), "cities_check.get_happiness: ", 40, with_eta = True)
	else:
		it = w.live_cities().items()
	
	queries = []
	for city_id, the_city in it:
		queries.append("UPDATE cities SET happiness = %d WHERE id = %d;" % (city_rules.get_happiness(w, the_city), city_id))
	
	database.query(cursor, *queries)
Beispiel #6
0
	def train(self):
		self.current_inputs = self.inputs
		
		try:
			for c in cli_f.progressbar(range(0, self.cycles), prefix = "", size = 60, with_eta=True):
			# for c in range(0, self.cycles):
				self._cycle()
		except KeyboardInterrupt as e:
			# Flush progress bar
			print(" ".join([" " for x in range(0,40)]))
			print("Exiting due to keyboard interrupt:")
		except Exception as e:
			raise
		finally:
			self.end()
Beispiel #7
0
def city_wealth(cursor, verbose):
	queries = []
	
	w = world.World(database.get_cursor())
	city_f.apply_city_matrix(w, compress=False)
	
	if verbose:
		it = cli_f.progressbar(w.live_cities().items(), "cities_check.city_wealth: ", 40, with_eta = True)
	else:
		it = w.live_cities().items()
	
	for k, c in it:
		c.wealth = city_rules.wealth_rate(w, c)
		queries.append("UPDATE cities SET wealth = %d WHERE id = %d;" % (c.wealth, k))
	
	database.query(cursor, *queries)
Beispiel #8
0
def city_terrain(cursor, verbose):
	queries = []
	city_dict = city_q.get_live_cities(cursor)
	
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "cities_check.city_terrain: ", 40, with_eta = True)
	else:
		it = city_dict.items()
	
	for k, c in it:
		t = mapper_q.get_terrain(cursor, c.x, c.y)
		
		if t != c.terrain:
			queries.append("UPDATE cities SET terrain = %d WHERE id = %d;" % (t, k))
	
	database.query(cursor, *queries)
Beispiel #9
0
def overlapping_cities(cursor, verbose):
	city_dict = city_q.get_live_cities(cursor)
	
	checked = []
	overlap_dict = {}
	
	for id1, c1 in city_dict.items():
		c1.overlap = 0
	
	# Cache some stuff
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "cities_check.overlapping_cities: ", 40, with_eta = True)
	else:
		it = city_dict.items()
	
	for id1, c1 in it:
		checked.append(id1)
		
		for id2, c2 in city_dict.items():
			if id2 in checked: continue
			
			amount = city_f.overlap(c1, c2)
			
			c1.overlap += city_f.overlap_percentage(c1, amount)
			c2.overlap += city_f.overlap_percentage(c2, amount)
	
	# Reset all cities
	query = """UPDATE cities SET overlap = 0"""
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	updates = 0
	for id1, c1 in city_dict.items():
		if c1.overlap >= 1:
			updates += 1
			
			query = "UPDATE cities SET overlap = %d WHERE id = %d;" % (c1.overlap, id1)
			# print("%s - %s" % (query, c1.name))
			# continue
			
			try: cursor.execute(query)
			except Exception as e:
				raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
Beispiel #10
0
def build_supplies(cursor, verbose):
	city_dict = city_q.get_live_cities(cursor)
	city_supply_dict = {}
	
	for k, v in city_dict.items():
		v.icon_size = map_data.map_image_size(v.population+v.slaves)/4
	
	if verbose:
		it = cli_f.progressbar(map_resources.data_list, "cities_check.build_supplies: ", 40, with_eta = True)
	else:
		it = map_resources.data_list
	
	for r, x, y in it:
		this_city = (-1, 9999)
		
		for k, v in city_dict.items():
			dist = path_f.pythagoras((v.x, v.y), (x, y))
			if dist < v.icon_size:
				if this_city[1] > v.founded:
					this_city = (k, v.founded)
		
		if this_city[0] > 0:
			if this_city[0] not in city_supply_dict:
				city_supply_dict[this_city[0]] = []
			city_supply_dict[this_city[0]].append(r)
	
	query = "UPDATE cities SET str_supplies = '';"
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	for k, v in city_supply_dict.items():
		vset = [str(r) for r in set(v)]
		
		query = "UPDATE cities SET str_supplies = '{0}' WHERE id = {1:d};".format(
			",".join(vset), k,
		)
		
		try: cursor.execute(query)
		except Exception as e:
			raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
Beispiel #11
0
def check_for_garrisons(cursor, verbose):
	garrisons_made = 0
	garrisons_named = 0
	
	city_list = []
	city_names = {}
	garrison_names = {}
	# Get cities
	query = "SELECT id, name FROM cities WHERE dead < 1"
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	for row in cursor:
		city_list.append(row['id'])
		city_names[row['id']] = row['name']
	
	# Get garrisons
	query = "SELECT garrison, name FROM armies WHERE garrison > 0;"
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	for row in cursor:
		garrison_names[row['garrison']] = row['name']
	
	if verbose:
		it = cli_f.progressbar(city_list, "military_check.check_for_garrisons: ", 40, with_eta = True)
	else:
		it = city_list
	
	for city_id in it:
		# row = cursor.fetchone()
		if city_id not in garrison_names:
			# No garrison exists for this city, best create one
			database.query(cursor, army_f.create_garrison(cursor, city_id))
			garrisons_made += 1
		else:
			# Has a garrison, lets check the name
			if garrison_names[city_id] != "%s garrison" % city_names[city_id]:
				database.query(cursor, army_f.name_garrison(city_id, city_names[city_id]))
				garrisons_named += 1
Beispiel #12
0
def find_buys(w, city_dict):
    # city_dict = w.live_cities()

    # End point stopper
    w.suppliers = {r: set() for r in sad_rules.res_list}
    for city_id, the_city in city_dict.items():
        for r in sad_rules.res_list:
            if the_city.goods[r] > 0:
                w.suppliers[r].add(city_id)

    i = 0
    # for city_id, the_city in city_dict.items():
    for city_id, the_city in cli_f.progressbar(city_dict.items(), "Finding buys: ", 60, True):
        needs = the_city.current_demands()

        i += 1
        # 20 = 115
        # 100 = 622.5
        # Full data at max hops 2 =
        # if i >= 10: return

        # For each supply we want
        for r in needs:
            prices = []
            for c, d in the_city.connections.items():
                if city_id in city_dict[c].connections:
                    prices.append(request_price(w, city_dict, the_city, city_dict[c], r, current_path=[city_id]))

                    # We want to filter out the best
            best = best_price(prices)
            if best != None:
                # We need to work out how much of this we can afford
                availiable = the_city.wealth / len(needs)

                best.set_amount(min(availiable / best.price, -the_city.goods[r]))

                the_city.buys.append(best)
                best.get_actual().sells.append(best)
Beispiel #13
0
def approve_buys(w, city_dict):
    # city_dict = w.live_cities()
    team_dict = w.teams()

    for city_id, the_city in cli_f.progressbar(city_dict.items(), "Approving buys: ", 60, True):
        # for city_id, the_city in city_dict.items():

        accepted_sells = []

        # We need to work out which sells we're gonna do
        # preferential treatment is given to those that we have a low tax rate to
        # it's possible we can honour more than one sell
        # the sells should all be for just a single supply

        # Temporary counters
        goods = sum([(a if a > 0 else 0) for r, a in the_city.goods.items()])
        goods_dict = dict(the_city.goods)

        # Keep going while we can
        while goods > 0 and len(accepted_sells) < len(the_city.sells):
            favoured = (999999, None)

            for s in the_city.sells:
                if s in accepted_sells:
                    continue
                if w.get_taxes(the_city.team, s.get_2nd_seller()) < favoured[0]:
                    favoured = (w.get_taxes(the_city.team, s.buyer.team), s)

                    # Actual amount needs to be limited
            accepted = favoured[1]
            accepted.set_amount(min(goods_dict[accepted.resource], accepted.amount))

            accepted_sells.append(accepted)
            goods -= accepted.amount
            goods_dict[accepted.resource] -= accepted.amount

        the_city.sells = accepted_sells
Beispiel #14
0
def approve_buys(w, city_dict, verbose=True):
	team_dict = w.teams()
	
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "Approving buys: ", 60, True)
	else:
		it = city_dict.items()
	
	sales_count = 0
	sales_lowered = 0
	
	for city_id, the_city in it:
		if len(the_city.sells) == 0: continue
		
		# print("\n\n")
		# print(the_city.sells)
		# exit()
		
		accepted_sells = []
		marked_sells = []
		
		# We need to work out which sells we're gonna do
		# preferential treatment is given to those that we have a low tax rate to
		# it's possible we can honour more than one sell
		# the sells should all be for just a single supply
		
		# If the sells are not for a single supply it will be an inefficent system as only 1 favoured is tracked
		
		# Temporary counters
		goods = sum([(a if a > 0 else 0) for r, a in the_city.goods.items()])
		goods_dict = dict(the_city.goods)
		
		# Keep going while we can
		i = 0
		while goods > 0 and len(accepted_sells) < len(the_city.sells):
			i += 1
			if i > 100:
				break
			
			favoured = None
			favoured_tax = 9999
			
			for i, s in enumerate(the_city.sells):
				if i in marked_sells: continue
				
				# s[1] is the path
				# 0 is us
				# 1 is the first buyer
				buyer = s[1][1]
				
				if w.tax_cache[(the_city.team, city_dict[buyer].team)] < favoured_tax:
					favoured_i = i
					favoured = s
					favoured_tax = w.tax_cache[(the_city.team, city_dict[buyer].team)]
			
			# print("Fav: %s, %s" % (favoured_tax, str(favoured)))
			
			# Actual amount needs to be limited
			# marked_sells.append(favoured)
			marked_sells.append(favoured_i)
			final_buyer = favoured[1][-1]
			r = favoured[0]
			
			sales_count += 1
			if goods_dict[r] < favoured[2]:
				sales_lowered += 1
			
			amount = min(goods_dict[r], favoured[2])
			
			# print(amount, "                        ")
			
			# Move counters, add amount to the sell
			favoured = (favoured[0], favoured[1], amount)
			accepted_sells.append(favoured)
			goods -= amount
			goods_dict[r] -= amount
			
			# goods = -100
		
		the_city.sells = accepted_sells
		# for s in the_city.sells:
		# 	print(s)
		# exit()
	
	print("Sale count: %s" % sales_count)
	print("Sales lowered: %s" % sales_lowered)
Beispiel #15
0
def find_buys(w, city_dict, verbose=True):
	# city_dict = w.live_cities()
	
	# End point stopper
	# w.suppliers = {r:set() for r in sad_rules.res_list}
	# for city_id, the_city in city_dict.items():
	# 	the_city.best_price = {}
	# 	
	# 	for r in sad_rules.res_list:
	# 		if the_city.goods[r] > 0:
	# 			w.suppliers[r].add(city_id)
	
	for city_id, the_city in city_dict.items():
		the_city.needs_cache = the_city.current_demands()
	
	
	if verbose:
		it = cli_f.progressbar(range(0, config['hops']+1), "Hopping: ", 60, True)
	else:
		it = range(0, config['hops']+1)
	
	for h in it:
	# for h in range(0, max_hops+1):
		# for city_id, the_city in cli_f.progressbar(city_dict.items(), "Hopping %d: " % h, 60, True):
		for city_id, the_city in city_dict.items():
			_discover(w, city_dict, the_city, h)
	
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "Finding buys: ", 60, True)
	else:
		it = city_dict.items()
	
	for city_id, the_city in it:
		if the_city.wealth <= 1: continue
		
		needs = the_city.current_demands()
		
		offers = []
		current_best_price = {}
		for r in needs:
			current_best_price[r] = (9999, [])
		
		# For each supply we want
		for c, d in the_city.connections.items():
			if city_id in city_dict[c].connections:
				for r in needs:
					if city_dict[c].best_price[config['hops']][r][0] > 1000: continue
					
					offers.append()
					
					# Price is made from price saved at other city times the get_price multiplier
					offer_price = get_price(w, the_city, city_dict[c]) * city_dict[c].best_price[config['hops']][r][0]
					
					if new_price < current_best_price[r][0]:
						availiable = the_city.wealth/len(needs)
						
						amount = min(availiable/new_price, -the_city.goods[r])
						
						current_best_price[r] = (new_price, list(city_dict[c].best_price[config['hops']][r][1]) + [the_city.id], amount)
		
		# Now to turn them into Buys
		for r in needs:
			if current_best_price[r][0] > 1000: continue
			city_dict[current_best_price[r][1][0]].sells.append((r, current_best_price[r][1], current_best_price[r][2]))
Beispiel #16
0
def test_all(options):
	options.all = True
	
	tests(options)
	
	options.verbose = True
	
	the_world = spy_world.Spy_world(database.get_cursor())
	cli_f.output_ti(options, the_world, skip_upload=True)
	cli_f.output_to(options, the_world, skip_upload=True)
	cli_f.output_stats(options, the_world, skip_upload=True)
	cli_f.output_map(options, the_world, skip_upload=True)
	cli_f.output_wh(options, the_world, skip_upload=True)
	cli_f.output_oh(options, the_world, skip_upload=True)
	cli_f.output_spyrep(options, the_world, skip_upload=True)
	cli_f.output_tmap(options, the_world, skip_upload=True)
	cli_f.output_json(options, skip_upload=True)
	
	funcs = (
		the_world.relations,
		the_world.border_history,
		# the_world.prep_for_orders(self):,
		# the_world.prep_for_to(self):,
		# the_world.prep_for_stats(self):,
		# the_world.prep_for_oh(self):,
		# the_world.prep_for_ti(self):,
		# the_world.prep_for_start(self):,
		# the_world.building_requirements(self):,
		# the_world._lookup(self, name, lower=False, force_requery=False):,
		the_world.artefacts_lookup,
		the_world.armies_lookup,
		the_world.buildings_lookup,
		the_world.cities_lookup,
		the_world.campaigns_lookup,
		the_world.deities_lookup,
		the_world.equipment_lookup,
		the_world.evolutions_lookup,
		the_world.operatives_lookup,
		the_world.powers_lookup,
		the_world.spells_lookup,
		the_world.techs_lookup,
		the_world.teams_lookup,
		the_world.squads_lookup,
		the_world.units_lookup,
		the_world.wonders_lookup,
		# the_world._build_lookup_from_team(self, name, force_requery=False):,
		# the_world._lookup_all_from_team(self, name, force_requery=False):,
		# the_world._lookup_from_team(self, name, team_id, force_requery=False):,
		# the_world.armies_lookup_from_team(self, team_id, force_requery=False):,
		# the_world.units_lookup_from_team(self, team_id, force_requery=False):,
		# the_world._dict(self, name, force_requery=False):,
		the_world.armies,
		the_world.artefacts,
		the_world.buildings,
		the_world.cities,
		the_world.campaigns,
		the_world.deities,
		the_world.equipment,
		the_world.evolutions,
		the_world.kills,
		the_world.servants,
		the_world.operatives,
		the_world.powers,
		the_world.players,
		the_world.spells,
		the_world.techs,
		the_world.squads,
		the_world.teams,
		the_world.units,
		# the_world.json_ti(self, team, turn, force_requery=False),
		the_world.wonders,
		# the_world._build_from_team(self, name, force_requery=False):,
		# the_world._all_from_team(self, name, force_requery=False):,
		# the_world._from_team(self, name, team_id, force_requery=False):,
		# the_world.armies_from_team(self, team_id, force_requery=False):,
		# the_world.cities_from_team(self, team_id, force_requery=False):,
		# the_world.kills_from_turn(self, team_id, force_requery=False):,
		# the_world.kills_from_camp(self, team_id, force_requery=False):,
		# the_world.players_from_team(self, team_id, force_requery=False):,
		# the_world.operatives_from_team(self, team_id, force_requery=False):,
		# the_world.squads_from_team(self, team_id, force_requery=False):,
		# the_world.units_from_team(self, team_id, force_requery=False):,
		# the_world.squads_lookup_from_army(self, army_id, force_requery=False):,
		the_world.cities_with_wonders,
		the_world.cities_with_artefacts,
		the_world.active_teams,
		the_world.live_cities,
		# the_world.live_cities_from_team(self, team_id, force_requery=False):,,
		
		# armies_by_base(self, base, force_requery=False)
		# armies_in_area(self, area, radius=10, force_requery=False)
		# operatives_in_area(self, area, radius=10, force_requery=False)
		# operatives_in_city(self, city_id, force_requery=False)
		# cities_in_area(self, area, radius=10, force_requery=False)
		# race_difference(self, race_1, race_2)
	)
	
	for f in cli_f.progressbar(funcs, "Testing world: ", 60, True):
		f()
Beispiel #17
0
def merge_squads(cursor, verbose):
	the_world = world.World(cursor)
	
	squad_dict = the_world.squads()
	army_dict = the_world.armies()
	teams_dict = the_world.teams()
	
	squad_by_army = {}
	for k, s in squad_dict.items():
		if s.army not in squad_by_army: squad_by_army[s.army] = []
		squad_by_army[s.army].append(s.id)
	
	# Get active teams
	active_teams = []
	for team_id, the_team in teams_dict.items():
		if the_team.ir or not the_team.active: continue
		active_teams.append(team_id)
	
	# Pairs will contain tuples of what we want to merge
	queries = []
	
	if verbose:
		it = cli_f.progressbar(army_dict.items(), "military_check.merge_squads: ", 40, with_eta = True)
	else:
		it = army_dict.items()
	
	for army_id, the_army in it:
		if the_army.team not in active_teams: continue
		if army_id not in squad_by_army: continue
	
		skip_squads = []
	
		# Outside loop looks at the squad we may want to merge
		for squad_id_1 in squad_by_army[army_id]:
			if squad_id_1 in skip_squads: continue
		
			the_squad_1 = squad_dict[squad_id_1]
		
			for squad_id_2 in squad_by_army[army_id]:
				if squad_id_1 == squad_id_2: continue
				if squad_id_2 in skip_squads: continue
			
				the_squad_2 = squad_dict[squad_id_2]
			
				if the_squad_1.unit == the_squad_2.unit:
					if the_squad_1.name == the_squad_2.name:
						skip_squads.append(squad_id_2)
					
						# Update size
						queries.append("UPDATE squads SET amount = %d WHERE id = %d;" % (the_squad_1.amount + the_squad_2.amount, squad_id_1))
					
						# Delete 2nd squad
						queries.append("DELETE FROM squads WHERE id = %d" % squad_id_2)
	
	# print "\n".join(queries)
	cursor.execute("BEGIN")
	for query in queries:
		try: cursor.execute(query)
		except Exception as e:
			cursor.execute("ROLLBACK")
			raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	cursor.execute("COMMIT")		
Beispiel #18
0
def check_unit_categories(cursor, verbose):
	queries = []
	unit_dict = unit_q.get_all_live_units(cursor)
	equipment_dict = equipment_q.get_all_equipment(cursor)
	
	unit_q.mass_get_unit_equipment(cursor, unit_dict)
	
	# Default
	query = """UPDATE units SET crew = 1;"""
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	if verbose:
		it = cli_f.progressbar(unit_dict.items(), "military_check.check_unit_categories: ", 40, with_eta = True)
	else:
		it = unit_dict.items()
	
	for unit_id, the_unit in it:
		the_unit.transport = 0
		the_unit.move_type = 0
		the_unit.move_speed = 0
		the_unit.crew = 1
		
		the_unit.weapon_cat = 0
		the_unit.armour_cat = 0
		the_unit.move_cat = 0
		the_unit.training_cat = 0
		
		ranged = False
		melee = False
		
		# Loop through all it's equipment
		for e in the_unit.equipment:
			the_e = equipment_dict[e]
			
			if the_e.range > 2:
				ranged = True
			elif the_e.range == 0:
				melee = True
			
			the_unit.transport = max(the_e.transport, the_unit.transport)
			
			the_unit.crew = max(the_unit.crew, the_e.crew)
			
			# the_unit.move_type = 0
			# the_unit.move_speed = 0
			# the_unit.type_cat = 0
			
			the_unit.armour_cat = max(the_unit.armour_cat, the_e.armour_cat)
			the_unit.move_cat = max(the_unit.move_cat, the_e.move_cat)
			the_unit.training_cat = max(the_unit.training_cat, the_e.training_cat)
			
			if the_e.category == equipment.cat_list.index("Boat hull"):
				the_unit.type_cat = unit.categories.index("Ship")
			elif the_e.category == equipment.cat_list.index("Balloon"):
				the_unit.type_cat = unit.categories.index("Airship")
			else:
				pass
		
		# Work out categories
		if ranged and melee:
			the_unit.weapon_cat = unit.weapon_categories.index("Melee and Ranged")
		elif ranged and not melee:
			the_unit.weapon_cat = unit.weapon_categories.index("Ranged")
		elif melee and not ranged:
			the_unit.weapon_cat = unit.weapon_categories.index("Melee")
		else:
			the_unit.weapon_cat = unit.weapon_categories.index("Neither")
		
		# Query
		queries.append("""UPDATE units SET
			transport = {transport}, move_type = {move_type}, move_speed = {move_speed}, crew = {crew},
			type_cat = {type_cat}, weapon_cat = {weapon_cat}, armour_cat = {armour_cat}, move_cat = {move_cat}, training_cat = {training_cat}
				WHERE id = {id};""".format(
			transport = the_unit.transport,
			move_type = the_unit.move_type,
			move_speed = the_unit.move_speed,
			crew = the_unit.crew,
			type_cat = the_unit.type_cat,
			weapon_cat = the_unit.weapon_cat,
			armour_cat = the_unit.armour_cat,
			move_cat = the_unit.move_cat,
			training_cat = the_unit.training_cat,
			id = the_unit.id,
		))
	
	database.query(cursor, queries)
Beispiel #19
0
def build_distance_matrix(the_world, verbose=False):
	borders		= the_world.relations()
	city_dict	= the_world.live_cities()
	
	# print(borders)
	# exit()
	
	distance_matrix = {}
	city_contintent = {}
	
	func_start = time.time()
	
	i = 0
	paths = 0
	
	it = city_dict.items()
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "Pathing:", 60, True)
	
	worst_land_path = (-1, -1, -1)
	worst_water_path = (-1, -1, -1)
	for i1, c1 in it:
		# i1 = 1224
		# c1 = city_dict[i1]
		
		started = time.time()
		links = 0
		
		i += 1
		
		if i1 not in city_contintent:
			city_contintent[i1] = path_f.get_continent(the_world.cursor, (c1.x, c1.y))
		
		for i2, c2 in city_dict.items():
			# i2 = 1280
			# c2 = city_dict[i2]
			
			# print()
			# print(city_contintent[i1])
			# print(path_f.get_continent(the_world.cursor, (c2.x, c2.y)))
			
			# A city can't trade with itself...
			if i2 == i1:
				continue
			
			# Check we've not already done this
			if (i1, i2) in distance_matrix:
				continue
			
			# Check borders
			# [Host][Visitor]
			# if borders.get[c2.team][c1.team] <= team.border_states.index("Closed"):
			if the_world.get_border(c2.team, c1.team) <= team.border_states.index("Closed"):
				continue
			
			# if borders[c1.team][c2.team] <= team.border_states.index("At war"):
			if the_world.get_border(c1.team, c2.team) <= team.border_states.index("At war"):
				continue
			
			# Get continent stuff
			if i2 not in city_contintent:
				city_contintent[i2] = path_f.get_continent(the_world.cursor, (c2.x, c2.y))
			
			# Reset distance
			dist = None
			crow_dist = path_f.pythagoras_cities(c1, c2)
			
			# If on same continent
			if city_contintent[i1] == city_contintent[i2] and crow_dist < sad_rules.max_crow_dist_land:
				if crow_dist <= sad_rules.min_trade_distance:
					dist = DeadPath(sad_rules.min_trade_distance)
				else:
					path_time = time.time()
					try:
						dist = path_f.path(the_world.cursor, [(c1.x, c1.y), (c2.x, c2.y)], move_speed="Merchant", move_type="Merchant", exception_in_timeout=True, timeout_limit=1000)
						paths += 1
					except Exception as e:
						print("Trying to path %s (%d) to %s (%d)" % (c1.name, i1, c2.name, i2))
						print("Continent %s to %s" % (city_contintent[i1], city_contintent[i2]))
						raise
					path_time = time.time() - path_time
					if path_time > worst_land_path[2]:
						worst_land_path = ((c1.x, c1.y), (c2.x, c2.y), path_time, "points={0}%2C+{1}%2C+{2}%2C+{3}&move_speed=Merchant&move_type=Merchant".format(
							c1.x, c1.y, c2.x, c2.y
						))
			
			# If both are ports then we can try the water
			if c1.port and c2.port and crow_dist < sad_rules.max_crow_dist_water:
				path_time = time.time()
				try:
					dist_sea = path_f.path(the_world.cursor, [(c1.x, c1.y), (c2.x, c2.y)], move_speed="Sailing", move_type="Sail", exception_in_timeout=True)
					paths += 1
				except Exception as e:
					print("Trying to path %s (%d) to %s (%d)" % (c1.name, i1, c2.name, i2))
					raise
				
				path_time = time.time() - path_time
				if path_time > worst_water_path[2]:
					worst_water_path = ((c1.x, c1.y), (c2.x, c2.y), path_time, "points={0}%2C+{1}%2C+{2}%2C+{3}&move_speed=Sailing&move_type=Sail".format(
						c1.x, c1.y, c2.x, c2.y
					))
				
				# Now pick the fastest
				if dist == None or dist.time_cost > dist_sea.time_cost:
					dist = dist_sea
			
			# Is it none?
			if dist == None:
				time_cost = 99999
			else:
				time_cost = sad_rules.trade_distance(dist.time_cost)
				links += 1
			
			# if borders[c2.team][c1.team] == team.border_states.index("Segregated"):
			if the_world.get_border(c2.team, c1.team) <= team.border_states.index("Segregated"):
				time_cost *= sad_rules.segregated_multiplier
			
			if time_cost > sad_rules.max_trade_travel_time: continue
			distance_matrix[(i1, i2)] = time_cost
			
			# If we have the same borders round the other way then we can skip this path later
			# if borders[c2.team][c1.team] == borders[c1.team][c2.team]:
			if the_world.get_border(c2.team, c1.team) == the_world.get_border(c1.team, c2.team):
				distance_matrix[(i2, i1)] = distance_matrix[(i1, i2)]
		
		# print("%d of %d in %ss (%d links)" % (i, len(city_dict), round(time.time() - started, 2), links))
		"""
		Origional
		Tried 103,505 paths
		Completed in 446 seconds
		
		After applying: "if (i1, i2) in distance_matrix" with same border checking
		Tried 79,979 paths
		Completed in 338 seconds
		
		After dropping the timeout exception from 10k to 1k
		Tried 79,979 paths
		Completed in 335 seconds
		
		After adding in the min distance (10)
		Tried 79,958 paths
		Completed in 337 seconds
		
		Adding in dead tiles and a smaller (10 not 1000) move cost
		Tried 79,958 paths
		Completed in 336 seconds
		"""
	
	# Some stats stuff
	if verbose:
		print("Worst land path: %s -> %s in %s = http://localhost/rob3/web.py?mode=path_map&%s" % worst_land_path)
		print("Worst water path: %s -> %s in %s = http://localhost/rob3/web.py?mode=path_map&%s" % worst_water_path)
		
		total_time = time.time() - func_start
		print("Tried %s paths in %s seconds, avg %ss per path or %s paths per second" % (format(paths, ','), int(total_time), round(total_time/paths, 3), round(paths/total_time, 2)))
	
	# Now to save it
	q = "INSERT INTO trade_distances (city_1, city_2, distance) values %s;" % ",".join(
		["(%d, %d, %d)" % (c[0], c[1], d) for c, d in distance_matrix.items()]
	)
	
	the_world.cursor.execute("DELETE FROM trade_distances")
	if verbose:
		print("Completed in %d seconds" % int(time.time() - func_start))
	
	the_world.cursor.execute(q)
Beispiel #20
0
def check_army_bases(cursor, verbose):
	team_dict = team_q.get_all_teams(cursor)
	army_dict = army_q.get_armies_from_team_list(cursor, list(team_dict.keys()))
	city_dict = city_q.get_live_cities(cursor)
	relations = team_q.get_relations(cursor)# [Host][Visitor]
	
	# Build up a shortlist dict of cities by team
	city_by_team = {}
	for team_id, the_team in team_dict.items():
		if team_id not in city_by_team:
			city_by_team[team_id] = []
		
		for city_id, the_city in city_dict.items():
			if the_city.team == team_id or relations.get(the_city.team, {}).get(team_id, {}).get('border', team_dict[the_city.team].default_borders) >= team.border_states.index("Allied"):
				city_by_team[team_id].append(city_id)
	
	# Now to run through the armies and find their paths
	new_bases = set()
	# for i in progressbar(range(15), "Computing: ", 40):
	# for army_id, the_army in army_dict.items():
	
	if verbose:
		it = cli_f.progressbar(army_dict.items(), "military_check.check_army_bases: ", 40, with_eta = True)
	else:
		it = army_dict.items()
	
	for army_id, the_army in it:
		army_terrain = mapper_q.get_terrain(cursor, the_army.x, the_army.y)
		
		for city_id in city_by_team[the_army.team]:
			if army_terrain < 1:
				if not the_city.port: continue
			
			the_city = city_dict[city_id]
			if the_city.dead > 0: continue
			dist = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y))
			
			if dist < 10:
				the_army.base = city_id
				the_army.distance = (dist/map_data.movement_speeds['Marching'])*10# Distance over speed in km, 1 distance unit is 10k
				new_bases.add(army_id)
			
		# Extend the search a little
		if army_id not in new_bases:
			for city_id in city_by_team[the_army.team]:
				if army_terrain < 1:
					if not the_city.port: continue
				
				the_city = city_dict[city_id]
				dist = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y))
			
				if dist < 30:
					the_army.base = city_id
					the_army.distance = (dist/map_data.movement_speeds['Marching'])*10# Distance over speed in km, 1 distance unit is 10k
					new_bases.add(army_id)
		
		# Extend the search a little
		if army_id not in new_bases:
			for city_id in city_by_team[the_army.team]:
				if army_terrain < 1:
					if not the_city.port: continue
				
				the_city = city_dict[city_id]
				dist = path_f.pythagoras((the_army.x, the_army.y), (the_city.x, the_city.y))
			
				if dist < 60:
					the_army.base = city_id
					the_army.distance = (dist/map_data.movement_speeds['Marching'])*10# Distance over speed in km, 1 distance unit is 10k
					new_bases.add(army_id)
		
		# If we can't find an easy solution we start pathing
		if army_id not in new_bases:
			fastest_path = (-1, 9999999)
			
			for city_id in city_by_team[the_army.team]:
				the_city = city_dict[city_id]
				
				# Small cities won't support an army a long way away right?
				if the_city.size < 5000: continue
				
				# Is it a fleet?
				if army_terrain < 1:
					if not the_city.port: continue
					
					# Now lets try water
					dist = path_f.path(cursor, ((the_army.x, the_army.y), (the_city.x, the_city.y)), move_speed="Sailing", move_type="Sail")
					
					if dist.time_cost < fastest_path[1]:
						fastest_path = (city_id, dist.time_cost)
				
				else:
					# I'm sure there's a way to improve this...
					dist = path_f.path(cursor, ((the_army.x, the_army.y), (the_city.x, the_city.y)), move_speed="Marching", move_type="Medium foot")
					
					if dist.time_cost == 0:
						continue
					
					# if army_id == 960 and city_id == 1098:
					# 	print("")
					# 	print(dir(dist))
					# 	print(((the_army.x, the_army.y), (the_city.x, the_city.y)))
					# 	print(dist.time_cost)
					# 	print(dist.walk_distance)
					# 	print(len(dist.steps))
					# 	print("")
					
					if dist.time_cost < fastest_path[1]:
						fastest_path = (city_id, dist.time_cost)
				
			the_army.base = fastest_path[0]
			the_army.distance = fastest_path[1]
			new_bases.add(army_id)
	
	# Reset all armies
	query = """UPDATE armies SET base = -1, distance = -1 WHERE garrison = 0;"""
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	for a in new_bases:
		query = """UPDATE armies SET base = %d, distance = %d WHERE id = %d;""" % (army_dict[a].base, army_dict[a].distance, a)
		try: cursor.execute(query)
		except Exception as e:
			raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	# Garrisons automatically go to their city
	query = """UPDATE armies SET base = garrison, distance = 0 WHERE garrison > 0;"""
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
Beispiel #21
0
def run_orders(options):
	start_time = time.time()
	cursor = database.get_cursor()
	cursor.track_queries = True
	the_world = spy_world.Spy_world(cursor)
	team_dict = the_world.active_teams()
	
	#	Run orders
	#------------------------
	print(database.shell_text("Running orders"), end="")
	queries, orders, debug = [], ["Team orders\n"], []
	the_world.prep_for_orders()
	
	try:
		player_updates = {}
		the_orders = order_post_f.get_turn_orders(cursor, the_world)
		
		blocks = []
		# for o in the_orders:
		for o in cli_f.progressbar(the_orders, "Splitting: ", 60, True):
			o.split()
			blocks.extend(o.blocks)
		
		# Setup
		# for b in blocks:
		for b in cli_f.progressbar(blocks, "Setting up: ", 60, True):
			b.setup()
			b.always_debug = True
		
		# Execution, in order of priority
		for priority in order_block.priorities:
			c = 0
			
			for b in blocks:
				if b.priority != priority:
					continue
				
				try:
					b.execute()
				except Exception as e:
					print("")
					print(b.title_name)
					print(the_world.teams()[b.team].name)
					print("\n".join(cursor.queries[-5:-1]))
					print("")
					raise
		
		# Ensure we've handled all blocks
		for b in blocks:
			if not b.handled:
				raise Exception("Block with priority '%s' not handled" % b.priority)
		
		team_output = {}
		manual_output = {}
		team_debug = {}
		team_failures = {}
		for b in cli_f.progressbar(blocks, "Running Blocks: ", 60, True):
		# for b in blocks:
			if b.team not in team_output:
				team_output[b.team] = []
			
			if b.team not in team_debug:
				team_debug[b.team] = []
			
			if b.team not in team_failures:
				team_failures[b.team] = []
			
			if b.team not in manual_output:
				manual_output[b.team] = []
			
			# Player activity needs to get updated
			player_updates[b.post.player] = b.post.team
			
			# team_output[b.team].append("[o]%s[/o]" % b.title_name)
			team_output[b.team].append("\n".join(b.results))
			team_output[b.team].append("")
			
			if b.manual_handle:
				manual_output[b.team].append("\n".join(b.results))
				manual_output[b.team].append("")
			
			# Failures
			if len(b.failures) > 0:
				team_failures[b.team].append("\n".join(b.failures))
				team_failures[b.team].append("")
			
			# Debug
			team_debug[b.team].append(b.debug[0])
			team_debug[b.team].append("\n---\n".join(b.debug[1:len(b.debug)]))
			team_debug[b.team].append("")
			
			# Foreign results
			for team_id, res in b.foreign_results.items():
				if team_id not in team_output:
					team_output[team_id] = []
				team_output[team_id].insert(0, "")
				team_output[team_id].insert(0, "\n".join(res))
			
			# Queries
			for team_id, fqueries in b.foreign_queries.items():
				queries.extend(fqueries)
			
			queries.extend(b.queries)
		
		
		
		for team_id, the_team in team_dict.items():
			if the_team.ir: continue
			
			orders.append("""# %s
######################################################################
[fullbox=#EEF,#AAF][h4]Turn %d Results[/h4][/fullbox]

[url=http://woarl.com/stats/%s.html]Rob results[/url]

""" % (the_team.name, common.current_turn(), team_f.team_hash(the_team.name)))
			
			if team_id in team_output:
				if team_id in manual_output:
					# orders.extend(team_output[team_id])
					orders.extend(manual_output[team_id])
			
			if team_id in team_debug:
				debug.extend(team_debug[team_id])
		
		# Update player activity
		database.query(cursor,
			player_f.update_player_activity(player_updates))
		
		# Save results
		results_f.save_results(cursor, team_output)
		results_f.save_failures(cursor, team_failures)
		
		# Now we work out the costs
		team_costs = {}
		for t, the_team in team_dict.items():
			r = res_dict.Res_dict(the_team.resources)
			queries.extend(r.make_set_queries(t))
		
		# Write queries to file
		f = open('%s/script_output/queries.sql' % common.data['server_fpath'], 'w')
		f.write("\n".join(queries))
		f.close()
		
		# Write orders to file
		f = open('%s/script_output/orders.txt' % common.data['server_fpath'], 'w')
		f.write("\n".join(orders))
		f.close()
		
		# Write debug to file
		f = open('%s/script_output/debug.txt' % common.data['server_fpath'], 'w')
		f.write("Team orders\n\n")
		f.write("\n".join(debug))
		f.close()
		
	except Exception as e:
		print(database.shell_text("[r]Failure[/r]"))
		print(database.shell_text("[r]Re run as 'rob3 start -l True[/r]'"))
		raise
	
	# print(database.shell_text(" - [g]Done[/g]"))
	# os.system('mate %s' % '%s/queries.sql' % common.data['server_fpath'])
	# os.system('mate %s' % '%s/orders.txt' % common.data['server_fpath'])
	
	# Failable orders
	failable = (
		re.compile(r'DELETE FROM squads WHERE id = [0-9]*;?'),
	)
	
	failed_queries = []
	
	#	Execute order queries
	#------------------------
	# print(database.shell_text("Executing order queries"), end="")
	for q in cli_f.progressbar(queries, "Running queries: ", 60, True):
	# for q in queries:
		if q == '': continue
		if q[0:2] == '--': continue
		
		try:
			cursor.execute(q)
		except Exception as e:
			ignorable = False
			
			for f in failable:
				if f.search(q) != None:
					ignorable = True
					failed_queries.append(q)
			
			if not ignorable:
				for f in failable:
					print("")
					print(f.search(q))
					print("")
			
				cursor.execute('ROLLBACK')
				print(database.shell_text(" - [r]Failure[/r]"))
				print("Query: %s\n" % q)
				print(database.shell_text("[r]Re run as 'rob3 start -l True'[/r]"))
				raise
	
	# print(database.shell_text(" - [g]Done[/g]"))
	
	if len(failed_queries) > 0:
		print("Failed queries")
		print("\n".join(failed_queries))
	
	# Build up a dict of the queries
	query_dict = {}
	for q in cursor.queries:
		if q in ("BEGIN", "COMMIT", "ROLLBACK"): continue
		
		if q not in query_dict:
			query_dict[q] = 0
		
		query_dict[q] += 1
	
	# What's our most popular query?
	pop_count, pop_query = 0, ""
	for q, c in query_dict.items():
		if c > pop_count:
			pop_count = c
			pop_query = q
	
	print("\n\n--- Info ---")
	print("Time taken: %s" % str(round(time.time() - start_time, 3))[0:5])
	print("Queries: %d" % len(cursor.queries))
	print("Uniques: %d" % len(set(cursor.queries)))
	print("Most queried: %s (%d)" % (pop_query, pop_count))
	
	#	Verbose mode
	#------------------------
	if options.verbose:
		cursor.execute("ROLLBACK")
		print("Rolled back")
	else:
		cursor.execute("COMMIT")
		print("Startup scripts executed")
		os.system("open %s/script_output/orders.txt" % common.data['server_fpath'])
Beispiel #22
0
def find_buys(w, city_dict, verbose=True):
	for city_id, the_city in city_dict.items():
		the_city.needs_cache = the_city.current_demands()
	
	# Discover
	if verbose:	it = cli_f.progressbar(range(0, config['hops']+1), "Hopping: ", 60, True)
	else:		it = range(0, config['hops']+1)
	
	for h in it:
		for city_id, the_city in city_dict.items():
			_discover(w, city_dict, the_city, h)
	
	# Find buys
	if verbose:	it = cli_f.progressbar(city_dict.items(), "Finding buys: ", 60, True)
	else:		it = city_dict.items()
	
	for city_id, the_city in it:
		needs = the_city.current_demands()
		offers = {k:[] for k in needs}
		
		# For each city we know, we ask them what price they can do for us
		for c, d in the_city.connections.items():
			for r in needs:
				if city_dict[c].best_price[config['hops']][r][0] > 1000: continue
				
				# Price is made from price saved at other city times the get_price multiplier
				offer_price = get_price(w, the_city, city_dict[c]) * city_dict[c].best_price[config['hops']][r][0]
				availiable = the_city.wealth/len(needs)
				amount = min(availiable/offer_price, -the_city.goods[r])
				offers[r].append((offer_price, list(city_dict[c].best_price[config['hops']][r][1]) + [the_city.id], amount))
		
		# Now to turn them into actual Buys
		for r in needs:
			availiable		= the_city.wealth/len(needs)
			amount_needed	= -the_city.goods[r]
			sources_used	= []
			
			acceptable_buy = True
			while acceptable_buy:
				acceptable_buy = False
				if availiable <= 0 or amount_needed <= 0: continue
				
				best_offer = None
				best_price = 99999
				
				for i, the_offer in enumerate(offers[r]):
					price, path, amount = the_offer
					
					# If we have already used this source then we can look elsewhere
					if path[0] in sources_used:
						continue
					
					# Compare
					if price < best_price:
						best_offer = i
						best_price = price
				
				# Now assign our accepted offer
				if best_offer == None: continue
				
				acceptable_buy = True
				accepted_offer = offers[r][best_offer]
				del(offers[r][best_offer])
				
				# Add it to the sells
				sources_used.append(accepted_offer[1][0])
				amount_needed -= accepted_offer[2]
				city_dict[accepted_offer[1][0]].sells.append((r, accepted_offer[1], accepted_offer[2]))
Beispiel #23
0
def find_buys(w, city_dict, verbose=True):
	# city_dict = w.live_cities()
	
	# End point stopper
	# w.suppliers = {r:set() for r in sad_rules.res_list}
	# for city_id, the_city in city_dict.items():
	# 	the_city.best_price = {}
	# 	
	# 	for r in sad_rules.res_list:
	# 		if the_city.goods[r] > 0:
	# 			w.suppliers[r].add(city_id)
	
	for city_id, the_city in city_dict.items():
		the_city.needs_cache = the_city.current_demands()
	
	
	if verbose:
		it = cli_f.progressbar(range(0, config['hops']+1), "Hopping: ", 60, True)
	else:
		it = range(0, config['hops']+1)
	
	for h in it:
	# for h in range(0, max_hops+1):
		# for city_id, the_city in cli_f.progressbar(city_dict.items(), "Hopping %d: " % h, 60, True):
		for city_id, the_city in city_dict.items():
			_discover(w, city_dict, the_city, h)
	
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "Finding buys: ", 60, True)
	else:
		it = city_dict.items()
	
	for city_id, the_city in it:
		if the_city.wealth <= 5: continue
		
		needs = the_city.current_demands()
		
		offers = {}
		for r in needs:
			offers[r] = []
		
		# For each supply we want
		for c, d in the_city.connections.items():
			if city_id in city_dict[c].connections:
				for r in needs:
					if city_dict[c].best_price[config['hops']][r][0] > 1000: continue
					
					# Price is made from price saved at other city times the get_price multiplier
					offer_price = get_price(w, the_city, city_dict[c]) * city_dict[c].best_price[config['hops']][r][0]
					availiable = the_city.wealth/len(needs)
					amount = min(availiable/offer_price, -the_city.goods[r])
					offers[r].append((offer_price, list(city_dict[c].best_price[config['hops']][r][1]) + [the_city.id], amount))
		
		# Now to turn them into Buys
		for r in needs:
			availiable = the_city.wealth/len(needs)
			amount_needed = -the_city.goods[r]
			
			while amount_needed > 0 and len(offers[r]) > 0:
				best_offer = None
				best_price = 99999
				
				for i, o in enumerate(offers[r]):
					if o[0] < best_price:
						best_offer = i
						best_price = o[0]
				
				accepted_offer = offers[r][best_offer]
				
				del(offers[r][best_offer])
				
				# print("")
				# print(accepted_offer)
				city_dict[accepted_offer[1][0]].sells.append((r, accepted_offer[1], accepted_offer[2]))
Beispiel #24
0
def check_available(cursor, verbose):
	the_world = world.World(cursor)
	
	unit_dict				= the_world.units()
	unit_q.mass_get_unit_equipment(cursor, the_world._units)
	
	equipment_dict			= the_world.equipment()
	city_dict				= the_world.cities()
	terrain_tuples			= mapper_q.get_all_terrain(cursor)
	map_continent_tiles		= path_f.get_map_continent_tiles(cursor)
	
	# First we need to get the continents and terrains of each team
	team_dict = {}
	
	if verbose:
		it = cli_f.progressbar(city_dict.items(), "military_check.check_available: ", 40, with_eta = True)
	else:
		it = city_dict.items()
	
	for city_id, the_city in it:
		if the_city.dead > 0: continue
		if the_city.team not in team_dict: team_dict[the_city.team] = Team_lands(the_city.team)
		
		city_loc = (the_city.x - (the_city.x % 10), the_city.y - (the_city.y % 10))
		
		city_terrain, city_continent = 0, 0
		
		if city_loc in terrain_tuples: city_terrain = terrain_tuples[city_loc]
		if city_loc in map_continent_tiles: city_continent = map_continent_tiles[city_loc]
		
		team_dict[the_city.team].add_city(city_continent, city_terrain)
	
	# Next we'd get the techs too if possible
	
	
	# Now we go through each unit and find out if it's availiable
	not_available			= []
	for unit_id, the_unit in unit_dict.items():
		if the_unit.team < 2: continue# Skip units that are for all teams
		
		# If a team doesn't exist in the dictionary then it's because they've no cities
		if the_unit.team not in team_dict:
			# not_available.append(unit_id)
			continue
		
		checked_unit = False
		the_team = team_dict[the_unit.team]
		
		for e in the_unit.equipment:
			if checked_unit: continue
			the_equipment = equipment_dict[e]
			
			if the_equipment.continent > 0:
				if the_equipment.terrain > 0:
					# Need both
					if not the_team.check_matrix(the_equipment.continent, the_equipment.terrain):
						not_available.append(unit_id)
						checked_unit = True
				else:
					# Just continent
					if the_equipment.continent not in the_team.continents:
						not_available.append(unit_id)
						checked_unit = True
			else:
				if the_equipment.terrain > 0:
					# Just terrain
					if the_equipment.terrain not in the_team.terrain:
						not_available.append(unit_id)
						checked_unit = True
			
			# Now we can check tech level too
				
			# self.add_field("terrain",				"int")# 0 = Any terrain
			# self.add_field("tech",					"int")# 0 = No tech needed
			# self.add_field("tech_level",			"int")# 0 = No tech needed
	
	query = """UPDATE units SET available = True;"""
	try: cursor.execute(query)
	except Exception as e:
		raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))
	
	if not_available != []:
		query = """UPDATE units
			SET available = False
				WHERE id IN (%s);""" % "".join([str(u) for u in not_available])
		
		try: cursor.execute(query)
		except Exception as e:
			raise Exception("Database error: %s\nQuery: %s" % (str(e.args[0]).replace("\n",""), query))