mastermind-game 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b6d5bc9c19b85777bb6a3b1a77892337bfb0b75c
4
+ data.tar.gz: 8e6dede81fcfd1347048900504939e8116fd7ad9
5
+ SHA512:
6
+ metadata.gz: 3dbaf6735bc410f513e8fdf125ae5d84ddf171cb146c0e885d32778a238a2490f13b1212dcfa213184ecfe3413f67b9b52cb84364f9c6d1d3bc15f1f1d458133
7
+ data.tar.gz: c237db2c005d129d476a5a754ed67c8a7f5eef43a16aee3a154cd3ea99e5973c51b108446d8ee3b01009e75aba2894e8359d69ced94ade5b938a1f638328f827
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mastermind.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Andur Carr
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.
@@ -0,0 +1,79 @@
1
+ # Mastermind
2
+
3
+ [Mastermind](https://en.wikipedia.org/wiki/Mastermind_(board_game)) is a two-player board game created in 1970 by [Mordecai Meirowitz](https://en.wikipedia.org/wiki/Mordecai_Meirowitz). This gem provides an API for building this game, as well as a demonstration version that can be run in the console.
4
+
5
+ In the game, one player is assigned the role of "Code Maker" and the other "Code Breaker". The Code Maker creates a secret code sequence, which is represented by four pegs, each of one of six colors. The Code Breaker then has 12 attempts to determine what the secret code sequence is, with information on how many pegs were matched with the correct color in the correct position or a correct color in an incorrect position.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'mastermind-game'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install mastermind-game
22
+
23
+ ## Usage
24
+
25
+ If you are using bundler, a demonstration of this game can be run in the terminal once the gem is installed:
26
+
27
+ ```bash
28
+ $ mastermind
29
+ ```
30
+
31
+ ### Game
32
+
33
+ The `Mastermind::Game` object is the primary point of interaction. Instances of this object contain all the information for a complete game.
34
+
35
+ ```ruby
36
+ # Instantiate a game with a random secret
37
+ game = Mastermind::Game.new
38
+
39
+ # Prepare a guess
40
+ guess = [:red, :red, :red, :red]
41
+ game.guess(guess)
42
+
43
+ # Find how many turns there have been
44
+ game.attempts # => 1
45
+
46
+ # Check if the game is over
47
+ game.over? # => false
48
+
49
+ # Determine who has won (returns a Player instance)
50
+ game.winner # => nil
51
+ ```
52
+
53
+ ### Knuth Algorithm
54
+
55
+ In 1977, Donald Knuth developed an algorithm by which the correct code can be guessed in at most five turns. An implementation of this algorithm is included with this gem. To make use of it, create a new instance of the Knuth algorithm, supplying a game object:
56
+
57
+ ```ruby
58
+ game = Mastermind::Game.new
59
+ knuth = Mastermind::Knuth.new(game)
60
+ guess = knuth.prepare_guess
61
+ game.guess(guess)
62
+ ```
63
+
64
+ A first guess can be obtained almost instantly. However, due to this problem being NP-Complete, the second guess may take several seconds. Follow-on guesses will take less time due to fewer possibilities remaining.
65
+
66
+ ## Development
67
+
68
+ 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.
69
+
70
+ 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).
71
+
72
+ ## Contributing
73
+
74
+ Bug reports and pull requests are welcome on GitHub at https://github.com/lamarseillaise/mastermind.
75
+
76
+
77
+ ## License
78
+
79
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mastermind"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "mastermind"
5
+
6
+ Mastermind::Console.run
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,15 @@
1
+ require "mastermind/version"
2
+ require "mastermind/game"
3
+ require "mastermind/game/piece"
4
+ require "mastermind/game/code"
5
+ require "mastermind/game/turn"
6
+ require "mastermind/player"
7
+ require "mastermind/player/computer"
8
+ require "mastermind/player/human"
9
+ require "mastermind/console"
10
+ require "mastermind/console/view"
11
+ require "mastermind/console/controller"
12
+ require "mastermind/knuth"
13
+
14
+ module Mastermind
15
+ end
@@ -0,0 +1,9 @@
1
+ module Mastermind
2
+ module Console
3
+ def self.run
4
+ controller = Controller.new
5
+ controller.setup
6
+ loop { controller.start_game }
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,64 @@
1
+ module Mastermind
2
+ module Console
3
+ class Controller
4
+ def setup
5
+ puts View.introduction
6
+ print "How many players will there be? "
7
+ number_of_players = Player::Human.get_input.to_i
8
+
9
+ @player1 = get_player(1)
10
+ @player2 = get_player(2) if number_of_players > 1
11
+ @player2 ||= Player::Computer.new(name: "Computer")
12
+ end
13
+
14
+ def start_game
15
+ codebreaker = get_codebreaker
16
+ codemaker = (codebreaker == @player1) ? @player2 : @player1
17
+
18
+ play Game.new(
19
+ secret: get_secret_from(codemaker),
20
+ codemaker: codemaker,
21
+ codebreaker: codebreaker
22
+ )
23
+
24
+ puts "\n\n"
25
+ end
26
+
27
+ def play(game)
28
+ width = game.secret_length
29
+ puts "#{game.codebreaker.name} must guess the code."
30
+ puts View.grading_scheme
31
+ puts View.top_border(width: width)
32
+ make_guess(game) until game.over?
33
+ puts View.bottom_border(width: width)
34
+ puts "#{game.winner.name} wins! (#{game.attempts} guesses)"
35
+ end
36
+
37
+
38
+ private
39
+
40
+ def get_player(number)
41
+ print "What is Player #{number}'s name? "
42
+ Player::Human.new(name: Player::Human.get_input)
43
+ end
44
+
45
+ def get_codebreaker
46
+ puts "Who will be the code breaker?\n1. #{@player1.name}\n2. #{@player2.name}"
47
+ (selection = Player::Human.get_input.to_i) until (1..2) === selection
48
+ [@player1, @player2][selection - 1]
49
+ end
50
+
51
+ def get_secret_from(codemaker)
52
+ puts View.color_codes
53
+ puts "#{codemaker.name}: What will the secret code be?" if codemaker.is_a? Player::Human
54
+ codemaker.get_code(length: 4)
55
+ end
56
+
57
+ def make_guess(game)
58
+ guess = game.codebreaker.get_guess_for(game)
59
+ game.guess(guess)
60
+ puts "\r" + View.attempt_line(game.turns.last, width: game.secret_length)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,62 @@
1
+ require "colorize"
2
+
3
+ module Mastermind
4
+ module Console
5
+ class View
6
+ TL_CORNER = "\u250F"
7
+ TM_INTER = "\u2533"
8
+ TR_CORNER = "\u2513"
9
+ BL_CORNER = "\u2517"
10
+ BM_INTER = "\u253B"
11
+ BR_CORNER = "\u251B"
12
+ HORIZONTAL = "\u2501"
13
+ SIDE = "\u2503"
14
+ BLANK = " "
15
+ PIECE = "\u25CF"
16
+ EXACT = "\u25CF".red
17
+ PARTIAL = "\u25CF".white
18
+
19
+ def self.introduction
20
+ "MASTERMIND\n" +
21
+ "" +
22
+ "\n"
23
+ end
24
+
25
+ def self.grading_scheme
26
+ "#{EXACT}: Matched color and position #{PARTIAL}: Matched color"
27
+ end
28
+
29
+ def self.color_codes
30
+ Game::Piece::COLORS.map.with_index do |color, idx|
31
+ "#{idx + 1}: #{piece_icon(color)}"
32
+ end.join(" ") + " q: exit"
33
+ end
34
+
35
+ def self.top_border(width: 4)
36
+ " " + TL_CORNER + HORIZONTAL * width + TM_INTER + HORIZONTAL * width + TR_CORNER
37
+ end
38
+
39
+ def self.bottom_border(width: 4)
40
+ " " + BL_CORNER + HORIZONTAL * width + BM_INTER + HORIZONTAL * width + BR_CORNER
41
+ end
42
+
43
+ def self.attempt_line(turn, width: 4)
44
+ "#{turn.number}:".ljust(4) +
45
+ SIDE + guess_bar(turn.guess.sequence) + BLANK * (width - turn.guess.sequence.length) + SIDE +
46
+ feedback_line(exact: turn.exact, partial: turn.partial, width: width) + SIDE
47
+ end
48
+
49
+ def self.feedback_line(exact: 0, partial: 0, width: 4)
50
+ EXACT * exact + PARTIAL * partial + BLANK * (width - exact - partial)
51
+ end
52
+
53
+ def self.piece_icon(color)
54
+ PIECE.colorize(color)
55
+ end
56
+
57
+ def self.guess_bar(sequence)
58
+ sequence.map { |piece| piece_icon(piece.color) }.join("")
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,50 @@
1
+ module Mastermind
2
+ class Game
3
+ attr_reader :turns, :codemaker, :codebreaker, :max_attempts
4
+
5
+ def initialize(secret: nil, codemaker: nil, codebreaker: nil)
6
+ @secret = (secret && Code.from(secret)) || Code.random
7
+ @turns = []
8
+ @codemaker = codemaker || Player.new(name: "AbstractCodemaker")
9
+ @codebreaker = codebreaker || Player.new(name: "AbstractCodebreaker")
10
+ @max_attempts = 12
11
+ end
12
+
13
+ def attempts
14
+ turns.length
15
+ end
16
+
17
+ def secret_length
18
+ @secret.length
19
+ end
20
+
21
+ def guess(guess_sequence)
22
+ code = Code.from(guess_sequence)
23
+ @turns << Turn.new(
24
+ guess: code, number: attempts + 1,
25
+ exact: @secret.exact_matches_with(code),
26
+ partial: @secret.partial_matches_with(code)
27
+ )
28
+ end
29
+
30
+ def over?
31
+ max_attempts_reached? || code_guessed?
32
+ end
33
+
34
+ def winner
35
+ return codebreaker if code_guessed?
36
+ return codemaker if max_attempts_reached?
37
+ end
38
+
39
+
40
+ private
41
+
42
+ def max_attempts_reached?
43
+ attempts >= max_attempts
44
+ end
45
+
46
+ def code_guessed?
47
+ turns.first(max_attempts).any? { |turn| turn.guess == @secret }
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,62 @@
1
+ module Mastermind
2
+ class Game
3
+ class Code
4
+ attr_reader :sequence
5
+
6
+ def self.random(number_of_pieces = 4)
7
+ sequence = Array.new(number_of_pieces) { Piece.new }
8
+ new(sequence: sequence)
9
+ end
10
+
11
+ def self.from(colors)
12
+ new(sequence: colors.map { |color| Piece.new(color: color) })
13
+ end
14
+
15
+ def initialize(sequence:)
16
+ raise ArgumentError unless sequence.all? { |piece| piece.is_a? Piece }
17
+ @sequence = sequence
18
+ end
19
+
20
+ def length
21
+ @sequence.length
22
+ end
23
+
24
+ def color_counts
25
+ sequence.each_with_object({}) do |piece, counts|
26
+ counts[piece.color] ||= 0
27
+ counts[piece.color] += 1
28
+ end
29
+ end
30
+
31
+ def exact_matches_with(code)
32
+ raise ArgumentError unless code.is_a? Code
33
+ sum = 0
34
+ sequence.each_with_index do |piece, idx|
35
+ sum += 1 if piece == code.sequence[idx]
36
+ end
37
+ sum
38
+ end
39
+
40
+ def color_matches_with(code)
41
+ raise ArgumentError unless code.is_a? Code
42
+ other_colors = code.color_counts
43
+ sum = 0
44
+ color_counts.each do |color, quantity|
45
+ sum += [quantity, other_colors[color] || 0].min
46
+ end
47
+ sum
48
+ end
49
+
50
+ def partial_matches_with(code)
51
+ raise ArgumentError unless code.is_a? Code
52
+ color_matches_with(code) - exact_matches_with(code)
53
+ end
54
+
55
+ def ==(code)
56
+ code.is_a?(Code) &&
57
+ length == code.length &&
58
+ exact_matches_with(code) == length
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,18 @@
1
+ module Mastermind
2
+ class Game
3
+ class Piece
4
+ COLORS = [:red, :green, :blue, :yellow, :white, :black]
5
+
6
+ attr_reader :color
7
+
8
+ def initialize(color: COLORS.sample)
9
+ raise ArgumentError.new("Invalid color.") unless COLORS.include?(color)
10
+ @color = color
11
+ end
12
+
13
+ def ==(piece)
14
+ piece.is_a?(Piece) && color == piece.color
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ module Mastermind
2
+ class Game
3
+ class Turn
4
+ attr_reader :guess, :exact, :partial, :number
5
+
6
+ def initialize(guess:, number:, exact: 0, partial: 0)
7
+ @guess = guess
8
+ @exact = exact
9
+ @partial = partial
10
+ @number = number
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,81 @@
1
+ module Mastermind
2
+ class Knuth
3
+ attr_reader :game
4
+
5
+ def initialize(game)
6
+ @game = game
7
+ # 1. Create the set S of 1296 possible codes
8
+ @possible_guesses = Game::Piece::COLORS.repeated_permutation(game.secret_length).to_a
9
+ @set = Game::Piece::COLORS.repeated_permutation(game.secret_length).to_a
10
+ @game.turns.each { |turn| prune(turn) }
11
+ end
12
+
13
+ def prepare_guess
14
+ return first_guess if @game.attempts == 0
15
+ prune(@game.turns.last)
16
+ return @set.first if @set.length == 1
17
+ exploratory_guess
18
+ end
19
+
20
+ # 2. Make initial guess of 1122
21
+ def first_guess
22
+ first_color = Game::Piece::COLORS.sample
23
+ second_color = Game::Piece::COLORS.select { |color| color != first_color }.sample
24
+ Array.new(@game.secret_length) do |position|
25
+ position < @game.secret_length / 2 ? first_color : second_color
26
+ end
27
+ end
28
+
29
+ # 5. Choose from the set of guesses with the maximum score, preferring members of S
30
+ def exploratory_guess
31
+ max_scoring = maximum_scoring_guesses
32
+ (max_scoring & @set).sample || max_scoring.sample
33
+ end
34
+
35
+ private
36
+
37
+ # 3. Remove from S any code that would not give the same response if the guess were the code.
38
+ def prune(turn)
39
+ @set.select! do |combination|
40
+ code = Game::Code.from(combination)
41
+ !(turn.guess == code) &&
42
+ turn.exact == code.exact_matches_with(turn.guess) &&
43
+ turn.partial == code.partial_matches_with(turn.guess)
44
+ end
45
+
46
+ @possible_guesses.delete(turn.guess.sequence.map(&:color))
47
+ end
48
+
49
+ # 4. For each possible guess, find the minimum highest match count
50
+ def minimum_match_count
51
+ lowest = @set.length
52
+ @possible_guesses.each do |possible|
53
+ count = highest_match_count(Game::Code.from(possible))
54
+ lowest = count if count < lowest
55
+ end
56
+ lowest
57
+ end
58
+
59
+ def highest_match_count(guess)
60
+ highest = 0
61
+ # for a given number of matches
62
+ (0..@game.secret_length).each do |matches|
63
+ # count how many possibilities in S would be retained
64
+ count = @set.count do |combination|
65
+ Game::Code.from(combination).color_matches_with(guess) == matches
66
+ end
67
+ # track the highest of these
68
+ highest = count if count > highest
69
+ end
70
+ highest
71
+ end
72
+
73
+ # Find the possible guesses for which the highest match count is the minimum match count.
74
+ def maximum_scoring_guesses
75
+ min_matches = minimum_match_count
76
+ @possible_guesses.select do |possible|
77
+ highest_match_count(Game::Code.from(possible)) == min_matches
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,17 @@
1
+ module Mastermind
2
+ class Player
3
+ attr_reader :name
4
+
5
+ def initialize(name:)
6
+ @name = name
7
+ end
8
+
9
+ def get_code
10
+ raise NotImplementedError.new("Abstract player cannot make code.")
11
+ end
12
+
13
+ def get_guess_for(game)
14
+ raise NotImplementedError.new("Abstract player cannot guess code.")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,14 @@
1
+ module Mastermind
2
+ class Player
3
+ class Computer < Player
4
+ def get_guess_for(game)
5
+ @knuth = Knuth.new(game) unless @knuth && @knuth.game == game
6
+ @knuth.prepare_guess
7
+ end
8
+
9
+ def get_code(length:)
10
+ Array.new(length) { Game::Piece::COLORS.sample }
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ module Mastermind
2
+ class Player
3
+ class Human < Player
4
+ def get_code(length: 4, attempt: nil)
5
+ sequence = []
6
+
7
+ length.times do
8
+ turn = Game::Turn.new(guess: Game::Code.from(sequence), number: attempt)
9
+ print "\r" + Console::View.attempt_line(turn, width: length) if attempt
10
+ color = Game::Piece::COLORS[Human.get_choice(choices: ("1".."6")).to_i - 1]
11
+ sequence << color
12
+ end
13
+
14
+ sequence
15
+ end
16
+
17
+ def get_guess_for(game)
18
+ length = game.secret_length
19
+ get_code(length: length, attempt: game.attempts + 1)
20
+ end
21
+
22
+ def self.get_choice(choices:)
23
+ begin
24
+ choice = STDIN.getch
25
+ exit if choice.start_with?('q') && !puts
26
+ end until choices.include? choice
27
+
28
+ choice
29
+ end
30
+
31
+ def self.get_input
32
+ input = gets.chomp
33
+ exit if input.downcase.start_with?('q')
34
+ input
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,3 @@
1
+ module Mastermind
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mastermind/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "mastermind-game"
8
+ spec.version = Mastermind::VERSION
9
+ spec.authors = ["Andur Carr"]
10
+ spec.email = ["carr.andur@gmail.com"]
11
+
12
+ spec.summary = %q{An API for creating the game "Mastermind".}
13
+ spec.description = %q{An API for creating the game "Mastermind".}
14
+ spec.homepage = "https://github.com/lamarseillaise/mastermind"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.executables = ["mastermind"]
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.12"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec", "~> 3.0"
24
+ spec.add_runtime_dependency "colorize", "~> 0.8.1"
25
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mastermind-game
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Andur Carr
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: colorize
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.1
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.1
69
+ description: An API for creating the game "Mastermind".
70
+ email:
71
+ - carr.andur@gmail.com
72
+ executables:
73
+ - mastermind
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - ".gitignore"
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/console
83
+ - bin/mastermind
84
+ - bin/setup
85
+ - lib/mastermind.rb
86
+ - lib/mastermind/console.rb
87
+ - lib/mastermind/console/controller.rb
88
+ - lib/mastermind/console/view.rb
89
+ - lib/mastermind/game.rb
90
+ - lib/mastermind/game/code.rb
91
+ - lib/mastermind/game/piece.rb
92
+ - lib/mastermind/game/turn.rb
93
+ - lib/mastermind/knuth.rb
94
+ - lib/mastermind/player.rb
95
+ - lib/mastermind/player/computer.rb
96
+ - lib/mastermind/player/human.rb
97
+ - lib/mastermind/version.rb
98
+ - mastermind.gemspec
99
+ homepage: https://github.com/lamarseillaise/mastermind
100
+ licenses:
101
+ - MIT
102
+ metadata: {}
103
+ post_install_message:
104
+ rdoc_options: []
105
+ require_paths:
106
+ - lib
107
+ required_ruby_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ requirements: []
118
+ rubyforge_project:
119
+ rubygems_version: 2.5.1
120
+ signing_key:
121
+ specification_version: 4
122
+ summary: An API for creating the game "Mastermind".
123
+ test_files: []