Skip to content

Commit

Permalink
extend coin flip syntax to support multiple flips
Browse files Browse the repository at this point in the history
  • Loading branch information
lunakv committed Nov 18, 2023
1 parent 4bc2b75 commit bf3584a
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
57 changes: 53 additions & 4 deletions dice.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,58 @@ func validateDice(input string, dice []string) (Roll, error) {
return wellFormedDice, nil
}

func flipCoin() string {
coin := []string{"Heads", "Tails"}
side := coin[rand.Intn(len(coin))]
func flipCoin(input string) string {
coinCount, err := parseCoinCount(input)
if err != nil {
return err.Error()
}

flips := make([]int, coinCount)
for i := 0; i < coinCount; i++ {
flips[i] = rand.Intn(2)
}
return formatFlips(flips, coinCount)
}

func parseCoinCount(input string) (int, error) {
coinMaximum := 50

coins := coinRegex.FindStringSubmatch(input)
if coins[1] == "" {
// no number specified - implicit one flip
return 1, nil
}

numCoins, err := strconv.Atoi(coins[1])
if err != nil {
return 0, errors.New("malformed coin toss")
}

return fmt.Sprintf("%s.", side)
if numCoins > coinMaximum {
return 0, errors.New("malformed coin toss (max count is 50)")
}
if numCoins < 1 {
return 0, errors.New("malformed coin toss (min count is 1)")
}
return numCoins, nil
}

func formatFlips(flips []int, count int) string {
prefix := ""
coinNames := []string{"Heads", "Tails"}
joiner := ", "
if count > 5 {
prefix = fmt.Sprintf("%d coins: ", count)
coinNames = []string{"H", "T"}
joiner = ""
}

formatted := make([]string, len(flips))
for i := 0; i < len(formatted); i++ {
formatted[i] = coinNames[flips[i]]
}

return fmt.Sprintf("%s%s.", prefix, strings.Join(formatted, joiner))
}


2 changes: 1 addition & 1 deletion dice_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

func TestFlipCoin(t *testing.T) {
for i := 1; i < 10; i++ {
result := flipCoin()
result := flipCoin("")
validOutput := regexp.MustCompile(`(?:Heads|Tails).`)
if !(validOutput.MatchString(result)) {
t.Errorf(`FAIL: Expected heads or tails in output, but result was \"%s\"`, result)
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ func handleCommand(params *fryatogParams, c chan string) {
c <- rollDice(message)
return

case message == "coin":
case coinRegex.MatchString(message):
log.Debug("Coin flip")
c <- flipCoin()

Check failure on line 439 in main.go

View workflow job for this annotation

GitHub Actions / lint

not enough arguments in call to flipCoin

Check failure on line 439 in main.go

View workflow job for this annotation

GitHub Actions / build

not enough arguments in call to flipCoin
return
Expand Down
1 change: 1 addition & 0 deletions utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
wordStartingWithBang = regexp.MustCompile(`\s+! *\S+`)

diceRegex = regexp.MustCompile(`^(?:roll )?\s*(.*?)d(\d+)([+-]\d+)?`)
coinRegex = regexp.MustCompile(`^coin(?:\s+(\d+))?`)

cardMetadataRegex = regexp.MustCompile(`(?i)^(?:rulings?|reminder|flavou?r) `)

Expand Down

0 comments on commit bf3584a

Please sign in to comment.