重み付きじゃんけん

一般に、じゃんけん は、「グーはチョキに勝ち、チョキはパーに勝ち、パーはグーに勝つ」。そして、もう一つ重要なことは、どんな勝ち方でも、1勝とカウントされることだ。

しかし、現実において、同じ勝利でも、その1つの勝利当たりの価値は、勝ち方によって異なるのが大半だ。大差をつけて楽に勝つより、接戦の末、逆転サヨナラ勝ちの方が、勝利の価値は大きい。

というわけで、じゃんけんに勝ち方に応じて、点数をつけて見た。その前に、Rock、Scissor、Paperの頭文字を以降グーチョキパーを表す記号とする。

Rで勝つ→1点

Sで勝つ→2点

Pで勝つ→5点

とする。

合計100回勝負するものとして、あいこならもう一度出せるものとする。

もし、自分の相手が、常にランダムに手を出す(rspすべて1/3の確率で出す)とすると、自分はどうすれば良いか、学習させてみる。

 

import random
def oponent():
  num = random.random()
  if num<1/3:
    return 0
  elif 1/3<=num<2/3:
    return 1
  else:
    return 2
rewards= [1,2,5]
def judge(my_actionoponent_action):
  if my_action == oponent_action:
    return 0
  elif (my_action-oponent_action)%3==2:
    return rewards[my_action]
  else:
    return -rewards[oponent_action]
def get_action(actions):
  num = random.random()
  if num<actions[0]/sum(actions):
    return 0
  elif num>= 1-actions[2]/sum(actions):
    return 2
  else:
    return 1
def learning(alpha):
#  sum_score = 0
#  for j in range(10):
    score = 0
    for i in range(1000):
      while True:
        action = get_action(actions)
        reward = judge(action, oponent())
        if reward != 0:
          break
      actions[action] += alpha*reward
      score += reward
#    sum_score += score
    return score   
% matplotlib inline
import matplotlib.pyplot as plt
actions = [100,100,100]
x = [for i in range(100)]
y = [learning(i) for i in range(100)]
z = [learning(i)]


print(sum(y)/len(y))
plt.plot(x, y)

 

1000回勝負させてみた時、横軸は学習のしやすさに関するパラメータα、横軸は1000回勝負したときの相対的な点差。

f:id:medical-science:20210827154750p:plain

およそ1500くらいにとどまる。これは、常にパーを出す戦略の時の期待値である。実際に、α=20の時の、それぞれの重みは、-9, 4494, 7529199となり、圧倒的にパーを出している。

よって、期待値の計算通り、相手が何も考えない人(失礼)の時は、パーを出していこう。