mathangman 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/5desk.txt +61406 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +53 -0
- data/Rakefile +6 -0
- data/bin/mathangman +6 -0
- data/bin/setup +7 -0
- data/circle.yml +8 -0
- data/lib/mathangman.rb +18 -0
- data/lib/mathangman/difficulty.rb +36 -0
- data/lib/mathangman/display.rb +123 -0
- data/lib/mathangman/filer.rb +109 -0
- data/lib/mathangman/game.rb +154 -0
- data/lib/mathangman/utility.rb +64 -0
- data/lib/mathangman/version.rb +3 -0
- data/loc +5 -0
- data/mathangman.gemspec +35 -0
- data/saved_games/ola/1444150684.txt +5 -0
- data/saved_games/olaide/1443824192.txt +5 -0
- data/saved_games/olaide/1443833662.txt +5 -0
- data/saved_games/olaide/1443911063.txt +5 -0
- data/saved_games/olaide/1443992363.txt +5 -0
- data/saved_games/olaide/1443992435.txt +5 -0
- data/saved_games/olaide/1444038183.txt +5 -0
- data/saved_games/olaide/1444042277.txt +5 -0
- data/saved_games/olaide/1444043867.txt +5 -0
- data/saved_games/olaide/1444150628.txt +5 -0
- data/saved_games/olaide/1444168593.txt +5 -0
- data/test_saved_games/5desk.txt +61406 -0
- data/test_saved_games/tests/test_games.txt +5 -0
- metadata +150 -0
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 TODO: Write your name
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# Mathangman
|
2
|
+
|
3
|
+
Hi,
|
4
|
+
I have implemented the popular hangman game with ruby. You can play the game by selecting the difficulty level you prefer.
|
5
|
+
You will be prompted to guess letters of the alphabet that make up a randomly selected word by the computer. The minimum length of the word and the number of allowed wrong guesses depends on your chosen difficulty level. You may chose to save the session of a started game and continue later. You may also save more than one game session.
|
6
|
+
Get your hands on the game and enjoy! Bug discoveries, suggestions and general feedback will always be appreciated.
|
7
|
+
Olaide.
|
8
|
+
|
9
|
+
[![Coverage Status](https://coveralls.io/repos/andela-oojewale/mathangman/badge.svg?branch=development&service=github)](https://coveralls.io/github/andela-oojewale/mathangman?branch=development)
|
10
|
+
|
11
|
+
TODO: Delete this and the text above, and describe your gem
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'mathangman'
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install mathangman
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
TODO: Write usage instructions here
|
32
|
+
|
33
|
+
## Development
|
34
|
+
|
35
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
36
|
+
|
37
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
38
|
+
|
39
|
+
## Contributing
|
40
|
+
|
41
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/andela-oojewale/mathangman.
|
42
|
+
|
43
|
+
* Fork it ( https://github.com/andela-oojewale/mathangman/fork)
|
44
|
+
* Create your feature branch (git checkout -b my-new-feature)
|
45
|
+
* Commit your changes (git commit -am 'Add some feature')
|
46
|
+
* Push to the branch (git push origin my-new-feature)
|
47
|
+
* Create a new Pull Request
|
48
|
+
|
49
|
+
|
50
|
+
## License
|
51
|
+
|
52
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
53
|
+
|
data/Rakefile
ADDED
data/bin/mathangman
ADDED
data/bin/setup
ADDED
data/circle.yml
ADDED
data/lib/mathangman.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "mathangman/version"
|
2
|
+
require "mathangman/utility"
|
3
|
+
require "mathangman/game"
|
4
|
+
require "mathangman/display"
|
5
|
+
require "mathangman/filer"
|
6
|
+
require "mathangman/difficulty"
|
7
|
+
|
8
|
+
module Mathangman
|
9
|
+
|
10
|
+
class Hangman
|
11
|
+
def initialize
|
12
|
+
@disp = Mathangman::Display.new
|
13
|
+
@game = Mathangman::Game.new(@disp)
|
14
|
+
@game.show_disp_menu
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Mathangman
|
2
|
+
|
3
|
+
module Difficulty
|
4
|
+
|
5
|
+
def check_difficulty
|
6
|
+
diff = gets.chomp
|
7
|
+
levels = ["7", "8", "9"]
|
8
|
+
if levels.include? diff
|
9
|
+
first_guess(diff)
|
10
|
+
elsif diff == "*"
|
11
|
+
quitter("pre_game")
|
12
|
+
else
|
13
|
+
puts @display.invalid_entry
|
14
|
+
puts @display.difficulty
|
15
|
+
check_difficulty
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def diff_level(diff)
|
20
|
+
@diff = diff
|
21
|
+
if diff == "7"
|
22
|
+
@wrongs_num = @len / 2 + @guess_bonus
|
23
|
+
return unusable = false if @len > 4 && @len < 13
|
24
|
+
elsif diff == "8"
|
25
|
+
@wrongs_num = @len / 2 + ( @guess_bonus - 1 )
|
26
|
+
return unusable = false if @len > 6 && @len < 13
|
27
|
+
elsif diff == "9"
|
28
|
+
@wrongs_num = @len / 2
|
29
|
+
return unusable = false if @len > 9 && @len < 13
|
30
|
+
end
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require_relative "utility"
|
2
|
+
module Mathangman
|
3
|
+
|
4
|
+
class Display
|
5
|
+
|
6
|
+
def greeting
|
7
|
+
<<-EOS
|
8
|
+
*************************************************
|
9
|
+
* HANGMAN *
|
10
|
+
* *
|
11
|
+
* Press 1 to start a new game *
|
12
|
+
* Press 2 to load a saved game *
|
13
|
+
* Press 3 for more information *
|
14
|
+
* Press * to quit the game at anytime *
|
15
|
+
* *
|
16
|
+
*************************************************
|
17
|
+
EOS
|
18
|
+
end
|
19
|
+
|
20
|
+
def difficulty
|
21
|
+
<<-EOS
|
22
|
+
Choose a difficulty level.
|
23
|
+
7 - for beginner
|
24
|
+
8 - for intermediate
|
25
|
+
9 - for PRO
|
26
|
+
EOS
|
27
|
+
end
|
28
|
+
|
29
|
+
def invalid_entry
|
30
|
+
<<-EOS
|
31
|
+
*************************************************
|
32
|
+
* Invalid entry. *
|
33
|
+
*************************************************
|
34
|
+
EOS
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_name
|
38
|
+
<<-EOS
|
39
|
+
*************************************************
|
40
|
+
* Please enter a username *
|
41
|
+
*************************************************
|
42
|
+
EOS
|
43
|
+
end
|
44
|
+
|
45
|
+
def complete_disp
|
46
|
+
<<-EOS
|
47
|
+
|
48
|
+
******************************************
|
49
|
+
* YOU WIN! *
|
50
|
+
* YOU HANGED HANGMAN! *
|
51
|
+
YOU ARE THE BOSS! *
|
52
|
+
******************************************
|
53
|
+
EOS
|
54
|
+
end
|
55
|
+
|
56
|
+
def lost(word)
|
57
|
+
<<-EOS
|
58
|
+
*************************************
|
59
|
+
* YOU HAVE BEEN HANGED! *
|
60
|
+
* GAME OVER! *
|
61
|
+
THE WORD IS: #{word}
|
62
|
+
*************************************
|
63
|
+
EOS
|
64
|
+
end
|
65
|
+
|
66
|
+
def msg(anything)
|
67
|
+
<<-EOS
|
68
|
+
|
69
|
+
* #{anything} *
|
70
|
+
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
|
74
|
+
def info
|
75
|
+
<<-EOS
|
76
|
+
**************************************************
|
77
|
+
* This is HANGMAN game v0.1.0 *
|
78
|
+
* By Olaide Ojewale *
|
79
|
+
* Enjoy and expect the next version *
|
80
|
+
* Press * at anytime to quit the game. *
|
81
|
+
* You will be prompted to save a started... *
|
82
|
+
* ...game whenever you attempt to quit. *
|
83
|
+
* You can also load and continue saved... *
|
84
|
+
* ... games by uisng your username. *
|
85
|
+
* Press Y to continue with the game. *
|
86
|
+
**************************************************
|
87
|
+
EOS
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.confirm_quit
|
91
|
+
<<-EOS
|
92
|
+
****************************************************************
|
93
|
+
* Are you sure you want to quit the game? Press Y to confirm *
|
94
|
+
****************************************************************
|
95
|
+
EOS
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.quit_notice
|
99
|
+
<<-EOS
|
100
|
+
*************************************************
|
101
|
+
* You have successfully ended the game. *
|
102
|
+
*************************************************
|
103
|
+
EOS
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.save_notice
|
107
|
+
<<-EOS
|
108
|
+
***********************************************************
|
109
|
+
* Would you like to save your game? Press Y to confirm *
|
110
|
+
***********************************************************
|
111
|
+
EOS
|
112
|
+
end
|
113
|
+
|
114
|
+
def self.no_source
|
115
|
+
<<-EOS
|
116
|
+
***************************************
|
117
|
+
* No file to source words from. *
|
118
|
+
***************************************
|
119
|
+
EOS
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
require_relative "utility"
|
2
|
+
require "time"
|
3
|
+
require "fileutils"
|
4
|
+
|
5
|
+
module Mathangman
|
6
|
+
|
7
|
+
module Filer
|
8
|
+
|
9
|
+
attr_accessor :folder, :restart, :files
|
10
|
+
|
11
|
+
def save_game
|
12
|
+
moment = get_time
|
13
|
+
save_name = moment.to_s + '.txt'
|
14
|
+
loc = check_repeated save_name
|
15
|
+
save_state loc
|
16
|
+
end
|
17
|
+
|
18
|
+
def check_repeated(name)
|
19
|
+
if @restart.nil?
|
20
|
+
create_dir
|
21
|
+
loc = "saved_games/#{@folder}/#{name}"
|
22
|
+
else
|
23
|
+
File.delete "saved_games/#{@folder}/#{@restart}"
|
24
|
+
loc = "saved_games/#{@folder}/#{name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def get_time
|
29
|
+
Time.now.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
def create_dir
|
33
|
+
@folder = @name.downcase
|
34
|
+
Dir.mkdir("saved_games") unless Dir.exist?("saved_games")
|
35
|
+
Dir.mkdir("saved_games/#{@folder}") unless Dir.exist?("saved_games/#{@folder}")
|
36
|
+
end
|
37
|
+
|
38
|
+
def del_dir
|
39
|
+
Dir.rmdir("saved_games/#{@folder}") unless !Dir["saved_games/#{@folder}/*"].empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def load_game
|
43
|
+
puts @display.get_name
|
44
|
+
@folder = gets.chomp.downcase
|
45
|
+
if !folder_not_exist?
|
46
|
+
@files = get_folder_items
|
47
|
+
puts @display.msg "Your most recent game is at the BOTTOM\nEnter the number corresponding to the file you want to load"
|
48
|
+
load_file
|
49
|
+
else
|
50
|
+
puts @display.msg "No archive with this username."
|
51
|
+
show_disp_menu
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def folder_not_exist?
|
56
|
+
true unless Dir.exist?("saved_games/#{@folder}")
|
57
|
+
end
|
58
|
+
|
59
|
+
def get_folder_items
|
60
|
+
files_hash = {}
|
61
|
+
i = 1
|
62
|
+
Dir.entries("saved_games/#{@folder}").sort.each do | file |
|
63
|
+
if file.include? ".txt"
|
64
|
+
files_hash[i] = file
|
65
|
+
i += 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
files_hash.each { | key, value | puts "#{key}) #{value}" }
|
69
|
+
end
|
70
|
+
|
71
|
+
def load_file
|
72
|
+
@restart = @files[gets.chomp.to_i]
|
73
|
+
unless @restart.nil?
|
74
|
+
game_file = File.readlines archives "saved_games"
|
75
|
+
game_data = []
|
76
|
+
game_file.each { | item | game_data << item }
|
77
|
+
restore_state(game_data)
|
78
|
+
guesses(self)
|
79
|
+
else
|
80
|
+
puts @display.msg "Incorrect entry. Please check and retype."
|
81
|
+
load_file
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def archives(link)
|
86
|
+
"#{link}/#{@folder}/#{@restart}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def save_state(loc)
|
90
|
+
File.open(loc, "w") do | line |
|
91
|
+
line.puts @diff
|
92
|
+
line.puts @word
|
93
|
+
line.puts @secret_word
|
94
|
+
line.puts @wrongs_num.to_s
|
95
|
+
line.puts @len
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def restore_state(info)
|
100
|
+
@diff = info[0].to_s
|
101
|
+
puts @word = info[1].to_s
|
102
|
+
@secret_word = info[2].to_s
|
103
|
+
@wrongs_num = info[3].to_i
|
104
|
+
@len = info[4].to_i
|
105
|
+
@disp_word = @word if !@word.nil?
|
106
|
+
@disp_word = "-" * @len if @word.nil?
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require_relative "utility"
|
2
|
+
require_relative "difficulty"
|
3
|
+
require_relative "filer"
|
4
|
+
|
5
|
+
module Mathangman
|
6
|
+
|
7
|
+
class Game
|
8
|
+
|
9
|
+
include Utility
|
10
|
+
include Difficulty
|
11
|
+
include Filer
|
12
|
+
|
13
|
+
attr_reader :display
|
14
|
+
attr_accessor :secret_word, :name, :folder, :restart, :files, :word, :len, :wrongs_num, :disp_word, :guess
|
15
|
+
|
16
|
+
def initialize(disp = nil)
|
17
|
+
@guess_bonus = 2
|
18
|
+
@wrongs_num = 0
|
19
|
+
@display = disp unless disp.nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
def rand_word(diff = nil)
|
23
|
+
dict = check_source "/5desk.txt"
|
24
|
+
unusable = true
|
25
|
+
while unusable
|
26
|
+
@secret_word = dict.sample.chomp.downcase
|
27
|
+
@len = @secret_word.length
|
28
|
+
unusable = diff_level(diff)
|
29
|
+
end
|
30
|
+
@secret_word
|
31
|
+
end
|
32
|
+
|
33
|
+
def first_guess(diff = nil)
|
34
|
+
wrd = rand_word diff
|
35
|
+
puts @disp_word = "-" * @len
|
36
|
+
guesses
|
37
|
+
end
|
38
|
+
|
39
|
+
def input_from_user
|
40
|
+
@guess = gets.chomp.downcase
|
41
|
+
end
|
42
|
+
|
43
|
+
def guesses(obj = nil)
|
44
|
+
puts @display.msg "Enter an alphabet guess for the #{@len} letter word."
|
45
|
+
input_from_user
|
46
|
+
if @guess == "*"
|
47
|
+
quitter(self)
|
48
|
+
end
|
49
|
+
process
|
50
|
+
end
|
51
|
+
|
52
|
+
def process
|
53
|
+
if is_alpha? @guess
|
54
|
+
act_on_guess
|
55
|
+
else
|
56
|
+
puts @display.msg "Invalid input. Only alphabets are allowed."
|
57
|
+
end
|
58
|
+
puts @display.msg "You have #{@wrongs_num} wrong guess(es) left."
|
59
|
+
guesses
|
60
|
+
end
|
61
|
+
|
62
|
+
def act_on_guess
|
63
|
+
if is_correct?
|
64
|
+
print @word = show_letter
|
65
|
+
completed
|
66
|
+
else
|
67
|
+
wrong_guess
|
68
|
+
print @disp_word
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def completed
|
73
|
+
if !@word.include? "-"
|
74
|
+
puts @display.complete_disp
|
75
|
+
if @restart
|
76
|
+
File.delete "saved_games/#{@folder}/#{@restart}"
|
77
|
+
del_dir
|
78
|
+
end
|
79
|
+
show_disp_menu
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def is_correct?
|
84
|
+
@word_arr = @secret_word.split('')
|
85
|
+
@word_arr.include? @guess
|
86
|
+
end
|
87
|
+
|
88
|
+
def show_letter
|
89
|
+
matches = []
|
90
|
+
i = 0
|
91
|
+
@word_arr.each do | char |
|
92
|
+
matches << i if char == @guess
|
93
|
+
i += 1
|
94
|
+
end
|
95
|
+
matches.each { | item | @disp_word[item] = @guess }
|
96
|
+
@disp_word
|
97
|
+
end
|
98
|
+
|
99
|
+
def wrong_guess
|
100
|
+
@wrongs_num -= 1
|
101
|
+
if @wrongs_num == 0
|
102
|
+
secret_word = @secret_word
|
103
|
+
puts @display.lost secret_word
|
104
|
+
show_disp_menu
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def player_choice(choice)
|
109
|
+
if supported_actions.include? choice
|
110
|
+
send(supported_actions[choice])
|
111
|
+
elsif choice == "*"
|
112
|
+
quitter("force")
|
113
|
+
else
|
114
|
+
puts @display.invalid_entry
|
115
|
+
show_disp_menu
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def call_name
|
120
|
+
begin
|
121
|
+
puts @display.get_name
|
122
|
+
@name = gets.chomp.downcase
|
123
|
+
end until check_validity
|
124
|
+
end
|
125
|
+
|
126
|
+
def call_info
|
127
|
+
puts @display.info
|
128
|
+
response = gets.chomp.downcase
|
129
|
+
return show_disp_menu if response == "y" || response == "yes"
|
130
|
+
exit
|
131
|
+
end
|
132
|
+
|
133
|
+
def supported_actions
|
134
|
+
{
|
135
|
+
"1" => 'call_name',
|
136
|
+
"2" => 'load_game',
|
137
|
+
"3" => 'call_info'
|
138
|
+
}
|
139
|
+
end
|
140
|
+
|
141
|
+
def check_validity
|
142
|
+
true if is_alpha? @name
|
143
|
+
end
|
144
|
+
|
145
|
+
def show_disp_menu
|
146
|
+
puts @display.greeting
|
147
|
+
choice = gets.chomp
|
148
|
+
player_choice(choice)
|
149
|
+
puts @display.difficulty
|
150
|
+
check_difficulty
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
end
|