rochambeau 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 0c507e4a422648c5da20a64647fa103c302426fe0d4d891e1d3f9669a60abc2c
4
+ data.tar.gz: 699067dee47107c716c00f539180878f377ee17802ab0d71f211ff51401ffd61
5
+ SHA512:
6
+ metadata.gz: 4198c70160ce838c5ee79a948f7cc0b87fccc9504d483d19f972d476498ae33cf48dc43054ba0bfdda93521a39a7d2fac35a71ecba873375aa6525357c426013
7
+ data.tar.gz: d2d014b7840d76cd97c545bfed97e7b8bad3b6d5a716e96b5de2f08ead56b7b978a85a236ab131fc609de750c368588ae70754d7381c21ba04b51bafa34e9296
data/lib/rochambeau.rb ADDED
@@ -0,0 +1,11 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ class Rochambeau
5
+ extend T::Sig
6
+
7
+ VERSION = '1.9'
8
+
9
+ class InvalidOptionError < StandardError
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../rochambeau'
5
+ require_relative '../rochambeau/option'
6
+ require_relative '../rochambeau/game_mode'
7
+
8
+ class Rochambeau
9
+ class Cli < Thor
10
+ extend T::Sig
11
+
12
+ desc 'version', 'Display version information.'
13
+ sig { void }
14
+ def version
15
+ puts <<~VERSION
16
+ Rochambeau #{Rochambeau::VERSION}
17
+ GitHub: https://github.com/jigarius/rochambeau
18
+ VERSION
19
+ end
20
+
21
+ desc 'play', 'Play Rock-Paper-Scissors.'
22
+ option 'advanced',
23
+ aliases: ['a'],
24
+ type: :boolean,
25
+ default: false,
26
+ desc: 'Advanced mode contains the options "Lizard" and "Spock".'
27
+ sig { void }
28
+ def play
29
+ system 'clear'
30
+
31
+ game_mode =
32
+ options.advanced ? GameMode::ADVANCED : GameMode::BASIC
33
+
34
+ choice = input_choice(game_mode)
35
+ random = T.cast(game_mode.options.sample, Option)
36
+
37
+ puts '------'
38
+ puts "Bot: #{random}"
39
+ puts "You: #{choice}"
40
+ puts '------'
41
+
42
+ puts Option.explain(choice, random) unless random == choice
43
+
44
+ case choice <=> random
45
+ when 1
46
+ puts 'You won (:'
47
+ when -1
48
+ puts 'Bot won :('
49
+ puts 'Better luck next time.'
50
+ else
51
+ puts 'Match draw.'
52
+ end
53
+ end
54
+
55
+ default_task :play
56
+
57
+ private
58
+
59
+ no_commands do
60
+ def input_choice(game_mode)
61
+ T.cast(game_mode, GameMode)
62
+ puts game_mode.options.map(&:label).join(' · ')
63
+ chosen_initial = ask('Make a choice', {
64
+ limited_to: game_mode.options.map(&:initial)
65
+ })
66
+ Rochambeau::Option.from_initial chosen_initial
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,32 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'option'
5
+
6
+ class Rochambeau
7
+ class GameMode < T::Struct
8
+ extend T::Sig
9
+
10
+ const :options, T::Array[Option]
11
+
12
+ private_class_method :new
13
+
14
+ BASIC = T.let(
15
+ new(
16
+ options: [
17
+ Option::ROCK,
18
+ Option::PAPER,
19
+ Option::SCISSORS,
20
+ ]
21
+ ),
22
+ GameMode
23
+ )
24
+
25
+ ADVANCED = T.let(
26
+ new(
27
+ options: Option::ALL
28
+ ),
29
+ GameMode
30
+ )
31
+ end
32
+ end
@@ -0,0 +1,121 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ class Rochambeau
5
+ class Option
6
+ extend T::Sig
7
+
8
+ sig { returns(String) }
9
+ attr_reader :initial, :name
10
+
11
+ private_class_method :new
12
+
13
+ sig { params(initial: String, name: String).void }
14
+ def initialize(initial, name)
15
+ @initial = initial
16
+ @name = name
17
+ end
18
+
19
+ ROCK = T.let(new('r', 'rock'), Option)
20
+ PAPER = T.let(new('p', 'paper'), Option)
21
+ SCISSORS = T.let(new('s', 'scissors'), Option)
22
+ LIZARD = T.let(new('l', 'lizard'), Option)
23
+ SPOCK = T.let(new('v', 'spock'), Option)
24
+
25
+ ALL = T.let(
26
+ [ROCK, PAPER, SCISSORS, LIZARD, SPOCK],
27
+ T::Array[Option]
28
+ )
29
+
30
+ OUTCOMES = T.let(
31
+ {
32
+ ROCK => {
33
+ ROCK => { result: 0, explanation: nil },
34
+ PAPER => { result: -1, explanation: 'Paper covers rock.' },
35
+ SCISSORS => { result: 1, explanation: 'Rock crushes scissors.' },
36
+ LIZARD => { result: 1, explanation: 'Rock crushes lizard.' },
37
+ SPOCK => { result: -1, explanation: 'Spock vaporizes rock.' }
38
+ },
39
+ PAPER => {
40
+ ROCK => { result: 1, explanation: 'Paper covers rock.' },
41
+ PAPER => { result: 0, explanation: nil },
42
+ SCISSORS => { result: -1, explanation: 'Scissors cut paper.' },
43
+ LIZARD => { result: -1, explanation: 'Lizard eats paper.' },
44
+ SPOCK => { result: 1, explanation: 'Paper disproves Spock.' }
45
+ },
46
+ SCISSORS => {
47
+ ROCK => { result: -1, explanation: 'Rock crushes scissors.' },
48
+ PAPER => { result: 1, explanation: 'Scissors cut paper.' },
49
+ SCISSORS => { result: 0, explanation: nil },
50
+ LIZARD => { result: 1, explanation: 'Scissors decapitate lizard.' },
51
+ SPOCK => { result: -1, explanation: 'Spock smashes scissors.' }
52
+ },
53
+ LIZARD => {
54
+ ROCK => { result: -1, explanation: 'Rock crushes lizard.' },
55
+ PAPER => { result: 1, explanation: 'Lizard eats paper.' },
56
+ SCISSORS => { result: -1, explanation: 'Scissors decapitate lizard.' },
57
+ LIZARD => { result: 0, explanation: nil },
58
+ SPOCK => { result: 1, explanation: 'Lizard poisons Spock.' }
59
+ },
60
+ SPOCK => {
61
+ ROCK => { result: 1, explanation: 'Spock vaporizes rock.' },
62
+ PAPER => { result: -1, explanation: 'Paper disproves Spock.' },
63
+ SCISSORS => { result: 1, explanation: 'Spock smashes scissors.' },
64
+ LIZARD => { result: -1, explanation: 'Lizard poisons Spock.' },
65
+ SPOCK => { result: 0, explanation: nil }
66
+ }
67
+ },
68
+ T::Hash[
69
+ Option,
70
+ T::Hash[
71
+ Option,
72
+ { result: Integer, explanation: T.nilable(String) }
73
+ ]
74
+ ]
75
+ )
76
+ private_constant(:OUTCOMES)
77
+
78
+ sig { params(other: Option).returns(Integer) }
79
+ def <=>(other)
80
+ unless OUTCOMES[self] && T.must(OUTCOMES[self])[other]
81
+ raise StandardError, "Could not compare #{self} with #{other}"
82
+ end
83
+
84
+ T.must(T.must(OUTCOMES[self])[other])[:result]
85
+ end
86
+
87
+ sig { returns(String) }
88
+ def to_s
89
+ @name
90
+ end
91
+
92
+ sig { returns(String) }
93
+ def label
94
+ "#{@name.capitalize} (#{@initial})"
95
+ end
96
+
97
+ class << self
98
+ extend(T::Sig)
99
+
100
+ sig do
101
+ params(option1: Option, option2: Option)
102
+ .returns(T.nilable(String))
103
+ end
104
+ def explain(option1, option2)
105
+ unless OUTCOMES[option1] && T.must(OUTCOMES[option1])[option2]
106
+ raise StandardError, "Unexpected combination: #{option1}, #{option2}"
107
+ end
108
+
109
+ T.must(T.must(OUTCOMES[option1])[option2])[:explanation]
110
+ end
111
+
112
+ sig { params(initial: String).returns(Option) }
113
+ def from_initial(initial)
114
+ result = ALL.detect { |o| o.initial == initial }
115
+ return result if result
116
+
117
+ raise Rochambeau::InvalidOptionError, "Invalid initial '#{initial}'."
118
+ end
119
+ end
120
+ end
121
+ end
metadata ADDED
@@ -0,0 +1,46 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rochambeau
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Jigar Mehta
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-17 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Command-line edition of the Rock-Paper-Scissors game.
14
+ email: hello@jigarius.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/rochambeau.rb
20
+ - lib/rochambeau/cli.rb
21
+ - lib/rochambeau/game_mode.rb
22
+ - lib/rochambeau/option.rb
23
+ homepage: https://rubygems.org/gems/rochambeau
24
+ licenses:
25
+ - LGPL-2.1
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 2.7.0
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubygems_version: 3.1.4
43
+ signing_key:
44
+ specification_version: 4
45
+ summary: 'Rock, paper, scissors: Command line edition.'
46
+ test_files: []