Question 1

Le joueur biaisé

1.

\(P^{(A)}\) = (1/4,1/4,1/2) (“Pierre”,“Feuille”,“Ciseaux”)

\(P^{(B)}\) = (1/4,1/4,1/2)

Ici, A et B ont exactement les mêmes probabilités, ainsi B peut espérer gagner autant de fois que A.

p_a = c(1/4,1/4,1/2)
p_b = c(1/4,1/4,1/2)

calcul_resultat = function(adv, joueur){
  if(adv == joueur)
      0
    else if(joueur == (adv%%3) + 1)
      1
    else
      -1
}

victoireB = function(N = 100, p_a, p_b){
  choixA = sample(c(1,2,3), N, replace = T, prob = p_a)
  choixB = sample(c(1,2,3), N, replace = T, prob = p_b)
  resultats = c()
  for(k in 1:N){
      resultats[k] = calcul_resultat(choixA[k], choixB[k])
  }
  resultats/N
}

r = victoireB(1000, p_a, p_b)
sum(r)
## [1] -0.031

On constate qu’avec un grand N l’espérance empirique tend vers 0.

2.

Maintenant \(P^{(B)}\) = (1/3,1/3,1/3)

p_b = c(1/3,1/3,1/3)

r = victoireB(10000, p_a, p_b)
sum(r)
## [1] 0.0045

On remarque que l’espérance est toujours proche de 0. Cela semble normal car même si le joueur fait plus de pierre, pour en profiter il faudrait baiser la probabilité de faire feuille pour gagner contre A.

3.

Les résultats sont présentés sous forme de matrice et non de graphique pour plus de concision.

seq_x = seq(0, 1, by = 0.1)

  for (x in seq_x) {
  resultat = c()
  seq_y = seq(0, 1 - x, by = 0.1)
  
    for (y in seq_y) {
      p_b = c(x, y, 1 - x - y)
      r = victoireB(1000, p_a, p_b)
      resultat[1 + y * 10] = sum(r)
    }
  cat("espérance de y en fonction de x = ", x)
  cat("\n")
  print(resultat)
}
## espérance de y en fonction de x =  0
##  [1] -0.024 -0.038 -0.028 -0.090 -0.078 -0.140 -0.165 -0.182 -0.232 -0.249
## [11] -0.275
## espérance de y en fonction de x =  0.1
##  [1]  0.047  0.006 -0.026 -0.032 -0.057 -0.094 -0.110 -0.115 -0.180 -0.202
## espérance de y en fonction de x =  0.2
## [1]  0.086  0.001  0.009  0.021 -0.059 -0.087 -0.080 -0.161 -0.131
## espérance de y en fonction de x =  0.3
## [1]  0.076  0.062  0.048 -0.004 -0.002 -0.027 -0.095 -0.069
## espérance de y en fonction de x =  0.4
## [1]  0.048  0.067  0.060  0.003  0.004 -0.063 -0.059
## espérance de y en fonction de x =  0.5
## [1] 0.113 0.117 0.107 0.024 0.029 0.001
## espérance de y en fonction de x =  0.6
## [1] 0.171 0.088 0.120 0.020
## espérance de y en fonction de x =  0.7
## [1] 0.173 0.165 0.113
## espérance de y en fonction de x =  0.8
## [1] 0.224 0.185
## espérance de y en fonction de x =  0.9
## [1] 0.225
## espérance de y en fonction de x =  1
## [1] 0.25

Ici, on remarque que plus \(y\) est petit et \(x\) grand, plus l’esperance sera positive. Ici, on atteint au mieux 0,25 d’esperance.

4.

Ainsi la stratégie optimale pour B est de faire le plus de “Pierre” possible, il lui faut donc une probabilité : \(P^{(B)} = (1, 0, 0)\)

5.

Nous allons définir trois événements :

\(x_{1}\) : “Le joueur B gagne cette manche”

\(x_{2}\) : “Il y a égalité pour cette manche”

\(x_{3}\) : “Le joueur B perd cette manche”

Selon les règles du jeu, on a :

\(x_{1}\) = 1

\(x_{2}\) = 0

\(x_{3}\) = -1

Rappelons la formule de l’espérance :

\(E(X) = \sum\limits_{i=1}^3 x_{i} * P(X=x_{i})\)

Or si B joue avec \(P^{(B)} = (x, y, 1-x-y)\), on a :

\(P(X = x_{1}) = P^{(B)}(Pierre) * P^{(A)}(Ciseaux) + P^{(B)}(Feuille) * P^{(A)}(Pierre) + P^{(B)}(Ciseaux) * P^{(A)}(Feuille)\)

\(P(X = x_{1}) = (x * \frac{1}{2} + y * \frac{1}{4} + (1 - x - y) * \frac{1}{4})\)

\(P(X = x_{2}) = (x * \frac{1}{4} + y * \frac{1}{4} + (1 - x - y) * \frac{1}{2})\)

\(P(X = x_{3}) = (x * \frac{1}{4} + y * \frac{1}{2} + (1 - x - y) * \frac{1}{4})\)

En appliquant la formule de l’espérance on obtient :

\(E(X) = 1 * P(X = x_{1}) + 0 * P(X = x_{2}) + (-1) * P(X = x_{3})\)

\(E(X) = \frac{1}{4} * x - \frac{1}{4} * y\)

\(E(X) = \frac{1}{4} * (x - y)\)

Ceci nous confirme bien nos résultats obtenus en question 1. et 2., en effet dans les deux cas \(E(X)=0\) car \(x=y=\frac{1}{4}\) ou bien \(x=y=\frac{1}{3}\).

Nous pouvons en déduire également que pour la stratégie optimale il faut bien avoir x=1 et y=0 et on ne pourra jamais avoir une espérance plus grande que 0,25.

Le joueur non biaisé

p_a = c(1/3,1/3,1/3)
seq_x = seq(0, 1, by = 0.1)

  for (x in seq_x) {
  resultat = c()
  seq_y = seq(0, 1 - x, by = 0.1)
  
    for (y in seq_y) {
      p_b = c(x, y, 1 - x - y)
      r = victoireB(1000, p_a, p_b)
      resultat[1 + y * 10] = sum(r)
    }
  cat("espérance de y en fonction de x = ", x)
  cat("\n")
  print(resultat)
}
## espérance de y en fonction de x =  0
##  [1]  0.013 -0.073 -0.015 -0.002  0.011  0.012  0.019  0.041  0.003 -0.028
## [11]  0.006
## espérance de y en fonction de x =  0.1
##  [1] -0.014 -0.002 -0.002  0.060 -0.045  0.035  0.044  0.006 -0.019  0.021
## espérance de y en fonction de x =  0.2
## [1] -0.028 -0.020 -0.035  0.027  0.022 -0.016 -0.004 -0.039 -0.042
## espérance de y en fonction de x =  0.3
## [1]  0.018 -0.027  0.056  0.004  0.020  0.028 -0.002  0.068
## espérance de y en fonction de x =  0.4
## [1]  0.027 -0.017 -0.006 -0.004 -0.037 -0.051 -0.036
## espérance de y en fonction de x =  0.5
## [1]  0.025  0.024  0.002 -0.002 -0.013  0.011
## espérance de y en fonction de x =  0.6
## [1] 0.034 0.021 0.075 0.008
## espérance de y en fonction de x =  0.7
## [1]  0.027 -0.013  0.001
## espérance de y en fonction de x =  0.8
## [1] -0.007  0.003
## espérance de y en fonction de x =  0.9
## [1] 0.018
## espérance de y en fonction de x =  1
## [1] 0.011

Qu’importe la valeur de x ou y, on remarque que l’espérance est toujours proche de 0 donc un joueur non biaisé ne peut pas gagner ni perdre à long terme.

Question 2 : Apprentissage

1.

Selon le sujet, l’humain maîtrise mal le hasard et n’est pas capable de tenir l’uniformité sur le long terme. Ainsi ses probabilités sont différentes de (1/3,1/3,1/3). Or nous avons montré dans les questions précédentes que lorsqu’un joueur a une probabilité plus forte de jouer un signe plus que les autres, on peut le battre en adaptant notre stratégie. C’est à dire en jouant toujours le signe qui contre le signe le plus probable.

strategie = function(p_adversaire){
  if(p_adversaire[1] >= p_adversaire[2] && p_adversaire[1]>= p_adversaire[3]){
    c(0,1,0)
  }else if(p_adversaire[2] >= p_adversaire[1] && p_adversaire[2]>= p_adversaire[3]){
    c(0,0,1)
  }else{
    c(1,0,0)
  }
}

La fonction stratégie permet de renvoyer la tactique a appliqué en fonction de la fréquence de jeu du joueur adverse.

jeu = function(vrai_p_adv, nb_manches){
  esp = c()
  resultat = 0
  nb_coup_adv = c(0,0,0) #(pierre,feuille,ciseaux)
  p_adversaire = c(1/3,1/3,1/3)
  choixAdversaire = sample(c(1,2,3), nb_manches, replace = T, prob = vrai_p_adv)
  for(i in 1:nb_manches){
    p_ordi = strategie(p_adversaire)
    coup_ordi = sample(c(1,2,3), 1, replace = T, prob = p_ordi)
    resultat = resultat + calcul_resultat(adv = choixAdversaire[i], joueur = coup_ordi)
    nb_coup_adv[choixAdversaire[i]] = nb_coup_adv[choixAdversaire[i]] +1
    p_adversaire = nb_coup_adv/i
    esp[i]= resultat/i
  }
  plot(esp)
  esperance = resultat/nb_manches
  esperance
}


vrai_p_adv = c(1/4,1/4,1/2)
nb_manches = 200

jeu(vrai_p_adv, nb_manches)

## [1] 0.185

On voit bien qu’au cours du temps notre esperance de victoire augmente. On remarque que notre statégie devient efficace et stable au bout d’environs 100 manches. On peut dire ainsi que notre algorithme est capable de “apprendre” les fréquences de jeu au bout de 100 manches.

3.

Malheuresement un humain pas trop bête peut facilement détecter que la machine joue toujours le même coup et la tromper. La meilleure facon de tromper l’humain que nous avons pu imaginer et de garder un tirage aléatoire en partant d’une probabilité (1/3,1/3,1/3) mais en augmentant legerement la probabilité “gagnante” en ne la faisant pas dépasser un certain seuil.

Il faut donc ici changer notre fonction strategie.

strategie2 = function(p_adversaire){
  if(p_adversaire[1] >= p_adversaire[2] && p_adversaire[1]>= p_adversaire[3]){
    c(1/4,1/2,1/4)
  }else if(p_adversaire[2] >= p_adversaire[1] && p_adversaire[2]>= p_adversaire[3]){
    c(1/4,1/4,1/2)
  }else{
    c(1/2,1/4,1/4)
  }
}

jeu2 = function(vrai_p_adv, nb_manches){
  esp = c()
  resultat = 0
  nb_coup_adv = c(0,0,0) #(pierre,feuille,ciseaux)
  p_adversaire = c(1/3,1/3,1/3)
  choixAdversaire = sample(c(1,2,3), nb_manches, replace = T, prob = vrai_p_adv)
  for(i in 1:nb_manches){
    p_ordi = strategie2(p_adversaire)
    coup_ordi = sample(c(1,2,3), 1, replace = T, prob = p_ordi)
    resultat = resultat + calcul_resultat(adv = choixAdversaire[i], joueur = coup_ordi)
    nb_coup_adv[choixAdversaire[i]] = nb_coup_adv[choixAdversaire[i]] +1
    p_adversaire = nb_coup_adv/i
    esp[i]= resultat/i
  }
  plot(esp)
  esperance = resultat/nb_manches
  esperance
}


vrai_p_adv = c(1/4,1/4,1/2)
nb_manches = 1000

jeu2(vrai_p_adv, nb_manches)

## [1] 0.049

4.

Notre algorithme renvoi maintenant une esperance d’environ 0,05. Cette espérance est beaucoup moins bonne que précedemment, mais c’est le prix de la discrétion ;)

Question 3 : Pierre-Papier-Ciseaux-Lézard-Spock

Pour cet exercice il suffit simplement d’adapter le programme en changeant nos vecteur de triplet en cinq-uplet. Les probabilités au hasard passeront donc de 1/3 À 1/5 pour chaque signe.

De plus si l’humain fait plus souvent le ciseaux, il y aura deux méthodes gagnante contre lui, on pourra donc augmenter deux de nos probabilités pour avoir une meilleure espérance de gain sans être détecté par l’humain. Il faudra aussi un peu plus de temps à l’ordinateur pour trouver quel est le signe que l’humain répete le plus.

Pour l’algorithme, il faut augmenter le nombre de sous cas pour calculer les victoires ou défaites.