Created
February 6, 2024 05:22
-
-
Save alairock/68e3789f47211a7c0b4db519a6f62a7e to your computer and use it in GitHub Desktop.
Secret Hitler Night Phase Code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sh | |
import ( | |
"errors" | |
"math/rand" | |
) | |
type Game struct{} | |
type GameState struct { | |
IsHitler bool | |
IsFascist bool | |
OtherFascists []string | |
HitlerID string | |
} | |
// create error with name ErrInvalidNumberOfPlayers | |
var ErrInvalidNumberOfPlayers = errors.New("invalid number of players") | |
func (g Game) Night(users []string) (map[string]*GameState, error) { | |
if len(users) < 5 || len(users) > 10 { | |
return nil, ErrInvalidNumberOfPlayers | |
} | |
userStates := make(map[string]*GameState) | |
// Shuffle the list | |
rand.Shuffle(len(users), func(i, j int) { | |
users[i], users[j] = users[j], users[i] | |
}) | |
numberOfFascists := 1 | |
if len(users) >= 7 && len(users) <= 10 { | |
numberOfFascists = len(users) / 3 | |
} | |
// assign roles to each user | |
fascistIds := make([]string, 0) | |
for i, user := range users { | |
state := &GameState{IsHitler: false, IsFascist: false, OtherFascists: []string{}, HitlerID: ""} | |
if i < numberOfFascists { | |
state.IsFascist = true | |
fascistIds = append(fascistIds, user) | |
} else if i == numberOfFascists { | |
state.IsHitler = true | |
state.IsFascist = true | |
} | |
userStates[user] = state | |
} | |
// if there are only 5 or 6 players, then we let hitler know who the other fascists are | |
if len(users) == 5 || len(users) == 6 { | |
userStates[users[numberOfFascists]].OtherFascists = fascistIds | |
} | |
// Now we let the fascists know who eachother and hitler are. (This is the rule for all games with 5-10 players.) | |
for i := 0; i < len(fascistIds); i++ { | |
userStates[fascistIds[i]].OtherFascists = fascistIds | |
userStates[fascistIds[i]].HitlerID = users[numberOfFascists] | |
} | |
return userStates, nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package sh | |
import ( | |
"testing" | |
) | |
func TestGame_Night(t *testing.T) { | |
game := Game{} | |
users := []string{"ZAlice", "Bob", "Charlie", "Diana"} | |
_, err := game.Night(users) | |
if err != nil { | |
if err != ErrInvalidNumberOfPlayers { | |
t.Errorf("Expected error to be ErrInvalidNumberOfPlayers, got %v", err) | |
} | |
} | |
users = []string{"ZAlice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Hannah", "Ivan", "Jack", "Katie"} | |
_, err = game.Night(users) | |
if err != nil { | |
if err != ErrInvalidNumberOfPlayers { | |
t.Errorf("Expected error to be ErrInvalidNumberOfPlayers, got %v", err) | |
} | |
} | |
// 5 users | |
users = []string{"Alice", "Bob", "Charlie", "Diana", "Eve"} | |
AssertFascistsAndHitler(t, users, 1, 1) | |
// 6 users | |
users = []string{"Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"} | |
AssertFascistsAndHitler(t, users, 1, 1) | |
// 7 users | |
users = []string{"Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace"} | |
AssertFascistsAndHitler(t, users, 2, 1) | |
// 8 users | |
users = []string{"Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Hannah"} | |
AssertFascistsAndHitler(t, users, 2, 1) | |
// 9 users | |
users = []string{"Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Hannah", "Ivan"} | |
AssertFascistsAndHitler(t, users, 3, 1) | |
// 10 users | |
users = []string{"Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Hannah", "Ivan", "Jack"} | |
AssertFascistsAndHitler(t, users, 3, 1) | |
} | |
func AssertFascistsAndHitler(t *testing.T, users []string, expectedFascists int, expectedHitler int) { | |
game := Game{} | |
states, err := game.Night(users) | |
if err != nil { | |
t.Errorf("Expected no error, got %v", err) | |
} | |
// Test for correct number of fascists and Hitler | |
fascistsCount := 0 | |
hitlerCount := 0 | |
for _, state := range states { | |
if state.IsFascist && !state.IsHitler { | |
fascistsCount++ | |
} | |
if state.IsHitler { | |
hitlerCount++ | |
} | |
} | |
if fascistsCount != expectedFascists { | |
t.Errorf("Expected %d fascists, got %d", expectedFascists, fascistsCount) | |
} | |
if hitlerCount != expectedHitler { | |
t.Errorf("Expected 1 Hitler, got %d", hitlerCount) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment