Code:
import math
'''
function to generate all the team distributions of a given number of players
taking care that teams have at least 2 players and only the first teams are filled
n: number of players to assign
distrib: list with the number of players in each team. Initially all zeros
indexes: 0: unassigned players, 1,2,3,4: teams
t: team to asign, initially 1
'''
def team_variations(n,distrib,t):
#list with all the variations to be retrieved after all team_variations executions finish
global variations
#case of unassigned players, team 5
if t == 5:
distrib[0]=n #add players to the unasigned players team
variations.append(distrib)#add distribution to the list of variations
return
#don't assign less than 2 players to a team
elif n < 2: #if you have less than two players to assign
team_variations(n,distrib,t+1) #step team counter until reaching 5, unassigned case
return
#don't leave teams empty
elif t >= 2 and distrib[t-1] == 0: #if the team to assign is 2 or more but the previous is empty
team_variations(n,distrib,t+1) #step team counter until reaching 5, unassigned case
return
#fill the team with every possible variation of number of players
#for number of players between 2 and n
for i in range(2,n+1):
#create a copy of the current distribution and set the number of players
#on the current team to assign to i
distrib_aux = distrib[:]
distrib_aux[t] = i
#recursive call with less available players and for the next team
team_variations(n-i,distrib_aux,t+1)
#recursive call with all the players in the next team, used to get to the unassigned case
team_variations(n,distrib,t+1)
'''
function that computes the number of teams with positive number of players
variation: list with the number of players in each team.
indexes: 0: unassigned players, 1,2,3,4: teams
'''
def number_of_teams(variation):
k = 0
for i in range(1,5):
if variation[i] > 0:
k += 1
return k
'''
function that returns a string with the team and the number of players in it
variation: list with the number of players in each team.
indexes: 0: unassigned players, 1,2,3,4: teams
i: team to display
'''
def team_size(variations,i):
return 'TEAM'+str(i)+'_SIZE'+str(variations[i])
'''
Function that computes the coordinates of a player base along a circle
radius: of the circle from the center of the map, measured in percent of total length
players: number of players to fit in the circle
per_player: number of positions available to every player.
this controls that, when computing for 2 players, one can create more than 2 positions
but still have the players opposed.
'''
def circle(radius, players, per_player=1):
'''
rotations and events handle the probability distribution.
rotations decide the overall position of players, there are as many as the value of per-player
events decide which of the positions belong to which player, there are as many as the value of players
'''
#rotations, given by per_player
rotations = [100//per_player]*per_player #probabilities have to be an integer number
#events, given by players
events = [100//players]*players #probabilities have to be an integer number
#distribute the remining probability up to 100
#per_player
rem = 100 - rotations[0]*per_player
while rem > 0:
for i in range(per_player):
rotations[i] += 1
rem -= 1
if rem == 0:
break
#players
rem = 100 - events[0]*players
while rem > 0:
for p in range(players):
events[p] += 1
rem -= 1
if rem == 0:
break
#angle to generate as many rotations as given in per_player
pp_angle = 2*math.pi/(players*per_player)
#angle between players
angle = 2*math.pi/(players)
'''
output string will hold all the text that nedds to be added to the rms file
'''
output = ''
#write the random sample that generates the cases:
#rotations
if per_player > 1:
output+=' start_random\n'
for i in range(per_player):
output+=' percent_chance '+str(rotations[i])
output+=' #define ROTATION_'+str(i+1)+'\n'
output+=' end_random\n\n'
#events
output+=' start_random\n'
for p in range(players):
output+=' percent_chance '+str(events[p])
output+=' #define PLACE_'+str(p+1)+'\n'
output+=' end_random\n\n\n'
#write the coordinates of the positions
global variations, constants
'''
variations will hold all the valid combinations of players and teams
constants holds the text that has to go in all the create_land entries
'''
variations = []
team_variations(players,[0]*5,1)
#now variations holds all the possible variations of players per team
#Create as many lands as players, adding the random cases given by rotation
for p in range(players):
'''
create the player land
'''
output += ' create_land {\n'
output += constants #text that has to be written always
if per_player > 1: #if there is more than one rotation
first_rotation = True #flag to write "if" or "elseif"
for i in range(per_player):
if first_rotation:
output += ' if '
first_rotation = False
else:
output += ' elseif '
output += 'ROTATION_'+str(i+1)+'\n'
coord_x = round(50 + radius*math.cos(angle*p+pp_angle*i))
coord_y = round(50 + radius*math.sin(angle*p+pp_angle*i))
output+=' land_position '+str(coord_x)+' '+str(coord_y)+'\n'
output += ' endif\n\n'
else: #per_player == 1
coord_x = round(50 + radius*math.cos(angle*p))
coord_y = round(50 + radius*math.sin(angle*p))
output+=' land_position '+str(coord_x)+' '+str(coord_y)+'\n\n'
'''
assign the player land
'''
#for each variation of teams
for v in variations:
if v[1]==v[2] and v[1]+v[2]==players and v[1]>=3: #if there are two even teams
output += ' if '
output += str(number_of_teams(v))+'_TEAM_GAME\n'
#write all the sizes of each team in the variation (with actual players)
#this creates several nested "if" clauses to act as "and"
for t in range(1,5): #skip team 0, unassigned
if v[t] == 0: #if the team is empty, the others will be too
break
output += ' if '+team_size(v,t)+'\n'
#Distribute land for teams
#list with as many elements as the number of players, sorted by team (odds, evens)
colors =list(range(1,players+1,2))+list(range(2,players+1,2))
first_players = True #flag to write "if" or "elseif"
#for each player
for l in range(players):
string = 'PLACE_'+str(l+1)#random sample given by the events list, one per player
if first_players:
output+=' if '
first_players = False
else:
output+=' elseif '
output += string+'\n'
#in each iteration of the l loop, the index (p+l)%players will increase by one
#the value p is placed so that each land is assigned to consecutive players
output += ' assign_to AT_COLOR '+str(colors[(p+l)%players])+' 0 0\n'
output += ' endif\n'
#endif for team sizes, this closes the nested "if" from above
for t in range(1,5): #skip team 0, unassigned
if v[t] == 0: #if the team is empty, the others will be too
break
output += ' endif\n'
#endif of variation v
output += ' endif\n\n'
output += ' }\n\n' #end of the create_land
return output
global constants #text that has to be written in every create_land
'''
EDIT THIS with the constants of the particular map
'''
constants = ' terrain_type LAYER_A\n land_percent 4\n base_size 9\n'
file=open('fixed_positions.txt','w')
file.write('if ')
file.write('6'+'_PLAYER_GAME\n')
#generate the code for the circle of the given number of players and write it in the file
file.write(circle(37,6,1))
file.write('elseif ')
file.write('8'+'_PLAYER_GAME\n')
#generate the code for the circle of the given number of players and write it in the file
file.write(circle(38,8,1))
file.write('endif')
file.close()