console-blackjack 1.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: 6d6b53cff41f5f86ff9b279267559148007288ad2d6a64002308bd2c60b15519
4
+ data.tar.gz: 35c2c4bc1d8fe0f20fdab6a22da8f8395724b8a7c0eb8c72a0a384f8072dd0b2
5
+ SHA512:
6
+ metadata.gz: ded02e0f2f976b44fe6c24300d58c1107d6555a7fd35bcdb4908cf5dbabfa7ea9c0c5fe6d3d47da7ee34be4728df00baf744b4a13f3de4c7af70687e18b07b8e
7
+ data.tar.gz: 24294265189ea7d8cc29973c2a3a285b38d5ac41fae3d6b8fb88f331599381828d640c6cb92b1be629bd31281f8ba0d8d8298c12c85193e0f82028ffaf177e99
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'coveralls', require: false
6
+ gem 'factory_bot'
7
+ gem 'pry'
8
+ gem 'rake'
9
+ gem 'rest-client', '>= 1.8.0'
10
+ gem 'rspec'
11
+ gem 'rubocop', require: false
12
+ gem 'rubocop-rspec'
13
+ gem 'simplecov', require: false
data/Gemfile.lock ADDED
@@ -0,0 +1,108 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (6.0.1)
5
+ concurrent-ruby (~> 1.0, >= 1.0.2)
6
+ i18n (>= 0.7, < 2)
7
+ minitest (~> 5.1)
8
+ tzinfo (~> 1.1)
9
+ zeitwerk (~> 2.2)
10
+ ast (2.4.0)
11
+ coderay (1.1.2)
12
+ concurrent-ruby (1.1.5)
13
+ coveralls (0.7.1)
14
+ multi_json (~> 1.3)
15
+ rest-client
16
+ simplecov (>= 0.7)
17
+ term-ansicolor
18
+ thor
19
+ diff-lcs (1.3)
20
+ docile (1.3.2)
21
+ domain_name (0.5.20190701)
22
+ unf (>= 0.0.5, < 1.0.0)
23
+ factory_bot (5.1.1)
24
+ activesupport (>= 4.2.0)
25
+ http-accept (1.7.0)
26
+ http-cookie (1.0.3)
27
+ domain_name (~> 0.5)
28
+ i18n (1.7.0)
29
+ concurrent-ruby (~> 1.0)
30
+ jaro_winkler (1.5.4)
31
+ json (2.2.0)
32
+ method_source (0.9.2)
33
+ mime-types (3.3)
34
+ mime-types-data (~> 3.2015)
35
+ mime-types-data (3.2019.1009)
36
+ minitest (5.13.0)
37
+ multi_json (1.14.1)
38
+ netrc (0.11.0)
39
+ parallel (1.18.0)
40
+ parser (2.6.5.0)
41
+ ast (~> 2.4.0)
42
+ pry (0.12.2)
43
+ coderay (~> 1.1.0)
44
+ method_source (~> 0.9.0)
45
+ rainbow (3.0.0)
46
+ rake (13.0.0)
47
+ rest-client (2.1.0)
48
+ http-accept (>= 1.7.0, < 2.0)
49
+ http-cookie (>= 1.0.2, < 2.0)
50
+ mime-types (>= 1.16, < 4.0)
51
+ netrc (~> 0.8)
52
+ rspec (3.9.0)
53
+ rspec-core (~> 3.9.0)
54
+ rspec-expectations (~> 3.9.0)
55
+ rspec-mocks (~> 3.9.0)
56
+ rspec-core (3.9.0)
57
+ rspec-support (~> 3.9.0)
58
+ rspec-expectations (3.9.0)
59
+ diff-lcs (>= 1.2.0, < 2.0)
60
+ rspec-support (~> 3.9.0)
61
+ rspec-mocks (3.9.0)
62
+ diff-lcs (>= 1.2.0, < 2.0)
63
+ rspec-support (~> 3.9.0)
64
+ rspec-support (3.9.0)
65
+ rubocop (0.76.0)
66
+ jaro_winkler (~> 1.5.1)
67
+ parallel (~> 1.10)
68
+ parser (>= 2.6)
69
+ rainbow (>= 2.2.2, < 4.0)
70
+ ruby-progressbar (~> 1.7)
71
+ unicode-display_width (>= 1.4.0, < 1.7)
72
+ rubocop-rspec (1.36.0)
73
+ rubocop (>= 0.68.1)
74
+ ruby-progressbar (1.10.1)
75
+ simplecov (0.17.1)
76
+ docile (~> 1.1)
77
+ json (>= 1.8, < 3)
78
+ simplecov-html (~> 0.10.0)
79
+ simplecov-html (0.10.2)
80
+ term-ansicolor (1.7.1)
81
+ tins (~> 1.0)
82
+ thor (0.20.3)
83
+ thread_safe (0.3.6)
84
+ tins (1.22.0)
85
+ tzinfo (1.2.5)
86
+ thread_safe (~> 0.1)
87
+ unf (0.1.4)
88
+ unf_ext
89
+ unf_ext (0.0.7.6)
90
+ unicode-display_width (1.6.0)
91
+ zeitwerk (2.2.1)
92
+
93
+ PLATFORMS
94
+ ruby
95
+
96
+ DEPENDENCIES
97
+ coveralls
98
+ factory_bot
99
+ pry
100
+ rake
101
+ rest-client (>= 1.8.0)
102
+ rspec
103
+ rubocop
104
+ rubocop-rspec
105
+ simplecov
106
+
107
+ BUNDLED WITH
108
+ 2.0.2
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2019 Greg Donald
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # blackjack-ruby
2
+
3
+ ## Console
4
+
5
+ ![Blackjack](https://raw.githubusercontent.com/gdonald/blackjack-ruby/master/bj.png)
6
+
7
+ ## Getting Started
8
+
9
+ Install gems:
10
+
11
+ bundle install
12
+
13
+ Run tests:
14
+
15
+ rake
16
+
17
+ Run:
18
+
19
+ ruby blackjack.rb
20
+
21
+ ## Status
22
+
23
+ [![Build Status](https://travis-ci.org/gdonald/blackjack-ruby.svg?branch=master)](https://travis-ci.org/gdonald/blackjack-ruby)
24
+ [![Coverage Status](https://coveralls.io/repos/github/gdonald/blackjack-ruby/badge.svg?branch=master)](https://coveralls.io/github/gdonald/blackjack-ruby?branch=master)
25
+
26
+ ## License
27
+
28
+ blackjack-ruby is released under the [MIT License](http://www.opensource.org/licenses/MIT)
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/core/rake_task'
4
+ task default: :spec
5
+ RSpec::Core::RakeTask.new
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative '../lib/blackjack'
5
+ Blackjack.new.run
data/bj.png ADDED
Binary file
data/bj.txt ADDED
@@ -0,0 +1 @@
1
+ 8|1153000|500
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rake'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'console-blackjack'
7
+ spec.version = '1.0.0'
8
+ spec.date = '2019-11-09'
9
+ spec.summary = 'Console Blackjack'
10
+ spec.description = 'Blackjack for your console, full version.'
11
+ spec.author = 'Greg Donald'
12
+ spec.email = 'gdonald@gmail.com'
13
+ spec.bindir = 'bin'
14
+ spec.executables << 'console-blackjack'
15
+ spec.files = FileList['lib/**/*.rb',
16
+ 'bin/*',
17
+ '[A-Z]*',
18
+ 'spec/**/*.rb'].to_a
19
+ spec.homepage = 'https://github.com/gdonald/console-blackjack-ruby'
20
+ spec.metadata = {
21
+ 'source_code_uri' => 'https://github.com/gdonald/console-blackjack-ruby'
22
+ }
23
+ spec.license = 'MIT'
24
+ spec.post_install_message = "\nType `console-blackjack` to run!\n\n"
25
+ end
data/lib/blackjack.rb ADDED
@@ -0,0 +1,382 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'blackjack/shoe'
4
+ require_relative 'blackjack/dealer_hand'
5
+ require_relative 'blackjack/player_hand'
6
+
7
+ SAVE_FILE = 'bj.txt'
8
+ MIN_BET = 500
9
+ MAX_BET = 10_000_000
10
+
11
+ class Blackjack
12
+ attr_accessor :shoe, :money, :player_hands, :dealer_hand, :num_decks, :current_bet, :current_hand
13
+
14
+ def initialize
15
+ @num_decks = 1
16
+ @money = 10_000
17
+ @current_bet = 500
18
+ end
19
+
20
+ def run
21
+ load_game
22
+ @shoe = Shoe.new(num_decks)
23
+ deal_new_hand
24
+ end
25
+
26
+ def current_player_hand
27
+ player_hands[current_hand]
28
+ end
29
+
30
+ def build_new_hand
31
+ self.player_hands = []
32
+ player_hand = PlayerHand.new(self, current_bet)
33
+ player_hands << player_hand
34
+ self.current_hand = 0
35
+
36
+ self.dealer_hand = DealerHand.new(self)
37
+
38
+ 2.times do
39
+ player_hand.deal_card
40
+ dealer_hand.deal_card
41
+ end
42
+ player_hand
43
+ end
44
+
45
+ def deal_new_hand
46
+ shoe.new_regular if shoe.needs_to_shuffle?
47
+ player_hand = build_new_hand
48
+
49
+ if dealer_hand.upcard_is_ace? && !player_hand.blackjack?
50
+ draw_hands
51
+ ask_insurance
52
+ elsif player_hand.done?
53
+ dealer_hand.hide_down_card = false
54
+ pay_hands
55
+ draw_hands
56
+ draw_bet_options
57
+ else
58
+ draw_hands
59
+ player_hand.action?
60
+ save_game
61
+ end
62
+ end
63
+
64
+ def more_hands_to_play?
65
+ current_hand < player_hands.size - 1
66
+ end
67
+
68
+ def play_more_hands
69
+ self.current_hand += 1
70
+ current_player_hand.deal_card
71
+
72
+ if current_player_hand.done?
73
+ current_player_hand.process
74
+ else
75
+ draw_hands
76
+ current_player_hand.action?
77
+ end
78
+ end
79
+
80
+ def need_to_play_dealer_hand?
81
+ player_hands.each do |player_hand|
82
+ return true unless player_hand.busted? || player_hand.blackjack?
83
+ end
84
+ false
85
+ end
86
+
87
+ def normalize_current_bet
88
+ if current_bet < MIN_BET
89
+ self.current_bet = MIN_BET
90
+ elsif current_bet > MAX_BET
91
+ self.current_bet = MAX_BET
92
+ end
93
+
94
+ self.current_bet = money if current_bet > money
95
+ end
96
+
97
+ def pay_hands
98
+ dealer_hand_value = dealer_hand.value(SOFT)
99
+ dealer_busted = dealer_hand.busted?
100
+
101
+ player_hands.each do |player_hand|
102
+ player_hand.pay(dealer_hand_value, dealer_busted)
103
+ end
104
+
105
+ normalize_current_bet
106
+ save_game
107
+ end
108
+
109
+ def clear
110
+ return if ENV['CLEAR_TERM'] == '0'
111
+
112
+ system('export TERM=linux; clear')
113
+ end
114
+
115
+ def draw_hands
116
+ clear
117
+ out = String.new
118
+ out << "\n Dealer:\n#{dealer_hand.draw}\n"
119
+
120
+ out << "\n Player $"
121
+ out << Blackjack.format_money(money / 100.0)
122
+ out << ":\n"
123
+
124
+ player_hands.each_with_index do |player_hand, index|
125
+ out << player_hand.draw(index)
126
+ end
127
+
128
+ puts out
129
+ end
130
+
131
+ def new_bet
132
+ clear
133
+ draw_hands
134
+
135
+ puts " Current Bet: $#{Blackjack.format_money(current_bet / 100)}\n"
136
+ print ' Enter New Bet: $'
137
+
138
+ tmp = STDIN.gets.to_i
139
+ self.current_bet = tmp * 100
140
+
141
+ normalize_current_bet
142
+ deal_new_hand
143
+ end
144
+
145
+ def draw_game_options
146
+ puts ' (N) Number of Decks (T) Deck Type (B) Back'
147
+
148
+ loop do
149
+ br = false
150
+ case Blackjack.getc
151
+ when 'n'
152
+ br = true
153
+ clear
154
+ draw_hands
155
+ new_num_decks
156
+ when 't'
157
+ br = true
158
+ clear
159
+ draw_hands
160
+ new_deck_type
161
+ clear
162
+ draw_hands
163
+ draw_bet_options
164
+ when 'b'
165
+ br = true
166
+ clear
167
+ draw_hands
168
+ draw_bet_options
169
+ else
170
+ clear
171
+ draw_hands
172
+ draw_game_options
173
+ end
174
+
175
+ break if br
176
+ end
177
+ end
178
+
179
+ def new_num_decks
180
+ puts " Number Of Decks: #{num_decks}"
181
+ print ' New Number Of Decks (1-8): '
182
+ self.num_decks = STDIN.gets.to_i
183
+
184
+ normalize_num_decks
185
+
186
+ clear
187
+ draw_hands
188
+ draw_game_options
189
+ end
190
+
191
+ def normalize_num_decks
192
+ self.num_decks = 1 if num_decks < 1
193
+ self.num_decks = 8 if num_decks > 8
194
+ end
195
+
196
+ def new_deck_type
197
+ puts ' (1) Regular (2) Aces (3) Jacks (4) Aces & Jacks (5) Sevens (6) Eights'
198
+
199
+ loop do
200
+ br = false
201
+ case Blackjack.getc
202
+ when '1'
203
+ br = true
204
+ shoe.new_regular
205
+ when '2'
206
+ br = true
207
+ shoe.new_aces
208
+ when '3'
209
+ br = true
210
+ shoe.new_jacks
211
+ when '4'
212
+ br = true
213
+ shoe.new_aces_jacks
214
+ when '5'
215
+ br = true
216
+ shoe.new_sevens
217
+ when '6'
218
+ br = true
219
+ shoe.new_eights
220
+ else
221
+ clear
222
+ draw_hands
223
+ new_deck_type
224
+ end
225
+
226
+ break if br
227
+ end
228
+ end
229
+
230
+ def ask_insurance
231
+ puts ' Insurance? (Y) Yes (N) No'
232
+
233
+ loop do
234
+ br = false
235
+ case Blackjack.getc
236
+ when 'y'
237
+ br = true
238
+ insure_hand
239
+ when 'n'
240
+ br = true
241
+ no_insurance
242
+ else
243
+ clear
244
+ draw_hands
245
+ ask_insurance
246
+ end
247
+
248
+ break if br
249
+ end
250
+ end
251
+
252
+ def insure_hand
253
+ player_hand = current_player_hand
254
+ player_hand.bet /= 2
255
+ player_hand.played = true
256
+ player_hand.payed = true
257
+ player_hand.status = LOST
258
+
259
+ self.money -= player_hand.bet
260
+
261
+ draw_hands
262
+ draw_bet_options
263
+ end
264
+
265
+ def no_insurance
266
+ if dealer_hand.blackjack?
267
+ dealer_hand.hide_down_card = false
268
+
269
+ pay_hands
270
+ draw_hands
271
+ draw_bet_options
272
+ else
273
+ player_hand = current_player_hand
274
+
275
+ if player_hand.done?
276
+ play_dealer_hand
277
+ else
278
+ draw_hands
279
+ player_hand.action?
280
+ end
281
+ end
282
+ end
283
+
284
+ def play_dealer_hand
285
+ dealer_hand.play
286
+ draw_hands
287
+ draw_bet_options
288
+ end
289
+
290
+ def split_current_hand
291
+ if current_player_hand.can_split?
292
+ player_hands << PlayerHand.new(self, current_bet)
293
+
294
+ x = player_hands.size - 1
295
+ while x > current_hand
296
+ player_hands[x] = player_hands[x - 1].clone
297
+ x -= 1
298
+ end
299
+
300
+ this_hand = player_hands[current_hand]
301
+ split_hand = player_hands[current_hand + 1]
302
+
303
+ split_hand.cards = []
304
+ split_hand.cards << this_hand.cards.last
305
+ this_hand.cards.pop
306
+
307
+ this_hand.cards << shoe.next_card
308
+ if this_hand.done?
309
+ this_hand.process
310
+ else
311
+ draw_hands
312
+ current_player_hand.action?
313
+ end
314
+ else
315
+ draw_hands
316
+ current_player_hand.action?
317
+ end
318
+ end
319
+
320
+ def draw_bet_options
321
+ puts ' (D) Deal Hand (B) Change Bet (O) Options (Q) Quit'
322
+
323
+ loop do
324
+ br = false
325
+ case Blackjack.getc
326
+ when 'd'
327
+ br = true
328
+ deal_new_hand
329
+ when 'b'
330
+ br = true
331
+ new_bet
332
+ when 'o'
333
+ br = true
334
+ clear
335
+ draw_hands
336
+ draw_game_options
337
+ when 'q'
338
+ clear
339
+ exit
340
+ else
341
+ clear
342
+ draw_hands
343
+ draw_bet_options
344
+ end
345
+
346
+ break if br
347
+ end
348
+ end
349
+
350
+ def all_bets
351
+ player_hands.inject(0) { |sum, player_hand| sum + player_hand.bet }
352
+ end
353
+
354
+ def save_game
355
+ File.open(SAVE_FILE, 'w') do |file|
356
+ file.puts "#{num_decks}|#{money}|#{current_bet}"
357
+ end
358
+ end
359
+
360
+ def load_game
361
+ return unless File.readable?(SAVE_FILE)
362
+
363
+ a = File.read(SAVE_FILE).split('|')
364
+ self.num_decks = a[0].to_i
365
+ self.money = a[1].to_i
366
+ self.current_bet = a[2].to_i
367
+ end
368
+
369
+ def self.getc
370
+ begin
371
+ system('stty raw -echo')
372
+ c = STDIN.getc
373
+ ensure
374
+ system('stty -raw echo')
375
+ end
376
+ c.chr
377
+ end
378
+
379
+ def self.format_money(value)
380
+ format('%.2f', value)
381
+ end
382
+ end