Skip to content

Instantly share code, notes, and snippets.

@dpup
Created April 1, 2014 03:18
Show Gist options
  • Save dpup/9907069 to your computer and use it in GitHub Desktop.
Save dpup/9907069 to your computer and use it in GitHub Desktop.
Simple command line hangman game
package main
import (
"flag"
"fmt"
"io/ioutil"
"math/rand"
"strings"
"time"
)
var wordFile = flag.String("word_file", "", "Word file.")
const NUM_GUESSES = 10
func main() {
flag.Parse()
if *wordFile == "" {
fmt.Println("Please provide a word file. For example:")
fmt.Println(" go hangman.go --word_file /usr/share/dict/words")
return
}
game := NewGame(findWord(*wordFile))
game.Start()
}
func NewGame(target string) GameState {
return GameState{[]byte(target), NUM_GUESSES, map[byte]bool{}}
}
type GameState struct {
target []byte
remainingGuesses int
guesses map[byte]bool
}
func (game *GameState) Start() {
fmt.Printf("Welcome, here's your word: %s\n", game.DisplayWord())
for {
var guess string
fmt.Printf("Enter a character: ")
_, err := fmt.Scanln(&guess)
if err != nil || len(guess) != 1 {
fmt.Printf("That wasn't a valid guess, try entering just one character.\n")
} else {
game.MakeGuess(guess[0])
time.Sleep(500 * time.Millisecond)
if game.IsWin() {
fmt.Printf("Congratulations, you win! The word was %s\n", game.target)
return
} else if game.remainingGuesses == 0 {
fmt.Printf("Boo, you loose. Here's the answer: %s\n", game.target)
return
} else {
fmt.Printf("%s, %d guesses remaining.\n", game.DisplayWord(), game.remainingGuesses)
time.Sleep(250 * time.Millisecond)
}
}
}
}
func (game *GameState) IsWin() bool {
for _, c := range game.target {
if _, exists := game.guesses[c]; !exists {
return false
}
}
return true
}
func (game *GameState) IsCorrectGuess(guess byte) bool {
for _, c := range game.target {
if c == guess {
return true
}
}
return false
}
func (game *GameState) MakeGuess(guess byte) {
if _, exists := game.guesses[guess]; !exists {
correct := game.IsCorrectGuess(guess)
game.guesses[guess] = correct
if !correct {
game.remainingGuesses--
}
}
}
func (game *GameState) DisplayWord() string {
s := make([]byte, len(game.target)*2)
for i, c := range game.target {
if _, exists := game.guesses[c]; exists {
s[i*2] = c
} else {
s[i*2] = '_'
}
s[i*2+1] = ' '
}
return string(s)
}
func findWord(filename string) string {
bytes, err := ioutil.ReadFile(filename)
if err != nil {
panic(err)
}
lines := strings.Split(string(bytes), "\n")
rand.Seed(time.Now().Unix())
return strings.ToLower(strings.TrimSpace(lines[rand.Intn(len(lines))]))
}
@andybons
Copy link

andybons commented Apr 1, 2014

constantsLikeThis NOT_LIKE_THIS – https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Mixed_Caps

unsolicited #drivebycodereview #yolo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment