1

I have created a dictionary named Teams and I use a struct to make hold an integer, a string and a boolean.

So if anyone joins a red team, the bool will be false to prevent other players from joining same team.

I tried to set the boolean to false but it failed.

public Dictionary <int , myCustomType> Teams = new Dictionary<int,myCustomType>();

private ExitGames.Client.Photon.Hashtable m_PlayerCustomPropeties = new ExitGames.Client.Photon.Hashtable();

private void addTeams() 
{
    myCustomType t=new myCustomType();

    t.name="Yellow"; 
    t.flag= true;
    Teams.Add(1,t);

    t.name="Red"; 
    t.flag= true;
    Teams.Add(2,t);

    t.name="Blue"; 
    t.flag= true;
    Teams.Add(3,t);

    t.name="Green"; 
    t.flag= true;
    Teams.Add(4,t);

    Debug.Log("Teams created.");
}

public void getPlayers() 
{
    Debug.Log(Teams[1].flag);
    Teams[1] = new myCustomType { flag = false };
}
Anteeiiku
  • 13
  • 5
  • 2
    What do you mean by *"I failed"*? What exactly happens? And what do you see when you debug the code? – UnholySheep Sep 02 '18 at 14:32
  • 1
    You are not just editing the flag, you are replacing the entire object. Try Teams[1].flag = false; – Ron Beyer Sep 02 '18 at 14:36
  • @UnholySheep Hello, when I write " Debug.Log(Teams[1].name); " its give me error Null so its replace all – Anteeiiku Sep 02 '18 at 14:39
  • @RonBeyer Hello , it's say " Cannot modify the return value of 'Dictionary.this[int]' because it is not a variable [Assembly-CSharp] " in "Team[1] " – Anteeiiku Sep 02 '18 at 14:41
  • Is `myCustomType` a `struct`, not a `class`? Because in `addTeams` you re-use the same `t` over and over again. Maybe you should show the definition of `myCustomType`. – Jeppe Stig Nielsen Sep 02 '18 at 14:41
  • The error message you write about is as if you said `Teams[1].flag = false` where `Teams[1]` is a ___value___ of your `struct` type. – Jeppe Stig Nielsen Sep 02 '18 at 14:43

2 Answers2

4

Your type is defined as:

public struct myCustomType
{
  public string name;
  public bool flag;
}

And Teams is a Dictionary<int, myCustomType>. When you tried something like:

Teams[1].flag = false;

it failed because Teams[1] is just a value (the return value of the Dictionary<,> indexer getter).

Your type myCustomType is a mutable struct. The struct is returned by value, so it makes no sense to try to modify the returned copy of the value.

You will need:

var mct = Teams[1];  // 'mct' is a copy of the value from the 'Dictionary<,>'.
mct.flag = false;    // You modify the copy which is allowed because 'mct' is a variable.
Teams[1] = mct;      // You overwrite the old value with 'mct'.

Some people consider mutable structs evil.

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • thank you , is there anyway to add teams without repeating "t" ? – Anteeiiku Sep 02 '18 at 15:05
  • @Anteeiiku What you do now in `addTeams`, works well enough with the `struct` because each time you call `Teams.Add`, a copy of the current `t` is passed. Another option would be `Teams.Add(1, new myCustomType { name = "Yellow", flag = true, }); Teams.Add(2, new myCustomType { name = "Red", flag = true, });` and so on. You can even write it all as one huge collection initializer if you prefer. – Jeppe Stig Nielsen Sep 02 '18 at 15:11
  • Thank you , you made my day =D . – Anteeiiku Sep 02 '18 at 15:19
1

This seems like an anti-pattern. Make your struct immutable (you may not want a struct for this anyway, especially if the team needs other functionality):

public struct myCustomType
{   
    public string Name { get; }

    public myCustomType(string name)
    {
        this.Name = name;
    }
}

Create a set of available teams, which you populate similarly to your addteams method:

public Dictionary<string, myCustomType> AvailableTeams; //color, team
public void InitializeTeams()
{
    AvailableTeams = new Dictionary<string, myCustomType>()
    {
        ["Yellow"] = new myCustomType("Yellow"),
        ["Red"] = new myCustomType("Red"),
        ["Blue"] = new myCustomType("Blue"),
        ["Green"] = new myCustomType("Green")
    };
}

When a player joins a team, remove that team from the available set, and add it to a set of ActiveTeams:

public Dictionary<int, myCustomType> ActiveTeams; //player #, team

public void JoinTeam(int playerNumber, string teamColor)
{
    if (!AvailableTeams.TryGetValue(teamColor, out myCustomType team)
    // handle team already taken.

    ActiveTeams.Add(playerNumber, team);
    AvailableTeams.Remove(teamColor);
}
Parrish Husband
  • 3,148
  • 18
  • 40