Created
April 1, 2014 03:18
-
-
Save dpup/9907069 to your computer and use it in GitHub Desktop.
Simple command line hangman game
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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))])) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
constantsLikeThis NOT_LIKE_THIS – https://code.google.com/p/go-wiki/wiki/CodeReviewComments#Mixed_Caps
unsolicited #drivebycodereview #yolo