# Strategy パターン # # Java言語で学ぶデザインパターンと同様の例題をRubyで記述した。 # # coded by Takehiro Kaga # class JankenHand @@name = ["グー", "チョキ", "パー"] def initialize(handvalue) @handvalue = handvalue @name = @@name[handvalue] end def value @handvalue end def name @name end def isStrongerThan(handH) # selfがhandHよりも強いときtrue fight(handH) == 1 end def isWeekerThan(handH) # selfがhandHよりも弱いときtrue fight(handH) == -1 end def fight(handH) if self == handH return 0 elsif (self.value + 1) % 3 == handH.value return 1 else return -1 end end end class Hand < JankenHand @@handvalue_guu = 0 @@handvalue_cho = 1 @@handvalue_paa = 2 @@hand = [JankenHand.new(@@handvalue_guu), JankenHand.new(@@handvalue_cho), JankenHand.new(@@handvalue_paa)] def initialize end def getHand(handvalue) # 値からインスタンスを得る @hand = @@hand[handvalue] end end # kaga = Hand.new # kagaHand = kaga.getHand(1) # puts kagaHand.name # puts kagaHand.value.to_s # you = Hand.new # youHand = you.getHand(2) # ans = kagaHand.isStrongerThan(youHand) # puts ans.to_s class Strategy def nextHand end def study(win) end end class WinningStrategy < Strategy def initialize @won = false end def nextHand if !@won @prevHand = Hand.new.getHand(rand(3)) end @prevHand end def study(win) @won = win end end class ProbStrategy < Strategy def initialize @prevHandValue = 0 @currentHandValue = 0 @history = [[1,1,1],[1,1,1],[1,1,1]] end def nextHand bet = rand(getSum(@currentHandValue)) handvalue = 0 if bet < @history[@currentHandValue][0] handvalue = 0 elsif bet < @history[@currentHandValue][0] + @history[@currentHandValue][1] handvalue = 1 else handvalue = 2 end @prevHandValue = @currentHandValue @currentHandValue = handvalue Hand.new.getHand(handvalue) end def getSum(hv) sum = 0 for i in 0..2 sum += @history[hv][i] end sum end def study(win) if win @history[@prevHandValue][@currentHandValue] += 1 else @history[@prevHandValue][(@currentHandValue + 1) % 3] += 1 @history[@prevHandValue][(@currentHandValue + 2) % 3] += 1 end end end class Player def initialize(name, strategy) @name = name @strategy = strategy @wincount = 0 @losecount = 0 @gamecount = 0 end def nextHand @strategy.nextHand end def win @strategy.study(true) @wincount += 1 @gamecount += 1 end def lose @strategy.study(false) @losecount += 1 @gamecount += 1 end def even @gamecount += 1 end def name @name end def toString "[" + @name + ":" + @gamecount.to_s + " games, " + @wincount.to_s + " win, " + @losecount.to_s + " lose" + "]" end end # --- Main --- # player1 = Player.new("Taro", WinningStrategy.new) player2 = Player.new("Hana", ProbStrategy.new) for i in 1..10000 nextHand1 = player1.nextHand nextHand2 = player2.nextHand if nextHand1.isStrongerThan(nextHand2) puts "Winner: " + player1.toString player1.win player2.lose elsif nextHand2.isStrongerThan(nextHand1) puts "Winner: " + player2.toString player2.win player1.lose else puts "Even..." player1.even player2.even end end puts "Total result:" puts " " + player1.toString puts " " + player2.toString