diff --git a/game.go b/game.go new file mode 100644 index 0000000..f98d168 --- /dev/null +++ b/game.go @@ -0,0 +1,56 @@ +package main + +import ( + "fmt" + "time" +) + +func game() { + + // TODO: Catch SIGINT so you can ask the user if he wants to quit or not + // TODO: Do not do what I said above, I have to first learn how goroutines actually work + + for { + gameStatus() + checkLose() + checkWin() + + checkEmpty: + for { + fmt.Printf("Guess: ") + //fmt.Scanln(&guess) + guess = scanLine() + + if isEmpty(guess) == false && len([]rune(guess)) == 1 { + break checkEmpty + } else { + gameStatus() + } + + } + + if getLetter(guess) == true { + if alreadyCorrect(guess) == true { + fmt.Printf("[-] You've already guessed this correct letter") + time.Sleep(1 * time.Second) + } else { + correctChars = append(correctChars, guess) + } + } + + if getLetter(guess) == false { + if alreadyWrong(guess) == true { + fmt.Printf("[-] You've already guessed this wrong letter") + time.Sleep(1 * time.Second) + } else { + fmt.Printf("Wrong!") + wrongChars = append(wrongChars, guess) + player.lives-- + time.Sleep(1 * time.Second) + } + } + // Realized entering empty input would still cause "already guessed" errors + // because guess wasn't being reset + guess = "" + } +} diff --git a/logic.go b/logic.go new file mode 100644 index 0000000..6e7dd54 --- /dev/null +++ b/logic.go @@ -0,0 +1,12 @@ +package main + +func getLetter(letter string) (isFound bool) { + isFound = false + for i, v := range randWord { + if letter == string(v) { + isFound = true + hiddenChars[i] = string(v) + } + } + return isFound +} diff --git a/main.go b/main.go index 42e14ab..0256af1 100644 --- a/main.go +++ b/main.go @@ -1,15 +1,9 @@ package main import ( - "bufio" "fmt" - "github.com/inancgumus/screen" - "math/rand" "os" - "reflect" - "runtime" "strconv" - "strings" "time" ) @@ -32,22 +26,6 @@ type PlayerStats struct { lives int8 } -func fillSecrets() { - // Filling the array that will contain the unrevealed characters - for _, v := range randWord { - if string(v) == " " { - hiddenChars = append(hiddenChars, " ") - } else { - hiddenChars = append(hiddenChars, "_") - } - } - - // Filling the array that will contain the revealed characters - for _, v := range randWord { - revealedChars = append(revealedChars, string(v)) - } -} - func main() { if len(os.Args) != 2 { fmt.Println("Usage: ./hangman words.txt") @@ -63,10 +41,11 @@ func main() { clear() fmt.Printf("Welcome to the hanged man game!\nMay I know your name?\nName: ") player.name = scanLine() + fmt.Printf("How many lives would you like to have?\nLives: ") stringLives := scanLine() - intLives, err := strconv.Atoi(stringLives) + if catchErr(err) != true { player.lives = int8(intLives) break @@ -91,184 +70,3 @@ func main() { } } } - -func getLetter(letter string) (isFound bool) { - isFound = false - for i, v := range randWord { - if letter == string(v) { - isFound = true - hiddenChars[i] = string(v) - } - } - return isFound -} - -// TODO: Make gameStatus() prettier -func gameStatus() { - clear() - fmt.Printf("Player: %v\n", player.name) - fmt.Printf("Lives: %v\n\n", player.lives) - fmt.Printf("Word: %v\n\n", hiddenChars) - fmt.Printf("Wrong characters: %v\n", wrongChars) - fmt.Printf("Correct characters: %v\n\n", correctChars) -} - -func checkWin() { - var winStatus bool = reflect.DeepEqual(revealedChars, hiddenChars) - if winStatus == true { - fmt.Println("You win!") - os.Exit(0) - } -} - -func checkLose() { - if player.lives < 0 { - fmt.Println("You lose!") - fmt.Printf("The word was %v!\n", revealedChars) - os.Exit(0) - } -} - -// func alreadyGuessed() (isGuess bool) { -// var isAlreadyGuessed bool = false -// for _, v := range wrongChars { -// if v == guess { -// isAlreadyGuessed = true -// } -// } -// for _, v := range revealedChars { -// if v == guess { -// isAlreadyGuessed = true -// } -// } -// return isAlreadyGuessed -// } - -// Iterate over wrongChars and if the guess from the main game matches any of the elements, -// return True -func alreadyWrong(gs string) (isGuess bool) { - var isAlreadyGuessed bool = false - for _, v := range wrongChars { - if v == gs { - isAlreadyGuessed = true - } - } - return isAlreadyGuessed -} - -// Iterate over correctChars and if the guess from the main game matches any of the elements, -// return True -func alreadyCorrect(gs string) (isGuess bool) { - var isAlreadyGuessed bool = false - for _, v := range correctChars { - if v == gs { - isAlreadyGuessed = true - } - } - return isAlreadyGuessed -} - -func isEmpty(guess string) (isEmpty bool) { - isEmpty = false - if guess == "" { - isEmpty = true - } - return isEmpty -} - -func game() { - for { - gameStatus() - checkLose() - checkWin() - - checkEmpty: - for { - fmt.Printf("Guess: ") - //fmt.Scanln(&guess) - guess = scanLine() - - if isEmpty(guess) == false && len([]rune(guess)) == 1 { - break checkEmpty - } else { - gameStatus() - } - - } - - if getLetter(guess) == true { - if alreadyCorrect(guess) == true { - fmt.Printf("[-] You've already guessed this correct letter") - time.Sleep(1 * time.Second) - } else { - correctChars = append(correctChars, guess) - } - } - - if getLetter(guess) == false { - if alreadyWrong(guess) == true { - fmt.Printf("[-] You've already guessed this wrong letter") - time.Sleep(1 * time.Second) - } else { - fmt.Printf("Wrong!") - wrongChars = append(wrongChars, guess) - player.lives-- - time.Sleep(1 * time.Second) - } - } - // Realized entering empty input would still cause "already guessed" errors - // because guess wasn't being reset - guess = "" - } -} - -func catchErr(err error) (errHappened bool) { - errHappened = false - if err != nil { - //fmt.Println(err) - errHappened = true - } - return errHappened -} - -func getWord(path string) (word string) { - file, err := os.Open(path) - if err != nil { - fmt.Println(err) - os.Exit(2) - } - defer file.Close() - - scanner := bufio.NewScanner(file) - - for scanner.Scan() { - names = append(names, scanner.Text()) - } - - randName := names[rand.Intn(len(names)-0)] - return randName -} - -func clear() { - screen.Clear() - screen.MoveTopLeft() - //fmt.Print("\033[H\033[2J") -} - -func scanLine() (line string) { - switch runtime.GOOS { - case "linux": - in := bufio.NewReader(os.Stdin) - lineNew, err := in.ReadString('\n') - catchErr(err) - line = strings.Trim(lineNew, "\n") - - // I hate Windows - case "windows": - in := bufio.NewReader(os.Stdin) - lineNew, err := in.ReadString('\r') - catchErr(err) - line = strings.Trim(lineNew, "\r") - } - return line -} diff --git a/tools.go b/tools.go new file mode 100644 index 0000000..b962030 --- /dev/null +++ b/tools.go @@ -0,0 +1,152 @@ +package main + +import ( + "bufio" + "fmt" + "github.com/inancgumus/screen" + "math/rand" + "os" + "reflect" + "runtime" + "strings" +) + +////////////////////////////////////////////////////////////////////// + +func clear() { + screen.Clear() + screen.MoveTopLeft() + //fmt.Print("\033[H\033[2J") +} + +////////////////////////////////////////////////////////////////////// + +func scanLine() (line string) { + switch runtime.GOOS { + case "linux": + in := bufio.NewReader(os.Stdin) + lineNew, err := in.ReadString('\n') + catchErr(err) + line = strings.Trim(lineNew, "\n") + + // I hate Windows + case "windows": + in := bufio.NewReader(os.Stdin) + lineNew, err := in.ReadString('\r') + catchErr(err) + line = strings.Trim(lineNew, "\r") + } + return line +} + +////////////////////////////////////////////////////////////////////// +// Section for checking whether the player has lost or won + +func checkWin() { + var winStatus bool = reflect.DeepEqual(revealedChars, hiddenChars) + if winStatus == true { + fmt.Println("You win!") + os.Exit(0) + } +} + +func checkLose() { + if player.lives < 0 { + fmt.Println("You lose!") + fmt.Printf("The word was %v!\n", revealedChars) + os.Exit(0) + } +} + +////////////////////////////////////////////////////////////////////// + +func fillSecrets() { + // Filling the array that will contain the unrevealed characters + for _, v := range randWord { + if string(v) == " " { + hiddenChars = append(hiddenChars, " ") + } else { + hiddenChars = append(hiddenChars, "_") + } + } + + // Filling the array that will contain the revealed characters + for _, v := range randWord { + revealedChars = append(revealedChars, string(v)) + } +} + +////////////////////////////////////////////////////////////////////// + +func alreadyWrong(gs string) (isGuess bool) { + var isAlreadyGuessed bool = false + for _, v := range wrongChars { + if v == gs { + isAlreadyGuessed = true + } + } + return isAlreadyGuessed +} + +// Iterate over correctChars and if the guess from the main game matches any of the elements, +// return True +func alreadyCorrect(gs string) (isGuess bool) { + var isAlreadyGuessed bool = false + for _, v := range correctChars { + if v == gs { + isAlreadyGuessed = true + } + } + return isAlreadyGuessed +} + +////////////////////////////////////////////////////////////////////// + +func getWord(path string) (word string) { + file, err := os.Open(path) + if err != nil { + fmt.Println(err) + os.Exit(2) + } + defer file.Close() + + scanner := bufio.NewScanner(file) + + for scanner.Scan() { + names = append(names, scanner.Text()) + } + + randName := names[rand.Intn(len(names)-0)] + return randName +} + +////////////////////////////////////////////////////////////////////// + +func catchErr(err error) (errHappened bool) { + errHappened = false + if err != nil { + //fmt.Println(err) + errHappened = true + } + return errHappened +} + +////////////////////////////////////////////////////////////////////// + +// TODO: Make gameStatus() prettier +func gameStatus() { + clear() + fmt.Printf("Player: %v\n", player.name) + fmt.Printf("Lives: %v\n\n", player.lives) + fmt.Printf("Word: %v\n\n", hiddenChars) + fmt.Printf("Wrong characters: %v\n", wrongChars) + fmt.Printf("Correct characters: %v\n\n", correctChars) +} + +func isEmpty(guess string) (isEmpty bool) { + isEmpty = false + if guess == "" { + isEmpty = true + } + return isEmpty +}