mastermind_ruby 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/exe/mastermind +8 -0
- data/lib/mastermind_ruby.rb +3 -0
- data/lib/mastermind_ruby/code.rb +116 -0
- data/lib/mastermind_ruby/console_interface.rb +63 -0
- data/lib/mastermind_ruby/game.rb +55 -0
- metadata +54 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a3ad4cf50286b09c3bec1e6e74f96642b075a346
|
4
|
+
data.tar.gz: 44a19863fda1c35ace0ce9ba35e6dd8c9eb960eb
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a6b55153f5459955aed6b529d6597a4bb7e105773c9947a75543806e59b9079bb98d16a91a5dc26be6f49ce41d6efc239b2629777cc865c77ffc103e480d4fa0
|
7
|
+
data.tar.gz: 75f75a96928525d51d61356502442d2a1018425ffe4744ba035a3ac42f9a113ee32f9e8feb124e9211d64c11c437434f7dcdde769d4013799e4f4c11f0ef1080
|
data/exe/mastermind
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
module MastermindRuby
|
2
|
+
class Code
|
3
|
+
AVAILABLE_CHARACTERS = %w(R Y G O M P)
|
4
|
+
CODE_PATTERN = /\A[#{AVAILABLE_CHARACTERS.join("")}]{4}\z/
|
5
|
+
|
6
|
+
def initialize(code)
|
7
|
+
@code = code
|
8
|
+
end
|
9
|
+
|
10
|
+
# Parse a string to a code object
|
11
|
+
# Params:
|
12
|
+
# +str+:: the string which is to parse to a code object
|
13
|
+
def self.parse(str)
|
14
|
+
new str.split('')
|
15
|
+
end
|
16
|
+
|
17
|
+
# Method to generate a code
|
18
|
+
def self.random
|
19
|
+
new 4.times.map { AVAILABLE_CHARACTERS.sample }
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns a code object containing 'BBBB'
|
23
|
+
def self.solution
|
24
|
+
@solution ||= Code.parse('BBBB')
|
25
|
+
end
|
26
|
+
|
27
|
+
# Checks if a code is valid (must be 4 characters long and can only contain the available characters)
|
28
|
+
def valid?
|
29
|
+
@code.join =~ CODE_PATTERN
|
30
|
+
end
|
31
|
+
|
32
|
+
# Returns true if code is 'BBBB'
|
33
|
+
def solution?
|
34
|
+
self == Code.solution
|
35
|
+
end
|
36
|
+
|
37
|
+
# Get assesment for solution
|
38
|
+
# e.g. self is YYRG and solution is MMGR it will return WW-- (Code Object)
|
39
|
+
# Params:
|
40
|
+
# +solution+:: the solution which an assessment should be made with
|
41
|
+
def assessment_for_solution(solution)
|
42
|
+
tmp = @code.dup
|
43
|
+
tmp = mark_right_position(tmp, solution)
|
44
|
+
tmp = mark_right_color(tmp, solution)
|
45
|
+
tmp = mark_unmatched(tmp)
|
46
|
+
Code.parse(tmp.sort.join('').tr('X', '-'))
|
47
|
+
end
|
48
|
+
|
49
|
+
# Search for same character at same index and mark it with 'B'
|
50
|
+
# Params:
|
51
|
+
# +input+:: the input
|
52
|
+
# +solution+:: the solution to compare with
|
53
|
+
def mark_right_position(input, solution)
|
54
|
+
input.each.with_index.map do |char, index|
|
55
|
+
if solution[index] == char
|
56
|
+
'B'
|
57
|
+
else
|
58
|
+
char
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# Search for character contained in solution
|
64
|
+
# Params:
|
65
|
+
# +input+:: the input
|
66
|
+
# +solution+:: the solution to compare with
|
67
|
+
def mark_right_color(input, solution)
|
68
|
+
rest_solution = solution.map.with_index { |char, index| input[index] == 'B' ? nil : char }
|
69
|
+
input.each.with_index.map do |char, index|
|
70
|
+
if index = rest_solution.index(char)
|
71
|
+
rest_solution[index] = nil
|
72
|
+
'W'
|
73
|
+
else
|
74
|
+
char
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Mark unmatched with an '-'
|
80
|
+
# Params:
|
81
|
+
# +input+:: the input which should be filled with '-'
|
82
|
+
def mark_unmatched(input)
|
83
|
+
input.map do |char|
|
84
|
+
if %w(B W).include? char
|
85
|
+
char
|
86
|
+
else
|
87
|
+
'X'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def [](index)
|
93
|
+
@code[index]
|
94
|
+
end
|
95
|
+
|
96
|
+
def map(&block)
|
97
|
+
@code.map(&block)
|
98
|
+
end
|
99
|
+
|
100
|
+
def ==(other)
|
101
|
+
to_s == other.to_s
|
102
|
+
end
|
103
|
+
|
104
|
+
def eql?(other)
|
105
|
+
to_s.eql?(other.to_s)
|
106
|
+
end
|
107
|
+
|
108
|
+
def hash
|
109
|
+
to_s.hash
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_s
|
113
|
+
@code.join
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
trap 'SIGINT' do
|
2
|
+
puts "\r\rThe game was interrupted :("
|
3
|
+
exit 130
|
4
|
+
end
|
5
|
+
|
6
|
+
module MastermindRuby
|
7
|
+
# The console interface represents the game
|
8
|
+
# interacting with the UI (in that case a terminal window)
|
9
|
+
|
10
|
+
# Must have methods
|
11
|
+
# * :read_playername
|
12
|
+
# * :read_next_guess
|
13
|
+
# * :display_welcome_message
|
14
|
+
# * :display_assessment
|
15
|
+
# * :display_invalid_code
|
16
|
+
class ConsoleInterface
|
17
|
+
|
18
|
+
# Method which reads the playername
|
19
|
+
# Return the playername as string
|
20
|
+
def read_playername
|
21
|
+
# User inital input
|
22
|
+
print 'Please enter a name: '
|
23
|
+
gets.chomp
|
24
|
+
end
|
25
|
+
|
26
|
+
# Method which is called when the next turn is initiated
|
27
|
+
# Return next guess as Code object
|
28
|
+
# Params:
|
29
|
+
# +try_count+:: what number of guess
|
30
|
+
def read_next_guess(try_count)
|
31
|
+
print "#{try_count}: "
|
32
|
+
MastermindRuby::Code.parse(gets.strip)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Method which is called when the game is initiated to display the game has been started
|
36
|
+
# Params:
|
37
|
+
# +playername+:: the playername which was read before with :read_playername
|
38
|
+
def display_welcome_message(playername)
|
39
|
+
puts '-------- Mastermind Ruby Project -------'
|
40
|
+
puts "Hello #{playername}, your code is generated!"
|
41
|
+
puts "Avaliable Characters:\t#{MastermindRuby::Code::AVAILABLE_CHARACTERS.join("\t")}"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Method which is called when the guess is evaluated
|
45
|
+
# Params:
|
46
|
+
# +result+:: the result (e.g. BBW-, ATTENTION: Code object)
|
47
|
+
def display_assessment(result)
|
48
|
+
puts (result)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Method which is called when the guess was not a valid code
|
52
|
+
def display_invalid_code
|
53
|
+
puts 'Invalid code'
|
54
|
+
end
|
55
|
+
|
56
|
+
# Method which is called when the game is ended
|
57
|
+
# Params:
|
58
|
+
# +try_count+:: how many times guessed until finished
|
59
|
+
def display_end_game(try_count)
|
60
|
+
puts "Congrats! You made it with #{try_count} tries."
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module MastermindRuby
|
2
|
+
class Game
|
3
|
+
attr_reader :try_count
|
4
|
+
|
5
|
+
def initialize(ui, solution: Code.random)
|
6
|
+
@solution_code = solution
|
7
|
+
@ui = ui
|
8
|
+
@try_count = 1
|
9
|
+
@started = false
|
10
|
+
end
|
11
|
+
|
12
|
+
# Method to start a game
|
13
|
+
# Requests by calling read_playername for the playername on the UI
|
14
|
+
def start
|
15
|
+
@started = true
|
16
|
+
@playername = @ui.read_playername
|
17
|
+
@ui.display_welcome_message(@playername)
|
18
|
+
run
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
# Method to run the game (prevent from dying if the solution was not found yet)
|
24
|
+
# Requests by calling read_next_guess for a new guess on the UI
|
25
|
+
# Shows an assessment on the UI by calling display_assessment
|
26
|
+
def run
|
27
|
+
while running?
|
28
|
+
guess = @ui.read_next_guess(@try_count)
|
29
|
+
if guess.valid?
|
30
|
+
result = guess.assessment_for_solution(@solution_code)
|
31
|
+
if result.solution?
|
32
|
+
stop
|
33
|
+
else
|
34
|
+
@try_count += 1
|
35
|
+
@ui.display_assessment(result)
|
36
|
+
end
|
37
|
+
else
|
38
|
+
@ui.display_invalid_code
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Method to stop the game
|
44
|
+
# On the ui display_end_game is called
|
45
|
+
def stop
|
46
|
+
@started = false
|
47
|
+
@ui.display_end_game(@try_count)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Method to check if the game is running
|
51
|
+
def running?
|
52
|
+
@started
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mastermind_ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Yves Siegrist
|
8
|
+
- Yves Senn
|
9
|
+
autorequire:
|
10
|
+
bindir: exe
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-08-06 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: |-
|
15
|
+
Mastermind or Master Mind is a code-breaking game for two players.
|
16
|
+
The modern game with pegs was invented in 1970 by Mordecai Meirowitz, an Israeli postmaster and telecommunications expert.
|
17
|
+
It resembles an earlier pencil and paper game called Bulls and Cows that may date back a century or more.
|
18
|
+
The library is here to reuse the game logic I wrote, and to make your game (UI) as easy as possible to manage.
|
19
|
+
email: y.siegrist@4teamwork.ch
|
20
|
+
executables:
|
21
|
+
- mastermind
|
22
|
+
extensions: []
|
23
|
+
extra_rdoc_files: []
|
24
|
+
files:
|
25
|
+
- exe/mastermind
|
26
|
+
- lib/mastermind_ruby.rb
|
27
|
+
- lib/mastermind_ruby/code.rb
|
28
|
+
- lib/mastermind_ruby/console_interface.rb
|
29
|
+
- lib/mastermind_ruby/game.rb
|
30
|
+
homepage: https://github.com/Elektron1c97/Mastermind_ruby
|
31
|
+
licenses:
|
32
|
+
- MIT
|
33
|
+
metadata: {}
|
34
|
+
post_install_message:
|
35
|
+
rdoc_options: []
|
36
|
+
require_paths:
|
37
|
+
- lib
|
38
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: '0'
|
43
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 2.4.5
|
51
|
+
signing_key:
|
52
|
+
specification_version: 4
|
53
|
+
summary: A mastermind library
|
54
|
+
test_files: []
|