ttt 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +6 -0
- data/Gemfile.lock +51 -0
- data/MIT-License.md +8 -0
- data/Rakefile +324 -0
- data/Readme.md +35 -0
- data/bin/ttt +6 -0
- data/features/binary.feature +39 -0
- data/features/computer_player.feature +62 -0
- data/features/create_game.feature +63 -0
- data/features/finish_game.feature +53 -0
- data/features/finished_states.feature +56 -0
- data/features/mark_board.feature +24 -0
- data/features/step_definitions/binary_steps.rb +42 -0
- data/features/step_definitions/ttt_steps.rb +82 -0
- data/features/support/env.rb +8 -0
- data/features/view_board_as_developer.feature +13 -0
- data/features/view_board_as_tester.feature +9 -0
- data/lib/ttt.rb +1 -0
- data/lib/ttt/binary.rb +96 -0
- data/lib/ttt/computer_player.rb +74 -0
- data/lib/ttt/game.rb +129 -0
- data/lib/ttt/interface.rb +22 -0
- data/lib/ttt/interface/cli.rb +95 -0
- data/lib/ttt/interface/cli/players.rb +56 -0
- data/lib/ttt/interface/cli/views.rb +124 -0
- data/lib/ttt/interface/limelight.rb +18 -0
- data/lib/ttt/interface/limelight/players/restart_as_first.rb +5 -0
- data/lib/ttt/interface/limelight/players/restart_as_second.rb +6 -0
- data/lib/ttt/interface/limelight/players/square.rb +105 -0
- data/lib/ttt/interface/limelight/props.rb +10 -0
- data/lib/ttt/interface/limelight/styles.rb +101 -0
- data/lib/ttt/ratings.rb +849 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/ttt/computer_player_spec.rb +86 -0
- data/spec/ttt/game_spec.rb +294 -0
- data/spec/ttt/rating_spec.rb +75 -0
- metadata +139 -0
@@ -0,0 +1,62 @@
|
|
1
|
+
Feature: Computer player
|
2
|
+
|
3
|
+
In order to hone my tic-tac-toe skills
|
4
|
+
As a player
|
5
|
+
I want an unbeatable computer opponent
|
6
|
+
|
7
|
+
The following scenarios should cover a sampling of possible boards. As there are
|
8
|
+
765 possible game possible congruence classes of boards, I won't attempt to cover
|
9
|
+
them all, but will verify that the computer plays optimally in a number of common
|
10
|
+
situations (two game boards are in a congruence class, such as the two below,
|
11
|
+
if one can be turned into the other by rotating or mirroring).
|
12
|
+
|
13
|
+
For a list of all congruent states, there are some rake tasks which compute them
|
14
|
+
and explore some of their properties.
|
15
|
+
|
16
|
+
Example of congruent boards (rotate the left board 90 degrees to get the right board):
|
17
|
+
|
18
|
+
1 | | | | 1
|
19
|
+
---|---|--- ---|---|---
|
20
|
+
| | | |
|
21
|
+
---|---|--- ---|---|---
|
22
|
+
| | | |
|
23
|
+
|
24
|
+
|
25
|
+
Scenario Outline: Computer's moves
|
26
|
+
When I create a game with "<configuration>"
|
27
|
+
And a computer player as player <player>
|
28
|
+
Then it is player<player>s turn
|
29
|
+
And the computer moves to one of the following: <possible boards>
|
30
|
+
|
31
|
+
Scenarios: Computer always takes a win when it is available
|
32
|
+
| configuration | player | possible boards | description |
|
33
|
+
| 110200200 | 1 | 111200200 | can win across top |
|
34
|
+
| 220000110 | 1 | 220000111 | can win across bottom and opponent can win across top |
|
35
|
+
| 201201000 | 1 | 201201001 | can win vertically on RHS opponent can win too |
|
36
|
+
| 120120000 | 1 | 120120100 | can win vertically on RHS opponent can win too |
|
37
|
+
| 102210000 | 1 | 102210001 | can win diagonally |
|
38
|
+
| 120112020 | 1 | 120112120 120112021 | can win in two positions |
|
39
|
+
| 120021001 | 2 | 120021021 | takes win when 2nd player and 1st can also win |
|
40
|
+
|
41
|
+
Scenarios: Computer blocks opponent's win
|
42
|
+
| configuration | player | possible boards | description |
|
43
|
+
| 120100000 | 2 | 120100200 | blocks lhs |
|
44
|
+
| 122110000 | 2 | 122110200 122110002 | blocks either of opponent's possible wins |
|
45
|
+
| 211200000 | 1 | 211200100 | blocks when first player |
|
46
|
+
|
47
|
+
Scenarios: Finds best moves for likely game states
|
48
|
+
| configuration | player | possible boards | description |
|
49
|
+
| 000000000 | 1 | 100000000 001000000 000000100 000000001 | makes best 1st move |
|
50
|
+
| 120000000 | 1 | 120000100 120010000 120100000 | makes move that will guarantee win in future |
|
51
|
+
| 100000002 | 1 | 101000002 100000102 | makes move that will guarantee win in future |
|
52
|
+
| 100000020 | 1 | 100000120 101000020 100010020 | makes move that will guarantee win in future |
|
53
|
+
| 102000000 | 1 | 102100000 102000100 102000001 | makes move that will guarantee win in future |
|
54
|
+
| 102100200 | 1 | 102110200 | makes move that will guarantee win next turn |
|
55
|
+
| 100020000 | 1 | 110020000 100120000 | makes move with highest probability of win in future |
|
56
|
+
| 100000000 | 2 | 100020000 | makes move with lowest probability of losing in future |
|
57
|
+
|
58
|
+
Scenario: Plays correctly for current player
|
59
|
+
Given I create a game with "000000000"
|
60
|
+
And I have a computer player
|
61
|
+
Then the computer will play for 1
|
62
|
+
Then the computer will play for 2
|
@@ -0,0 +1,63 @@
|
|
1
|
+
Feature: Create game
|
2
|
+
|
3
|
+
TTT is the core lib that underlies an interface, where the interface allows users to play the game.
|
4
|
+
|
5
|
+
In order to allow users to play the game
|
6
|
+
An interface must be able to create a game in various states.
|
7
|
+
|
8
|
+
A board can be represented as a string of 9 digits, where a 0 indicates that neither player has moved
|
9
|
+
into that position, a 1 indicates that player1 has moved there, and a 2 indicates that player2 has moved there.
|
10
|
+
The digits correspond to the board in the following manner:
|
11
|
+
|
12
|
+
abcdefghi
|
13
|
+
|
14
|
+
a | b | c
|
15
|
+
---|---|---
|
16
|
+
d | e | f
|
17
|
+
---|---|---
|
18
|
+
g | h | i
|
19
|
+
|
20
|
+
So the game board "001002100" would look like this (let "x" represent player 1 and "o" represent player2):
|
21
|
+
|
22
|
+
| | x
|
23
|
+
---|---|---
|
24
|
+
| | o
|
25
|
+
---|---|---
|
26
|
+
x | |
|
27
|
+
|
28
|
+
|
29
|
+
Scenario: Create a new game
|
30
|
+
When I create a new game
|
31
|
+
Then the game board is "000000000"
|
32
|
+
And it is player1s turn
|
33
|
+
|
34
|
+
Scenario Outline: Create an existing game
|
35
|
+
When I create a game with "<configuration>"
|
36
|
+
Then the game board is "<configuration>"
|
37
|
+
And it is player<player>s turn
|
38
|
+
|
39
|
+
Scenarios: Player1s turn
|
40
|
+
| configuration | player |
|
41
|
+
| 000000000 | 1 |
|
42
|
+
| 120000000 | 1 |
|
43
|
+
| 120120000 | 1 |
|
44
|
+
| 120120210 | 1 |
|
45
|
+
| 000010002 | 1 |
|
46
|
+
| 120221112 | 1 |
|
47
|
+
|
48
|
+
Scenarios: Player2s turn
|
49
|
+
| configuration | player |
|
50
|
+
| 100000000 | 2 |
|
51
|
+
| 012100000 | 2 |
|
52
|
+
| 001112200 | 2 |
|
53
|
+
| 100200100 | 2 |
|
54
|
+
| 120221110 | 2 |
|
55
|
+
|
56
|
+
Scenario: Know who is where
|
57
|
+
Given I create a game with "000120000"
|
58
|
+
When I ask who is at position 4, it returns 1
|
59
|
+
When I ask who is at position 5, it returns 2
|
60
|
+
When I ask who is at position 6, it returns nil
|
61
|
+
|
62
|
+
|
63
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
Feature: Finish game
|
2
|
+
|
3
|
+
In order to allow for actual gameplay
|
4
|
+
As a player
|
5
|
+
I can win, lose, and tie
|
6
|
+
|
7
|
+
Scenario: Player1 wins
|
8
|
+
Given I create a game with "120120000"
|
9
|
+
Then the game is not over
|
10
|
+
When I mark position 7
|
11
|
+
Then the game board is "120120100"
|
12
|
+
And the game is over
|
13
|
+
And player1 wins
|
14
|
+
And player2 loses
|
15
|
+
And it is no one's turn
|
16
|
+
|
17
|
+
Scenario: Player2 wins
|
18
|
+
Given I create a game with "121120000"
|
19
|
+
Then the game is not over
|
20
|
+
When I mark position 8
|
21
|
+
Then the game board is "121120020"
|
22
|
+
And the game is over
|
23
|
+
And player2 wins
|
24
|
+
And player1 loses
|
25
|
+
And it is no one's turn
|
26
|
+
|
27
|
+
Scenario: The players tie
|
28
|
+
Given I create a game with "121221012"
|
29
|
+
Then the game is not over
|
30
|
+
When I mark position 7
|
31
|
+
Then the game board is "121221112"
|
32
|
+
And the game is over
|
33
|
+
And player1 ties
|
34
|
+
And player2 ties
|
35
|
+
And it is no one's turn
|
36
|
+
|
37
|
+
Scenario Outline: I can ask which positions won
|
38
|
+
Given I create a game with "<configuration>"
|
39
|
+
When I ask what positions won
|
40
|
+
Then it tells me [<p1>, <p2>, <p3>]
|
41
|
+
|
42
|
+
Scenarios:
|
43
|
+
| configuration | p1 | p2 | p3 |
|
44
|
+
| 111220000 | 1 | 2 | 3 |
|
45
|
+
| 220111000 | 4 | 5 | 6 |
|
46
|
+
| 220000111 | 7 | 8 | 9 |
|
47
|
+
| 120120100 | 1 | 4 | 7 |
|
48
|
+
| 210210010 | 2 | 5 | 8 |
|
49
|
+
| 201201001 | 3 | 6 | 9 |
|
50
|
+
| 120210001 | 1 | 5 | 9 |
|
51
|
+
| 021210100 | 3 | 5 | 7 |
|
52
|
+
| 021210100 | 3 | 5 | 7 |
|
53
|
+
| 211210200 | 1 | 4 | 7 |
|
@@ -0,0 +1,56 @@
|
|
1
|
+
Feature: Finished states
|
2
|
+
|
3
|
+
In order to finish the game, the library must know what a finished state is.
|
4
|
+
A finished state is a state that either has no available moves left, or where
|
5
|
+
a player has won the game. A player has won the game if they have marked
|
6
|
+
three consecutive spaces in a horizontal, vertical, or diagonal direction.
|
7
|
+
|
8
|
+
Scenario: No winner, no available moves left
|
9
|
+
Given a tie game
|
10
|
+
Then the game is over
|
11
|
+
|
12
|
+
Scenario Outline: Three marks in a row
|
13
|
+
When I create a game with "<configuration>"
|
14
|
+
Then the game is over
|
15
|
+
And player<winner> wins
|
16
|
+
|
17
|
+
Scenarios: Horizontal win
|
18
|
+
| configuration | winner |
|
19
|
+
| 111000000 | 1 |
|
20
|
+
| 000111000 | 1 |
|
21
|
+
| 000000111 | 1 |
|
22
|
+
| 222000000 | 2 |
|
23
|
+
| 000222000 | 2 |
|
24
|
+
| 000000222 | 2 |
|
25
|
+
|
26
|
+
Scenarios: Vertical win
|
27
|
+
| configuration | winner |
|
28
|
+
| 100100100 | 1 |
|
29
|
+
| 010010010 | 1 |
|
30
|
+
| 001001001 | 1 |
|
31
|
+
| 200200200 | 2 |
|
32
|
+
| 020020020 | 2 |
|
33
|
+
| 002002002 | 2 |
|
34
|
+
|
35
|
+
Scenarios: Diagonal win
|
36
|
+
| configuration | winner |
|
37
|
+
| 100010001 | 1 |
|
38
|
+
| 001010100 | 1 |
|
39
|
+
| 200020002 | 2 |
|
40
|
+
| 002020200 | 2 |
|
41
|
+
|
42
|
+
Scenario Outline: Unfinished states
|
43
|
+
When I create a game with "<configuration>"
|
44
|
+
Then the game is not over
|
45
|
+
|
46
|
+
Scenarios: Playing to a tie game
|
47
|
+
| configuration |
|
48
|
+
| 000000000 |
|
49
|
+
| 100000000 |
|
50
|
+
| 100020000 |
|
51
|
+
| 101020000 |
|
52
|
+
| 121020000 |
|
53
|
+
| 121020010 |
|
54
|
+
| 121220010 |
|
55
|
+
| 121221010 |
|
56
|
+
| 121221012 |
|
@@ -0,0 +1,24 @@
|
|
1
|
+
Feature: Mark board
|
2
|
+
|
3
|
+
In order to play the game
|
4
|
+
As a player (or, more probably, an interface translating a player's desire)
|
5
|
+
I want to mark the board
|
6
|
+
|
7
|
+
Scenario: Marking an empty board
|
8
|
+
Given I create a new game
|
9
|
+
When I mark position 1
|
10
|
+
Then the game board is "100000000"
|
11
|
+
|
12
|
+
Scenario: Marking a board when it is player1s turn
|
13
|
+
Given I create a game with "120000000"
|
14
|
+
Then it is player1s turn
|
15
|
+
When I mark position 4
|
16
|
+
Then the game board is "120100000"
|
17
|
+
And it is player2s turn
|
18
|
+
|
19
|
+
Scenario: Marking a board when it is player2s turn
|
20
|
+
Given I create a game with "120100000"
|
21
|
+
Then it is player2s turn
|
22
|
+
When I mark position 7
|
23
|
+
Then the game board is "120100200"
|
24
|
+
And it is player1s turn
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Given /^I look at (.*)$/ do |location|
|
2
|
+
@location = location
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I see it is executable$/ do
|
6
|
+
File.executable?(@location).should be
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^I pass the it "([^"]*)" on the command line$/ do |args|
|
10
|
+
pending "Yet again don't know how to test, it hangs b/c it expects input."\
|
11
|
+
"I can put it in a thread and kill it later, but inconsistent results."
|
12
|
+
require 'open3' # from stdlib
|
13
|
+
binary = Class.new Struct.new(:exitstatus, :stdout, :stderr) do
|
14
|
+
def initialize(args)
|
15
|
+
Open3.popen3 "bin/ttt #{args}" do |stdin, stdout, stderr, wait_thr|
|
16
|
+
super(wait_thr.value.exitstatus, stdout.read.strip, stderr.read.strip)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
@binary = binary.new args
|
21
|
+
end
|
22
|
+
|
23
|
+
Then %r{^it should display /([^/]*)/$} do |message|
|
24
|
+
Then "it should print /#{message}/ to stdout"
|
25
|
+
end
|
26
|
+
|
27
|
+
Then %r{^it should print /([^/]*)/ to (\w+)$} do |message, output_name|
|
28
|
+
output = @binary.send output_name
|
29
|
+
output.should match Regexp.new(message)
|
30
|
+
end
|
31
|
+
|
32
|
+
Then /^it should exit with code of (\d+)$/ do |code|
|
33
|
+
@binary.exitstatus.should be code.to_i
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
# a simple greeting we'll have the CLI write
|
38
|
+
# just to make sure everything is hooked up correctly
|
39
|
+
Then /^it should welcome me to Tic Tac Toe$/ do
|
40
|
+
Then "it should display /Welcome to Tic Tac Toe/"
|
41
|
+
end
|
42
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
When /^I create a new game$/ do
|
2
|
+
@game = TTT::Game.new
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^the game board is "([^"]*)"$/ do |board|
|
6
|
+
@game.board.should == board
|
7
|
+
end
|
8
|
+
|
9
|
+
Then /^it is (player(\d+)s|no one's) turn$/ do |turn, player_number|
|
10
|
+
if player_number
|
11
|
+
@game.turn.should == player_number.to_i
|
12
|
+
else
|
13
|
+
@game.turn.should be_nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^I ask what positions won$/ do
|
18
|
+
@winning_positions = @game.winning_positions
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^it tells me \[(\d+), (\d+), (\d+)\]$/ do |p1, p2, p3|
|
22
|
+
@winning_positions.sort.should == [p1, p2, p3].map(&:to_i).sort
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
When /^I create a game with "([^"]*)"$/ do |configuration|
|
27
|
+
@game = TTT::Game.new configuration
|
28
|
+
end
|
29
|
+
|
30
|
+
When /^I mark position (\d+)$/ do |position|
|
31
|
+
@game.mark position.to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
Then /^board\(:ttt\) will be "([^"]*)"$/ do |board|
|
35
|
+
@game.board(:ttt).should == board.gsub('\\n', "\n")
|
36
|
+
end
|
37
|
+
|
38
|
+
Then /^the game is (not )?over$/ do |not_over|
|
39
|
+
if not_over
|
40
|
+
@game.should_not be_over
|
41
|
+
else
|
42
|
+
@game.should be_over
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
When /^I ask who is at position (\d+), it returns (\w+)$/ do |position, player|
|
47
|
+
player = player.to_i
|
48
|
+
player = nil if player.zero?
|
49
|
+
@game[position.to_i].should == player
|
50
|
+
end
|
51
|
+
|
52
|
+
Then /^player(\d+) (wins|loses|ties)$/ do |player, status|
|
53
|
+
@game.status(player.to_i).should == status.to_sym
|
54
|
+
end
|
55
|
+
|
56
|
+
Given /^a tie game$/ do
|
57
|
+
@game = TTT::Game.new '121221112'
|
58
|
+
end
|
59
|
+
|
60
|
+
When /^a computer player as player (\d+)$/ do |current_turn|
|
61
|
+
@game.turn.should == current_turn.to_i
|
62
|
+
end
|
63
|
+
|
64
|
+
Then /^the computer moves to one of the following: ((?:\d+ ?)+)$/ do |possible_boards|
|
65
|
+
@computer = TTT::ComputerPlayer.new @game
|
66
|
+
@computer.take_turn
|
67
|
+
possible_boards.split.should include @game.board
|
68
|
+
end
|
69
|
+
|
70
|
+
Given /^I have a computer player$/ do
|
71
|
+
@computer = TTT::ComputerPlayer.new @game
|
72
|
+
end
|
73
|
+
|
74
|
+
Then /^the computer will play for (\d+)$/ do |player_number|
|
75
|
+
player_number = player_number.to_i
|
76
|
+
@game.turn.should == player_number
|
77
|
+
@computer.player_number.should == player_number
|
78
|
+
@computer.take_turn
|
79
|
+
@game.turn.should_not == player_number
|
80
|
+
@computer.player_number.should_not == player_number.to_i
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: View board as developer
|
2
|
+
|
3
|
+
In order to be able to do exploratory testing
|
4
|
+
As a developer
|
5
|
+
I want to be able to view the board in standard tic-tac-toe format
|
6
|
+
|
7
|
+
Scenario: View board in tic-tac-toe format
|
8
|
+
Given I create a game with "abcdefghi"
|
9
|
+
Then board(:ttt) will be " a | b | c \n----|---|----\n d | e | f \n----|---|----\n g | h | i "
|
10
|
+
|
11
|
+
Scenario: Viewing a board with spaces no one has moved into
|
12
|
+
Given I create a game with "120000000"
|
13
|
+
Then board(:ttt) will be " 1 | 2 | \n----|---|----\n | | \n----|---|----\n | | "
|
data/lib/ttt.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ttt/game'
|
data/lib/ttt/binary.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'optparse'
|
2
|
+
|
3
|
+
require 'ttt/interface'
|
4
|
+
|
5
|
+
module TTT
|
6
|
+
|
7
|
+
# The code for ttt/bin
|
8
|
+
class Binary
|
9
|
+
|
10
|
+
attr_accessor :filein, :fileout, :fileerr
|
11
|
+
|
12
|
+
def initialize(argv, io={})
|
13
|
+
self.fileout = io.fetch :fileout, $stdout
|
14
|
+
self.fileerr = io.fetch :fileerr, $stderr
|
15
|
+
self.filein = io.fetch :filein, $stdin
|
16
|
+
parse argv
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse(argv)
|
20
|
+
argv = ['-h'] if argv.empty?
|
21
|
+
Parser.new(self).parse argv
|
22
|
+
rescue OptionParser::MissingArgument => e
|
23
|
+
fileerr.puts e.message
|
24
|
+
Kernel.exit 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def has_interface?(interface_name)
|
28
|
+
TTT::Interface.registered? interface_name
|
29
|
+
end
|
30
|
+
|
31
|
+
def list_of_registered
|
32
|
+
TTT::Interface.registered_names.map(&:inspect).join(', ')
|
33
|
+
end
|
34
|
+
|
35
|
+
def interface(interface_name)
|
36
|
+
TTT::Interface.registered[interface_name]
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
|
41
|
+
class Parser
|
42
|
+
|
43
|
+
attr_accessor :binary
|
44
|
+
|
45
|
+
def initialize(binary)
|
46
|
+
self.binary = binary
|
47
|
+
end
|
48
|
+
|
49
|
+
def method_missing(meth, *args, &block)
|
50
|
+
super unless binary.respond_to? meth
|
51
|
+
binary.send meth, *args, &block
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse(argv)
|
55
|
+
options.parse argv
|
56
|
+
end
|
57
|
+
|
58
|
+
def options
|
59
|
+
OptionParser.new do |options|
|
60
|
+
define_banner options
|
61
|
+
define_interface options
|
62
|
+
define_help options
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def options_for_interface
|
67
|
+
return :filein => filein, :fileout => fileout, :fileerr => fileerr
|
68
|
+
end
|
69
|
+
|
70
|
+
def define_banner(options)
|
71
|
+
options.banner = "Usage: ttt --interface interface_name\n" \
|
72
|
+
"ttt is an implementation of Tic Tac Toe by Josh Cheek\n\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
def define_interface(options)
|
76
|
+
options.on '-i', '--interface TYPE', "Specify which interface to play on. Select from: #{list_of_registered}" do |interface_name|
|
77
|
+
if interface_name.equal? true
|
78
|
+
fileerr.puts "Please supply interface type"
|
79
|
+
Kernel.exit 1
|
80
|
+
elsif has_interface? interface_name
|
81
|
+
interface(interface_name).new(options_for_interface).play
|
82
|
+
else
|
83
|
+
fileerr.puts "#{interface_name.inspect} is not a valid interface, select from: #{list_of_registered}"
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def define_help(options)
|
89
|
+
options.on '-h', '--help', 'Display this screen' do
|
90
|
+
fileout.puts options
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|