2

So I created a program to help me decide which game to play. Before I start my problem let me show you my code:

package main

import (
    "fmt"
    "strconv"
    "time"
)

func main() {
    isArray := [10]string{"Paladins", "Overwatch", "CS:GO", "Tanki", "Left 4 Dead", "Rocket League", "Call Of Duty : AW", "Portal", "Star Citizen", "Star Wars : Battlefront"}
    fmt.Print("0,1,2,3,4,5,6,7,8,9 := ")

    var (
        va string
        ar string
    )

    fmt.Scanln(&va)
    i, _ := strconv.Atoi(va)

    fmt.Print("You Should Play : ")
    fmt.Print(isArray[i], "\n")
    fmt.Print("[Y/N] := ")
    fmt.Scanln(&ar)

    if ar != "N" || ar != "n" {
        fmt.Print("OK")
    }

    time.Sleep(3 * time.Second)
}

So the problems start when I already know which number would trigger a game, if I use it twice. So I am trying to make the strings random, like shuffling each time I use it, how can I do that?

icza
  • 389,944
  • 63
  • 907
  • 827
Dr.Topaz
  • 87
  • 2
  • 8
  • 3
    http://stackoverflow.com/questions/12264789/shuffle-array-in-go –  May 17 '17 at 13:55
  • 1
    Possible duplicate of [Randomize order of a MongoDB query in Go](http://stackoverflow.com/questions/43157290/randomize-order-of-a-mongodb-query-in-go/43166390#43166390). – icza May 17 '17 at 13:56
  • Possible duplicate of [shuffle array in Go](http://stackoverflow.com/questions/12264789/shuffle-array-in-go) – superfell May 17 '17 at 14:31

4 Answers4

2
 package main

 import (
         "fmt"
         "math/rand"
         "time"
 )

 func shuffle(src []string) []string {
         final := make([]string, len(src))
         rand.Seed(time.Now().UTC().UnixNano())
         perm := rand.Perm(len(src))

         for i, v := range perm {
                 final[v] = src[i]
         }
         return final
 }
abdel
  • 665
  • 1
  • 11
  • 25
0

Well, literally for your problem why not use rand.Intn() to choose a random number and print the game rather than make the user pick a number?

isArray := [10]string{"Paladins", "Overwatch", "CS:GO", "Tanki", "Left 4 Dead", "Rocket League", "Call Of Duty : AW", "Portal", "Star Citizen", "Star Wars : Battlefront"}
n := rand.Intn(9)
fmt.Printf("You Should Play : %s\n", isArray[n])

But if you want to shuffle strings in an array for the sake of it, then you can do it in place like this:

// Shuffle array in place
l := len(isArray)-1
for i := 0; i <=l; i++ {
    n := rand.Intn(l)
    // swap
    x := isArray[i]
    isArray[i] = isArray[n]
    isArray[n] = x
}

This should be O(n), though I'm not sure about the complexity of Intn. If you really want to be fancy, you could:

  1. Create a second array (randomArray) of touples, containing a random number and element position in isArray.
  2. Sort this array by the random number
  3. Create a new array, copying elements of isArray, but ordered by our randomArray
denis.lobanov
  • 359
  • 1
  • 8
  • I thought about using your first example and it doesn't work.Everytime i run the code ,it always says Left 4 Dead. PS ( i changed the value of rand.Intn(10) to rand.Intn(9) as arrays begin at 0. – Dr.Topaz May 18 '17 at 14:23
  • 1
    Did you call something like `rand.Seed(time.Now().UTC().UnixNano())` before `rand.Intn()`? Otherwise it will always generate the same number: 5 – denis.lobanov May 18 '17 at 14:28
  • whoaaa whoa whoa whoa ; i added it just now and it works :-) ,thanks man – Dr.Topaz May 18 '17 at 14:39
  • can you please explain why is it neccesary to add it before rand.Intn() – Dr.Topaz May 18 '17 at 14:40
  • so i tried to implement it to my real code(the user defined) and it works to man,it shuffles the strings.Thanks @denis.lobanov – Dr.Topaz May 18 '17 at 14:53
  • 1
    `rand` is a **pseudo** random number generator - given a starting number an algorithm will generate other numbers which appear random (hard to guess the next one). Because its an algorithm, if you start on the same number (seed), the next will always be the same. So you need to seed it before first use – denis.lobanov May 18 '17 at 17:09
0
package main

import (
    "fmt"
    "math/rand"
    "time"
)

type list []string

func main() {

    s := list{
        "Tanki",
        "Left 4 Dead",
        "Rocket League",
        "Call Of Duty : AW",
    }
    s.shuffle()
    s.print()
}

func (l list) print() {
    for i, v := range l {
        fmt.Println(i, v)
    }
}

func (l list) shuffle() list {
    src := rand.NewSource(time.Now().UnixNano())
    r := rand.New(src)
    for i := range l {
        n := r.Intn(len(l) - 1)
        l[i], l[n] = l[n], l[i]
    }
    return l
}
  • Welcome to stackoverflow. Please fully explain your answer. Just posting code does not help other users understand your answer. – Simon.S.A. Dec 09 '18 at 19:58
0

You can now use the rand.Shuffle function from the math package.

    var games = [10]string{"Paladins", "Overwatch", "CS:GO", "Tanki", "Left 4 Dead", "Rocket League", "Call Of Duty : AW", "Portal", "Star Citizen", "Star Wars : Battlefront"}

    rand.Seed(time.Now().UnixNano())
    rand.Shuffle(len(games), func(i, j int) {
        games[i], games[j] = games[j], games[i]
    })

    fmt.Println(games)

docs: https://pkg.go.dev/math/rand#Shuffle

leonardo
  • 1,686
  • 15
  • 15