#`rand.Intn` Not Working As Expected

25 messages · Page 1 of 1 (latest)

upbeat moon
#

I'm working on making a simple dice rolling command for a discord bot, but rand.Intn(n) isn't working as I would expect. I would expect it to give me a number 0-n but it is giving me numbers almost double of n. Am I misunderstanding the docs or something?

Relevant Code

This should be all the code that is relevant, but, if you want to check something else, the repo is public. I'm on the dice-tests branch at the moment.

GitHub

Don't be crabby, use CraBot! Contribute to ArkhamCookie/crabot development by creating an account on GitHub.

#

Releveant Code

// lib/dice/roll/roll.go
package roll

import "math/rand"

// Roll *dice* and return the roll.
func Roll(dice int) int {
    // Add 1 so it 1-int rather than 0-int
    return rand.Intn(dice) + 1
}
// lib/dice/diceTypes.go
package dice

import (
    "crabot/dice/roll"
)

var (
    result int
)

// D2 rolls a D2 (1-2)
func D2(count int) int {
    for count > 0 {
        result += roll.Roll(2)
        count--
    }
    return result
}

// D4 rolls a D4 (1-4)
func D4(count int) int {
    for count > 0 {
        result += roll.Roll(4)
        count--
    }
    return result
}
// lib/dice/diceTypes_test.go
package dice_test

import (
    "testing"

    "crabot/dice"
)

var (
    result int
)

func TestD2(t *testing.T) {
    result = dice.D2(1)

    if result < 0 {
        t.Fatal("dice.D2(1) was negative")
    }

    if result == 0 {
        t.Fatal("dice.D2(1) was 0")
    }

    if result > 2 {
        t.Fatal("dice.D2(1) was greater than 2")
    }

    result = dice.D2(2)

    if result < 0 {
        t.Fatal("dice.D2(2) was negative")
    }

    if result == 0 {
        t.Fatal("dice.D2(2) was 0")
    }

    if result < 2 {
        t.Fatal("dice.D2(2) was less than 2")
    }
}

func TestD4(t *testing.T) {
    result = dice.D4(1)

    if result < 0 {
        t.Fatal("dice.D4(1) was negative")
    }

    if result == 0 {
        t.Fatal("dice.D4(1) was 0")
    }

    if result > 4 {
        t.Fatal("dice.D4(1) was greater than 4")
    }

    result = dice.D4(2)

    if result < 0 {
        t.Fatal("dice.D4(2) was negative")
    }

    if result == 0 {
        t.Fatal("dice.D4(2) was 0")
    }

    if result < 2 {
        t.Fatal("dice.D4(2) was less than 2")
    }
}
modest plaza
#

you should use math/rand/v2 for new code, this being said, even the old one works

#

what doesn't ?

upbeat moon
#

It is outputting a value that is almost double of the given n. I'll try using v2.

modest plaza
#

btw stuff like

    if result < 0 {
        t.Fatal("dice.D2(2) was negative")
    }

    if result == 0 {
        t.Fatal("dice.D2(2) was 0")
    }

    if result < 2 {
        t.Fatal("dice.D2(2) was less than 2")
    }

is a bit silly... just do

    if result < 2 {
        t.Fatalf("dice.D2(2) was less than 2: %d", result)
#

It is outputting a value that is almost double of the given n
do you have a proof of that... show output/code?

upbeat moon
#
--- FAIL: TestD4 (0.00s)
    diceTypes_test.go:55: dice.D4(1) was greater than 4
FAIL
FAIL    crabot/dice    0.001s
FAIL
#

I'll do it with the new output one sec

modest plaza
#

also

for count > 0 {
        result += roll.Roll(2)
        count--
    }

should be

for range count {
           result += roll.Roll(2)
}
#

and your bug is using a global variable

#

is this AI generated bad code 😉 ?

upbeat moon
#

no just my own bad code xD

modest plaza
#

you keep using the same variable so it keeps growing

#
func D4(count int) int {
    for count > 0 {
        result += roll.Roll(4)
        count--
    }
    return result
}

should be

func D4(count int) int {
    result := 0
    for range count {
        result += roll.Roll(4)
    }
    return result
}
upbeat moon
#

I thought it would reset but that makes sense. This is what I get for coding this at 3AM

#

here I thought I was being clever and avoiding some boiler plate by declaring it there xD

modest plaza
#

from another discord:

Your order of blame should be:

yourself -> yourself again -> yourself again -> maybe it's a library bug? -> nope, yourself again -> maybe I'll check the library again -> environment -> editor -> standard library -> compiler

upbeat moon
#

I was thinking I was misunderstanding the docs not that it was a bug tbh

#

thank you for the help

modest plaza
#

you can write it like that as well if somehow you wanted short

func D4(count int) (result int) {
    for range count {
        result += roll.Roll(4)
    }
    return result
}

but using a global variable is pretty much never a good thing

upbeat moon
modest plaza
#

yes range X with X an integer means repeat the loop X times