Como funciona o algoritmo
Quando o jogo começa, devemos distribuir os jogadores para que cada equipe tenha uma quantidade adequada de jogadores.
Ao contrário dos jogos em que a distribuição dos jogadores é simétrica e os jogadores são distribuídos uniformemente entre as equipes, equilibrar as equipes de forma assimétrica significa que cada uma deve ter um número relativo de jogadores. Em outras palavras, os tamanhos das equipes devem seguir uma proporção relativa.
Por exemplo, digamos que você queira que uma equipe sempre tenha o dobro do número de jogadores da outra. À medida que os jogadores entram, devemos distribuí-los de maneira a preservar esse número relativo. Nos modos de jogo em que uma equipe é mais poderosa ou tem habilidades diferentes em relação a outra equipe, o equilíbrio assimétrico cria experiências de jogo mais harmoniosas ao distribuir cuidadosamente o número de jogadores em cada equipe.
Neste exemplo, você precisa garantir que as equipes com um número máximo maior de jogadores (neste caso, os defensores) sempre tenham mais jogadores do que as equipes com um máximo menor (como os infiltradores).
Para distribuir os jogadores corretamente, você terá que colocar cada jogador na equipe com a maior diferença em relação ao número máximo de jogadores.
Para isso, para cada novo jogador, você terá que verificar cada equipe e armazenar uma referência tanto para o número máximo quanto para o número atual de jogadores dessa equipe, bem como da equipe à qual atribuir esse jogador. Você pode subtrair o número máximo de jogadores do número atual para obter a diferença em relação ao máximo. Ao encontrar uma equipe com uma diferença maior em relação ao máximo, você definirá o jogador a ser atribuído a essa equipe.
Ao iterar entre as equipes, você garante que encontrará a equipe com a maior diferença.
Como definir o algoritmo
Esta etapa mostra como distribuir equipes de jogadores de maneira assimétrica no início de um jogo.
- Adicione um novo método chamado
BalanceTeams()à classetriad_infiltration_game. Esse método atribui um jogador à equipe com a maior diferença em relação ao seu número máximo de jogadores. ~~~(verse) # Equilibra todos os jogadores de todas as equipes do jogo BalanceTeams():void= Logger.Print("Começando a distribuir as equipes") ~~~ - Coloque todos os jogadores no jogo e armazene-os em uma matriz de variáveis
AllPlayers. Em seguida, embaralheAllPlayers. Isso garantirá que os jogadores sejam atribuídos às equipes aleatoriamente, e não com base na ordem em que entraram inicialmente no jogo.# Equilibra todos os jogadores de todas as equipes do jogo BalanceTeams():void= Logger.Print("Começando a distribuir as equipes") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) - Agora, você deve percorrer todos os jogadores e atribuí-los à equipe com a maior diferença em relação ao número máximo de jogadores. Você fará isso por meio de uma função auxiliar que criará na próxima etapa, denominada
FindTeamWithLargestDifference(), mas primeiro, inicialize uma variável de opção chamadaTeamToAssignpara atribuir um jogador e defina-a com o valor retornado deFindTeamWithLargestDifference(). ~~~(verse) for (TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() ~~~ - Crie a função
FindTeamWithLargestDifference()na definição da classetriad_infiltration_game. Essa função encontrará a equipe com a maior diferença no número de jogadores em comparação com seu máximo e retornará umateamopcional. É importante que a funçãoteamretornada seja uma opção para evitar a reatribuição de um jogador quando ele já estiver na equipe com a maior diferença. ~~~(verse) # Encontrar a equipe com a maior diferença no número de jogadores em comparação com seu # número máximo de jogadores FindTeamWithLargestDifference():?team = Logger.Print("Tentativa de encontrar a menor equipe") ~~~ - Inicialize uma variável de equipe opcional chamada
TeamToAssignque armazenará uma referência à equipe com a maior diferença de jogadores e um número inteiroLargestDifferencepara rastrear essa diferença de jogadores. ~~~(verse) # Encontrar a equipe com a maior diferença no número de jogadores em comparação com seu # número máximo de jogadores. FindTeamWithLargestDifference():?team = Logger.Print("Tentativa de encontrar a menor equipe") var TeamToAssign:?team = false var LargestDifference:int = 0 ~~~ - Agora percorra a lista de equipes, obtendo o tamanho atual e máximo dessa equipe. ~~~(verse) var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] ~~~
- Para cada equipe, calcule
DifferenceFromMaximum, que é a diferença entre o tamanho máximo dessa equipe e o número de jogadores que ela possui atualmente. Se a equipe tiver uma diferença maior queLargestDifference, definaLargestDifferencecomoDifferenceFromMaximume envolvaTeamToAssignem umaoption. ~~~(verse) for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Verificando uma equipe...") Logger.Print("O tamanho máximo desta equipe é {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("A diferença do máximo é {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Foi encontrada uma equipe abaixo do máximo de jogadores: {DifferenceFromMaximum}") ~~~ - Por fim, retorne
TeamToAssign. Seu códigoFindTeamWithLargestDifference()agora deve ter a seguinte aparência: ~~~(verse) # Encontrar a equipe com a maior diferença no número de jogadores em comparação com seu # número máximo de jogadores. FindTeamWithLargestDifference():?team = Logger.Print("Tentativa de encontrar a menor equipe") var TeamToAssign:?team = false var LargestDifference:int = 0 for: CandidateTeam:Teams CurrentTeamSize := GetPlayspace().GetTeamCollection().GetAgents[CandidateTeam].Length MaximumTeamSize := TeamsAndTotals[CandidateTeam] do: Logger.Print("Verificando uma equipe...") Logger.Print("O tamanho máximo da equipe {CandidateTeamIndex + 1} é {MaximumTeamSize}") DifferenceFromMaximum := MaximumTeamSize - CurrentTeamSize Logger.Print("A diferença em relação ao mínimo é {DifferenceFromMaximum}") if(LargestDifference < DifferenceFromMaximum): set LargestDifference = DifferenceFromMaximum set TeamToAssign = option{CandidateTeam} Logger.Print("Foi encontrada uma equipe abaixo do mínimo de jogadores: {DifferenceFromMaximum}") return TeamToAssign ~~~ - De volta a
BalanceTeams(), atribua o jogador a uma nova equipe por meio da funçãoFortTeamCollection.AddToTeam[]. Se essa atribuição falhar, o jogador já estava na menor equipe. ~~~(verse) var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Tentando atribuir um jogador a uma nova equipe") ~~~ -
Sua função
BalanceTeams()deve ter a seguinte aparência: ~~~(verse) # Equilibra todos os jogadores de todas as equipes do jogo BalanceTeams():void= Logger.Print("Começando a distribuir as equipes") var AllPlayers:[]player := GetPlayspace().GetPlayers() set AllPlayers = Shuffle(AllPlayers) Logger.Print("O comprimento de AllPlayers é {AllPlayers.Length}")for (TeamPlayer:AllPlayers): var TeamToAssign:?team = false set TeamToAssign = FindTeamWithLargestDifference() if (AssignedTeam := TeamToAssign?, FortTeamCollection.AddToTeam[TeamPlayer, AssignedTeam]): Logger.Print("Jogador atribuído a uma nova equipe") ~~~
Como teletransportar jogadores para suas áreas de surgimento
Mesmo que os jogadores acabem na equipe com a maior diferença, eles podem não surgir na área correta. Isso ocorre porque os jogadores surgem antes de serem designados a uma nova equipe. Para lidar com essa situação, você criará uma nova função para teletransportar os jogadores para o ponto de surgimento após a distribuição das equipes.
- Crie a função
TeleportPlayersToStartLocations()na definição de classetriad_infiltration_game. Essa função teletransportará os jogadores para o ponto de surgimento da equipe após o término da distribuição. ~~~(verse) # Teletransporta os jogadores até a plataforma de surgimento de suas respectivas equipes após o término do equilíbrio de equipes. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando jogadores para locais iniciais") ~~~ - Em um loop
for, percorra todas as equipes na matrizTeams, obtendo o índice para essa equipe e armazenando-o em uma variávelTeamIndex. ~~~(verse) # Teletransporta os jogadores até a plataforma de surgimento de suas respectivas equipes após o término do equilíbrio de equipes. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando jogadores para locais iniciais") for: TeamIndex -> PlayerTeam:Teams ~~~ - Coloque os jogadores em
PlayerTeamchamandoGetAgents[]com o uso dePlayerTeam. Em seguida, obtenha o teletransportador associado a essa equipe indexando-o na matrizTeleporterscomTeamIndexe armazenando-o em uma variávelTeamTeleporter. Armazene a transformação desse teletransportador em uma variávelTransform. ~~~(verse) # Teletransporta os jogadores até a plataforma de surgimento de suas respectivas equipes após o término do equilíbrio de equipes. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando jogadores para locais iniciais") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform() ~~~Certifique-se de que a ordem de suas equipes em
Teamscorresponda à ordem de seus teletransportadores emTeleporters. Se os Infiltradores forem da Equipe 1, o primeiro teletransportador emTeleportersdeverá ser para os Infiltradores. Verifique novamente no editor se esses valores estão corretos. -
Agora, em um segundo loop
for, percorra cada jogador emTeamPlayerse faça-os ressurgir na transformação do teletransportador usandoRespawn()e a translação e rotação doTransform. Sua funçãoTeleportPlayersToStartLocations()deve se parecer com: ~~~(verse) # Teletransporta os jogadores até a plataforma de surgimento de suas respectivas equipes após o término do equilíbrio de equipes. TeleportPlayersToStartLocations():void= Logger.Print("Teletransportando jogadores para locais iniciais") for: TeamIndex -> PlayerTeam:Teams TeamPlayers := GetPlayspace().GetTeamCollection().GetAgents[PlayerTeam] TeamTeleporter := Teleporters[TeamIndex] Transform := TeamTeleporter.GetTransform() do: for(TeamPlayer:TeamPlayers): TeamPlayer.Respawn(Transform.Translation, Transform.Rotation) Logger.Print("Teletransportou este jogador para o local inicial") ~~~ -
Em
OnBegin(), adicione uma chamada paraBalanceTeams()depois de embaralharAllPlayers. Assim, os jogadores ficarão distribuídos em ordem aleatória, em vez de terminarem na mesma equipe todas as vezes. Em seguida, teletransporte os jogadores para seus locais iniciais chamandoTeleportPlayersToStartLocations(). ~~~(verse) OnBegin() : void = # Obtenha todas as equipes. set Teams = GetPlayspace().GetTeamCollection().GetTeams() # Salve as equipes para fazer referência a elas mais tarde set MaybeInfiltrators = option{Teams[0]} set MaybeAttackers = option{Teams[1]} set MaybeDefenders = option{Teams[2]} if: Infiltrators := MaybeInfiltrators? Attackers := MaybeAttackers? Defenders := MaybeDefenders? Logger.Print("As três equipes foram encontradas") set TeamsAndTotals[Infiltrators] = MaximumInfiltrators set TeamsAndTotals[Attackers] = MaximumAttackers set TeamsAndTotals[Defenders] = MaximumDefenders Logger.Print("Coloque as três equipes em TeamsAndTotals") then: BalanceTeams() TeleportPlayersToStartLocations() else: Logger.Print("Não foi possível encontrar todas as equipes, certifique-se de atribuir as equipes corretas nas configurações da ilha.") ~~~
-
Salve o script, compile-o e clique em "Iniciar sessão" na barra de ferramentas do UEFN para testar o nível. Quando fizer isso, cada jogador deverá terminar na equipe com a maior diferença e surgir na área de surgimento dessa equipe. Confirme esse comportamento usando o log. É possível ajustar o número máximo de jogadores por equipe em seu
triad_infiltration_gamepara testar essa funcionalidade quando tiver menos do que o número máximo de jogadores. Por exemplo, ao testar por conta própria, tente definir um número máximo de jogadores mais alto para a equipe na qual você quer ficar do que para as outras duas equipes. Se quiser ficar nos atacantes, defina um valor mais alto paraMaximumAttackers. Se quiser ficar nos infiltradores, defina um valor mais alto paraMaximumInfiltrators.
Próxima etapa
Na próxima etapa deste tutorial, você aprenderá a distribuir armas aos jogadores no início do jogo e quando eles surgirem.