Fixed Positions code




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()
 
Back
Top Bottom