games_bfox 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +6 -0
- data/exe/mastermind +8 -0
- data/exe/setup +8 -0
- data/exe/tictactoe +8 -0
- data/games.gemspec +36 -0
- data/lib/games/mastermind/board.rb +43 -0
- data/lib/games/mastermind/board_builder.rb +9 -0
- data/lib/games/mastermind/board_presenter_terminal.rb +69 -0
- data/lib/games/mastermind/colors.rb +14 -0
- data/lib/games/mastermind/game.rb +64 -0
- data/lib/games/mastermind/game_config.rb +48 -0
- data/lib/games/mastermind/game_resetter.rb +19 -0
- data/lib/games/mastermind/game_state_changer.rb +41 -0
- data/lib/games/mastermind/guess_evaluator.rb +85 -0
- data/lib/games/mastermind/input_helper.rb +54 -0
- data/lib/games/mastermind/move_generator.rb +46 -0
- data/lib/games/mastermind/peg.rb +15 -0
- data/lib/games/mastermind/pegs.rb +50 -0
- data/lib/games/mastermind/pegs_factory.rb +26 -0
- data/lib/games/mastermind/players_factory.rb +15 -0
- data/lib/games/mastermind.rb +13 -0
- data/lib/games/shared/array_iterator.rb +28 -0
- data/lib/games/shared/game.rb +155 -0
- data/lib/games/shared/input_helper.rb +74 -0
- data/lib/games/shared/io_terminal.rb +25 -0
- data/lib/games/shared/player.rb +15 -0
- data/lib/games/shared/version.rb +3 -0
- data/lib/games/tictactoe/board.rb +40 -0
- data/lib/games/tictactoe/board_builder.rb +10 -0
- data/lib/games/tictactoe/board_presenter_terminal.rb +28 -0
- data/lib/games/tictactoe/game.rb +60 -0
- data/lib/games/tictactoe/game_config.rb +73 -0
- data/lib/games/tictactoe/game_resetter.rb +16 -0
- data/lib/games/tictactoe/game_state_changer.rb +17 -0
- data/lib/games/tictactoe/input_helper.rb +80 -0
- data/lib/games/tictactoe/minimax.rb +81 -0
- data/lib/games/tictactoe/move_generator.rb +68 -0
- data/lib/games/tictactoe/player.rb +11 -0
- data/lib/games/tictactoe/players_factory.rb +11 -0
- data/lib/games/tictactoe/square.rb +30 -0
- data/lib/games/tictactoe/squares.rb +129 -0
- data/lib/games/tictactoe/squares_factory.rb +56 -0
- data/lib/games/tictactoe.rb +13 -0
- data/lib/games/version.rb +3 -0
- data/lib/games.rb +5 -0
- metadata +173 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
require_relative '../shared/input_helper'
|
2
|
+
|
3
|
+
module TTT
|
4
|
+
class InputHelper < Shared::InputHelper
|
5
|
+
def get_number_of_rows_cols_max_3
|
6
|
+
get_user_input("Please choose how many squares you would like in each row.", "Please choose number between 2 and 3.") do |input|
|
7
|
+
input.to_i >=2 && input.to_i <=3
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_number_of_rows_cols_max_9
|
12
|
+
get_user_input("Please choose how many squares you would like in each row.", "Please choose number between 2 and 3.") do |input|
|
13
|
+
input.to_i >=2 && input.to_i <=9
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def get_player_1_value(player_name = "Player 1")
|
18
|
+
user_choice = get_user_input("#{player_name}, please enter a value of either X or O", "Must be X or O. Please re-enter.") do |input|
|
19
|
+
input == 'x' || input == 'X' || input == 'o' || input == 'O'
|
20
|
+
end
|
21
|
+
user_choice.upcase
|
22
|
+
end
|
23
|
+
|
24
|
+
def get_player_2_name
|
25
|
+
user_choice = get_user_input("Player 2, please enter your name", "Please re-enter your name, using only letters") do |input|
|
26
|
+
input =~ /^[a-zA-Z]+$/
|
27
|
+
end
|
28
|
+
user_choice.capitalize
|
29
|
+
end
|
30
|
+
|
31
|
+
def get_player_2_type
|
32
|
+
user_choice = get_user_input("Please enter \"C\" if you would like to play the Computer. Enter \"H\" if you would like to play the human sitting next to you.", "Invalid character. Please enter either C(Computer) or H(Human).") do |input|
|
33
|
+
input == 'c' || input == 'C' || input == 'h' || input == 'H'
|
34
|
+
end
|
35
|
+
user_choice = user_choice.upcase
|
36
|
+
if user_choice == "C"
|
37
|
+
:computer
|
38
|
+
elsif user_choice == "H"
|
39
|
+
:human
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_computer_difficulty_level
|
44
|
+
user_choice = get_user_input("Please enter \"E\" if you would like to play an easy Computer. Enter \"D\" if you would like to play an extremely difficult computer.", "Invalid character. Please enter either E (Easy) or D (Difficult).") do |input|
|
45
|
+
input == 'd' || input == 'D' || input == 'e' || input == 'E'
|
46
|
+
end
|
47
|
+
user_choice = user_choice.upcase
|
48
|
+
if user_choice == "D"
|
49
|
+
:difficult
|
50
|
+
elsif user_choice == "E"
|
51
|
+
:easy
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def get_player_2_value(taken_value)
|
56
|
+
user_choice = get_user_input("Player 2, please enter your value", "Must not be #{taken_value}, please re-enter") do |input|
|
57
|
+
input.upcase != taken_value.upcase
|
58
|
+
end
|
59
|
+
user_choice.upcase
|
60
|
+
end
|
61
|
+
|
62
|
+
def get_player_choice(game)
|
63
|
+
get_user_input("#{game.current_player_name}, please enter the number of the square that you would like to change.", "Invalid entry. Please try again.") do |input|
|
64
|
+
game.available_choices.include?(input)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def draw_prompt
|
69
|
+
io.present_with_new_line("Draw! Please try again.")
|
70
|
+
end
|
71
|
+
|
72
|
+
def winning_prompt(current_player_name)
|
73
|
+
io.present_with_new_line("#{current_player_name} wins!")
|
74
|
+
end
|
75
|
+
|
76
|
+
def no_winner_prompt
|
77
|
+
io.present_with_new_line("Draw!")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'logging'
|
2
|
+
|
3
|
+
module TTT
|
4
|
+
class Minimax
|
5
|
+
attr_accessor :board, :number_of_turns_taken, :human_value, :computer_value, :choice
|
6
|
+
|
7
|
+
def initialize(board, number_of_turns_taken, human_value, computer_value)
|
8
|
+
@board = board
|
9
|
+
@number_of_turns_taken = number_of_turns_taken
|
10
|
+
@human_value = human_value
|
11
|
+
@computer_value = computer_value
|
12
|
+
end
|
13
|
+
|
14
|
+
def run_minimax
|
15
|
+
scores = []
|
16
|
+
choices = []
|
17
|
+
|
18
|
+
board_won = board.won?
|
19
|
+
board_full = board.full?
|
20
|
+
|
21
|
+
if board_won || board_full
|
22
|
+
#rewind one player to see which player took last turn and therefore won the game
|
23
|
+
self.number_of_turns_taken -= 1
|
24
|
+
return score(board_won)
|
25
|
+
end
|
26
|
+
|
27
|
+
# @logger.debug "avaliable choices collection: #{available_choices}"
|
28
|
+
|
29
|
+
available_choices.each do |available_choice|
|
30
|
+
board_copy = Marshal.load(Marshal.dump(board))
|
31
|
+
board_copy.change_square(available_choice, player_value)
|
32
|
+
choices.push(available_choice)
|
33
|
+
minimax = TTT::Minimax.new(board_copy, number_of_turns_taken + 1, human_value, computer_value)
|
34
|
+
scores.push minimax.run_minimax
|
35
|
+
end
|
36
|
+
|
37
|
+
if computer_current_player?
|
38
|
+
#https://stackoverflow.com/questions/2149802/in-ruby-what-is-the-cleanest-way-of-obtaining-the-index-of-the-largest-value-in
|
39
|
+
max_score_index = scores.each_with_index.max[1]
|
40
|
+
self.choice = choices[max_score_index]
|
41
|
+
return scores[max_score_index]
|
42
|
+
else
|
43
|
+
# This is the min calculation
|
44
|
+
min_score_index = scores.each_with_index.min[1]
|
45
|
+
self.choice = choices[min_score_index]
|
46
|
+
return scores[min_score_index]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
private
|
52
|
+
def available_choices
|
53
|
+
board.available_choices
|
54
|
+
end
|
55
|
+
|
56
|
+
def player_value
|
57
|
+
if computer_current_player?
|
58
|
+
computer_value
|
59
|
+
else
|
60
|
+
human_value
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def computer_current_player?
|
65
|
+
#computer goes second, when number of turns taken is always odd
|
66
|
+
number_of_turns_taken.odd?
|
67
|
+
end
|
68
|
+
|
69
|
+
def score(board_won)
|
70
|
+
if board_won && computer_current_player?
|
71
|
+
return +1
|
72
|
+
elsif board_won && !computer_current_player?
|
73
|
+
return -1
|
74
|
+
else
|
75
|
+
return 0
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require_relative 'minimax'
|
2
|
+
|
3
|
+
module TTT
|
4
|
+
class MoveGenerator
|
5
|
+
|
6
|
+
attr_accessor :game
|
7
|
+
|
8
|
+
def get_player_choice(game)
|
9
|
+
@game = game
|
10
|
+
get_move
|
11
|
+
end
|
12
|
+
|
13
|
+
def get_move
|
14
|
+
if human?
|
15
|
+
input_helper.get_player_choice(game)
|
16
|
+
elsif computer?
|
17
|
+
input_helper.computer_choosing_graphic
|
18
|
+
if difficult?
|
19
|
+
perfect_move
|
20
|
+
elsif easy?
|
21
|
+
random_move
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def perfect_move
|
27
|
+
minimax = game_module::Minimax.new(game.board, game.number_of_turns_taken, game.player_1_value, game.player_2_value)
|
28
|
+
minimax.run_minimax
|
29
|
+
minimax.choice
|
30
|
+
end
|
31
|
+
|
32
|
+
def random_move
|
33
|
+
available_choices.sample
|
34
|
+
end
|
35
|
+
|
36
|
+
def available_choices
|
37
|
+
game.available_choices
|
38
|
+
end
|
39
|
+
|
40
|
+
def game_module
|
41
|
+
game.game_module
|
42
|
+
end
|
43
|
+
|
44
|
+
def current_player
|
45
|
+
game.current_player
|
46
|
+
end
|
47
|
+
|
48
|
+
def input_helper
|
49
|
+
game.input_helper
|
50
|
+
end
|
51
|
+
|
52
|
+
def human?
|
53
|
+
game.current_player_human?
|
54
|
+
end
|
55
|
+
|
56
|
+
def computer?
|
57
|
+
game.current_player_computer?
|
58
|
+
end
|
59
|
+
|
60
|
+
def difficult?
|
61
|
+
game.current_player_difficult_computer?
|
62
|
+
end
|
63
|
+
|
64
|
+
def easy?
|
65
|
+
game.current_player_easy_computer?
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require_relative 'player'
|
2
|
+
|
3
|
+
module TTT
|
4
|
+
class PlayersFactory
|
5
|
+
def generate_players(config)
|
6
|
+
player_1 = TTT::Player.new(value: config.player_1_value, name: config.player_1_name, type: :human)
|
7
|
+
player_2 = TTT::Player.new(value: config.player_2_value, name: config.player_2_name, type: config.player_2_type, difficulty_level: config.computer_difficulty_level)
|
8
|
+
[player_1, player_2]
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module TTT
|
2
|
+
class Square
|
3
|
+
attr_accessor :value, :display_value
|
4
|
+
attr_reader :row, :col
|
5
|
+
|
6
|
+
def initialize(args)
|
7
|
+
@value = args[:value]
|
8
|
+
@display_value = args[:display_value]
|
9
|
+
@row = args[:row]
|
10
|
+
@col = args[:col]
|
11
|
+
end
|
12
|
+
|
13
|
+
def change_value(new_value)
|
14
|
+
self.value = new_value
|
15
|
+
self.display_value = new_value
|
16
|
+
end
|
17
|
+
|
18
|
+
def empty?
|
19
|
+
return true unless full?
|
20
|
+
end
|
21
|
+
|
22
|
+
def full?
|
23
|
+
if value != nil
|
24
|
+
return true
|
25
|
+
else
|
26
|
+
return false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,129 @@
|
|
1
|
+
module TTT
|
2
|
+
class Squares
|
3
|
+
attr_reader :collection_of_squares
|
4
|
+
|
5
|
+
#collection_of_squares is a multi-dimensional array
|
6
|
+
|
7
|
+
def initialize(args)
|
8
|
+
@collection_of_squares = args[:collection_of_squares]
|
9
|
+
end
|
10
|
+
|
11
|
+
def retrieve_square(display_value)
|
12
|
+
row = (display_value - 1) / number_of_rows_cols
|
13
|
+
col = (display_value - 1) % number_of_rows_cols
|
14
|
+
if row >= number_of_rows_cols || col >= number_of_rows_cols
|
15
|
+
return nil
|
16
|
+
else
|
17
|
+
return collection_of_squares[row][col]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def display_values
|
22
|
+
collection_of_squares.map do |row|
|
23
|
+
row.map do |square|
|
24
|
+
square.display_value
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def available_choices
|
30
|
+
available_choices = Array.new
|
31
|
+
collection_of_squares.each do |row|
|
32
|
+
row.each do |square|
|
33
|
+
if square.empty?
|
34
|
+
available_choices.push(square.display_value)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
available_choices
|
39
|
+
end
|
40
|
+
|
41
|
+
def full?
|
42
|
+
collection_of_squares.each do |row|
|
43
|
+
return false if row.all? { |square| square.full? } == false
|
44
|
+
end
|
45
|
+
return true
|
46
|
+
end
|
47
|
+
|
48
|
+
def any_combination_won?
|
49
|
+
possible_winning_combinations.any? do |possible_winning_combination|
|
50
|
+
won?(possible_winning_combination)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def won?(array)
|
55
|
+
#https://stackoverflow.com/questions/3233278/how-do-i-test-if-all-items-in-an-array-are-identical
|
56
|
+
return false if array[0].value == nil
|
57
|
+
array.all? {|square| square.value == array[0].value}
|
58
|
+
end
|
59
|
+
|
60
|
+
def number_of_rows_cols
|
61
|
+
collection_of_squares.length
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def cols
|
66
|
+
number_of_rows_cols = collection_of_squares.size
|
67
|
+
cols = Array.new
|
68
|
+
col = 0
|
69
|
+
while col < number_of_rows_cols
|
70
|
+
cols.push (
|
71
|
+
collection_of_squares.map do |row|
|
72
|
+
row[col]
|
73
|
+
end
|
74
|
+
)
|
75
|
+
col += 1
|
76
|
+
end
|
77
|
+
cols
|
78
|
+
end
|
79
|
+
|
80
|
+
#return collection_of_squares because set up as multidimensional array consisting of rows
|
81
|
+
def rows
|
82
|
+
collection_of_squares
|
83
|
+
end
|
84
|
+
|
85
|
+
def l_to_r_diag
|
86
|
+
number_of_rows_cols = collection_of_squares.size
|
87
|
+
diag = Array.new
|
88
|
+
row = 0
|
89
|
+
col = 0
|
90
|
+
while row < number_of_rows_cols
|
91
|
+
diag.push (
|
92
|
+
collection_of_squares[row][col]
|
93
|
+
)
|
94
|
+
row += 1
|
95
|
+
col += 1
|
96
|
+
end
|
97
|
+
diag
|
98
|
+
end
|
99
|
+
|
100
|
+
def r_to_l_diag
|
101
|
+
number_of_rows_cols = collection_of_squares.size
|
102
|
+
diag = Array.new
|
103
|
+
row = 0
|
104
|
+
col = number_of_rows_cols - 1
|
105
|
+
while row < number_of_rows_cols
|
106
|
+
diag.push (
|
107
|
+
collection_of_squares[row][col]
|
108
|
+
)
|
109
|
+
row += 1
|
110
|
+
col -= 1
|
111
|
+
end
|
112
|
+
diag
|
113
|
+
end
|
114
|
+
|
115
|
+
def possible_winning_combinations
|
116
|
+
winning_combinations = Array.new
|
117
|
+
winning_combinations.push(l_to_r_diag, r_to_l_diag)
|
118
|
+
|
119
|
+
rows.each do |row|
|
120
|
+
winning_combinations.push(row)
|
121
|
+
end
|
122
|
+
|
123
|
+
cols.each do |col|
|
124
|
+
winning_combinations.push(col)
|
125
|
+
end
|
126
|
+
winning_combinations
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require_relative 'squares'
|
2
|
+
require_relative 'square'
|
3
|
+
|
4
|
+
module TTT
|
5
|
+
module SquaresFactory
|
6
|
+
def self.build_custom_squares(config, squares_class = Squares)
|
7
|
+
|
8
|
+
rows_and_cols = config.length
|
9
|
+
|
10
|
+
#create multi-dimensional array
|
11
|
+
squares = Array.new(rows_and_cols) do
|
12
|
+
Array.new(rows_and_cols)
|
13
|
+
end
|
14
|
+
|
15
|
+
squares.each_with_index do |element, row|
|
16
|
+
element.each_index do |col|
|
17
|
+
squares[row][col] = create_custom_square(config[row][col][0],config[row][col][1], row, col)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
squares_class.new(collection_of_squares: squares)
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
def self.create_custom_square(display_value, value, row, col, square_class = Square)
|
27
|
+
square_class.new(display_value: display_value,
|
28
|
+
value: value,
|
29
|
+
row: row,
|
30
|
+
col: col )
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.build_empty_squares(rows_and_cols, squares_class = Squares)
|
34
|
+
squares = Array.new(rows_and_cols) do
|
35
|
+
Array.new(rows_and_cols)
|
36
|
+
end
|
37
|
+
|
38
|
+
i = 1
|
39
|
+
squares.each_with_index do |element, row|
|
40
|
+
element.each_index do |col|
|
41
|
+
squares[row][col] = create_empty_square(i, row, col)
|
42
|
+
i += 1
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
squares_class.new(collection_of_squares: squares)
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.create_empty_square(display_value, row, col, square_class = Square)
|
50
|
+
square_class.new(display_value: display_value,
|
51
|
+
value: nil,
|
52
|
+
row: row,
|
53
|
+
col: col )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Dir[File.join(File.expand_path(File.dirname(__FILE__)), 'shared', '*.rb')].each {|file| require file }
|
2
|
+
Dir[File.join(File.expand_path(File.dirname(__FILE__)), 'tictactoe', '*.rb')].each {|file| require file }
|
3
|
+
|
4
|
+
class TicTacToe
|
5
|
+
def self.run
|
6
|
+
io = Shared::IOTerminal.new
|
7
|
+
board_presenter = TTT::BoardPresenterTerminal.new
|
8
|
+
|
9
|
+
game = TTT::Game.new(game_module: TTT, io: io, board_presenter: board_presenter)
|
10
|
+
# game.setup
|
11
|
+
game.play
|
12
|
+
end
|
13
|
+
end
|
data/lib/games.rb
ADDED
metadata
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: games_bfox
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Brett Fox
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-16 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.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
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.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.10.4
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 0.10.4
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: logging
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.2'
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 2.2.2
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '2.2'
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 2.2.2
|
89
|
+
description: In order to play, download the gem, and type \"tictactoe\" or \"mastermind\"
|
90
|
+
at your terminal.
|
91
|
+
email:
|
92
|
+
- brettfox11@gmail.com
|
93
|
+
executables:
|
94
|
+
- mastermind
|
95
|
+
- setup
|
96
|
+
- tictactoe
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files: []
|
99
|
+
files:
|
100
|
+
- ".gitignore"
|
101
|
+
- ".rspec"
|
102
|
+
- ".travis.yml"
|
103
|
+
- Gemfile
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- exe/mastermind
|
107
|
+
- exe/setup
|
108
|
+
- exe/tictactoe
|
109
|
+
- games.gemspec
|
110
|
+
- lib/games.rb
|
111
|
+
- lib/games/mastermind.rb
|
112
|
+
- lib/games/mastermind/board.rb
|
113
|
+
- lib/games/mastermind/board_builder.rb
|
114
|
+
- lib/games/mastermind/board_presenter_terminal.rb
|
115
|
+
- lib/games/mastermind/colors.rb
|
116
|
+
- lib/games/mastermind/game.rb
|
117
|
+
- lib/games/mastermind/game_config.rb
|
118
|
+
- lib/games/mastermind/game_resetter.rb
|
119
|
+
- lib/games/mastermind/game_state_changer.rb
|
120
|
+
- lib/games/mastermind/guess_evaluator.rb
|
121
|
+
- lib/games/mastermind/input_helper.rb
|
122
|
+
- lib/games/mastermind/move_generator.rb
|
123
|
+
- lib/games/mastermind/peg.rb
|
124
|
+
- lib/games/mastermind/pegs.rb
|
125
|
+
- lib/games/mastermind/pegs_factory.rb
|
126
|
+
- lib/games/mastermind/players_factory.rb
|
127
|
+
- lib/games/shared/array_iterator.rb
|
128
|
+
- lib/games/shared/game.rb
|
129
|
+
- lib/games/shared/input_helper.rb
|
130
|
+
- lib/games/shared/io_terminal.rb
|
131
|
+
- lib/games/shared/player.rb
|
132
|
+
- lib/games/shared/version.rb
|
133
|
+
- lib/games/tictactoe.rb
|
134
|
+
- lib/games/tictactoe/board.rb
|
135
|
+
- lib/games/tictactoe/board_builder.rb
|
136
|
+
- lib/games/tictactoe/board_presenter_terminal.rb
|
137
|
+
- lib/games/tictactoe/game.rb
|
138
|
+
- lib/games/tictactoe/game_config.rb
|
139
|
+
- lib/games/tictactoe/game_resetter.rb
|
140
|
+
- lib/games/tictactoe/game_state_changer.rb
|
141
|
+
- lib/games/tictactoe/input_helper.rb
|
142
|
+
- lib/games/tictactoe/minimax.rb
|
143
|
+
- lib/games/tictactoe/move_generator.rb
|
144
|
+
- lib/games/tictactoe/player.rb
|
145
|
+
- lib/games/tictactoe/players_factory.rb
|
146
|
+
- lib/games/tictactoe/square.rb
|
147
|
+
- lib/games/tictactoe/squares.rb
|
148
|
+
- lib/games/tictactoe/squares_factory.rb
|
149
|
+
- lib/games/version.rb
|
150
|
+
homepage: https://github.com/brett11/games
|
151
|
+
licenses: []
|
152
|
+
metadata: {}
|
153
|
+
post_install_message:
|
154
|
+
rdoc_options: []
|
155
|
+
require_paths:
|
156
|
+
- lib
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
158
|
+
requirements:
|
159
|
+
- - ">="
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
requirements: []
|
168
|
+
rubyforge_project:
|
169
|
+
rubygems_version: 2.6.10
|
170
|
+
signing_key:
|
171
|
+
specification_version: 4
|
172
|
+
summary: Play tic tac toe and mastermind on the command line
|
173
|
+
test_files: []
|