First Programming Project Part II

Okay, let’s finish this first little program up. In the previous post I wrote a number guessing game and tried to follow the same thought process I did when I was eleven. Now that it works, we want to make some changes so that it’s easier to play and a tad more fun.

Validation

validate: to establish the soundness, accuracy, or legitimacy of: synonym: confirm

First thing we need to do is make sure that our players are typing in the right kind of guesses. We know the game is supposed to be played with guesses from 1 to 100 but you never know what a user/customer might type. Right now if we type in the word “green” as a guess we get back:

Enter your guess: green
Too low.
Enter your guess: Too low.
Enter your guess: Too low.
Enter your guess: Too low.
Enter your guess: Too low.
Enter your guess: Too low.

That wasn’t what we expected. It doesn’t give the player any useful information and tells them their guess is too low Enter your guess: Too low. 5 times.

Well first things first. Why does it print out the message five times? That seems odd.

Possible hour or two of troubleshooting later…Oh this will happen a lot in your programming career. You can’t fix the error without knowing why you got that particular error

Eureka!

The variable g that we’re putting the keyboard input into is of type int, an interger, but we’re giving it a word(a string) made up of letters, five letters to be exact. Since we don’t pass a value to g because a letter isn’t a number, it stays at value 0, which is too low. The program tells us that 0 is too low, reaches the end of the loop and goes back to the top, trying each letter until it gets to the end.

We don’t know what the user is going to enter at the command line. The current output for an incorrect entry isn’t helpful. How can “green” be too low? What we need to do is take any input from the command line and check to see if it’s a number. If it is, then we can start doing our comparisons. If it’s not a number we can tell the player and they can try again.

We’re going to add a new variable at the top of our main.go file, ug and we’re going to make it of type string. Now we’re going to make some changes to our code that handles the input:

    var inputError error
    fmt.Printf("Enter your guess: ")
    fmt.Scanln(&ug)
    c = c + 1
    g, inputError = strconv.Atoi(ug)
    if inputError != nil {
        fmt.Println("Not a number:", ug)
        fmt.Println("Try again.")
        continue
    }
  1. Now we are casting the input the user enters to a string, which can be letter, numbers, symbols or anything.
  2. Then we use the strconv package and make use of its Atoi function. It will take a string input and if it’s an interger, it will return that to our variable g. If it’s not an integer, g will stay 0 and the error will return to the variable intputError which is a special type of variable that holds errors (more on errors here).
  3. If the inputError variable is empty aka nil, then nothing went wrong and we got an interger. We proceed with the program.
  4. If it’s not nil, then the player entered something wrong. We tell them what was wrong and use the keyword continue to imediately take us back to the top of the for loop. No need to go through the rest of the if statements if we don’t have a proper interger.

Adding features

Let’s add two features to our fantastic number guessing game (It’s called marketing people!). First of all, let’s make it so that you have to guess the number in a certain number of guesses.

  1. We’ll make a variable called maxg and set it to 10
  2. We will tell the player how many guesses they have left after each guess
  3. If they use up all their guesses, we tell the player and the program should exit
  4. Guesses that aren’t integers will not be counted (ex: green)

After each guess we will lower the value of maxg by 1: maxg = maxg - 1. Then we will check to see if they guessed it correctly and if not we will check to see if they have used up all of their guesses:

    if maxg == 0 {
        fmt.Println("Out of guesses.  Better luck next time.")
        break
    }
    fmt.Println("You have", maxg, "guesses remaning.")
    fmt.Println("")

Cool! Now we can update the maxg value to whatever we want to make the game easier (1000 guesses!) or harder (1 guess EEK!).

What about the max possible number we could be guessing? Right now it’s 100 but we can change that value too. We can make a new variable, var maxnum int = 1000 and instead of calling n = rand.Intn(100) we could call n = rand.Intn(maxnum).

Parameters

The last thing we want to do is make it so that we can set the maximum number and the maximum guesses from the command line when we start the program. Sure we can update the source code and re-run the main.go file, but what if we want to compile this thing and share it with all our friends? What if we just want to play the darn game and not update soure code all the time?

If we spend some time searching the web for golang command line passing values or something like that, we will come across the flag package(more info). It’s pretty straight forward.

    flag.IntVar(&maxg, "guess", 10, "Number of guesses to win.  Default value is 10.")
    flag.IntVar(&maxnum, "maxnum", 100, "Maxium value the number to guess can be.  Default value is 100.")
	flag.Parse()

The above three lines will pull the two arguments into our program and assign them to maxg and maxnum. What are the &s for? They are telling the program to pass a pointer to the variable maxg and not the variable itself. What’s a pointer? You don’t need to know that right now (but you’ll want to learn at some point). What you do know is that it works when you copy paste out of the help article and it doesn’t work when you remove the &. The important thing is that the game now works like we want it to. As a bonus, we have something concrete we can learn about next.

Hurray! We did it!

Final code can be found here.

P.S.: I can already see a bug.