mastermind-cmdline 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/mastermind +9 -0
- data/lib/mastermind.rb +70 -0
- data/lib/mastermind/AIsolver.rb +36 -0
- data/lib/mastermind/GameRules.rb +73 -0
- data/lib/mastermind/GameStatus.rb +52 -0
- data/lib/mastermind/TerminalInterface.rb +37 -0
- data/lib/mastermind/UserInterface.rb +25 -0
- data/test/mastermind_spec.rb +256 -0
- metadata +53 -0
data/bin/mastermind
ADDED
data/lib/mastermind.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require_relative './mastermind/GameRules'
|
2
|
+
require_relative './mastermind/TerminalInterface'
|
3
|
+
require_relative './mastermind/GameStatus'
|
4
|
+
require_relative './mastermind/AIsolver'
|
5
|
+
|
6
|
+
module Mastermind
|
7
|
+
class Game
|
8
|
+
def initialize(game_text, terminal)
|
9
|
+
@game_text = game_text
|
10
|
+
@terminal = terminal
|
11
|
+
@code_length = 4
|
12
|
+
end
|
13
|
+
|
14
|
+
def play_game
|
15
|
+
@terminal.display(@game_text.message(:welcome))
|
16
|
+
colors = get_color_scheme
|
17
|
+
code = get_input(colors)
|
18
|
+
set_up_board(code, colors)
|
19
|
+
result = run_ai_player(colors)
|
20
|
+
end_of_game(result)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def get_color_scheme
|
26
|
+
@terminal.display(@game_text.message(:color_scheme))
|
27
|
+
colors = @terminal.formatted_input
|
28
|
+
Colors.new(colors).valid_colors
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_input(colors)
|
32
|
+
@terminal.display(@game_text.message(:prompt) )
|
33
|
+
input = @terminal.formatted_input
|
34
|
+
unless Validator.new(input, @code_length, colors ).valid?
|
35
|
+
get_input
|
36
|
+
else
|
37
|
+
input
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def set_up_board(code, colors)
|
42
|
+
@board = GameStatus.new(code, colors)
|
43
|
+
end
|
44
|
+
|
45
|
+
def run_ai_player(colors)
|
46
|
+
algorithm = NaiveAlgorithm.new(colors)
|
47
|
+
player = AIPlayer.new(@board, algorithm)
|
48
|
+
result = player.solve
|
49
|
+
until @board.end_of_game?(result)
|
50
|
+
result = player.solve
|
51
|
+
print_guess(result)
|
52
|
+
end
|
53
|
+
print_guess(result)
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
def print_guess(result)
|
58
|
+
@terminal.display(@game_text.message(:guess, result))
|
59
|
+
end
|
60
|
+
|
61
|
+
def end_of_game(result)
|
62
|
+
if(result.correct?)
|
63
|
+
@terminal.display(@game_text.message(:win, result))
|
64
|
+
else
|
65
|
+
@terminal.display(@game_text.message(:lose, result))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Mastermind
|
2
|
+
class NaiveAlgorithm
|
3
|
+
attr_accessor :possible_guesses
|
4
|
+
|
5
|
+
def initialize(valid_letters)
|
6
|
+
@valid_letters = valid_letters
|
7
|
+
@possible_guesses = valid_letters.repeated_permutation(4).to_a
|
8
|
+
end
|
9
|
+
|
10
|
+
def next_guess
|
11
|
+
@possible_guesses[rand(@possible_guesses.size)]
|
12
|
+
end
|
13
|
+
|
14
|
+
def discard_invalid_guesses(incorrect_guess)
|
15
|
+
discarded_guesses = @possible_guesses.select do |guess|
|
16
|
+
compare_result = CodeComparer.new(incorrect_guess.guess, guess).compare
|
17
|
+
compare_result != incorrect_guess.result_hash
|
18
|
+
end
|
19
|
+
@possible_guesses -= discarded_guesses
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class AIPlayer
|
24
|
+
def initialize(board, algorithm)
|
25
|
+
@board = board
|
26
|
+
@algorithm = algorithm
|
27
|
+
end
|
28
|
+
|
29
|
+
def solve
|
30
|
+
next_guess = @algorithm.next_guess
|
31
|
+
result = @board.process_guess(next_guess)
|
32
|
+
@algorithm.discard_invalid_guesses(result)
|
33
|
+
result
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Mastermind
|
2
|
+
DEFAULT_COLORS = %w{R G O Y B P}
|
3
|
+
class CodeComparer
|
4
|
+
def initialize(code, guess)
|
5
|
+
@code = code
|
6
|
+
@guess = guess
|
7
|
+
end
|
8
|
+
|
9
|
+
def compare
|
10
|
+
correct_colors = total_correct_colors - correct_positions
|
11
|
+
{
|
12
|
+
correct_positions: correct_positions,
|
13
|
+
correct_colors: correct_colors
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def correct_positions
|
20
|
+
code_with_indeces = @code.each_with_index.to_a
|
21
|
+
guess_with_indeces = @guess.each_with_index.to_a
|
22
|
+
intersection = code_with_indeces & guess_with_indeces
|
23
|
+
intersection.size
|
24
|
+
end
|
25
|
+
|
26
|
+
def total_correct_colors
|
27
|
+
correct_color = 0
|
28
|
+
@code.uniq.each do |letter|
|
29
|
+
correct_color += [@code.count(letter), @guess.count(letter)].min
|
30
|
+
end
|
31
|
+
correct_color
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Validator
|
36
|
+
def initialize(code, code_length, valid_letters)
|
37
|
+
@code = code
|
38
|
+
@code_length = code_length
|
39
|
+
@valid_letters = valid_letters
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
def valid?
|
44
|
+
correct_length? && valid_letters?
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def correct_length?
|
50
|
+
@code.size == @code_length
|
51
|
+
end
|
52
|
+
|
53
|
+
def valid_letters?
|
54
|
+
@code.uniq.all? do |letter|
|
55
|
+
@valid_letters.include?letter
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
class Colors
|
61
|
+
def initialize(colors = [])
|
62
|
+
if(colors.empty? || colors.size != 6)
|
63
|
+
@colors = DEFAULT_COLORS
|
64
|
+
else
|
65
|
+
@colors = colors
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def valid_colors
|
70
|
+
@colors
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Mastermind
|
2
|
+
WIN_HASH = {correct_positions: 4, correct_colors:0}
|
3
|
+
|
4
|
+
class GameStatus
|
5
|
+
def initialize(code, colors)
|
6
|
+
@code = code
|
7
|
+
@num_of_tries = 0
|
8
|
+
@colors = colors
|
9
|
+
end
|
10
|
+
|
11
|
+
def valid_letters
|
12
|
+
@colors
|
13
|
+
end
|
14
|
+
|
15
|
+
def process_guess(guess)
|
16
|
+
@num_of_tries += 1
|
17
|
+
if win?(guess)
|
18
|
+
#Is it worth checking win separately here?
|
19
|
+
result_hash = WIN_HASH
|
20
|
+
else
|
21
|
+
result_hash = CodeComparer.new(@code, guess).compare
|
22
|
+
end
|
23
|
+
CurrentResult.new(guess, @num_of_tries, result_hash)
|
24
|
+
end
|
25
|
+
|
26
|
+
def end_of_game?(result)
|
27
|
+
win?(result.guess) || result.num_of_tries == 10
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def win?(guess)
|
34
|
+
@code == guess
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class CurrentResult
|
39
|
+
attr_reader :result_hash
|
40
|
+
attr_reader :num_of_tries, :guess
|
41
|
+
|
42
|
+
def initialize(guess, num_of_tries, result_hash)
|
43
|
+
@guess = guess
|
44
|
+
@num_of_tries = num_of_tries
|
45
|
+
@result_hash = result_hash
|
46
|
+
end
|
47
|
+
|
48
|
+
def correct?
|
49
|
+
@result_hash == WIN_HASH
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Mastermind
|
2
|
+
class Terminal
|
3
|
+
def display(message)
|
4
|
+
puts message
|
5
|
+
end
|
6
|
+
|
7
|
+
def formatted_input(stdin = $stdin)
|
8
|
+
stdin.gets.upcase.split(%r{\s*} )
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class GameText
|
13
|
+
def message(message_type, game_result = [])
|
14
|
+
case message_type
|
15
|
+
when :welcome
|
16
|
+
"Welcome To Mastermind"
|
17
|
+
when :prompt
|
18
|
+
"Please Enter the Code: "
|
19
|
+
when :guess
|
20
|
+
"#{game_result.guess}"
|
21
|
+
when :win
|
22
|
+
if(game_result.num_of_tries == 1)
|
23
|
+
"Solved in #{game_result.num_of_tries} try!"
|
24
|
+
else
|
25
|
+
"Solved in #{game_result.num_of_tries} tries!"
|
26
|
+
end
|
27
|
+
when :lose
|
28
|
+
"Game over. Unable to solve in 10 turns."
|
29
|
+
when :color_scheme
|
30
|
+
"Enter a 6 letter color scheme or press Enter to use default"
|
31
|
+
else
|
32
|
+
"Come again?"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Mastermind
|
2
|
+
class CodeGenerator
|
3
|
+
def initialize(colors, code_length)
|
4
|
+
@colors = colors
|
5
|
+
@code_length = code_length
|
6
|
+
@terminal = Terminal.new
|
7
|
+
@game_text = GameText.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def get_valid_code
|
11
|
+
input = get_input
|
12
|
+
unless Validator.new(input, @code_length, @colors ).valid?
|
13
|
+
get_valid_code
|
14
|
+
else
|
15
|
+
input
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def get_input
|
20
|
+
@terminal.display(@game_text.message(:prompt) )
|
21
|
+
@terminal.formatted_input
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,256 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require_relative '../lib/mastermind'
|
3
|
+
require_relative '../lib/mastermind/AIsolver'
|
4
|
+
require_relative '../lib/mastermind/GameRules'
|
5
|
+
require_relative '../lib/mastermind/GameStatus'
|
6
|
+
require_relative '../lib/mastermind/TerminalInterface'
|
7
|
+
|
8
|
+
include Mastermind
|
9
|
+
|
10
|
+
DEFAULT_COLORS = %w{R G O Y B P}
|
11
|
+
|
12
|
+
describe 'Mastermind' do
|
13
|
+
WIN_HASH = {correct_positions: 4, correct_colors: 0}
|
14
|
+
|
15
|
+
let(:code){ %w{R R R R} }
|
16
|
+
let (:default_colors){ %w{R G O Y B P} }
|
17
|
+
|
18
|
+
describe 'GameStatus' do
|
19
|
+
let (:code){ %w{A B C D} }
|
20
|
+
let (:incorrect_guess){ %w{A C B E} }
|
21
|
+
let (:board){GameStatus.new(code, DEFAULT_COLORS)}
|
22
|
+
|
23
|
+
it 'stores the valid letters' do
|
24
|
+
expect(board.valid_letters).to eq(default_colors)
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns a CurrentResult after tries a guess'
|
28
|
+
|
29
|
+
it 'returns an incorrect result when incorrect guess' do
|
30
|
+
expect(board.process_guess(incorrect_guess).correct?).to eq(false)
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns a correct result when correct guess (win)' do
|
34
|
+
expect(board.process_guess(code).correct?).to eq(true)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'detects the end of game on a win' do
|
38
|
+
result = CurrentResult.new(code, nil, nil)
|
39
|
+
expect(board.end_of_game?(result)).to eq(true)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'detects the end of game on a loss' do
|
43
|
+
result = CurrentResult.new(nil, 10, nil)
|
44
|
+
expect(board.end_of_game?(result)).to eq(true)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'CurrentResult' do
|
49
|
+
it 'returns correct when winning result hash' do
|
50
|
+
correct_hash = {correct_positions: 4 , correct_colors:0}
|
51
|
+
expect(CurrentResult.new(nil, nil, correct_hash).correct?).to eq(true)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'returns incorrect when incorrect guess' do
|
55
|
+
incorrect_hash = {correct_positions: 1 , correct_colors:0}
|
56
|
+
expect(CurrentResult.new(nil, nil, incorrect_hash).correct?).to eq(false)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'stores the hash, num_of_tries and guess'
|
60
|
+
end
|
61
|
+
|
62
|
+
describe 'CodeComparer' do
|
63
|
+
let (:code){ %w{A B C D} }
|
64
|
+
let (:incorrect_guess){ %w{A C B E} }
|
65
|
+
let (:code_comparer){CodeComparer.new(code,incorrect_guess)}
|
66
|
+
|
67
|
+
it 'returns a hash with number of positions/colors' do
|
68
|
+
result_hash = {correct_positions: 1, correct_colors:2}
|
69
|
+
expect(code_comparer.compare).to eq(result_hash)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'Colors' do
|
74
|
+
let(:default_colors){%w{R G O Y B P}}
|
75
|
+
it 'returns default colors if incorrect size of input array' do
|
76
|
+
custom_colors = %w{Q Z F R}
|
77
|
+
expect(Colors.new(custom_colors).valid_colors).to match_array(default_colors)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'returns default colors if no arguments' do
|
81
|
+
expect(Colors.new.valid_colors).to match_array(default_colors)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'NaiveAlgorithm' do
|
86
|
+
let (:naive_algorithm){NaiveAlgorithm.new(default_colors)}
|
87
|
+
before(:all) do
|
88
|
+
result_hash = {correct_positions: 0, correct_colors: 0}
|
89
|
+
guess = %w{R R R R}
|
90
|
+
@incorrect_guess = CurrentResult.new(guess, nil, result_hash )
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'initializes possible guesses to all permutations' do
|
94
|
+
expect(naive_algorithm.possible_guesses.size).to eq(1296)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'chooses a valid next_guess' do
|
98
|
+
expect(naive_algorithm.next_guess).to be
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'randomizes the next guess' do
|
102
|
+
first_guess = naive_algorithm.next_guess
|
103
|
+
second_guess = naive_algorithm.next_guess
|
104
|
+
expect(first_guess).not_to eq(second_guess)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'discards invalid guesses based on previous result' do
|
108
|
+
expect(naive_algorithm.discard_invalid_guesses(@incorrect_guess)).not_to include( %w{R R R R} )
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'keeps guesses that are still valid' do
|
112
|
+
expect(naive_algorithm.discard_invalid_guesses(@incorrect_guess)).to include( %w{G G G G} )
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe 'AIPlayer' do
|
117
|
+
let(:algorithm){NaiveAlgorithm.new(DEFAULT_COLORS)}
|
118
|
+
let(:board){GameStatus.new(code, DEFAULT_COLORS)}
|
119
|
+
let(:ai_player){AIPlayer.new(board, algorithm)}
|
120
|
+
let(:solution){CurrentResult.new(code, 1, WIN_HASH )}
|
121
|
+
|
122
|
+
|
123
|
+
it 'calls process_guess once if wins on first try' do
|
124
|
+
allow(algorithm).to receive(:next_guess){ code }
|
125
|
+
expect(board).to receive(:process_guess).with(code).and_return(solution)
|
126
|
+
ai_player.solve
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'GameText' do
|
131
|
+
let(:game_text){GameText.new}
|
132
|
+
|
133
|
+
it 'displays welcome message' do
|
134
|
+
expect(game_text.message(:welcome)).to eq("Welcome To Mastermind")
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'prompts user for input' do
|
138
|
+
expect(game_text.message(:prompt)).to eq("Please Enter the Code: ")
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'displays winning message' do
|
142
|
+
code = %w{R R R R}
|
143
|
+
result = CurrentResult.new(code, 1, WIN_HASH)
|
144
|
+
expect(game_text.message(:win, result)).to eq("Solved in 1 try!")
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'pluralizes winning message' do
|
148
|
+
code = %w{R R R R}
|
149
|
+
result = CurrentResult.new(code, 2, WIN_HASH)
|
150
|
+
expect(game_text.message(:win, result)).to eq("Solved in 2 tries!")
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'displays losing message' do
|
154
|
+
expect(game_text.message(:lose)).to eq("Game over. Unable to solve in 10 turns.")
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'prompts user for color scheme' do
|
158
|
+
expect(game_text.message(:color_scheme)).to eq("Enter a 6 letter color scheme or press Enter to use default")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
describe 'Game' do
|
164
|
+
let(:game_text){GameText.new}
|
165
|
+
let(:terminal_obj){double('terminal_obj') }
|
166
|
+
let(:game){ Game.new(game_text, terminal_obj) }
|
167
|
+
|
168
|
+
#
|
169
|
+
# it 'returns input when valid' do
|
170
|
+
# allow(Terminal).to receive(:new){terminal_obj}
|
171
|
+
# expect(terminal_obj).to receive(:formatted_input).once.ordered.and_return(%w{R R R R} )
|
172
|
+
# expect(terminal_obj).to receive(:display)
|
173
|
+
#
|
174
|
+
# result = game.get_input
|
175
|
+
# expect(Validator.new(result).valid?).to eq(true)
|
176
|
+
# end
|
177
|
+
#
|
178
|
+
# it 'calls the function until valid' do
|
179
|
+
# allow(Terminal).to receive(:new){terminal_obj}
|
180
|
+
# expect(terminal_obj).to receive(:formatted_input).once.ordered.and_return(%w{Z Z Z Z} )
|
181
|
+
# expect(terminal_obj).to receive(:formatted_input).once.ordered.and_return(%w{R R R R} )
|
182
|
+
# expect(terminal_obj).to receive(:display)
|
183
|
+
# expect(terminal_obj).to receive(:display)
|
184
|
+
#
|
185
|
+
# result = game.get_input
|
186
|
+
# expect(Validator.new(result).valid?).to eq(true)
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# it 'gets a Solution from winning AIPlayer' do
|
190
|
+
# game.set_up_board(%w{R R R R})
|
191
|
+
# expect(game.run_ai_player.correct?).to eq(true)
|
192
|
+
# end
|
193
|
+
# it 'prints winning end message if win' do
|
194
|
+
# code = %w{R R R R}
|
195
|
+
# result = CurrentResult.new(code, 1, WIN_HASH)
|
196
|
+
# expect{game.end_of_game(result)}.to output("You win!\n").to_stdout
|
197
|
+
# end
|
198
|
+
#
|
199
|
+
# it 'prints losing end message if lose' do
|
200
|
+
# result = CurrentResult.new(nil, nil, nil)
|
201
|
+
# game.set_up_board(%w{R R R R})
|
202
|
+
# expect{game.end_of_game(result)}.to output("Haha! You lost!\n").to_stdout
|
203
|
+
# end
|
204
|
+
|
205
|
+
it 'runs through the game' do
|
206
|
+
allow(terminal_obj).to receive(:display){}
|
207
|
+
allow(game_text).to receive(:message)
|
208
|
+
expect(game).to receive(:get_input).and_return(%w{R O Y B} )
|
209
|
+
expect(game).to receive(:get_color_scheme).and_return(%w{ R G O Y B P})
|
210
|
+
game.play_game
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe 'Terminal' do
|
215
|
+
let(:terminal){Terminal.new}
|
216
|
+
|
217
|
+
it 'displays message' do
|
218
|
+
expect{terminal.display('test message')}.to output("test message\n").to_stdout
|
219
|
+
end
|
220
|
+
|
221
|
+
it 'returns array of input letters' do
|
222
|
+
uppercase_input = StringIO.new("ABCD\n")
|
223
|
+
expect(terminal.formatted_input(uppercase_input)).to eq( %w{A B C D} )
|
224
|
+
end
|
225
|
+
|
226
|
+
it 'converts input to uppercase' do
|
227
|
+
lowercase_input = StringIO.new("abcd\n")
|
228
|
+
expect(terminal.formatted_input(lowercase_input)).to eq(%w{A B C D})
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'ignores whitespace' do
|
232
|
+
whitespace_input = StringIO.new("a b c d\n")
|
233
|
+
expect(terminal.formatted_input(whitespace_input)).to eq(%w{A B C D})
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
|
238
|
+
describe 'Validator' do
|
239
|
+
it 'accepts a correct code' do
|
240
|
+
correct_validator = Validator.new( %w{R G O Y}, 4, DEFAULT_COLORS)
|
241
|
+
expect(correct_validator.valid?).to eq(true)
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'fails if code length is incorrect' do
|
245
|
+
wrong_length = Validator.new( %w{R R R R R R}, 4, DEFAULT_COLORS)
|
246
|
+
expect(wrong_length.valid?).to eq(false)
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
it 'fails if either letters or code length are incorrect' do
|
252
|
+
wrong_letters = Validator.new( %w{R G O Y}, 4, %w{Q W E R T Y})
|
253
|
+
expect(wrong_letters.valid?).to eq(false)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
metadata
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mastermind-cmdline
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Samantha Wojtowicz
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2014-06-25 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Naive Mastermind AI
|
15
|
+
email:
|
16
|
+
executables:
|
17
|
+
- mastermind
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/mastermind.rb
|
22
|
+
- lib/mastermind/TerminalInterface.rb
|
23
|
+
- lib/mastermind/GameStatus.rb
|
24
|
+
- lib/mastermind/AIsolver.rb
|
25
|
+
- lib/mastermind/UserInterface.rb
|
26
|
+
- lib/mastermind/GameRules.rb
|
27
|
+
- test/mastermind_spec.rb
|
28
|
+
- bin/mastermind
|
29
|
+
homepage:
|
30
|
+
licenses: []
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.23
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: mastermind-cmdline
|
53
|
+
test_files: []
|