宮鎖RubyのClass(二)

6736 ワード

前言:前回Class(一)の学習経験があり、今回はもう一つの新しい概念「継承」(inheritance)を学び、合わせて簡単な石、ハサミ、布ゲーム(RPSと略称)を実現することができます.
PS:石はさみ布ゲームを練習として選んだのも、最近私たちの子供の頃のゲームが注目され始めたからです.浙江大学、浙江工商大学、中科院理論物理研究所の研究者が予印本サイトで研究報告書(PDF)を発表し、実験を通じて石はさみ布の勝利戦略を発見しました.ネットユーザーの広範な討論を引き起こし、知乎、果核を検索することができる.
一、RPSゲームの簡単な説明
まず、私はただ簡単なヒューマンマシンRPSゲームを実現したいだけです(主に継承を学ぶためです).したがって,マルチプレイRPSゲームにおいて考慮すべきグループ化やグループ化などの複雑なアルゴリズム問題を回避した.△例えば、16人で遊ぶ場合、どのようにグループ化しますか.
次に、作成するクラスを考慮します.プレイヤー(Player)は作成しなければならないクラスであり、人間もコンピュータもゲーム中にこのクラスに属しているか継承されている.なお、ゲーム(Game)クラスを作成するには、選手グループ(@players_in_game)のインスタンスや、ゲームの勝敗を判定する方法などが含まれている.ゲームオブジェクトを作成すると、新しいゲームが開始されます.
コードを見てみましょう.
二、プレイヤークラスの作成(PlayerInGame)
player_in_game.rb
class PlayerInGame
    attr_reader :name, :player_choice

    def initialize(name, player_choice)
        @name = name
        @player_choice = player_choice
    end

    def choice_to_num
        if player_choice == "rock"
            return 0
        elsif player_choice == "paper"
            return 1
        elsif player_choice == "scissors"
            return 2
        else
            return "error"
        end
    end

    def to_s
        "I (#{@name}) choice #{@player_choice}"
    end
end

クラスと属性の作成はもちろんです(Class(一)を参照)、主にchoiceに注目してください.to_numメソッド.まず、ゲーム中の1 v 1の2人のプレイヤーにR/P/Sの3つの選択肢(@player_choice)があり、勝負の判定方法として、@player_choice属性はStringオブジェクトを格納しており,正規表現で2人のプレイヤーの選択を検証することは不可能であり,選択に基づいて勝負結果を出すのは煩雑である.
考えてみれば、2人のプレイヤー@player_チョイス属性が格納されているStringオブジェクトを数値オブジェクト(Numeric)に変換し,ある数式計算でRPSゲームの勝負結果を判定すると,より簡便になる.
コードのchoice_が得られましたto_numメソッド.プレイヤーの選択(Stringオブジェクト)を数値(Numericオブジェクト)に関連付けます.
三、コンピュータープレイヤー類(CompInGame)
comp_in_game.rb
require_relative 'player_in_game'

class CompInGame < PlayerInGame

    def initialize(name, player_choice)
        super(name, player_choice)
    end

    def num_to_choice
        if player_choice == 0
            return "rock"
        elsif player_choice == 1
            return "paper"
        elsif player_choice == 2
            return "scissors"
        else
            return "error"
        end
    end

    def to_s
        "#{@name} choice #{self.num_to_choice}"
    end
end

コンピューターとRPSゲームをすると、コンピューターもプレイヤーになります.しかし、コンピューターと人間はいつも違いがあり、一つのカテゴリに置くのは適切ではないようだ.例えば、コンピュータには電力の属性があるかもしれませんが、電力が足りないとゲームを続けることができません.人間のプレイヤーは電力の属性を必要としませんが、両者には共通の属性があります.例えば、@name、@player_choice.だからCompInGame類がありました.これによって新しい概念継承(inheritance)も引き出された.
継承(inheritance)Rubyプログラミング言語の父、松本行弘の継承に対する解釈を見てみましょう.
ソフトウェアの規模が拡大するにつれて、使用するクラスの個数も増加し、その中には性質が似ているクラスもたくさんあります.これは私たちがこれまで何度も強調したDRYの原則に反している.プログラムは繰り返して理解しにくくなります.プログラムを修正するコストも高くなり、生産性が低下します.だから、似たような部分をまとめる方法があるといいですね.継承はこの方法です.具体的には,継承は既存のクラスの性質を維持した上で新しいクラスを生成する方法である.元のクラスを親と呼び,新しく生成されたクラスを子と呼ぶ.子クラスは親クラスのすべてのメソッドを継承し、必要に応じて新しいメソッドを追加することもできます.子クラスは、必要に応じて親クラスから継承する方法を書き換えることもできます.
松本行弘松本行弘のプログラム世界(Kindle Locations 543-548).人民邮电出版社
PS:私のような初心者にもおすすめの『松本行弘のプログラムワールド』は、達人たちへの醍醐味ですが.しかし、個人的な感覚は初心者にとって、ルビーの起源、対象などを紹介することで、勉強を始める過程で良い基礎を築くことができます.
本題に戻り、継承の概念を理解した後、コードに戻ります.サブクラスの作成方法に注目します.前述したように、コンピュータもプレイヤーであり、人間プレイヤーと共通の属性を持っているが、人間プレイヤーとは異なる.では、コンピュータプレイヤークラスがプレイヤークラスであるサブクラスを作成します.以下のようにclass CompInGame < PlayerInGame、すなわち、CompInGameクラスはPlayerInGameクラスから継承されている.CompInGameクラスはPlayerInGameクラスのサブクラスであり、PlayerInGameクラスはCompInGameクラスの親であるとも言える.
次に、キーワードsuperに注目する必要があります.初期化メソッドでsuperを使用します.すなわち、親と同じプロパティを作成します.
def initialize(name, player_choice)
    super(name, player_choice)
end

四、ゲーム類(Game)
game.rb
require_relative 'player_in_game'
require_relative 'comp_in_game'

class Game

    def initialize
        @players_in_game = []
    end

    def read_in_argv(name, player_choice)
        @players_in_game << CompInGame.new("Wall_E", [0, 1, 2].sample)
        @players_in_game << PlayerInGame.new(name, player_choice)
    end

    def to_s
        @players_in_game.each do |player|
            puts "#{player.name}"
        end
    end

    def rps
        20.times { print "=" }
        puts
        puts "#{@players_in_game[0].name} choice #{@players_in_game[0].num_to_choice}."
        puts "#{@players_in_game[1].name} choice #{@players_in_game[1].player_choice}."
        20.times { print "=" }
        puts
        diff = (@players_in_game[0].player_choice - @players_in_game[1].choice_to_num) % 5
        if diff == 4 || diff == 2
            puts "#{@players_in_game[1].name} wins."
        elsif diff == 3 || diff == 1
            puts "#{@players_in_game[0].name} wins."
        else
            puts "Player and Computer tie."
        end
        puts
    end
end

まず、ゲームクラスでプレイヤーインスタンス変数を初期化する必要があることを考慮し、各プレイヤーの@player_choiceで比較します.したがって、@players_を初期化します.in_ゲームインスタンス変数は、ゲームに参加するプレイヤーオブジェクトを格納するために使用され、配列は自然に最適なデータ型である.
第2、def read_in_argv(name, player_choice)の方法.read_in_argvメソッドは,端末入力のパラメータを取得した後,コンピュータプレイヤーオブジェクトを自動的に生成するとともに,端末入力のパラメータに基づいて実写プレイヤーオブジェクトを生成する.2つのプレイヤーオブジェクトを@players_に格納します.in_gameインスタンス変数.
注意したいのはパソコンプレイヤー対象の@プレイヤー_choice属性は、文字列オブジェクトではなく、[0, 1, 2].sampleがランダムに生成した数字を指し、その後、コンピュータプレイヤークラス特有の方法def num_to_choiceを使用して、対応するRock、Paper、Scissorsにデジタルを変換することができる.
PS:@players_in_game << CompInGame.new("Wall_E", [0, 1, 2].sample)に注意してください.80後の学生はWallを覚えていますか.E(ブレイク5号)は?
80年代に人気のロボットコメディーで、最も精密なレーザー兵器を持つロボット「5号」が、短絡的な状況で動物保護に熱心なスティーブンの家に侵入し、人と付き合う過程から人間の知恵を学んだ人間性を描いている.
第3,def rps Gameクラスのrpsメソッドはゲームの核心であり,このメソッドによって勝負を判定するためである.
まず、各プレイヤーの名前(@name)とオプション(@player_choice)を印刷しますが、パソコンプレイヤーの@player_choiceは数字なので、Class CompInGameクラスのdef num_to_choiceメソッドを使用して、数字を対応するRock、Paper、Scissorsオプションに変換する必要があります.
次に、勝負はどう判定しますか?各プレイヤー@player_choiceの属性に対応する数値を減算して余剰演算を行うことで、最後に余剰を求める結果に基づいて条件文を用いて勝負を判定する.
五、試合しよう(annual_rps_match)
annual_rps_match.rb
require_relative 'game'

match = Game.new

puts
STDERR.puts "Processing ARGV data"
match.read_in_argv(ARGV[0], ARGV[1])
match.rps

六、問題
継承を学ぶために、この極めて簡単なRPSゲームを憶測しました.しかし、例えば、範囲外の選択(例えば、宇宙船)を入力すると、エラーが表示されます.RPSゲームをよりよく実現する方法もあるかもしれません.これは通りかかった皆さんにアドバイスをして、私たちは一緒に進歩しなければなりません.
PS:ニューヨークタイムズが提供したじゃんけんロボット.興味のある学生は游ぶことができます!http://www.nytimes.com/interactive/science/rock-paper-scissors.html
初心者(Novice)は拳の習慣に基づいて次の難易度(Veteran)レベルを推測するだけで、20万回以上のハサミ、石、布を集めたデータベースから、あなたの次のステップは何が出るか当ててみてください(5セットを過ぎたら、右上の「See What the Computer is Thinking」をクリックしてコンピュータがどのように推測しているかを見ることができます).