paitin_hangman 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ require_relative "messages"
2
+
3
+ module PaitinHangman
4
+ module SimpleMethods
5
+
6
+ def verify_name_integrity
7
+ name = gets.chomp.upcase.strip
8
+ while name.scan(/[^A-Z\s-]/).empty? == false || name.empty?
9
+ Message.verify_name
10
+ name = STDIN.gets.chomp.upcase.strip
11
+ end
12
+ name
13
+ end
14
+
15
+ # => This technically begins the game
16
+ def play(name)
17
+ Message.game_type
18
+ option_integrity
19
+ if @option == "2"
20
+ Computer.new.level_integrity(name)
21
+ else
22
+ Player.new.first_player_name(name)
23
+ end
24
+ end
25
+ # => The method makes sure a valid option is picked
26
+
27
+ def option_integrity
28
+ @option = gets.chomp
29
+ until @option == "1" || @option == "2"
30
+ puts "Enter either a '1' or a '2'"
31
+ @option = STDIN.gets.chomp
32
+ end
33
+ @option
34
+ end
35
+
36
+ def length_one?(parameter)
37
+ if parameter.length == 1
38
+ return true
39
+ else
40
+ puts "Enter just one letter or an hyphen or an apostrophe"
41
+ return false
42
+ end
43
+ end
44
+
45
+ def unique?(parameter)
46
+ if @misses.include?(parameter) || @right_guesses.include?(parameter)
47
+ puts "You have used #{parameter} already, try again"
48
+ return false
49
+ else
50
+ return true
51
+ end
52
+ end
53
+
54
+ def number?(parameter)
55
+ if parameter.scan(/\d/).empty?
56
+ return true
57
+ else
58
+ puts "You cannot enter a number! Try again"
59
+ return false
60
+ end
61
+ end
62
+
63
+ def choice_integrity
64
+ choice = gets.chomp.downcase
65
+ until choice == "r" || choice == "q" || choice == "quit"
66
+ puts "You must enter either a 'r' or 'q' or type 'quit'"
67
+ choice = STDIN.gets.chomp.downcase
68
+ end
69
+ decide(choice)
70
+ end
71
+
72
+ def decide(choice)
73
+ if choice == "r"
74
+ @player1 ? play(@player1) : play(@player2)
75
+ else
76
+ exit
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,20 @@
1
+ module PaitinHangman
2
+ class GameData
3
+ attr_accessor :player_name, :misses, :right_guesses, :chances, :word_control, :game_word, :count
4
+
5
+ def initialize(player_name, misses, right_guesses, chances, word_control, game_word, count)
6
+ @player_name = player_name
7
+ @misses = misses
8
+ @right_guesses = right_guesses
9
+ @chances = chances
10
+ @word_control = word_control
11
+ @game_word = game_word
12
+ @count = count
13
+ end
14
+
15
+ def to_s
16
+ "#{player_name} ===>>> #{word_control.upcase.gsub('_', '__ ')}\n"\
17
+ "\t #{chances} chances left and you have used #{misses.join(', ')}\n"
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,73 @@
1
+ require_relative "messages"
2
+ require_relative "levels"
3
+ require_relative "extra_methods"
4
+ # => This class only ensures the smooth transfer of control to the levels
5
+ module PaitinHangman
6
+ class Computer
7
+ def initialize
8
+ Message.level_choice
9
+ end
10
+
11
+ def level_integrity(name)
12
+ choice = gets.chomp
13
+ until choice == "1" || choice == "2" || choice == "3"
14
+ puts "Please press either '1', '2' or '3'"
15
+ choice = STDIN.gets.chomp
16
+ end
17
+ level(choice, name)
18
+ end
19
+
20
+ def level(choice, name)
21
+ case choice
22
+ when "1" then Levels.new(name, 4, 8, 10)
23
+ when "2" then Levels.new(name, 9, 12, 12)
24
+ when "3" then Levels.new(name, 13, 25, 15)
25
+ end
26
+ end
27
+ end
28
+
29
+ class Player
30
+ include SimpleMethods
31
+
32
+ def first_player_name(name)
33
+ player1 = name
34
+ get_friend_name(player1)
35
+ end
36
+
37
+ def get_friend_name(player1)
38
+ puts "Hi #{player1}, what is the name of your friend"
39
+ player2 = verify_name_integrity
40
+ puts "Hello, #{player1} and #{player2}, who will like to challenge"
41
+ game(player1, player2)
42
+ end
43
+
44
+ def game(player1, player2)
45
+ begin
46
+ puts "Please enter one of your names: #{player1} or #{player2}"
47
+ name = verify_name_integrity
48
+ end until name == player1 || name == player2
49
+ other_player = player2 if name == player1
50
+ other_player = player1 if name == player2
51
+ Message.level_choice
52
+ level_integrity(name, other_player)
53
+ end
54
+
55
+ def level_integrity(name, other_player)
56
+ choice = gets.chomp
57
+ until choice == "1" || choice == "2" || choice == "3"
58
+ puts "Please press either '1', '2' or '3'"
59
+ choice = STDIN.gets.chomp
60
+ end
61
+ select_level(choice, name, other_player)
62
+ end
63
+
64
+ def select_level(choice, name, other_player)
65
+ case choice
66
+ when "1" then Levels.new(other_player, 4, 8, 10, name)
67
+ when "2" then Levels.new(other_player, 9, 12, 12, name)
68
+ when "3" then Levels.new(other_player, 13, 25, 15, name)
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,180 @@
1
+ require "colorize"
2
+ require "io/console"
3
+ require "yaml"
4
+ require_relative "extra_methods"
5
+ require_relative "messages"
6
+ require_relative "game_data"
7
+ module PaitinHangman
8
+ class Levels
9
+ attr_reader :player2, :min, :max, :chances, :player1, :game_word
10
+ include SimpleMethods
11
+ def initialize(player, min, max, chances, another_player = nil)
12
+ @misses = []
13
+ @right_guesses = []
14
+ initialize_specs(player, min, max, chances, another_player)
15
+ puts "\t\tWelcome #{@player2}, In this level, you will have #{@chances}
16
+ chances to guess the word correctly"
17
+ word_generator(@min, @max) if @player1.nil?
18
+ challenge_word(@min, @max) if @player1.nil? == false
19
+ trials(@chances)
20
+ end
21
+
22
+ def initialize_specs(player, min, max, chances, another_player)
23
+ @player2 = player
24
+ @min = min
25
+ @max = max
26
+ @chances = chances
27
+ @player1 = another_player
28
+ end
29
+
30
+ def word_generator(min, max, path = "")
31
+ words = File.open(path + "dictionary.txt", "r").readlines.map!(&:chomp)
32
+ level_words = words.select { |i| i.length >= min && i.length <= max }
33
+ random_index = rand(level_words.length)
34
+ @game_word = level_words[random_index]
35
+ end
36
+
37
+ def challenge_word(min, max)
38
+ puts "Now, enter your challenge_word #{@player1}, it will be hidden"
39
+ @game_word = STDIN.noecho(&:gets).chomp.downcase.delete(" ")
40
+ until @game_word.length >= min && @game_word.length <= max &&
41
+ number?(@game_word)
42
+ puts "Word length not correct!Make it between #{min} & #{max} characters"
43
+ @game_word = STDIN.noecho(&:gets).chomp.downcase.delete(" ")
44
+ end
45
+ puts "The stage is set #{@player2}"
46
+ end
47
+
48
+ def trials(chances)
49
+ setup
50
+ chances.times do |counter|
51
+ @counter = counter
52
+ verify_guess
53
+ compare_guess
54
+ win_game(chances, counter)
55
+ end
56
+ end_game
57
+ end
58
+
59
+ def compare_guess
60
+ if @game_word.include?(@guess) == false
61
+ wrong_guess
62
+ else
63
+ correct_guess
64
+ end
65
+ end
66
+
67
+ def setup
68
+ @word_control = ""
69
+ @game_word.length.times { @word_control << "_" }
70
+ @count = 0
71
+ puts @word_control.gsub("_", "__ ")
72
+ end
73
+
74
+ def wrong_guess
75
+ @misses << @guess
76
+ puts "Bad guess, the noose tightens".red
77
+ puts "Try again"
78
+ puts @word_control.gsub("_", " __ ").upcase
79
+ end
80
+
81
+ def correct_guess
82
+ @game_word.each_char.with_index do |letter, index|
83
+ right_guess(letter, index)
84
+ end
85
+ @right_guesses << @guess
86
+ puts @word_control.gsub("_", " __ ").upcase
87
+ end
88
+
89
+ def right_guess(letter, index)
90
+ if letter == @guess
91
+ if @word_control.include?(@guess) == false
92
+ @count += 1
93
+ puts "Nice one!".green
94
+ end
95
+ @word_control[index] = @guess
96
+ end
97
+ end
98
+
99
+ def verify_guess
100
+ puts "Enter a guess"
101
+ @guess = gets.chomp.downcase
102
+ cheat_or_quit_or_history
103
+ until length_one?(@guess) && unique?(@guess) && number?(@guess)
104
+ @guess = STDIN.gets.chomp.downcase
105
+ puts @game_word if @guess == ":c"
106
+ puts "Your missed guesses: #{@misses.join(', ')}" if @guess == ":h"
107
+ end
108
+ end
109
+
110
+ def cheat_or_quit_or_history
111
+ if @guess == ":c"
112
+ puts @game_word
113
+ verify_guess
114
+ elsif @guess == "quit" || @guess == ":q"
115
+ quit_or_save
116
+ elsif @guess == ":h" || @guess == "history"
117
+ history_verify_guess
118
+ end
119
+ end
120
+
121
+ def history_verify_guess
122
+ history
123
+ verify_guess
124
+ end
125
+
126
+ def quit_or_save
127
+ exit if @player1.nil? == false
128
+ puts "Do you want to save your game? type 'Yes' or 'No'"
129
+ choice = STDIN.gets.chomp.downcase
130
+ until choice == "yes" || choice == "no"
131
+ puts "Please type a 'Yes' or a 'No'"
132
+ choice = STDIN.gets.chomp.downcase
133
+ end
134
+ choice == "no" ? exit : save_game
135
+ end
136
+
137
+ def save_game
138
+ game_data = GameData.new(@player2, @misses, @right_guesses,
139
+ @chances - @counter, @word_control,
140
+ @game_word, @count)
141
+ File.open("games.yml", "a") { |data| YAML.dump(game_data, data) }
142
+ puts "Goodbye, your game has been saved successfully".green
143
+ exit
144
+ end
145
+
146
+ def history
147
+ if @misses.empty? && @right_guesses.empty?
148
+ puts "you have not entered any guesses"
149
+ else
150
+ print_history
151
+ end
152
+ end
153
+
154
+ def print_history
155
+ if @misses.empty? && @right_guesses.empty? == false
156
+ puts "your right guesses are #{@right_guesses.join(', ')} but no misses"
157
+ elsif @misses.empty? == false && @right_guesses.empty?
158
+ puts "your misses are #{@misses.join(', ')} & you have no right guesses"
159
+ else
160
+ puts "\tyour misses are #{@misses.join(', ')} and your
161
+ right guesses are #{@right_guesses.join(', ')}"
162
+ end
163
+ end
164
+
165
+ def win_game(chances, counter, player = @player2)
166
+ if @count == @game_word.chars.uniq.length
167
+ puts "Congratulations #{player}! You have won the game".green
168
+ exit
169
+ end
170
+ puts "You have #{chances - 1 - counter} chance(s) left"
171
+ end
172
+
173
+ def end_game(player = @player2)
174
+ puts "Game over! You have been HANGED! Sorry #{player}".red
175
+ puts "The word is #{@game_word.upcase}"
176
+ Message.end_games
177
+ choice_integrity
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,75 @@
1
+
2
+ # This Message class basically supplies the game with
3
+ # messages to guide the user
4
+
5
+ require "colorize"
6
+ module PaitinHangman
7
+ class Message
8
+ # => The welcome message introduces the game to the player
9
+ def self.welcome
10
+ puts "\tWelcome to Hangman, the no-nonsense game
11
+ Be smart, then you live. if not, you'll have to die by Hanging.
12
+ You have a couple of options to pick from.....
13
+ Press 'P' or 'play' if you think you are ready for the challenge,
14
+ You may press 'I' or 'instructions' for a short explanation of how to play
15
+ You may continue a previously saved game by pressing 'L' or 'load'
16
+ Or you could just quit by pressing a 'Q' or typing 'quit'".green
17
+ end
18
+ # => The instruction tells the user what the game is about
19
+
20
+ def self.instruction
21
+ puts "\tThe word to guess is represented by a row of dashes
22
+ These dashes represent each letter of the word.
23
+ Words you cannot use include proper nouns such as names, places, and brands.
24
+ If the guessing player suggests a letter which occurs in the word,
25
+ the other player writes it in all its correct positions.".yellow
26
+ Message.instruction_continue
27
+ end
28
+
29
+ def self.instruction_continue
30
+ puts "\tThe guessing player wins the game if he gets all letters correctly
31
+ within number of chances afforded. He loses if he exhausts all his chances
32
+ without getting all the letters of the word completely".yellow
33
+ puts "\tNow decide whether you want to 'p'lay or 'q'uit.
34
+ Please do keep in mind that you can press ':h' or 'history' at any time
35
+ during the game to show your guess history or ':q'/'quit' to exit the game
36
+ While quitting the game, you may quit directly or decide to save your
37
+ session to resume at a later time at which point you must press 's'".yellow
38
+ end
39
+ # => This method basically instructs the player to pick a valid option
40
+
41
+ def self.valid_option
42
+ puts "Try and enter a valid option: 'p', 'i', 'l' or 'q'".yellow
43
+ end
44
+ # => game logic
45
+
46
+ def self.game_intro
47
+ puts "Now that you have chosen to play".green
48
+ print "What is your name: ".green
49
+ end
50
+ # => Instructs the user to enter a valid name
51
+
52
+ def self.verify_name
53
+ puts "Please enter your real name, I don't think it is just a".red
54
+ puts "space or it contains numbers.".red
55
+ end
56
+ # => game logic
57
+
58
+ def self.game_type
59
+ puts "1)\tPlay against a Human Player, press 1\n"\
60
+ "2)\tPlay against Computer, press 2"
61
+ end
62
+ # informs the player of the levels available & their respective difficulties
63
+
64
+ def self.level_choice
65
+ puts " Enter the Level you would like to play. You may press...
66
+ 1 for Beginner (4 - 8 character word)
67
+ 2 for Intermediate (9 - 12 character word)
68
+ 3 for Advanced (word has above 12 characters)".yellow
69
+ end
70
+
71
+ def self.end_games
72
+ puts "Press 'r' to restart the game or 'q' to quit."
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,89 @@
1
+ require_relative "levels"
2
+ module PaitinHangman
3
+ class GameResumption
4
+ def initialize
5
+ @all_games = YAML.load_stream(File.open("games.yml", "a+"))
6
+ puts "Enter the name you used to store the game"
7
+ name = STDIN.gets.chomp.upcase
8
+ @saved_game = @all_games.select do |game|
9
+ game.player_name == name
10
+ end
11
+ initialize_cont(name)
12
+ end
13
+
14
+ def initialize_cont(name)
15
+ if @saved_game.empty?
16
+ puts "You have no saved game with that name".red
17
+ puts "START A NEW GAME INSTEAD".yellow
18
+ exit
19
+ end
20
+ puts "Here are the saved games found for #{name}\n\n"
21
+ print_function
22
+ choice_integrity
23
+ end
24
+
25
+ def choice_integrity
26
+ puts "Now enter the number for the game you want to play"
27
+ @choice = STDIN.gets.chomp.to_i
28
+ until @choice > 0 && @choice <= @saved_game.length
29
+ puts "Enter a number that has a game please"
30
+ @choice = STDIN.gets.chomp.to_i
31
+ end
32
+ @choice -= 1
33
+ load_properties
34
+ end
35
+
36
+ def load_properties
37
+ @game_object = @saved_game[@choice]
38
+ @name = @game_object.player_name
39
+ @misses = @game_object.misses
40
+ @right_guesses = @game_object.right_guesses
41
+ @chances = @game_object.chances
42
+ @word_control = @game_object.word_control
43
+ @game_word = @game_object.game_word
44
+ load_properties_cont
45
+ end
46
+
47
+ def load_properties_cont
48
+ count = @game_object.count
49
+ Saved.new(@name, @chances, @word_control, @game_word,
50
+ @misses, @right_guesses, count).trials(@chances)
51
+ end
52
+
53
+ def print_function
54
+ @saved_game.length.times do |index|
55
+ print "#{index + 1}.\t"
56
+ puts @saved_game[index], "\n"
57
+ end
58
+ end
59
+ end
60
+
61
+ class Saved < Levels
62
+ def initialize(name, chances, word_control, game_word, misses, right_guesses,
63
+ count)
64
+ @player_name = name
65
+ @chances = chances
66
+ @word_control = word_control
67
+ @game_word = game_word
68
+ @misses = misses
69
+ @right_guesses = right_guesses
70
+ @count = count
71
+ end
72
+
73
+ def trials(chances)
74
+ setup
75
+ chances.times do |counter|
76
+ @counter = counter
77
+ verify_guess
78
+ compare_guess
79
+ win_game(chances, counter, @player_name)
80
+ end
81
+ end_game(@player_name)
82
+ end
83
+
84
+ def setup
85
+ puts "Now, continue playing..."
86
+ puts @word_control.gsub("_", "__ ").upcase
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,3 @@
1
+ module PaitinHangman
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,46 @@
1
+ require_relative "paitin_hangman/messages"
2
+ require_relative "paitin_hangman/saved_games"
3
+ require_relative "paitin_hangman/version"
4
+ require_relative "paitin_hangman/game_engine"
5
+ module PaitinHangman
6
+ class Paitin
7
+ include SimpleMethods
8
+ def game_control
9
+ Message.welcome
10
+ process
11
+ end
12
+
13
+ def process
14
+ choice = gets.chomp.downcase
15
+ choice_integrity(choice)
16
+ end
17
+
18
+ def choice_integrity(choice)
19
+ case choice
20
+ when "p", "play" then new_game
21
+ when "i", "instruction" then instruction
22
+ when "q", "quit" then exit
23
+ when "l", "load" then GameResumption.new
24
+ else
25
+ try_again
26
+ end
27
+ end
28
+
29
+ def try_again
30
+ Message.valid_option
31
+ process
32
+ end
33
+
34
+ def instruction
35
+ Message.instruction
36
+ process
37
+ end
38
+
39
+ def new_game
40
+ Message.game_intro
41
+ name = verify_name_integrity
42
+ puts "Hi #{name}, Select a mode"
43
+ play(name)
44
+ end
45
+ end
46
+ end
@@ -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 'paitin_hangman/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "paitin_hangman"
8
+ spec.version = PaitinHangman::VERSION
9
+ spec.authors = ["Mayowa Pitan"]
10
+ spec.email = ["mayowa.pitan@andela.com"]
11
+
12
+ spec.summary = %q{A Classic implementation of the hangman game}
13
+ spec.description = %q{The no-nonsense game, guess right and you live!}
14
+ spec.homepage = "https://www.github.com/andela-mpitan/paitin_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"
27
+ spec.executables = ["paitin_hangman"]
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_development_dependency "bundler", "~> 1.11"
31
+ spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rspec", "~> 3.0"
33
+ spec.add_runtime_dependency "colorize"
34
+ spec.add_development_dependency 'codeclimate-test-reporter'
35
+ spec.add_development_dependency 'simplecov'
36
+ end