Deutsch   English   Français   Italiano  
<tk649a$1aau$1@cabale.usenet-fr.net>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!2.eu.feeder.erje.net!3.eu.feeder.erje.net!feeder.erje.net!weretis.net!feeder8.news.weretis.net!proxad.net!feeder1-2.proxad.net!usenet-fr.net!.POSTED!not-for-mail
From: Olivier Miakinen <om+news@miakinen.net>
Newsgroups: fr.rec.jeux.enigmes
Subject: Re: F-Nim
Date: Sat, 5 Nov 2022 17:50:50 +0100
Organization: There's no cabale
Lines: 142
Message-ID: <tk649a$1aau$1@cabale.usenet-fr.net>
References: <titnme$31k8$1@cabale.usenet-fr.net>
 <tj0564$tm9$1@cabale.usenet-fr.net> <tk2qvq$vs$1@gioia.aioe.org>
 <tk63c3$1a60$1@cabale.usenet-fr.net>
NNTP-Posting-Host: 220.12.205.77.rev.sfr.net
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit
X-Trace: cabale.usenet-fr.net 1667667050 43358 77.205.12.220 (5 Nov 2022 16:50:50 GMT)
X-Complaints-To: abuse@usenet-fr.net
NNTP-Posting-Date: Sat, 5 Nov 2022 16:50:50 +0000 (UTC)
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101
 Firefox/52.0 SeaMonkey/2.49.4
In-Reply-To: <tk63c3$1a60$1@cabale.usenet-fr.net>
Bytes: 5708

Le 05/11/2022 17:35, je répondais à Jacques Mathon :
> 
> Au début du jeu, le programme demande de choisir un pourcentage. Supposons
> que j'aie choisi 80. Alors le programme avant de jouer commence à tirer au
> hasard un nombre entre 0 et 100. Si ce nombre est inférieur à 80, alors il
> applique la stratégie optimale pour ce coup. Sinon, il joue un nombre tiré
> au hasard entre 1 et le maximum permis (quand même plus petit que le tiers
> du nombre restant si c'est possible).
> 
>> Question subsidiaire: n est-il borné ?
> 
> Non. La stratégie est valable quel que soit N. D'ailleurs Python ne limite
> la taille des entiers que selon la taille mémoire disponible, ce qui fait
> qu'en pratique il n'y a pas vraiment de limite pour une partie de durée
> raisonnable.


Je vais donner ci-dessous le programme en Python (presque complet).


La partie du programme qui réalise la stratégie optimale est la fonction
'choix(have, maxi)' pour laquelle le paramètre 'have' est le nombre d'objets
restant et le paramètre 'maxi' est le nombre maximum que le programme a le
droit de retirer.

Voici cette fonction, dans laquelle j'ai remplacé les caractères non blancs
de la fin par des '#' :
=============================================================================
def choix(have, maxi):
    while True:
        if have <= maxi:
            return have
        ## # # ## #
        ##### # # #####
            ## # # ## ###
        #### ## #
=============================================================================

Comme vous pouvez le voir, l'algorithme est *trés* court.


Programme complet, modulo les '#' de la fonction 'choix' :
=============================================================================
#!/usr/bin/python3

import random

def choix(have, maxi):
    while True:
        if have <= maxi:
            return have
        ## # # ## #
        ##### # # #####
            ## # # ## ###
        #### ## #

def saisie(message, mini, maxi = 0):
    if maxi <= 0:
        invite = f'{message} (au moins {mini}) ? '
        erreur = f'Vous devez choisir un nombre au moins égal à {mini}.'
    else:
        invite = f'{message} (entre {mini} et {maxi}) ? '
        erreur = f'Vous devez choisir un nombre entre {mini} et {maxi}.'
    result = int(input(invite))
    while result < mini or result > maxi > 0:
        print(erreur)
        result = int(input(invite))
    return result

def premier_a_jouer():
    invite = "Qui commence ?"
    print("Choisissez qui va commencer.")
    print("1 = Vous jouez en premier.")
    print("2 = Vous jouez en deuxième.")
    print("3 = C'est le hasard qui décide.")
    result = saisie("Qui commence", 1, 3)
    if result == 3:
        result = random.randint(1, 2);
    if result == 1:
        print("Et donc vous commencez.")
    else:
        print("Et donc je commence.")
    return result

def joueur_humain(have, maxi):
    print()
    s = "s" if (have > 1) else ""
    print(f"C'est à vous de jouer. Il reste {have} objet{s}.")
    retire = saisie("Combien en retirez-vous", 1, maxi)
    return retire

TRACE_RANDOM = True
def joueur_ordi(have, maxi, percent):
    print()
    s = "s" if (have > 1) else ""
    print(f"C'est à moi de jouer. Il reste {have} objet{s}.")
    if have <= maxi:
        if TRACE_RANDOM: print("Mon choix est évident.")
        return have
    if random.uniform(0, 100) <= percent:
        if TRACE_RANDOM: print("Je joue au mieux.")
        retire = choix(have, maxi)
        if 3*retire < have:
            return retire
    else:
        if TRACE_RANDOM: print("Je joue au hasard.")
    if 3*maxi >= have:
        maxi = int((have-1)/3);
    if maxi <= 1:
        return 1
    return random.randint(1, maxi)

def main():
    print("Bienvenue à F-Nim !")
    have = saisie("Combien d'objets au départ", 2)
    percent = saisie("Pourcentage de fiabilité du programme", 0, 100)
    qui = premier_a_jouer()
    maxi = have - 1

    while have > 0:
        if qui == 1:
            retire = joueur_humain(have, maxi)
            qui = 2
        else:
            retire = joueur_ordi(have, maxi, percent)
            s = "s" if (retire > 1) else ""
            print(f"Je retire {retire} objet{s}.")
            qui = 1
        have = have - retire
        maxi = min(have, 2 * retire)

    if qui == 1:
        print("J'ai gagné !")
    else:
        print("Vous avez gagné !")

main()
=============================================================================


-- 
Olivier Miakinen