Aller au contenu

le jeu de Sowing

Le cadre

Le jeu de Sowing a été inventé par le mathématicien anglais John Horton Conway, qui l'a décrit en 1994 lors d'un atelier international sur la théorie des jeux combinatoires organisé par le Mathematical Sciences Research Institute (MSRI) à Berkeley, en Californie. Il s'agit d'un jeu de mancala 1 à un tour et à un rang.

Les règles

Un plateau est constitué d'une rangée de pots dans lesquels il y a initialement des graines.

Un plateau de 1x24 avec trois graines dans chaque pot peut être une bonne taille si le jeu est joué par des humains.

  • Deux joueurs se font face,
  • à chaque tour, un joueur :
    • choisit un pot non vide,
    • prend tout ce qu'il y a dans le pot,
    • sème ces graines une à une :
      • vers sa droite, dans les cases suivantes,
      • sans sortir du jeu,
      • et sans finir sur une case vide.
  • Le dernier joueur qui est en mesure de faire un mouvement légal gagne.

Exemples de partie

On modélise le plateau par une liste Python contenant le nombre de graines dans chaque pot.

On désigne par :

  • le joueur Sud : il est en bas de la liste, il joue vers notre droite.
  • le joueur Nord : il est en face, en haut de la liste, il joue vers notre gauche, (mais vers sa droite).

On choisit ici d'étudier toutes les parties où

  • [2, 2, 2, 2] est la condition initiale,
  • Sud commence à jouer.
  • [0, 3, 3, 2] : le joueur Sud a joué à l'indice 0
  • [0, 4, 4, 0] : le joueur Nord ne pouvait jouer qu'à l'indice 3
  • le joueur Sud a perdu, il ne peut plus jouer !

Sud n'aurait pas dû commencer à jouer en 0 !

  • [2, 0, 3, 3] : le joueur Sud a joué à l'indice 1
  • [3, 1, 4, 0] : le joueur Nord ne pouvait jouer qu'à l'indice 3
  • [3, 0, 5, 0] : le joueur Sud ne pouvait jouer qu'à l'indice 1
    • le joueur Nord a perdu, il ne peut plus jouer !

Si le joueur Sud commence en 1, il gagne !

Bilan avec un départ en [2, 2, 2, 2]

Il existe une stratégie gagnante pour le joueur qui commence dans la configuration [2, 2, 2, 2].

Exercice

Coder une fonction un_tour

  • qui prend en paramètres :
    • joueur : ou bien "Sud", ou bien "Nord", ou bien un intrus (à vérifier), le nom du joueur qui joue.
    • plateau : une liste d'entiers naturels qui indique le nombre de graines par pôt.
    • j : un entier, l'indice du coup à jouer, il devrait être positif et valide (à vérifier).
  • et qui, si le coup est valide, renvoie un nouveau plateau à l'issue de ce coup.
  • ou sinon qui provoque une erreur, la première dans l'ordre, parmi :
    1. raise KeyError("Joueur inconnu !") ; seuls "Nord" et "Sud" peuvent jouer.
    2. raise IndexError("Début hors des limites du plateau !") ; indices positifs obligatoires.
    3. raise ValueError("Début sur case vide !") ; interdit, voir règles.
    4. raise IndexError("Sorti du plateau !") ; interdit, voir règles.
    5. raise ValueError("Fin sur une case vide !") ; interdit, voir règles.

👍 On garantit que tableau ne contient que des entiers naturels. (Inutile de le vérifier donc.)

👍 Ne pas avoir peur des tests, il n'est pas nécessaire de comprendre la gestion des erreurs. C'est pourtant, ici, une très bonne occasion de découvrir une manière d'attraper une erreur.

Gestion des erreurs (facultatif)

Il n'est pas ici nécessaire de comprendre (même vaguement) la gestion des erreurs proposées, ni même de les créer. Voici, toutefois, des clés simples pour comprendre les tests.

🐍 Script Python
try:
    instruction_s()
except TrucError:
    action_si_erreur()
else:
    action_si_aucune_erreur()
  • try : On essaie d'exécuter une ou des instruction(s).
  • except TrucError : le cas où une erreur de type Truc est provoquée, on peut alors faire une action dédiée. En effet, le programme ne s'arrête pas ; l'erreur a été attrapée.
  • else : sinon, on peut réagir autrement.

Dans les tests ce cet exercice, on attend que les essais (try) conduisent aux erreurs spécifiques indiquées, et donc aux messages print("OK..."). Entrer dans la clause else n'est pas le comportement attendu.

Dans cet exercice, les différents types d'erreurs utilisés sont :

  • KeyError : une erreur liée à une clé (key).
  • IndexError : une erreur liée à un indice (index).
  • ValueError : une erreur liée à une valeur (value).

Il en existe bien d'autres !

Ainsi, quand votre fonction sera prête, vous aurez la sortie

📤 Sortie
OK. 'Autre' joueur n'a pas été autorisé à jouer.
OK. 'Sud' n'a pas été autorisé à jouer sur une case vide.
OK. 'Sud' n'a pas été autorisé à jouer hors du plateau.
OK. 'Sud' n'a pas été autorisé à jouer en finissant sur une case vide.
OK. 'Sud' n'a pas été autorisé à jouer en sortant du plateau.
Aide
  1. On pourra utiliser le dictionnaire {"Nord": -1, "Sud": +1} pour connaitre la direction dj à prendre sur l'axe. On pourra aussi s'en servir initialement pour tester si un autre joueur tente illégalement de jouer !
  2. On pourra utiliser suite = tableau.copy() pour avoir une copie indépendante à modifier.
  3. On pourra vérifier que le coup est dans les limites du plateau.
  4. Puis qu'on commence sur uen case non vide.
  5. On tentera ensuite de verser les graines dans la bonne direction.
    • si on sort du plateau, il faut le signifier.
    • si on finit sur une case vide également
  6. On renvoie le plateau modifié !
Guide
🐍 Script Python
def un_tour(joueur, tableau, j):
    direction = {"Nord": -1, "Sud": +1}
    if ...:
        raise KeyError("Joueur inconnu !")

    longueur = len(tableau)
    if not(...):
        raise IndexError("Début hors des limites du plateau !")

    suite = tableau.copy()
    nb_graines = ...
    if ...:
        raise ValueError("Début sur case vide !")

    suite[j] = ...
    i = j
    di = direction[...]
    while nb_graines > 0:
        i += di
        if ...:
            raise IndexError("Sorti du plateau !")

        suite[i] = ...
        nb_graines = ...

    if ...:
        raise ValueError("Fin sur une case vide !")

    return ...
###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Entrer ou sortir du mode "deux colonnes"
(Alt+: ; Ctrl pour inverser les colonnes)
Entrer ou sortir du mode "plein écran"
(Esc)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : 5/5
.128013!bv]fx}NK4jht_P).83[pos1càig25/Va0+;9rS7m:l =6-nuek(EFyIéRw,JD{d050:0Y0n0H0B0R0x0S0z0R0H0x0x0T010n0B0v010406050x0X0P0P0H0M0%040N0w0R0X140w0W050F1b1d1f1h190v041q1x051A0F1A1C1x190:0B0d0|0~10120m0B0C0m0R1Q0m0n17050@0c0R0Y1L0 11011P1R1T1R0n1Z1#1X0n0c0w0:1h1Y0M1y0n0m1%1N010f0_0Y0W0H0P0Y010|1k0x0v0H0W120D1X2d2f201)231#2628170a0S0p0M0w0v0w0x0B1n0W0S0=2b0M0M0Y0z2C1q2k0W1y0F1~2P0n1|1{1}0:2m121T0W252z1X1I1K0}1(2Z0B2#0W1^1J1X0v2I1y2N2P2`1a2e2D2+212:0M1e0R170S0y2M2~182}2l301)3234360D392f3b2N2Y013g0H35040S0t3k2O193n3e123q3s0S0k3w3m2~3o3C360E3G3y3I3A3p0w333r360U3N3c2 1M3f3S3h3t0O3X3z3!3B3$3U3t0s3*3P3,3R3T3D0L3=3d3@3K040y0I3|3Z2,3^3%0y381r3a3O3}453 0y3j4a3l4c44313.3s0y3v4i3x3Y3J4n170y3F4r3H4d4m3_4w3M4z4k4u4D403W4G4t3Q4f3)4M3+4e4v403;4R3?4T4J0y3{4X4B3#4J0D424%4l4)3%0D492`4H4O4U0D4h4?4N3~4_4q4|4S4C4:4y514Y533/0D4F564(3-4*4L5c4.5e4:4Q5h4I4:4W5m4^4*4$5q4~4J0t4,2|1D2^1q2)2S0:2W3o0z1^291y5D1B5B5z2|5I0=2_571)0Z170=0f3G4}450+365!523f0f170X0W0o0n0w0X0M5)5U1216040!5^5d3p170l5=0Y5?5~5i015{0Q3G0S5#310c170x2T663o5{0,6b6d3f171:0Y0H0X6j3Q696n5*3B6f041T6h6v3@5{0u6F4e6B2.0n6J215{0e6m4z6c6z60040l6O1)6x6T6o6A176M6Z5`170q6y5_010w170V020C0n0K6/5 0W6B6D6N4z6%68176I726V6~6)0W712|6V6Q6a4G0S7i6U6:0x2i04010*250d0w0B1$1#0S2:0X0d6s0X0S0v0~0n7B0S0A0S0R000B100X1$0:005.2b0X0v2E7C627P5?7I7K7M0W1I0z1$0l013N7j7k6}5X0B2I2K0B1o6|676=040T7|6k170/6+017m17010i3S0:7.776:6#2`7;7}6?850P0B4w856l813Q877o0N0X8c8p177g8h737~0J8l8n408y040h7/7j735W040B5Z6$786163658S6:0w5%042:7c3a8i3o8Z7a8r3~7?7^2L8e5 8g4b7:7:8N170M0^0x0Y8-4e5K0j0Y0%0#2H3S8I5}8=678t010-8V0M0S2.5I0W0W7C0b8d7d8f6-3N068`8T6C1o0C7!5@8X5 7~809D67796C259a850W6q0H1!7B8I6.7h8M6V8O8Q91218+8#0w8%3l735{9b9r5 8m175y8(8C17020R6`9G8B9x6Y9H8*9^9`6{a04O170R9z9B9T8A8^8_7i8{048}7N90a53~5K0(7)0Y0g972w9C9.679,859e0.0)0c1m0S0m3S0{0=0{1T8m7GaH7C7E0H7G6t0S9p9T9u9w6:9O041b2Bak9}8Y179|9?9x6r6t857~0r9N175I0v0%9a9U4?aX7=8#0c0o0Cai2#0x9!1)9Fb73B6g0Xa$8I76av3J618I0e8Laf9X6)8Ra(a 6~b2b40Yb6al459Fa+3l8)3Q9:049=9*7e8zbm8_agai8 ba3p5K0G3r7Pas999c825|ay7n01aAaC0n0S1b9i0z0 1$0d0B2FaUbY6w9t4G9v9WaYbcbeb^6G75a?6XbkbQb9by21bFbH3xa~9I6)c7a*bQaZ9 a}b}a 1Ich7 cj8/2J8;bhb_04bg3a73ck9hc69Vbn6:8O0+1P1#csb0bu0^b5cq6^6`bQcb8Iac4jaecGa 0Bcq0JbB2ObD8.04cpcFbMbo8Pbqa,9sb!c14ecgc9b8a*c)3tcBa7a964aucAbJ04a|c@9E8!bXbraw179-d7b~8PcRa3cU8Gcc5T8?6-cXcdcZce3o8ObOa%db9Ianapar98d6bIc^didJ5 9e1j0M147X7D7F7Hb@cwc2d9aWcZd2a!bd7Gbfc4c$c`6P17blc}128Dd0c+45bF4=adaed$btb3cPbwcq0Vd@73d`d!c!679Yc?bCd$a#d)d-6!c3ehbbdlek7404d:dfa17 e56Ve7en8@cYd#c;dAcjbSbU0YbWdI2O9+dhb#880$2.b+7#5.1$b.8 0Sb;b?9qdjdsdZb{dx3Qdz0?5?1pd;6WefdB4j1q5R0Y2P2@e^5C1J5E2S2U2Q1@1_2S9Q1#2P5D190F0=0@0_0x04.

  1. Mancala : ou jeu de semis, est le nom générique donné à une famille de jeux de société traditionnels principalement joués en Afrique, mais également dans le sud de l'Asie, dans les Caraïbes ainsi que sur la côte est de l'Amérique du Sud.