From 7a8714a727d7e375c6e1eb901be343c9843950cd Mon Sep 17 00:00:00 2001 From: raul Date: Sat, 24 Feb 2024 13:39:28 +0100 Subject: [PATCH] Reorganizing codebase My last ditch attempt at making sense out of this codebase by separating the functions into files, should make the project easier to read, but this'll probably be my last commit for hangman for a long while. --- game.go | 56 +++++++++++++++ logic.go | 12 ++++ main.go | 206 +------------------------------------------------------ tools.go | 152 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 222 insertions(+), 204 deletions(-) create mode 100644 game.go create mode 100644 logic.go create mode 100644 tools.go 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 +}