1

Our project is to make a functional Rock Paper Scissors game using Go. I figured this would be a great place to ask for some pointers on some obvious mistakes I could be making.

I am having several problems.

  1. No matter user input the program says I am always entering in "rock.
  2. No matter what I input the program also always tells me it is a "tie"

So it's quite apparent to me I am having issues with my if/else statements but I am unsure where and what exactly it is. Also I know my PlayerPlay func is ugly but for some reason when I originally had my display menu in there it would keep looping back to my menu without proceeding through the rest of the program.

package main

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

func ComputerPlay() int {

    return rand.Intn(2) + 1
}

func PlayerPlay(play int) int {

    fmt.Scanln(&play)

    return play
}

func PrintPlay(playerName string, play int) {

    fmt.Printf("%s picked ", playerName)

    if play == 0 {
        fmt.Printf("rock\n")
    } else if play == 1 {
        fmt.Printf("paper\n")
    } else if play == 2 {
        fmt.Printf("scissors\n")
    }



    fmt.Printf("Computer has chose ")
            switch ComputerPlay() {
            case 0:
                    fmt.Println("rock\n")
            case 1:
                    fmt.Println("paper\n")
            case 2:
                    fmt.Println("scissors\n")
}

}


func ShowResult(computerPlay int, humanPlay int){

    var play int
    computerPlay = ComputerPlay()
    humanPlay = PlayerPlay(play)

        if humanPlay == 0 && humanPlay == 0 {
        fmt.Printf("It's a tie\n")
    } else if humanPlay == 0 && computerPlay == 1 {
        fmt.Printf(" Rock loses to paper\n")
    }   else if humanPlay == 0 && computerPlay == 2 {
        fmt.Printf("Rock beats scissors\n")
    }   else if humanPlay == 1 && computerPlay == 0 {
        fmt.Printf(" Paper beats rock\n")
    }   else if humanPlay == 1 && computerPlay == 1 {
        fmt.Printf("It's a tie!\n")
    }   else if humanPlay == 1 && computerPlay == 2 {
        fmt.Printf("Paper loses to scissors\n")
    } else if humanPlay == 2 && computerPlay == 0 {
        fmt.Printf("Scissors loses to rock\n")
    } else if humanPlay == 2 && computerPlay == 1 {
        fmt.Printf(" Scissors beats paper\n")
    } else if humanPlay == 2 && computerPlay == 2 {
        fmt.Printf(" It's a tie!\n")
    }


}

func main() {
        rand.Seed(time.Now().UnixNano())

        fmt.Printf("Welcome to Rock, Paper, Scissors\n\n")
        fmt.Printf("What is your name?\n")
        var playerName string
        fmt.Scanln(&playerName)

        fmt.Printf("Choose\n")
        fmt.Printf("0. Rock\n")
        fmt.Printf("1. paper\n")
        fmt.Printf("2. scissors\n")
        fmt.Printf("Your choice -> ")
        var play int
        PlayerPlay(play)
        PrintPlay(playerName, play)

        var computerPlay int
        ComputerPlay()
        ShowResult(computerPlay, play)

}
Andreas
  • 2,455
  • 10
  • 21
  • 24
Trick
  • 33
  • 3
  • 2
    In your `main` function, try adding `fmt.Printf()` calls to print out the values of `play` and `computerPlay` in a couple of places. What values do those variables have? – David Maze Oct 16 '19 at 04:20
  • You might want to use a [debugger](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems) for that or look at [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) – Andreas Oct 16 '19 at 04:21
  • If instead of doing `fmt.Printf` directly inside your `func ShowResult`, you return the result string for print (i.e. `fmt.Printf(ShowResult(computerPlay, play))`), your `func ShowResult` can be easily tested with [unit test](https://medium.com/rungo/unit-testing-made-easy-in-go-25077669318). That way you get to check the output of certain inputs matches your expectation. – Koala Yeung Oct 16 '19 at 04:31
  • `if humanPlay == 0 && humanPlay == 0 ` s/b `if humanPlay == 0 && computerPlay == 0` – peterSO Oct 16 '19 at 05:21

1 Answers1

0

The problem is that you use a pass by value parameter instead of pass by reference parameter in your PlayerPlay function.

  • Function in golang are always passed by value (either 'primitive' or pointer). Pass by value parameters are immutable. It will be allocated new space in memory, different from the var play.

  • In your PlayerPlay() function, the fmt.Scanln(&play) attempts to read and copy the value of the newly alocated space and successfully did so, but in a wrong reference (not on your var play).

  • Thus, the var play variable will remain unchanged, in its default value (for int its 0). And you end up always choosing.

What you need to do is change your PlayerPlay() function to accept reference type, and fill it with reference of the var play so that the fmt.Scanln() could mutates the var play.

Eg.

func PlayerPlay(play *int) {
    fmt.Scanln(play)
}

And use them like so,

  var play int
  PlayerPlay(&play)

Notice the & symbol is used to obtain the reference (pointer) of the value.

Keenan Gebze
  • 1,366
  • 1
  • 20
  • 26