0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Ruby】High and Low ゲーム

Last updated at Posted at 2021-07-22

はじめに

  • Rubyのみで自作アプリ『High and Low』ゲームを作成しました。
high_and_low_photo

作成目的

  • ruby 言語を基礎的な部分から理解していこうと考えたため。
  • 実際に作りながら文法を使ったり、ロジックを組み立てていった方が効率よく学べると考えたため。

インストール方法

$ git clone https://github.com/ryokobayashi0321/high_and_low.git
$ cd high_and_low
$ ruby main.rb

環境

  • ruby 2.7.3

使い方

  1. ターミナルで ruby main.rb を実行。
  2. 画面のメッセージに従い、数値を入力Enter キーを押す。

フローチャート図

high_and_low_flow

説明

  • master がトランプカードを 2 枚引きます。player は 2 枚目の数値がhigh(高い)low(低い)かを当てるゲームです。
  • player の宣言通りになれば勝利です。
  • トランプカードの数値に則ります。(ex A=1, J=11, Q=12, K=13),ジョーカーは含まれていません。
  • 所持金が 0 円になったら、ゲームオーバーです。

ゲームの流れ

1. player は賭け金を設定します。($ 1〜player の所持金)

2. master が 2 枚カードを引きます(1 枚目:表、2 枚目:裏)

3. player は1(high) or 2(low)を選びます(1 or 2 の数値を入力し Enter キー)

4. 判定に入ります。

  • 1(high)を選んだ場合

    • 2 枚目カードの数値が 1 枚目より高ければ勝ち
    • 2 枚目カードの数値が 1 枚目より低ければ負け
    • 同じ数値は引き分け
  • 2(low)を選んだ場合

    • 2 枚目カードの数値が 1 枚目より高ければ負け
    • 2 枚目カードの数値が 1 枚目より低けば勝ち
    • 同じ数値は引き分け

5. 賭け金の計算をします。

  • 勝ち
    • 賭け金の2倍額を手に入れられます。(賭け金は含まれる)
  • 負け
    • 賭け金を失います。
  • 引き分け
    • 賭け金を返却します。

6. コンティニューの選択

  • player は1(ゲームを続ける) or 2(やめる) を選びます(1or2 の数値を入力し Enter キー)

  • 1(ゲームを続ける)を選んだ場合

    • 掛け金が変化した状態で、**掛け金設定(最初)**に移行します。
  • 2(やめる)を選んだ場合

    • ゲームを終了します。

配当金

  • 所持金 - $100000
  • 勝ち - 掛け金 × 2 倍
  • 引き分け- 掛け金を返却する
  • 負け - 掛け金を支払う

さいごに

今後はもっとRubyの理解を深めていき、学習期間2ヶ月目で作ったこのアプリのコードをリファクタリングできるようにしていきたいと考えています。

ぜひ遊んでみてください!!

ソースコード

main.rb
require_relative "high_and_low"

master = Master.new
player = Player.new
high_and_low = HighAndLow.new(master, player)

# ゲームスタート
high_and_low.start
high_and_low.rb
require_relative "card"
require_relative "deck"
require_relative "master"
require_relative "player"
require_relative "message"
class HighAndLow
  attr_reader :bet, :remaining_money, :paid, :first_card, :second_card

  HIGH_NUMBER = 1
  LOW_NUMBER = 2
  MAGNIFICATION_OF_MONEY = 2
  SELECT_NEW_GAME = 1
  SELECT_STOP_GAME = 2
  NO_MONEY = 0
  MINIMUM_AMOUNT_OF_MONEY = 1

  include Message

  def initialize(master, player)
    @master = master
    @player = player
  end

  def start
    start_message

    loop do
      @deck = Deck.new

      give_bet_message(@player)
      disp_bet(@player)

      drow_card_message
      disp_two_cards
      disp_card_message

      select_ation
      open_card_message
      number_message

      judge
      calculate_bet

      next_action
    end
  end

  private

  # <賭け金を提示する>
  def disp_bet(player)
    loop do
      @bet = gets.to_i
      # ¥1〜プレイヤーの所持金のみ入力できる
      if @bet.between?(MINIMUM_AMOUNT_OF_MONEY, player.money)
        @remaining_money = player.bet_money(@bet)
        disp_bet_message
        break
      else
        error_bet_message
      end
    end
  end

  # <2枚のカードを提示する>
  def disp_two_cards
    cards = @master.draw_card(@deck)
      @first_card = cards[0]
      @second_card = cards[1]
  end

  # <最初のカードの数字>
  def first_card_point
    @f_point = []
    @f_point << @first_card.instance_variable_get(:@point)
    @fist_point = @f_point.find { |i| i.integer? }
  end

  # # <次のカードの数字>
  def second_card_point
    @s_point = []
    @s_point << @second_card.instance_variable_get(:@point)
    @second_point = @s_point.find { |i| i.integer? }
  end

  # <highかlowの選択>
  def select_ation
    loop do
      high_low_message
      @select_num = gets.to_i

      case @select_num
      when HIGH_NUMBER
        high_message
        break
      when LOW_NUMBER
        low_message
        break
      else
        error_info_message
      end
    end
  end

  # <判定の条件分岐>
  def judge
    loop do
      case @select_num
      when HIGH_NUMBER
        judge_high
        break
      when LOW_NUMBER
        judge_low
        break
      end
    end
  end

  # <highを選択した場合>
  def judge_high
    if (@win = @select_num == HIGH_NUMBER && second_card_point > first_card_point)
      win_high_message
    elsif (@lose = @select_num == HIGH_NUMBER && first_card_point > second_card_point)
      lose_high_message
    elsif (@draw = @select_num == HIGH_NUMBER && first_card_point == second_card_point)
      draw_game_message
    end
  end

  # <lowを選択した場合>
  def judge_low
    if (@win = @select_num == LOW_NUMBER && first_card_point > second_card_point)
      win_low_message
    elsif (@lose = @select_num == LOW_NUMBER && second_card_point > first_card_point)
      lose_low_message
    elsif (@draw = @select_num == LOW_NUMBER && first_card_point == second_card_point)
      draw_game_message
    end
  end

  # <賭け金の計算>
  def calculate_bet
    if @win
      calculate_win_game
      take_paid_message
    elsif @lose
      calculate_lose_game
    elsif @draw
      calculate_draw_game
    end
      if @player.money <= NO_MONEY
        game_over_message
        exit
      end
  end

  # <勝利時の計算>
  def calculate_win_game
    @paid = @bet * MAGNIFICATION_OF_MONEY
    @remaining_money = @player.add_money(@paid.floor)
  end

  # 敗北時の計算
  def calculate_lose_game
    @paid = @bet
    @remaining_money = @player.bet_money(@paid.floor)
  end

  # <引き分け時の計算>
  def calculate_draw_game
    @remaining_money = @player.add_money(@bet)
  end

  # <次の行動>
  def next_action
    loop do
      next_action_message
      @new_game_num = gets.to_i

      case @new_game_num
      when SELECT_NEW_GAME
        continue_game_message
        break
      when SELECT_STOP_GAME
        stop_game_message
        exit
      else
        error_info_message
      end
    end
  end
end
master.rb
class Master
  def draw_card(deck)
    @card = deck.draw
  end
end
player.rb
class Player
  attr_reader :money

  # 所持金
  MONEY_IN_POSSESSION = 100_000

  def initialize
    @money = MONEY_IN_POSSESSION
  end

  # お金を賭ける
  def bet_money(bet)
    @money -= bet
  end

  # お金の移動
  def add_money(money)
    @money += money
  end
end
deck.rb
class Deck
  attr_reader :cards

  # デッキ生成
  def initialize
    @cards = []

    mk = %w[スペード ハート ダイヤ クラブ]
    num = %w[A 2 3 4 5 6 7 8 9 10 J Q K]

    mk.each do |mark|
      num.each do |number|
        card = Card.new(mark, number)
        @cards << card
      end
    end

    @cards.shuffle!
  end

  # カードの取り出し
  def draw
    @cards.shift(2)
  end
end
card.rb
class Card
  attr_reader :mark, :number, :point

  @@card_point = {
    "A" => 1,
    "2" => 2,
    "3" => 3,
    "4" => 4,
    "5" => 5,
    "6" => 6,
    "7" => 7,
    "8" => 8,
    "9" => 9,
    "10" => 10,
    "J" => 11,
    "Q" => 12,
    "K" => 13
  }

  # トランプ生成
  def initialize(mark, number)
    @mark = mark
    @number = number
    @point = @@card_point.fetch(@number)
  end

  # トランプの種類を提示
  def card_info
    "#{@mark}#{@number}"
  end
end
message.rb
module Message
  def start_message
    puts <<~TEXT
      =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
              high_and_low
      =*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=

            ~ゲームスタート~
    TEXT
  end

  def give_bet_message(player)
    puts <<~TEXT

      現在の所持金は[$#{player.money}]です
      賭け金を入力してください
    TEXT
  end

  def disp_bet_message
    puts <<~TEXT
      *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
      賭け金 : $#{bet}
      残金 : $#{remaining_money}
      *=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
    TEXT
  end

  def error_bet_message
    puts <<~TEXT
      ------------------------------------------
      error : 所持金の範囲で数値を入力してください
      ------------------------------------------
    TEXT
  end

  def drow_card_message
    puts <<~TEXT

      カードを2枚引きます。
      1枚目を表示します。

    TEXT
  end

  def disp_card_message
    puts <<~TEXT
      -------------cards--------------
      1枚目 : #{first_card.card_info}
      2枚目 : 伏せている
      -------------cards--------------
    TEXT
  end

  def high_low_message
    puts <<~TEXT

      2枚目のカード値が
      'high' or 'low' であるかを当ててください(数値で入力)

      1.high 2.low
    TEXT
  end

  def high_message
    puts "highですね"
  end

  def low_message
    puts "lowですね"
  end

  def error_info_message
    puts <<~TEXT

      --------------------------------
      error : 1か2を選択してください
      --------------------------------
    TEXT
  end

  def open_card_message
    puts <<~TEXT

      それではカードをめくります

    TEXT
  end

  def number_message
    puts <<~TEXT
      ----------------cards---------------------
      1枚目 :#{first_card.card_info}
      1枚目のカードの数字は[#{first_card_point}]です

      そして

      2枚目のカードの数字は[#{second_card_point}]です
      ----------------cards---------------------
    TEXT
  end

  # <high分岐>
  def win_high_message
    puts "\n2枚目の数字が'高い'ので、highを選んだあなたの勝ちです!"
  end

  def lose_high_message
    puts <<~TEXT

      2枚目の数字が'低い'ので、highを選んだあなたの負けです
      [$#{bet}]を失いました

    TEXT
  end

  # <low分岐>
  def win_low_message
    puts "\n2枚目の数字が'低い'ので、lowを選んだあなたの勝ちです"
  end

  def lose_low_message
    puts <<~TEXT

      2枚目の数字が'高い'ので、lowを選んだあなたの負けです
      [$#{bet}]を失いました

    TEXT
  end

  def draw_game_message
    puts "\n引き分けです。賭け金が戻されます"
  end

  def take_paid_message
    puts <<~TEXT

      賭け金が2倍になります!!
      [$#{paid}]を手に入れました。
    TEXT
  end

  def next_action_message
    puts <<~TEXT

      ゲームを続けますか?

      現在の所持金 : $#{remaining_money}
      ---------------------------------

      1.ゲームを続ける 2.やめる
    TEXT
  end

  def continue_game_message
    puts <<~TEXT
      ゲームを続けるですね!!

          ~~NEXT GAME~~
    TEXT
  end

  def stop_game_message
    puts <<~TEXT
      やめるですね。

      あなたは[$#{remaining_money}]を手に入れました。

      ゲームを終了します
    TEXT
  end

  def game_over_message
    puts <<~TEXT
      所持金が[$0]になりました。

      *=*=*=*=*=*=*=*=*=*=*
          ゲームオーバー
      *=*=*=*=*=*=*=*=*=*=*
    TEXT
  end
end
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?