diff --git a/config.json b/config.json index 58e4abb..0ce3d60 100644 --- a/config.json +++ b/config.json @@ -964,9 +964,9 @@ "difficulty": 4 }, { - "slug": "hangman", - "name": "Hangman", - "uuid": "20058254-0d41-486f-99d9-d7ee3f3ccb44", + "slug": "save-the-cow", + "name": "Save The Cow", + "uuid": "bc26a595-3d2a-4bea-90ef-25246e2cae9c", "practices": [], "prerequisites": [], "difficulty": 4 @@ -1290,6 +1290,15 @@ "prerequisites": [], "difficulty": 5, "status": "deprecated" + }, + { + "slug": "hangman", + "name": "Hangman", + "uuid": "20058254-0d41-486f-99d9-d7ee3f3ccb44", + "practices": [], + "prerequisites": [], + "difficulty": 4, + "status":"deprecated" } ] }, diff --git a/exercises/practice/save-the-cow/.docs/instructions.md b/exercises/practice/save-the-cow/.docs/instructions.md new file mode 100644 index 0000000..1ec98a4 --- /dev/null +++ b/exercises/practice/save-the-cow/.docs/instructions.md @@ -0,0 +1,7 @@ +# Instructions + +Implement the logic for a word-guessing game. + +A player tries to solve a secret word by guessing individual letters. +They win if they reveal all the letters in the secret word. +They lose if they make ten incorrect guesses before revealing the word. diff --git a/exercises/practice/save-the-cow/.docs/introduction.md b/exercises/practice/save-the-cow/.docs/introduction.md new file mode 100644 index 0000000..c87a7fa --- /dev/null +++ b/exercises/practice/save-the-cow/.docs/introduction.md @@ -0,0 +1,4 @@ +# Introduction + +Bessie the cow has wandered onto an alien spaceship. +Guess the secret door code to bring her home before the ship blasts off. diff --git a/exercises/practice/save-the-cow/.meta/SaveTheCow.example.ps1 b/exercises/practice/save-the-cow/.meta/SaveTheCow.example.ps1 new file mode 100644 index 0000000..17d56d4 --- /dev/null +++ b/exercises/practice/save-the-cow/.meta/SaveTheCow.example.ps1 @@ -0,0 +1,57 @@ +<# +.SYNOPSIS + Implement the logic for a word-guessing game. +.DESCRIPTION + Implement the logic and functionalities of a word-guessing game. + The game has 3 states: WIN, LOSE and ONGOING. + You are allowed to fail 9 times. + Incorrect guess and repeating guess will decrease the remaining failures by 1. + You win when you correctly guess the word. +#> + +Enum Status { + WIN + LOSE + ONGOING +} + +Class WordGame { + [int] $RemainingFailures + [Status] $State + [char[]] hidden $Masked + [char[]] $Secret + + WordGame([string] $word) { + $this.RemainingFailures = 9 + $this.Secret = $word + $this.Masked = @("_") * $word.Length + $this.State = [Status]::ONGOING + } + + [void] Guess([char]$letter) { + if ($this.State -ne [Status]::ONGOING) { + Throw "*Can't make further guess. Game is already finished : YOU $($this.State)*" + } + + if ($this.Secret -contains $letter -and $this.Masked -notcontains $letter) { + for ($i = 0; $i -lt $this.Secret.Count; $i++) { + if($this.Secret[$i] -eq $letter){ + $this.Masked[$i] = $letter + } + } + if ($this.Masked -notcontains "_") { + $this.State = [Status]::WIN + } + } else { #fail + if ($this.RemainingFailures -eq 0) { + $this.State = [Status]::LOSE + }else { + $this.RemainingFailures-- + } + } + } + + [string] Display() { + return -join $this.Masked + } +} diff --git a/exercises/practice/save-the-cow/.meta/config.json b/exercises/practice/save-the-cow/.meta/config.json new file mode 100644 index 0000000..205b0f7 --- /dev/null +++ b/exercises/practice/save-the-cow/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "glaxxie" + ], + "files": { + "solution": [ + "SaveTheCow.ps1" + ], + "test": [ + "SaveTheCow.tests.ps1" + ], + "example": [ + ".meta/SaveTheCow.example.ps1" + ] + }, + "blurb": "Implement a word-guessing game." +} diff --git a/exercises/practice/save-the-cow/.meta/tests.toml b/exercises/practice/save-the-cow/.meta/tests.toml new file mode 100644 index 0000000..eca72c4 --- /dev/null +++ b/exercises/practice/save-the-cow/.meta/tests.toml @@ -0,0 +1,40 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[71d340f9-fc29-4826-872e-ad7d0b83dd98] +description = "Initially 9 failures are allowed and no letters are guessed" + +[76759c24-8f1a-4fc8-9ffd-d6a1ff0cf03b] +description = "After 10 failures the game is over" + +[d6f2e202-7857-46fb-b709-43a7f3f3b2de] +description = "Losing with several correct guesses" + +[71bc0cda-2032-4637-80c8-fc8771124c08] +description = "Feeding a correct letter removes underscores" + +[5b568a1c-867d-418f-97a8-7b6f8a7ca0a2] +description = "Feeding a correct letter twice counts as a failure" + +[3d40f15b-0271-4c5d-b1a4-3e1f66ff221f] +description = "Guessing a repeated letter reveals all instances" + +[11a86435-e401-4250-a26e-3b0d8c4049ad] +description = "Getting all the letters right makes for a win" + +[b3d81876-84ee-45bb-b531-baa1b05b4709] +description = "Winning on the last guess is still a win" + +[cf204398-5e9f-402f-8bff-42cb7cbbbda9] +description = "Guessing after a lose is error" + +[c2ec5b3d-4923-4a0e-a485-6aa6e78c7ece] +description = "Guessing after a win is error" diff --git a/exercises/practice/save-the-cow/SaveTheCow.ps1 b/exercises/practice/save-the-cow/SaveTheCow.ps1 new file mode 100644 index 0000000..78ff9cf --- /dev/null +++ b/exercises/practice/save-the-cow/SaveTheCow.ps1 @@ -0,0 +1,33 @@ +<# +.SYNOPSIS + Implement the logic for a word-guessing game. +.DESCRIPTION + Implement the logic and functionalities of a word-guessing game. + The game has 3 states: WIN, LOSE and ONGOING. + You are allowed to fail 9 times. + Incorrect guess and repeating guess will decrease the remaining failures by 1. + You win when you correctly guess the word. +#> + +Enum Status { + WIN + LOSE + ONGOING +} + +Class WordGame { + [int] $RemainingFailures + [Status] $State + + WordGame([string] $word) { + Throw "Please implement this class" + } + + [void] Guess([char]$letter) { + Throw "Please implement this function" + } + + [string] Display() { + Throw "Please implement this function" + } +} diff --git a/exercises/practice/save-the-cow/SaveTheCow.tests.ps1 b/exercises/practice/save-the-cow/SaveTheCow.tests.ps1 new file mode 100644 index 0000000..a5039e1 --- /dev/null +++ b/exercises/practice/save-the-cow/SaveTheCow.tests.ps1 @@ -0,0 +1,107 @@ +BeforeAll { + . "./SaveTheCow.ps1" +} + +Describe "SaveTheCow test cases" { + It "Initially 9 failures are allowed and no letters are guessed" { + $game = [WordGame]::new("loot") + + $game.State | Should -BeExactly ONGOING + $game.RemainingFailures | Should -Be 9 + } + + It "After 10 failures the game is over" { + $game = [WordGame]::new("loot") + $guesses = @("a","b","c","d","e","f","g","h","i","j") + foreach ($letter in $guesses) { + $game.Guess($letter) + } + + $game.State | Should -BeExactly LOSE + $game.Display() | Should -BeExactly "____" + $game.RemainingFailures | Should -Be 0 + } + + It "Losing with several correct guesses" { + $game = [WordGame]::new("loot") + $guesses = @("t","o","a","b","c","d","e","f","g","h","i","j") + foreach ($letter in $guesses) { + $game.Guess($letter) + } + + $game.State | Should -BeExactly LOSE + $game.Display() | Should -BeExactly "_oot" + $game.RemainingFailures | Should -Be 0 + } + + It "Feeding a correct letter removes underscores" { + $game = [WordGame]::new("loot") + $game.Guess("t") + + $game.State | Should -BeExactly ONGOING + $game.Display() | Should -BeExactly "___t" + $game.RemainingFailures | Should -Be 9 + } + + It "Feeding a correct letter twice counts as a failure" { + $game = [WordGame]::new("loot") + $game.Guess("t") + $game.Guess("t") + + $game.State | Should -BeExactly ONGOING + $game.Display() | Should -BeExactly "___t" + $game.RemainingFailures | Should -Be 8 + } + + It "Guessing a repeated letter reveals all instances" { + $game = [WordGame]::new("loot") + $game.Guess("t") + $game.Guess("t") + $game.Guess("o") + + $game.State | Should -BeExactly ONGOING + $game.Display() | Should -BeExactly "_oot" + $game.RemainingFailures | Should -Be 8 + } + + It "Getting all the letters right makes for a win" { + $game = [WordGame]::new("loot") + $game.Guess("t") + $game.Guess("t") + $game.Guess("o") + $game.Guess("l") + + $game.State | Should -BeExactly WIN + $game.Display() | Should -BeExactly "loot" + $game.RemainingFailures | Should -Be 8 + } + + It "Winning on the last guess is still a win" { + $game = [WordGame]::new("loot") + $guesses = @("a","b","c","d","e","f","g","h","i","t","o","l") + foreach ($letter in $guesses) { + $game.Guess($letter) + } + + $game.State | Should -BeExactly WIN + $game.Display() | Should -BeExactly "loot" + $game.RemainingFailures | Should -Be 0 + } + + It "Guessing after a lose is error" { + $game = [WordGame]::new("loot") + $guesses = @("a","b","c","d","e","f","g","h","i","j") + foreach ($letter in $guesses) { + $game.Guess($letter) + } + {$game.Guess("k")} | Should -Throw "*Can't make further guess. Game is already finished : You LOSE*" + } + + It "Guessing after a win is error" { + $game = [WordGame]::new("loot") + $game.Guess("t") + $game.Guess("o") + $game.Guess("l") + {$game.Guess("l")} | Should -Throw "*Can't make further guess. Game is already finished : You WIN*" + } +}