Last active
September 23, 2018 08:17
-
-
Save iporsut/ac18ee59f95ec7c19da4ad76c5f5f8e2 to your computer and use it in GitHub Desktop.
Hangman The Series
This file contains hidden or 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 ( | |
"fmt" | |
) | |
func hangman(secretWord string, letters []rune) bool { | |
secrets := []rune(secretWord) | |
for _, s := range secrets { | |
var found bool | |
for _, l := range letters { | |
if s == l { | |
found = true | |
break | |
} | |
} | |
if !found { | |
return false | |
} | |
} | |
return true | |
} | |
func main() { | |
fmt.Println(hangman("bigbears", []rune{'a','e','i','o','u','c','d','p','r','k','l','j','h'})) | |
fmt.Println(hangman("bigbears", []rune{'a','e','i','b','r','g','s'})) | |
} |
This file contains hidden or 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 ( | |
"bufio" | |
"fmt" | |
"os" | |
"strings" | |
) | |
type Status int | |
const ( | |
InProcess Status = iota | |
Win | |
Lose | |
) | |
func (s Status) String() string { | |
switch s { | |
case InProcess: | |
return "in-process" | |
case Win: | |
return "win" | |
case Lose: | |
return "lose" | |
default: | |
return "" | |
} | |
} | |
type Result struct { | |
status Status | |
selectedLetters []rune | |
liftLeft int | |
secretWordLength int | |
knownSecretWord string | |
} | |
func (r *Result) Display() { | |
fmt.Println("Status:", r.status) | |
fmt.Println("Life:", r.liftLeft) | |
fmt.Println("knownSecretWord:", r.knownSecretWord) | |
} | |
func hangman(secretWord string, letterCh chan rune) chan Result { | |
resultCh := make(chan Result) | |
go func() { | |
secrets := []rune(secretWord) | |
// Current Result | |
cr := Result{ | |
status: InProcess, | |
selectedLetters: []rune{}, | |
liftLeft: 7, | |
secretWordLength: len(secretWord), | |
knownSecretWord: strings.Repeat("_", len(secretWord)), | |
} | |
resultCh <- cr | |
for l := range letterCh { | |
cr.selectedLetters = append(cr.selectedLetters, l) | |
var foundIndex []int | |
for i, s := range secrets { | |
if l == s { | |
foundIndex = append(foundIndex, i) | |
} | |
} | |
if len(foundIndex) == 0 { | |
cr.liftLeft-- | |
} else { | |
ksw := []rune(cr.knownSecretWord) | |
for _, i := range foundIndex { | |
ksw[i] = l | |
} | |
cr.knownSecretWord = string(ksw) | |
} | |
if cr.liftLeft == 0 { | |
cr.status = Lose | |
resultCh <- cr | |
break | |
} | |
if secretWord == cr.knownSecretWord { | |
cr.status = Win | |
resultCh <- cr | |
break | |
} | |
resultCh <- cr | |
} | |
close(resultCh) | |
}() | |
return resultCh | |
} | |
func main() { | |
letterCh := make(chan rune) | |
resultCh := hangman("bigbear", letterCh) | |
result := <-resultCh | |
result.Display() | |
scanner := bufio.NewScanner(os.Stdin) | |
for { | |
fmt.Print("Enter Letter: ") | |
fmt.Scanf("") | |
if scanner.Scan() { | |
ls := []rune(scanner.Text()) | |
letterCh <- ls[0] | |
} else { | |
close(letterCh) | |
return | |
} | |
result := <-resultCh | |
result.Display() | |
if result.status != InProcess { | |
close(letterCh) | |
return | |
} | |
} | |
} |
This file contains hidden or 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 ( | |
"testing" | |
) | |
func TestHangmanNewGame(t *testing.T) { | |
letterCh := make(chan rune) | |
resultCh := hangman("bigbear", letterCh) | |
defer func() { | |
close(letterCh) | |
}() | |
result := <-resultCh | |
if result.status != InProcess { | |
t.Fatal("status shound be in-process") | |
} | |
if result.liftLeft != 7 { | |
t.Fatal("lift left should be 7") | |
} | |
if string(result.selectedLetters) != "" { | |
t.Fatal("selectedLetters should be empty") | |
} | |
if result.knownSecretWord != "_______" { | |
t.Fatal("knownSecretWord should be _______") | |
} | |
} | |
func TestHangmanWin(t *testing.T) { | |
letterCh := make(chan rune) | |
resultCh := hangman("bigbear", letterCh) | |
defer func() { | |
close(letterCh) | |
}() | |
go func() { | |
for _, l := range []rune{'b', 'o', 'i', 'g', 'a', 'e', 'y', 'r'} { | |
letterCh <- l | |
} | |
}() | |
var result Result | |
for result = range resultCh { | |
// fetch result until win | |
if result.status == Win { | |
break | |
} | |
if result.status != InProcess { | |
t.Fatal("status shound be in-process") | |
} | |
} | |
if result.status != Win { | |
t.Fatal("status shound be win") | |
} | |
if result.liftLeft != 5 { | |
t.Fatal("lift left should be 5") | |
} | |
if string(result.selectedLetters) != "boigaeyr" { | |
t.Fatal("selectedLetters should be boigaeyr") | |
} | |
if result.knownSecretWord != "bigbear" { | |
t.Fatal("knownSecretWord should be bigbear") | |
} | |
} | |
func TestHangmanLose(t *testing.T) { | |
letterCh := make(chan rune) | |
resultCh := hangman("bigbear", letterCh) | |
defer func() { | |
close(letterCh) | |
}() | |
go func() { | |
for _, l := range []rune{'b', 'o', 'a', 'e', 'n', 'u', 't', 'z', 'x', 'v'} { | |
letterCh <- l | |
} | |
}() | |
var result Result | |
for result = range resultCh { | |
// fetch result until lose | |
if result.status == Lose { | |
break | |
} | |
if result.status != InProcess { | |
t.Fatal("status shound be in-process") | |
} | |
} | |
if result.status != Lose { | |
t.Fatal("status shound be lose") | |
} | |
if result.liftLeft != 0 { | |
t.Fatal("lift left should be 0") | |
} | |
if string(result.selectedLetters) != "boaenutzxv" { | |
t.Fatal("selectedLetters should be boaenutzxv") | |
} | |
if result.knownSecretWord != "b__bea_" { | |
t.Fatal("knownSecretWord should be b__bea_") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment