How can I set the default value of logic variables in a map

So I made a map which is basically a logic variable for each player, I use this to do other things but I don’t know how to set all of these variables to false by default, can anyone help? tia

You don’t need to, using a [player]logic map, you can omit the logic, it’s not really ‘logical’ but it’s how it’s done, you can just check like this :

MyMap : [player]logic = map{}

if(Player := player[Agent], MyMap[Player]): # If index exists, don't check the logic value
    # do this

# When you want to update your map just do this:
option{set MyMap = MyMap.WithRemovedKey[Player]}

# When you want to update to true, keep using:
option{set MyMap[Player] = true} # Even if the logic is not used, we need to set a value anyway

Put this somewhere :

# Returns the same map with the provided index removed, unchanged map if Index not found
(Input:[t]u where t:subtype(comparable), u:type).WithRemovedKey(KeyToRemove:t)<transacts><decides>:[t]u = 
    var RetMap:?[t]u = option{map{}}

    if(not Input[KeyToRemove]):
        set RetMap = option{Input}
    else:
        for (Key -> Value : Input, Key <> KeyToRemove, CurrentMap := RetMap?):
            set RetMap = option{ConcatenateMaps(CurrentMap, map{Key => Value})}

    return RetMap?

This way, you optimize memory by removing the player reference from the map, in case your island is not round based and can last for hours.
Also you don’t get confused between using MyMap[Player] and MyMap[Player]?, both will work since you never set the value to false.
Otherwise, if you forget to put the ? and check with MyMap[Player] the condition will succeed even if the value is false and the compiler will not throw any warning or error.

Using this method, you shall never do : option{set MyMap[Player] = false} because it can lead to errors if your conditions are not built properly.

Ok so that’s my way to do it, but if you want to initialize everything to false, you can just listen to spawner SpawnedEvent and call option{set MyMap[Player] = false} on the spawned player! Hope I didn’t loose you there :smiley:

Even better, you can use an array of players and use Array.Find[Player] as the logic, then remove them with set Array = Array.RemoveFirstElement[Player]

Arrays are not indexed, calling array.Find[] will iterate on all the elements which is a really bad practice :+1:
The RemoveFirstElement method will act the same way.

I guess I’m doing the same with my WithRemovedKey call, but atleast it only happens upon removal and this could evolve in a future where we don’t need to mutate the whole map :man_shrugging:

Fair point! Btw, are you sure your extension function is correct? I’m not sure why you’re using an option for the map, and if the key isn’t found then it seems to return an empty map

This should work:

(Input:[k]v where k:subtype(comparable), v:type).RemoveKey(KeyToRemove:k):[k]v=
    if (Input[KeyToRemove]):
        var NewMap:[k]v = map{}
        for (Key->Value : Input, Key <> KeyToRemove) do if:
            set NewMap[Key] = Value
        NewMap
    else:
        Input
1 Like

Thanks, I updated the function, yeah I could use an upgrade on this one!

1 Like

The ReturnSameMap is also unnecessary, you could just do that check directly :sweat_smile:

This is really helpful, thanks for writing and posting it. Very handy.

1 Like

You mentioned that I can’t set a player’s variable to false, i dont really understand. Would this work when I toggle the instigator’s variable to false because that’s what I need for my game, hopefully you can help tia

I think I went too far on this, maybe use the above solution :man_shrugging:

Just said that you don’t need to since it can lead to human errors, and it will cause small memory leaks.

Or use this, and check the value with if(MyMap[Player]?):