-** card.rb (card class) ** --I used attr_reader so that the card data for each card cannot be rewritten (so that the data is not corrupted).
-** deck.rb (deck class) ** --At the stage of instantiation, I made sure the deck was shuffled and tested it. --I wrote the deck generation as concisely as possible using each statement. --Using class variables, when you draw a card, it now counts what number of the deck is being drawn. -** player.rb (player class) ** --Common to players and dealers, in order to use the same deck, I assigned an instance of the deck to a class variable and used the deck.
-** judge.rb (judge class) ** --The class for judging, for the sake of clarity, I dared to use a module separately from the player.
-** test.rb (operation check test) ** --minitest is * "Introduction to Ruby for those who want to become a professional" , and I haven't used it since I wrote it, so I used it to deepen my understanding. -* main.rb (main file that runs blackjack) ** --For clarity, I wrote only the overall flow of the game first ――From there, I thought about the necessary classes and methods and added them.
--No bed. (Planned to be implemented at a later date) --"A" is recognized as "1" (will be converted to 10 at a later date) --Hit or stand only ――The one with the higher total score wins
card.rb
class Card
attr_reader :mark, :number
def initialize(mark, number)
@mark = mark.freeze
@number = number.freeze
end
def convert
if @number == 'J' || @number == 'Q' || @number == 'K'
10
elsif @number == 'A'
1
else
@number.to_i
end
end
end
deck.rb
require './card'
class Deck
attr_accessor :cards
@@draw_count = 0
def initialize
@cards = []
create
@cards = @cards.shuffle
end
def create
nums = ['A', 2, 3, 4, 5, 6, 7, 8, 9, 10, 'J', 'Q', 'K']
mark = ['❤︎', '♦︎', '♤', '♧']
mark.each do |m|
nums.each do |n|
@cards << Card.new(m, n)
end
end
end
def draw
cards[@@draw_count]
end
def draw_count
@@draw_count += 1
end
#Card reference method for testing
def show
52.times do |n|
puts "[ #{cards[n].mark} #{cards[n].number} ]"
end
end
end
player.rb
require './deck'
require './judge'
class Player
include Judge
attr_accessor :hands, :total_score, :name
@@deck = Deck.new
def initialize(name: "player")
@hands = []
@total_score = 0
@name = name
end
def draw
self.hands << @@deck.draw
self.total_score += @@deck.draw.convert
@@deck.draw_count
end
def show
puts "#{self.name}Is in your hand"
self.hands.each do |hand|
puts "[ #{hand.mark} #{hand.number} ]"
end
puts "[Total score#{@total_score} ]"
end
#Test method
def test
puts "Test --------"
end
def total_score_calc
self.hands.each do |hand|
@total_score += hand.convert
end
#puts "total"#{@total_score}」"
end
def reset
self.hands = []
self.total_score = 0
end
def in_blackjack
self.hands << Card.new("♦︎", "J")
self.hands << Card.new("♦︎", "A")
end
end
judge.rb
module Judge
# def game_judge(target)
# if self.total_score > target.total_score
# puts "Your total score[ #{self.total_score} ]"
# puts "Dealer total score[ #{target.total_score} ]"
# puts 'You win'
# elsif self.total_score == target.total_score
# puts "Your total score[ #{self.total_score} ]"
# puts "Dealer total score[ #{target.total_score} ]"
# puts 'It's a draw'
# else
# puts "Your total score[ #{self.total_score} ]"
# puts "Dealer total score[ #{target.total_score} ]"
# puts 'You lose'
# end
# end
def blackjack?
if self.hands[1].number == "A" || self.hands[0].number == "A"
if self.hands[0].number == "J" || self.hands[0].number == "Q"|| self.hands[0].number == "K" || \
self.hands[1].number == "J" || self.hands[1].number == "Q"|| self.hands[1].number == "K"
self.total_score = "black Jack"
true
else
false
end
else
false
end
end
def burst?
if self.total_score > 21
true
else
false
end
end
end
test.rb
require 'minitest/autorun'
require './player'
class BlackJackTest < Minitest::Test
#The test card mark is unified with "♦ ︎"
@@test_J = Card.new('♦︎', 'J')
@@test_Q = Card.new('♦︎', 'Q')
@@test_K = Card.new('♦︎', 'K')
@@test_A = Card.new('♦︎', 'A')
@@test_5 = Card.new('♦︎', 5)
@@test_10 = Card.new('♦︎', 10)
@@test_player = Player.new
def test_blackjack?
blackjack_player = Player.new
blackjack_player.hands << @@test_A
blackjack_player.hands << @@test_J
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_J
blackjack_player.hands << @@test_A
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_Q
blackjack_player.hands << @@test_A
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_A
blackjack_player.hands << @@test_Q
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_A
blackjack_player.hands << @@test_K
assert blackjack_player.blackjack?
blackjack_player.reset
blackjack_player.hands << @@test_K
blackjack_player.hands << @@test_A
assert blackjack_player.blackjack?
#false pattern
# blackjack_player.reset
# blackjack_player.hands << @@test_A
# blackjack_player.hands << @@test_10
# assert blackjack_player.blackjack?
# blackjack_player.reset
# blackjack_player.hands << @@test_5
# blackjack_player.hands << @@test_5
# assert blackjack_player.blackjack?
# blackjack_player.reset
# blackjack_player.hands << @@test_J
# blackjack_player.hands << @@test_Q
# assert blackjack_player.blackjack?
end
def test_burst?
burst_player = Player.new
burst_player.hands << @@test_J
burst_player.hands << @@test_J
burst_player.hands << @@test_5
burst_player.total_score_calc
burst_player.total_score
assert burst_player.burst?
# false
# burst_player.reset
# burst_player.hands << @@test_10
# burst_player.total_score
# assert burst_player.burst?
end
def test_total_score_calc
total_score_calc_player = Player.new
total_score_calc_player.hands << @@test_10
total_score_calc_player.hands << @@test_5
total_score_calc_player.total_score_calc
assert_equal 15, total_score_calc_player.total_score
# false
#assert_equal 10, total_score_calc_player.total_score
end
def test_convert
assert_equal 10, @@test_J.convert
assert_equal 10, @@test_Q.convert
assert_equal 10, @@test_K.convert
assert_equal 1, @@test_A.convert
assert_equal 5, @@test_5.convert
end
def test_draw_count
deck = Deck.new
assert_equal 1, @@test_player.draw
assert_equal 2, @@test_player.draw
assert_equal 3, @@test_player.draw
end
end
main.rb
require './player'
lose_message =<<~TEXT
You lose
TEXT
win_message =<<~TEXT
You win
TEXT
game_draw_message =<<~TEXT
It's a draw
TEXT
error_message = "Invalid character. Type it again"
class Play
attr_accessor :player, :dealer
def initialize
@player = Player.new
@dealer = Player.new(name: "dealer")
end
def test
@player.draw
@player.draw
@player.show
end
end
while true #Loop processing for replay
#First turn processing
player = Player.new
dealer = Player.new(name: "dealer")
puts "Welcome to Blackjack"
puts "Distribute cards"
player.draw
player.draw
dealer.draw
dealer.show
#Blackjack test
# dealer.reset
# dealer.in_blackjac
# dealer.show
# player.reset
# player.in_blackjack
# player.show
#Processing to confirm that the player is not blackjack
if player.blackjack?
puts "black Jack!"
player.show
else
player.show
puts h_or_s_message =<<~TEXT
Please select
Push「h」,hit
Push「s」,stand
TEXT
end
#Hit, stand processing (player's turn)
while true
#In the case of blackjack, the process of forcibly standing
if player.blackjack?
command = 's'
else
command = gets.chomp #Choose hit or stand
end
#Processing in case of hit
if command == "h"
while true
player.draw
if player.burst? #Check if there is a burst
player.show
puts "burst! !!"
puts lose_message
break
end
#Confirmation of total score after draw
player.show
#In the case of the maximum value (21), the stand is forcibly processed.
if player.total_score == 21
puts 'The total score has reached the maximum'
command = 's'
break
end
#If it is not the maximum value, hit again or process
puts "Would you like to pull it again?"
puts h_or_s_message
while true
command = gets.chomp #Again, hit or stand selection
if command == 'h'
break
elsif command == 's'
break
else
puts error_message
redo
end
end
#Hit or stand handling
if command == 'h'
redo
elsif command == 's'
break
end
end
#Forced termination processing at the time of burst
if player.burst?
break
end
else
# h,Processing when input other than s
puts error_message
redo
end
#Processing at stand (dealer's turn)
if command == 's'
#Dealer handling when player is blackjack
if player.blackjack?
dealer.draw
dealer.show
if !dealer.blackjack?
puts win_message
break
else
puts game_draw_message
break
end
end
#The dealer keeps hitting until he wins the player
while player.total_score > dealer.total_score
dealer.draw
dealer.show
if dealer.burst?
puts 'burst!'
puts win_message
break
elsif dealer.total_score == 21 && player.total_score == 21
break
end
end
if dealer.burst? #If there is a burst, processing ends
break
elsif dealer.total_score == 21 && player.total_score == 21 #Check if each other has not reached the maximum value
puts game_draw_message
break
else
puts lose_message
break
end
end
end
#Replay processing
puts <<~TEXT
Would you like to play again?
Please select
Push「h」,Yes
Push「s」,No
TEXT
while true
command = gets.chomp #Choose to replay
if command == "h"
command = nil
break
elsif command == "s"
break
else
puts error_message
redo
end
end
#Replay processing
if command == nil
redo
else
break
end
end
At first, I used "p" instead of minitest, but I understood that the work would be faster if I used it.
If you don't put "test" in the first word of the method name of minitest, I completely forgot not to test it and I was worried about 2 days but lol
Understanding will deepen if you actively use things that you have never used.
There are still many places that can be refactored, I was almost tired of making it, so I wrote Qiita once.
Recommended Posts