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.
This commit is contained in:
raul 2024-02-24 13:39:28 +01:00
parent 6656971e10
commit 7a8714a727
4 changed files with 222 additions and 204 deletions

56
game.go Normal file
View File

@ -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 = ""
}
}

12
logic.go Normal file
View File

@ -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
}

206
main.go
View File

@ -1,15 +1,9 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"github.com/inancgumus/screen"
"math/rand"
"os" "os"
"reflect"
"runtime"
"strconv" "strconv"
"strings"
"time" "time"
) )
@ -32,22 +26,6 @@ type PlayerStats struct {
lives int8 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() { func main() {
if len(os.Args) != 2 { if len(os.Args) != 2 {
fmt.Println("Usage: ./hangman words.txt") fmt.Println("Usage: ./hangman words.txt")
@ -63,10 +41,11 @@ func main() {
clear() clear()
fmt.Printf("Welcome to the hanged man game!\nMay I know your name?\nName: ") fmt.Printf("Welcome to the hanged man game!\nMay I know your name?\nName: ")
player.name = scanLine() player.name = scanLine()
fmt.Printf("How many lives would you like to have?\nLives: ") fmt.Printf("How many lives would you like to have?\nLives: ")
stringLives := scanLine() stringLives := scanLine()
intLives, err := strconv.Atoi(stringLives) intLives, err := strconv.Atoi(stringLives)
if catchErr(err) != true { if catchErr(err) != true {
player.lives = int8(intLives) player.lives = int8(intLives)
break 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
}

152
tools.go Normal file
View File

@ -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
}