hangman_game1 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 +4 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/5desk.txt +61406 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +62 -0
- data/Rakefile +6 -0
- data/bin/console +17 -0
- data/bin/hangman +10 -0
- data/bin/setup +7 -0
- data/cicle.yml +4 -0
- data/data.json +2 -0
- data/hangman.gemspec +36 -0
- data/lib/hangman/data.json +2 -0
- data/lib/hangman/engine.rb +17 -0
- data/lib/hangman/fileop.rb +55 -0
- data/lib/hangman/game.rb +198 -0
- data/lib/hangman/message.rb +80 -0
- data/lib/hangman/version.rb +3 -0
- data/lib/hangman.rb +10 -0
- metadata +141 -0
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/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,62 @@
|
|
1
|
+
|
2
|
+
# Hangman
|
3
|
+
[![Coverage Status](https://coveralls.io/repos/andela-aoko-odion/hangman/badge.svg?branch=master&service=github)](https://coveralls.io/github/andela-aoko-odion/hangman?branch=master)
|
4
|
+
|
5
|
+
This is a simulation of the classic Hangman Game in Ruby.
|
6
|
+
|
7
|
+
## Background
|
8
|
+
When a player initiates the game
|
9
|
+
The player is asked if he wants to start a new game or he wants to play from a previously saved game.
|
10
|
+
## example:
|
11
|
+
[n] start new game [l] load saved game [q] quit game
|
12
|
+
|
13
|
+
If [n] new game is selected, the computer selects a word
|
14
|
+
and scrambles the word by replace the hidden selected word with the underscore characters '______'
|
15
|
+
|
16
|
+
## example:
|
17
|
+
[n] start new game [l] load saved game [q] quit game
|
18
|
+
|
19
|
+
After 5 wrong guesses you have lost the game.
|
20
|
+
Guess word : _____
|
21
|
+
|
22
|
+
For every turn the player is expected to guess a letter
|
23
|
+
from the computer guessed word.
|
24
|
+
Each Incorrect guess will reduce the players entitled chance by 1
|
25
|
+
|
26
|
+
when the player finally guess a letter on the scrambled word correctly
|
27
|
+
tha view is updated with that correct letter
|
28
|
+
|
29
|
+
Guess_word : la_yngitis
|
30
|
+
r
|
31
|
+
Congratulations. You have won
|
32
|
+
|
33
|
+
Already started game can also be saved and loaded again later
|
34
|
+
|
35
|
+
## Installation
|
36
|
+
|
37
|
+
Add this line to your application's Gemfile:
|
38
|
+
|
39
|
+
gem 'hangman_game1'
|
40
|
+
|
41
|
+
|
42
|
+
And then execute:
|
43
|
+
|
44
|
+
$ bundle
|
45
|
+
|
46
|
+
Or install it yourself as:
|
47
|
+
|
48
|
+
$ gem install hangman_game1
|
49
|
+
|
50
|
+
## Development
|
51
|
+
|
52
|
+
$ gem install hangman_game1
|
53
|
+
|
54
|
+
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.
|
55
|
+
|
56
|
+
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.
|
57
|
+
|
58
|
+
## Contributing
|
59
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/andela-aoko-odion/hangman. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
|
60
|
+
## License
|
61
|
+
|
62
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/hangman
ADDED
data/bin/setup
ADDED
data/cicle.yml
ADDED
data/data.json
ADDED
data/hangman.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'hangman/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "hangman_game1"
|
8
|
+
spec.version = Hangman::VERSION
|
9
|
+
spec.authors = ["andrew oko-odion"]
|
10
|
+
spec.email = ["mrniceguy4net@yahoo.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Hangman, a game that allows its player to guess a word by guessing each letter per turn.}
|
13
|
+
spec.description = %q{Hangman . You will be told if your guess was correct or not for each guess till the game is won by the player or lives is equal to zero. Enjoy! :)}
|
14
|
+
spec.homepage = "https://rubygems.org/gems/hangman"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
|
18
|
+
# delete this section to allow pushing this gem to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
+
else
|
22
|
+
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
23
|
+
end
|
24
|
+
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
26
|
+
spec.bindir = "bin" #"exe"
|
27
|
+
spec.executables = ["hangman"]
|
28
|
+
#spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
29
|
+
spec.require_paths = ["lib"]
|
30
|
+
|
31
|
+
spec.add_dependency "bundler"
|
32
|
+
spec.add_dependency "rake"
|
33
|
+
spec.add_dependency "rspec"
|
34
|
+
spec.add_dependency "colorize"
|
35
|
+
spec.add_dependency "json"
|
36
|
+
end
|
@@ -0,0 +1,2 @@
|
|
1
|
+
{"word":"helloworld","lives":5,"scrambled_word":"h_ll____l_","word_index":{"e":[1],"o":[4,6],"w":[5],"r":[7],"d":[9]},"player":"smart"}
|
2
|
+
{"word":"helloworld","lives":5,"scrambled_word":"__ll___rl_","word_index":{"h":[0],"e":[1],"o":[4,6],"w":[5],"d":[9]},"player":"playersmith"}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Hangman
|
2
|
+
class Engine
|
3
|
+
|
4
|
+
def pick
|
5
|
+
upper_limit = File.readlines('../hangman/5desk.txt').size
|
6
|
+
word = File.readlines('../hangman/5desk.txt')[rand(upper_limit)].chomp.downcase
|
7
|
+
end
|
8
|
+
|
9
|
+
def pick_word
|
10
|
+
while true
|
11
|
+
word = pick
|
12
|
+
return word if word.length > 5 && word.length <= 12
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require "json"
|
2
|
+
require "colorize"
|
3
|
+
require_relative "message"
|
4
|
+
|
5
|
+
module Hangman
|
6
|
+
|
7
|
+
class FileOp
|
8
|
+
def load_game
|
9
|
+
index = gets.chomp.to_i
|
10
|
+
data = load_file('data.json', index)
|
11
|
+
end
|
12
|
+
|
13
|
+
def save_file(file_name, data)
|
14
|
+
File.open(file_name, 'a+') do |f|
|
15
|
+
f.puts data
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def load_file(file_name, index=nil)
|
20
|
+
if index
|
21
|
+
line = File.readlines(file_name)[index]
|
22
|
+
return data = JSON.parse(line)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete_line(ln)
|
27
|
+
str = ""
|
28
|
+
f = File.open("data.json", 'r+')
|
29
|
+
line = f.readlines.each_with_index do |line, index|
|
30
|
+
str += line if index != ln
|
31
|
+
end
|
32
|
+
str
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_data(data)
|
36
|
+
f = File.open("data.json", "w")
|
37
|
+
f.write(data)
|
38
|
+
f.close
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def get_player_name
|
43
|
+
puts "username: "
|
44
|
+
name = gets.chomp.downcase
|
45
|
+
if name.match /^[A-z]+$/
|
46
|
+
return name
|
47
|
+
else
|
48
|
+
puts "invalid character [a-z] only"
|
49
|
+
sleep 2
|
50
|
+
get_player_name
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
data/lib/hangman/game.rb
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
require "json"
|
2
|
+
require "colorize"
|
3
|
+
require_relative "message"
|
4
|
+
require_relative "fileop"
|
5
|
+
require_relative "engine"
|
6
|
+
|
7
|
+
module Hangman
|
8
|
+
class Game
|
9
|
+
attr_reader :quit, :status
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@msg = Message.new
|
13
|
+
@engine = Engine.new
|
14
|
+
@fileop = FileOp.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def find_index(word)
|
18
|
+
word_index = {}
|
19
|
+
word.downcase.split('').each_with_index{ |val, indx|
|
20
|
+
word_index[val] ||= []
|
21
|
+
word_index[val] << indx
|
22
|
+
}
|
23
|
+
word_index
|
24
|
+
end
|
25
|
+
|
26
|
+
def populate_scramble(word_index, scrambled_word, char)
|
27
|
+
word_index[char].each{ |i|
|
28
|
+
scrambled_word[i] = char
|
29
|
+
}
|
30
|
+
word_index.delete(char)
|
31
|
+
end
|
32
|
+
|
33
|
+
def winner(word_index)
|
34
|
+
word_index.empty?
|
35
|
+
end
|
36
|
+
|
37
|
+
def loser
|
38
|
+
@lives == 0
|
39
|
+
end
|
40
|
+
|
41
|
+
def incorrect_input
|
42
|
+
@lives -= 1
|
43
|
+
puts @msg.wrong_input(@lives)
|
44
|
+
end
|
45
|
+
|
46
|
+
def check_input(word_index, scrambled_word, m)
|
47
|
+
wrong_char = []
|
48
|
+
if word_index.keys.include? m
|
49
|
+
populate_scramble(word_index, scrambled_word, m)
|
50
|
+
else
|
51
|
+
incorrect_input
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def actions_allowed
|
56
|
+
{
|
57
|
+
'#' => :quit_game,
|
58
|
+
'*' => :save_game
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def start_actions
|
63
|
+
{
|
64
|
+
'l' => :load_game,
|
65
|
+
'n' => :new_game,
|
66
|
+
'q' => :quit_game
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def quit_game
|
71
|
+
@status = :quit
|
72
|
+
puts @msg.command
|
73
|
+
sleep 1
|
74
|
+
puts @msg.quiting_game
|
75
|
+
exit
|
76
|
+
end
|
77
|
+
|
78
|
+
def analyze_game_input(word_index)
|
79
|
+
if winner(word_index)
|
80
|
+
@fileop.write_data(@fileop.delete_line(@game_id)) if @game_id
|
81
|
+
puts @msg.game_won
|
82
|
+
start
|
83
|
+
elsif loser
|
84
|
+
@fileop.write_data(@fileop.delete_line(@game_id)) if @game_id
|
85
|
+
puts @msg.game_lose(@word)
|
86
|
+
start
|
87
|
+
elsif @status == :quit
|
88
|
+
exit
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def save_game
|
93
|
+
@fileop.write_data(@fileop.delete_line(@game_id)) if @game_id
|
94
|
+
@player = @fileop.get_player_name
|
95
|
+
data = { word: @word, lives: @lives, scrambled_word: @scrambled_word, word_index: @word_index, player: @player }.to_json
|
96
|
+
@fileop.save_file('data.json', data)
|
97
|
+
puts @msg.save_game_successful
|
98
|
+
exit
|
99
|
+
end
|
100
|
+
|
101
|
+
def play(char, word_index, scrambled_word)
|
102
|
+
unless actions_allowed.include? char
|
103
|
+
check_input(word_index, scrambled_word, char)
|
104
|
+
puts scrambled_word
|
105
|
+
else
|
106
|
+
send actions_allowed[char]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def play_new(word, lives, word_index, scrambled_word, player_name=nil)
|
111
|
+
puts @msg.guess_word(scrambled_word)
|
112
|
+
until analyze_game_input(word_index)
|
113
|
+
char = gets.chomp
|
114
|
+
play(char, word_index, scrambled_word)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def show_saved_sessions
|
119
|
+
line_no = []
|
120
|
+
print @msg.saved_header
|
121
|
+
line = File.readlines("data.json")
|
122
|
+
line.each_with_index do |data, indx|
|
123
|
+
ln = JSON.parse(data)
|
124
|
+
line_no << indx
|
125
|
+
p " #{indx} #{ln["scrambled_word"]} #{ln["lives"]} #{ln["player"]}"
|
126
|
+
end
|
127
|
+
line_no
|
128
|
+
end
|
129
|
+
|
130
|
+
#continue start
|
131
|
+
def continue_start
|
132
|
+
@ids = show_saved_sessions
|
133
|
+
puts @msg.supply_save_id
|
134
|
+
id = gets.chomp.to_i
|
135
|
+
end
|
136
|
+
|
137
|
+
def load_game_data
|
138
|
+
data = @fileop.load_file("data.json", @game_id)
|
139
|
+
@word, @lives, @word_index, @scrambled_word, @status, @player = data['word'], data['lives'], data['word_index'], data['scrambled_word'], :on, data['player']
|
140
|
+
puts @msg.greet_player(@player)
|
141
|
+
puts @msg.start_info_2
|
142
|
+
play_new(@word, @lives, @word_index, @scrambled_word, @player)
|
143
|
+
end
|
144
|
+
|
145
|
+
def continue_game
|
146
|
+
@game_id = continue_start
|
147
|
+
if show_saved_sessions.include? @game_id
|
148
|
+
load_game_data
|
149
|
+
else
|
150
|
+
puts @msg.invalid_game_id
|
151
|
+
sleep 1
|
152
|
+
continue_game
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
#continue end
|
157
|
+
|
158
|
+
|
159
|
+
# start start
|
160
|
+
def start_options
|
161
|
+
{
|
162
|
+
'n' => :setup_new_game,
|
163
|
+
'l' => :start_loaded,
|
164
|
+
'q' => :start_quit
|
165
|
+
}
|
166
|
+
end
|
167
|
+
|
168
|
+
def setup_new_game
|
169
|
+
@word = @engine.pick_word
|
170
|
+
@lives, @scrambled_word, @status, @word_index = 5, '_' * @word.length, :on, find_index(@word)
|
171
|
+
puts @msg.start_info_2
|
172
|
+
play_new(@word, @lives, @word_index, @scrambled_word)
|
173
|
+
end
|
174
|
+
|
175
|
+
def start
|
176
|
+
puts @msg.banner
|
177
|
+
puts @msg.start_info
|
178
|
+
input = gets.chomp
|
179
|
+
send start_options[input] if start_options.include?input
|
180
|
+
end
|
181
|
+
|
182
|
+
def start_loaded
|
183
|
+
puts @msg.loading_game
|
184
|
+
continue_game
|
185
|
+
end
|
186
|
+
|
187
|
+
def start_quit
|
188
|
+
puts @msg.quiting_game
|
189
|
+
exit
|
190
|
+
end
|
191
|
+
|
192
|
+
def start_invalid
|
193
|
+
puts "invalid character".red
|
194
|
+
start
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require "colorize"
|
2
|
+
module Hangman
|
3
|
+
class Message
|
4
|
+
|
5
|
+
def wrong_input(lives)
|
6
|
+
"wrong Guess entered ".red + " Lives Left: ".green + "#{lives}".white
|
7
|
+
end
|
8
|
+
|
9
|
+
def command
|
10
|
+
"Quit recieved!!!".red
|
11
|
+
end
|
12
|
+
|
13
|
+
def quiting_game
|
14
|
+
"Quiting Game ................................... done".green
|
15
|
+
end
|
16
|
+
|
17
|
+
def saving_command
|
18
|
+
"Save recieved!!!".green
|
19
|
+
end
|
20
|
+
|
21
|
+
def save_game_successful
|
22
|
+
"Save successful!!!".green
|
23
|
+
end
|
24
|
+
|
25
|
+
def game_won
|
26
|
+
"Congratulations!!! You Got Saved".green
|
27
|
+
end
|
28
|
+
|
29
|
+
def game_lose(word)
|
30
|
+
"The Word was :".yellow + " #{word} ".white + " You are hanged!\n".yellow
|
31
|
+
end
|
32
|
+
|
33
|
+
def saved_header
|
34
|
+
" id Scrambled_word Lives Username\n".yellow
|
35
|
+
end
|
36
|
+
|
37
|
+
def supply_save_id
|
38
|
+
"Enter Game id: ".yellow
|
39
|
+
end
|
40
|
+
|
41
|
+
def invalid_game_id
|
42
|
+
"invalid Game id".red
|
43
|
+
end
|
44
|
+
|
45
|
+
def invalid_name
|
46
|
+
"invalid characters! [a-z] only".red
|
47
|
+
end
|
48
|
+
|
49
|
+
def guess_word(scrambled_word)
|
50
|
+
"Whats your guess? : " + " #{scrambled_word}".yellow
|
51
|
+
end
|
52
|
+
|
53
|
+
def start_info
|
54
|
+
"[n] start new game [l] load saved game [q] quit game".yellow
|
55
|
+
end
|
56
|
+
def start_info_2
|
57
|
+
"\nRemember !!!".blue + "\n[*] => save [#] => quit\n".blue
|
58
|
+
end
|
59
|
+
|
60
|
+
def loading_game
|
61
|
+
" Loading saved game ...................................done".green
|
62
|
+
end
|
63
|
+
|
64
|
+
def greet_player(player)
|
65
|
+
"\nWelcome back #{player}:"
|
66
|
+
end
|
67
|
+
|
68
|
+
def banner
|
69
|
+
"\t\t#######################################################\n" \
|
70
|
+
"\t\t# #\n" \
|
71
|
+
"\t\t# Hangman Game #\n" \
|
72
|
+
"\t\t# #\n" \
|
73
|
+
"\t\t# In #\n" \
|
74
|
+
"\t\t# Ruby #\n" \
|
75
|
+
"\t\t#######################################################\n" \
|
76
|
+
.blue
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
end
|
data/lib/hangman.rb
ADDED