Advertisement
Guest User

Untitled

a guest
May 24th, 2019
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.09 KB | None | 0 0
  1. class Participant
  2. attr_reader :hand_value, :hand
  3. attr_accessor :wins, :name
  4.  
  5. def hit(cards)
  6. hand << cards.draw_card
  7. end
  8.  
  9. def stay?
  10. answer = nil
  11.  
  12. loop do
  13. puts "Hit(h) or Stay(s)?"
  14. answer = gets.chomp.downcase
  15. break if %w(h s).include?(answer)
  16. puts 'Sorry, please type h or s.'
  17. end
  18.  
  19. answer == 's' ? true : false
  20. end
  21.  
  22. def busted?
  23. @hand_value > TwentyOne::WIN_VALUE
  24. end
  25.  
  26. def total
  27. @hand_value = 0
  28.  
  29. hand.each do |card|
  30. @hand_value += if card.value == 'Ace'
  31. 11
  32. elsif card.value.to_i == 0
  33. 10
  34. else
  35. card.value.to_i
  36. end
  37. end
  38. end
  39.  
  40. def over_win_value?
  41. @hand_value > TwentyOne::WIN_VALUE
  42. end
  43.  
  44. def reduce_total_ace_value
  45. ace_total = 0
  46. hand.each { |card| ace_total += 1 if card.value == 'Ace' }
  47. ace_total.times { @hand_value -= 10 } if over_win_value?
  48. end
  49.  
  50. def pre_results_total
  51. total
  52. reduce_total_ace_value
  53. end
  54.  
  55. def card_values
  56. hand.map(&:value)
  57. end
  58.  
  59. def reset_hand_and_value
  60. @hand = []
  61. @hand_value = 0
  62. end
  63. end
  64.  
  65. class Player < Participant
  66. def initialize
  67. @name = 'Jondan'
  68. @hand = []
  69. @hand_value = 0
  70. @wins = 0
  71. end
  72. end
  73.  
  74. class Dealer < Participant
  75. def initialize
  76. @name = 'Dealer'
  77. @hand_value = 0
  78. @wins = 0
  79. @hand = []
  80. end
  81.  
  82. def stay?
  83. pre_results_total
  84. TwentyOne::DEALER_STAY_RANGE.include?(@hand_value)
  85. end
  86.  
  87. def first_card
  88. card_values.first
  89. end
  90. end
  91.  
  92. class Deck
  93. SUITS = ['H', 'S', 'D', 'C']
  94. VALUES = ['2', '3', '4', '5', '6',
  95. '7', '8', '9', '10', 'J',
  96. 'Q', 'K', 'A']
  97.  
  98. attr_reader :deck
  99.  
  100. def initialize
  101. @deck = []
  102. fill_deck
  103. end
  104.  
  105. def fill_deck
  106. @deck = []
  107. value_count = 0
  108.  
  109. 13.times do
  110. SUITS.each { |suit| @deck << Card.new(suit, VALUES[value_count]) }
  111. value_count += 1
  112. end
  113. end
  114.  
  115. def draw_card
  116. new_card = @deck.sample
  117. deck.delete_at(deck.index(new_card))
  118. new_card
  119. end
  120. end
  121.  
  122. class Card
  123. attr_reader :value, :suit
  124.  
  125. def initialize(suit, value)
  126. @suit = suit
  127. @value = value
  128. end
  129.  
  130. def value
  131. case @value
  132. when 'J' then 'Jack'
  133. when 'Q' then 'Queen'
  134. when 'K' then 'King'
  135. when 'A' then 'Ace'
  136. else @value
  137. end
  138. end
  139. end
  140.  
  141. class TwentyOne
  142. WIN_VALUE = 21
  143. DEALER_MIN_STAY = WIN_VALUE - 4
  144. DEALER_STAY_RANGE = (DEALER_MIN_STAY..WIN_VALUE).to_a
  145. POINTS_TO_WIN = 5
  146. attr_reader :deck, :player, :dealer
  147.  
  148. def initialize
  149. @deck = Deck.new
  150. @player = Player.new
  151. @dealer = Dealer.new
  152. end
  153.  
  154. def start
  155. choose_name
  156. loop do
  157. start_of_round_actions
  158.  
  159. loop do
  160. display_wins_and_cards
  161. player.stay? ? break : player_turn
  162. break if player.busted?
  163. end
  164.  
  165. loop do
  166. dealer_turn_over? ? break : dealer_turn
  167. end
  168.  
  169. end_of_round_actions
  170. break if someone_won? || not_play_again?
  171. end
  172. display_ending_message
  173. end
  174.  
  175. private
  176.  
  177. def display_initial_cards
  178. puts "#{player.name}'s cards: #{player.card_values}"
  179. end
  180.  
  181. def display_wins_and_cards
  182. clear
  183. puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  184. display_wins
  185. puts ''
  186. display_cards_and_val
  187. puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  188. end
  189.  
  190. def end_display_wins_and_cards
  191. clear
  192. puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  193. display_wins
  194. puts ''
  195. display_all_cards_and_val
  196. puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
  197. end
  198.  
  199. def display_card_values(participant)
  200. "#{participant.card_values} => #{participant.hand_value}."
  201. end
  202.  
  203. def display_cards_and_val
  204. puts "#{player.name}'s cards: #{display_card_values(player)}"
  205. puts "#{dealer.name}'s first card is: #{dealer.first_card}."
  206. end
  207.  
  208. def display_all_cards_and_val
  209. puts "#{player.name}'s cards: #{display_card_values(player)}"
  210. puts "#{dealer.name}'s cards: #{display_card_values(dealer)}"
  211. end
  212.  
  213. def display_wins
  214. puts "#{player.name}'s win total: #{player.wins}."
  215. puts "#{dealer.name}'s win total: #{dealer.wins}."
  216. end
  217.  
  218. def display_ending_message
  219. if player_won_match?
  220. puts "#{player.name} won the match."
  221. elsif dealer_won_match?
  222. puts "#{dealer.name} won the match."
  223. else
  224. puts "Come back soon, #{player.name}!"
  225. end
  226. puts "Thank you for playing 21."
  227. end
  228.  
  229. def display_results
  230. end_display_wins_and_cards
  231. if either_busted?
  232. display_busted
  233. elsif tie?
  234. msg_format("Tie.")
  235. else
  236. display_winner
  237. end
  238. end
  239.  
  240. def display_busted
  241. if player.busted?
  242. msg_format("#{player.name} busts. #{dealer.name} wins!")
  243. elsif dealer.busted?
  244. msg_format("#{dealer.name} busts. #{player.name} wins!")
  245. end
  246. end
  247.  
  248. def display_winner
  249. if player_won?
  250. msg_format("#{player.name} wins!")
  251. else
  252. msg_format("#{dealer.name} wins!")
  253. end
  254. end
  255.  
  256. def deal_cards
  257. 2.times do
  258. player.hit(deck)
  259. dealer.hit(deck)
  260. end
  261.  
  262. player.total
  263. end
  264.  
  265. def clear
  266. system 'clear'
  267. end
  268.  
  269. def msg_format(message)
  270. puts "*** #{message} ***"
  271. end
  272.  
  273. def start_of_round_actions
  274. reset
  275. deal_cards
  276. display_initial_cards
  277. end
  278.  
  279. def end_of_round_actions
  280. compute_winner
  281. display_results
  282. award_points
  283. end
  284.  
  285. def choose_name
  286. clear
  287. n = ''
  288.  
  289. loop do
  290. puts "What is your name, human?"
  291. n = gets.chomp.to_s
  292. break unless n.empty? || n == ' ' || not_valid_name?(n)
  293. puts 'Sorry, you must enter a value.'
  294. end
  295. player.name = n
  296. end
  297.  
  298. def not_valid_name?(name)
  299. invalid = [' ', '"', "'"]
  300. name.split('').each { |char| return true if invalid.include?(char) }
  301. false
  302. end
  303.  
  304. def player_turn
  305. player.hit(deck)
  306. player.total
  307. player.reduce_total_ace_value
  308. end
  309.  
  310. def dealer_turn
  311. dealer.hit(deck)
  312. dealer.total
  313. dealer.reduce_total_ace_value
  314. end
  315.  
  316. def dealer_turn_over?
  317. dealer.stay? || either_busted?
  318. end
  319.  
  320. def compute_winner
  321. display_cards_and_val
  322. compute_final_hand_value if neither_busted?
  323. end
  324.  
  325. def compute_final_hand_value
  326. player.pre_results_total
  327. dealer.pre_results_total
  328. end
  329.  
  330. def player_won?
  331. player.hand_value > dealer.hand_value
  332. end
  333.  
  334. def tie?
  335. player.hand_value == dealer.hand_value
  336. end
  337.  
  338. def neither_busted?
  339. !player.busted? && !dealer.busted?
  340. end
  341.  
  342. def either_busted?
  343. player.busted? || dealer.busted?
  344. end
  345.  
  346. def award_points
  347. if player.busted?
  348. dealer.wins += 1
  349. elsif dealer.busted?
  350. player.wins += 1
  351. elsif tie?
  352. puts "No points awarded for tie."
  353. elsif player_won?
  354. player.wins += 1
  355. else
  356. dealer.wins += 1
  357. end
  358. end
  359.  
  360. def not_play_again?
  361. answer = nil
  362.  
  363. loop do
  364. puts 'Would you like to play again? Y/N:'
  365. answer = gets.chomp.downcase
  366. break if %w(y n).include?(answer)
  367. puts 'Sorry, answer must be y or n.'
  368. end
  369.  
  370. answer == 'n' ? true : false
  371. end
  372.  
  373. def reset
  374. player.reset_hand_and_value
  375. dealer.reset_hand_and_value
  376. deck.fill_deck
  377. end
  378.  
  379. def player_won_match?
  380. player.wins == POINTS_TO_WIN
  381. end
  382.  
  383. def dealer_won_match?
  384. dealer.wins == POINTS_TO_WIN
  385. end
  386.  
  387. def someone_won?
  388. player_won_match? || dealer_won_match?
  389. end
  390. end
  391.  
  392. TwentyOne.new.start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement