Faisons dessiner du poker avec ruby ~ Implémentation 2 (rôle) ~

Aperçu

Faisons tirer le poker avec ruby-Preparation-Faisons un tirage au poker avec la préparation de ruby-test-unit-Faisons tirer le poker avec ruby-Implementation 1 (carte) -

Suivi par.

Source: https://github.com/rytkmt/ruby_poker

Cette fois, nous mettrons en œuvre le rôle.

Implémentation des rôles

Réorganisons les exigences.

Il est donc temps de mettre en œuvre.

Création de fichier

Tout d'abord, créez un fichier normalement

ruby_poker/hand.rb


module RubyPoker
  class Hand
    def intialize(cards:)
    end
  end
end

ruby_poker.rb


require "ruby_poker/hand"

Jugement de rôle

Si vous générez une classe «rôle», vous devez porter un jugement à ce moment. ..

Par conséquent, utilisez la méthode de jugement au moment de la génération et définissez la carte de comparaison pour le type et le même rôle.

produire

ruby_poker/hand.rb


    attr_reader :hand_type, :comparison_card

    def intialize(cards:)
      raise(ArgumentError) if cards.size != 5
      @hand_type, @comparison_card = judge(cards: cards)
    end

  private

    def judge(cards:)
    end

N'en faites pas une variable d'instance car vous n'avez pas besoin de la conserver simplement en utilisant des cartes pour juger du rôle.

Comment mettre en œuvre le jugement de rôle ...

Puisqu'il y a beaucoup de rôles, je sens que je n'ai pas pu les séparer en préparant les méthodes une à une. .. Alors, découpons-le comme un module de jugement.

Ensuite, le jugement doit être fait par ordre de force et celui qui correspond au début doit être défini. Tout d'abord, définissez-le comme vous l'avez fait pour la carte.

Définition du type

Voir ici pour les noms anglais ... lol https://en.wikipedia.org/wiki/List_of_poker_hands

ruby_poker.rb


  HAND_TYPES = %i[
    royal_straight_flush
    straight_flush
    four_of_a_kind
    full_house
    flush
    straight
    three_of_a_kind
    two_pair
    one_pair
    high_card
  ].reverse.freeze

Je veux obtenir la classe de module dynamiquement, donc je veux convertir de cas de serpent à cas de chameau et l'obtenir avec const_get. .. Alors utilisons la gemme ʻactive_support` pour la conversion de mots ici (Quand je touche habituellement des rails, il est pratique d'atteindre l'endroit qui démange ici et je veux l'utiliser)

Gemfile


gem "activesupport"
$ bundle install

Ceci termine l'installation

ruby_poker.rb


require "active_support/all"

N'oubliez pas de lire

Transférer le jugement au module

ruby_poker/hand.rb


Dir[__dir__ + "/hand/hand_type_judgers/*.rb"].each { |p| require p }

module RubyPoker
  class Hand

ruby_poker/hand.rb


  private

    def judge(cards:)
      matched_cards = nil
      matched_type = RubyPoker::HAND_TYPES.find do |type|
        judger = RubyPoker::Hand::HandTypeJudgers.const_get(type.to_s.classify) # <=Actif pour ici_support
        matched_cards = judger.judge(cards: cards)
      end

      [matched_type, matched_cards.max]
    end

Je pensais que c'était de la responsabilité de la main sous la forme de séparer le traitement interne de la main, donc je vais l'implémenter comme un module interne de la main Le .judge du juge renvoie toujours la carte qui est la cible du même jugement de rôle si elle correspond, et renvoie nil si elle ne correspond pas

Implémentation du module de jugement de rôle

quinte flush royale

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/royal_straight_flush.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module RoyalStraightFlush
        def self.judge(cards:)
          return nil unless cards.map(&:suit).uniq.size == 1
          return nil unless cards.sort.map(&:number) == [10, 11, 12, 13, 1]
          cards
        end
      end
    end
  end
end
Quinte flush

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/straight_flush.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module StraightFlush
        def self.judge(cards:)
          return nil unless cards.map(&:suit).uniq.size == 1
          min_number_level = cards.min.number_level
          expected = [*min_number_level..min_number_level + 4]
          return nil unless cards.sort.map(&:number_level) == expected
          cards
        end
      end
    end
  end
end
Quatre cartes

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/four_of_a_kind.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module FourOfAKind
        def self.judge(cards:)
          cards.group_by(&:number).detect { |k, v| v.size == 4 }&.second
        end
      end
    end
  end
end
Full house

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/full_house.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module FullHouse
        def self.judge(cards:)
          grouped_number_cards = cards.group_by(&:number)
          three_card_number, three_cards = grouped_number_cards.detect { |k, v| v.size == 3 }
          return nil unless three_card_number
          grouped_number_cards.delete(three_card_number)
          return nil unless grouped_number_cards.detect { |k, v| v.size == 2 }
          three_cards
        end
      end
    end
  end
end
éclat

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/flush.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module Flush
        def self.judge(cards:)
          return nil unless cards.map(&:suit).uniq.size == 1
          cards
        end
      end
    end
  end
end
tout droit

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/straight.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module Straight
        def self.judge(cards:)
          min_number_level = cards.min.number_level
          expected = [*min_number_level..min_number_level + 4]
          return nil unless cards.sort.map(&:number_level) == expected
          cards
        end
      end
    end
  end
end
Trois cartes

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/three_of_a_kind.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module ThreeOfAKind
        def self.judge(cards:)
          cards.group_by(&:number).detect { |k, v| v.size == 3 }&.second
        end
      end
    end
  end
end
Deux paires

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/two_pair.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module TwoPair
        def self.judge(cards:)
          pairs = cards.group_by(&:number_level).select { |k, v| v.size == 2 }
          return nil unless pairs.size == 2
          pairs.max.second
        end
      end
    end
  end
end
Une paire

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/one_pair.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module OnePair
        def self.judge(cards:)
          cards.group_by(&:number_level).detect { |k, v| v.size == 2 }&.second
        end
      end
    end
  end
end
Carte haute (cochon)

ruby_poker/lib/ruby_poker/hand/hand_type_judgers/high_card.rb


module RubyPoker
  class Hand
    module HandTypeJudgers
      module HighCard
        def self.judge(cards:)
          [cards.max]
        end
      end
    end
  end
end

C'était un peu difficile, y compris la mise en œuvre du test, mais la mise en œuvre était terminée. Vous pouvez maintenant effectuer le jugement de rôle et renvoyer la carte de jugement en même temps.

Ajout de jugement pour comparable

ruby_poker/hand.rb


+    include Comparable

ruby_poker/hand.rb


    def hand_level
      RubyPoker::HAND_TYPES.reverse.index(@hand_type)
    end

    def <=>(other)
      hand_comparison = hand_level <=> other.hand_level
      hand_comparison.zero? ? @comparison_card <=> other.comparison_card : hand_comparison
    end

Vous pouvez maintenant comparer les gains et les pertes de rôles par > etc.

À la fin

Avec ce contenu, je pense que tous les traitements importants pour le jeu, tels que les cartes et les rôles, sont terminés. La prochaine fois, j'aimerais créer des joueurs qui les utilisent et la progression du jeu.

A continué

Faisons tirer le poker avec ruby-Implementation 3 (joueur) -

Recommended Posts

Faisons dessiner du poker avec ruby ~ Implémentation 2 (rôle) ~
Faisons tirer le poker avec ruby ~ Implémentation 1 (carte) ~
Faisons dessiner du poker avec ruby ~ Implémentation 4 (Deck) ~
Faisons tirer le poker avec ruby ~ Implémentation 3 (joueur) ~
Faisons dessiner du poker avec du rubis ~ Préparation ~
Faisons Draw Poker avec Ruby ~ Préparation de l'unité de test ~
Faisons une carte de Noël avec Processing!
Faisons un écran d'erreur avec Rails
Faisons une fonction de recherche avec Rails (ransack)
[Bases de Java] Créons un triangle avec une instruction for
Faisons un Bot LINE avec Ruby + Sinatra - Partie 1
Faisons ressembler à des rails (vue)
Raclons avec Java! !!
Écrivons comment créer une API avec SpringBoot + Docker à partir de 0
Faisons une API simple avec EC2 + RDS + Spring boot ①