I am writing a simple console game and would like to map a player to a symbol. With two players my approach looks like this:
func playerToString(p player) string {
if p == 0 {
return "X"
}
return "O"
}
func stringToPlayer(s string) player {
if s == "X" {
return 0
}
return 1
}
Of cause you could also write this as two maps mapping int to string and string to int. Both the above approach and the map approach seem error-prone. Is there a more idiomatic way to write this in go? Maybe some non-iota enum way?
[I assume your example is just minimal and that your actual mapping has more than two options. I also assume you meant bi-directonal mapping]
I would write one map:
var player2string = map[int]string{
0: "0",
1: "X",
// etc...
}
And then would create a function to populate a different map string2player programmatically. Something like this:
var player2string = map[int]string{
0: "0",
1: "X",
// etc...
}
var string2player map[string]int = convertMap(player2string)
func convertMap(m map[int]string) map[string]int {
inv := make(map[string]int)
for k, v := range m {
inv[v] = k
}
return inv
}
func main() {
fmt.Println(player2string)
fmt.Println(string2player)
}
Try it on the Go playground
In addition to Eli's answer, two other changes you could make. You could make the to-symbol function a method of the player type. And because the player values are integers (sequential starting from zero), you can use a slice instead of a map to store the int-to-symbol mapping -- it's a bit more efficient to store and for lookup.
type player int
var playerSymbols = []string{"X", "O", "A", "B", "C", "D", "E", "F", "G", "H"}
func (p player) Symbol() string {
if int(p) < 0 || int(p) >= len(playerSymbols) {
return "?" // or panic?
}
return playerSymbols[p]
}
This method signature could even be String() string so it's a fmt.Stringer, which can be useful for printing stuff out and debugging.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With