Search Unity

Challenging Problem

Discussion in 'Scripting' started by kevin5141, Feb 24, 2017.

?

Is this even possible?

  1. yes

  2. no

  3. maybe... If the data was stored properly.

Results are only viewable after voting.
  1. kevin5141

    kevin5141

    Joined:
    Jan 11, 2017
    Posts:
    5
    Hi guys, I have a very challenging problem I would love some help with! I code in C#

    If a players chance of winning is increased based on their level.

    The Players Names are stored in List<string> Player. The Player level is List<int> Chances. If Amy is level 7 and George is level 9, Cindy is level 4, Dave is level 2, Emily is level 5, Frank is 17.

    The Game randomly shows a winner based of the new chances a player has to win, Frank should win.

    Here is my example code:
    {
    using System.Collections.Generic;
    using UnityEngine;

    public class DrawSetUpPetLevel : MonoBehaviour
    {
    private string winner;
    List<string> Player;
    List<int> Chances;
    List<string> PlayerChances;

    public void Start()
    {
    for (int j = 0; j < Player.Capacity; j++)
    {
    // PlayerChances = Player + Chances;
    }
    }
    public void whoWon()
    {
    // winner = Random.PlayerChances;
    Debug.Log(winner);
    }
    }
    }

    I would love the help! This might not be possible... How do I store the data to make it work? The data is collected from the client and sent to the server when a player clicks a UI button.
     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,188
    First, always use code tags https://forum.unity3d.com/threads/using-code-tags-properly.143875/
    Second, generally better not to include polls unless they are really necessary.

    Third, I honestly don't know what you are really asking. Can a winner be chosen from a list with a higher chance of winning based on level? Yes, there isn't anything really challenging there other then maybe creating the proper algorithm to choose the player. I would suggest you make either a strut or class so you can relate player with their level and maybe percent chance to win (basically just to associate the data together better).
     
  3. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    In addition to +1ing everything that @Brathnann said, it sounds like what you want is, essentially, that if Bob has 2 chances to win and Alice has 3 chances to win, you want an algorithm that will randomly choose Bob 40% of the time and Alice 60% of the time. Is that correct?

    Here is an algorithm to do this. It's not the most efficient algorithm, but it's the most easily understood:
    Code (csharp):
    1. List<PlayerClass> players; //to be populated elsewhere. Assumes .name is string and .chances is int
    2. PlayerClass RandomlyPickWinner() {
    3. int totalChances = 0;
    4. //first, what's our total?
    5. for (int p=0;p<players.Length;p++) {
    6. totalChances += players[p].chances;
    7. }
    8. //next, choose a number
    9. int chosenNumber = Random.Range(0, totalChances);
    10. //finally, run through the players, adding their chances, until our running total is higher than our random number
    11. int thisPlayerHigh = 0;
    12. for (int p=0;p<players.Length;p++) {
    13. thisPlayerHigh += players[p].chances;
    14. if (thisPlayerHigh > chosenNumber) {
    15. return players[p];
    16. }
    17. }
    18. return null; //if I wrote this algorithm correctly, the only way we ever get here is if the list is empty
    19. }
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,537
    Here's a somewhat recent post in which we all discuss weighted random selection:
    https://forum.unity3d.com/threads/random-numbers-with-a-weighted-chance.442190/#post-2859611

    In which I even link to an even older thread also about it:
    https://forum.unity3d.com/threads/making-random-range-generate-a-value-with-probability.336374/

    In which I actually go into detail about the concept of the algorithm.

    And of course my fully fleshed out version is found in here as 'PickRandom' with memory optimizations added:
    https://github.com/lordofduct/space...blob/master/SpacepuppyBase/Utils/ArrayUtil.cs
     
    Last edited: Feb 24, 2017
  5. Pavlon

    Pavlon

    Joined:
    Apr 15, 2015
    Posts:
    191
    I didnt test it but i am 99% sure that this should do it.

    Edit: just realized that @StarManta gave prettry mutch the same answer.
    Edit2: @lordofduct in your answer you use only 1 random value thats good but dont your
    prioritize "players" that come first in the list or am i missing some thing ?

    Code (CSharp):
    1.         List<int> chanceList = new List<int>();
    2.         float total = 0;
    3.         int winner = 0;
    4.  
    5.         foreach(int value in chanceList)
    6.             total += value;
    7.  
    8.         float leaderPoints = 0.0f;
    9.  
    10.         foreach(int value in chanceList)
    11.         {
    12.             float points = Random.Range(0.0f,(float)value / total);
    13.             if(points > leaderPoints)
    14.             {
    15.                 leaderPoints = points;
    16.                 winner = value;
    17.             }
    18.         }
    19.         //Debug.Log(playerList[winner]);
     
    Last edited: Feb 24, 2017