Identification automatique des prix des parchemins dans Nethack

21

OH DIEUX NON !! Vous ne pouvez pas nous laisser ici avec la poignée de porte! Ce sera nethack partout! - il y a 1j par Geobits

Eh bien, je ne pouvais pas décevoir ...

introduction

(vous pouvez ignorer cette section si vous ne vous souciez pas de l'exposition et / ou si vous souffrez du syndrome d'explosion des onglets )

L'une des mécaniques caractéristiques de Nethack (et Rogue, et des jeux similaires dans le même genre roguelike) est son système d'identification . Au début du jeu, seuls les objets de votre inventaire de départ sont "officiellement identifiés". La grande majorité des autres objets commencent inconnus; par exemple, un "bouclier de réflexion" s'affichera initialement comme un "bouclier en argent poli" avant d'être identifié.

Un "bouclier en argent poli" ne peut être qu'un bouclier de réflexion , mais cela a des conséquences intéressantes dans deux autres cas.

  1. Certains éléments sont différents les uns des autres, mais ont la même "apparence". Par exemple, si vous trouvez une " pierre grise ", cela pourrait être l'une des quatre choses: une pierre de silex (inutile), une pierre de touche (peut être utile), une pierre de charge (qui vous encombrera gravement car elle pèse une tonne et vous ne peut pas le laisser tomber), ou une pierre de chance (extrêmement utile, presque nécessaire pour gagner le jeu).

  2. De nombreux objets (parchemins, baguettes, anneaux, grimoires, certaines armures, etc.) ont une apparence aléatoire. Cela signifie qu'il existe une liste établie d'apparences possibles, par exemple, des potions pourraient avoir; par exemple, [ potion d' or , potion tourbillonnant , potion pétillante , potion rouge pourpre , etc.]. Ces apparences sont ensuite assignées au hasard à ce qu'elles sont réellement ( potion de guérison , potion de paralysie , potion de voir invisible , potion de polymorphe , etc.).

    Ce qui signifie qu'une amulette hexagonale pourrait vous sauver la vie en une partie (amulette de sauvetage) et vous étouffer à mort la prochaine (amulette d'étranglement) .

Naturellement, cela fait de l'identification des éléments une partie critique du jeu. Les articles peuvent être «formellement identifiés», ce qui signifie qu'ils apparaîtront sans ambiguïté comme étant définitivement un certain article (par exemple, toutes les baguettes de bijoux que vous trouverez apparaîtront comme des baguettes de création de monstre ); cela se fait principalement via des parchemins ou des grimoires d'identification. Cependant, ceux-ci sont généralement rares, ce qui nous amène à ...

Identification informelle. Cela signifie que vous êtes à peu près sûr (ou certain) qu'un certain élément non identifié est d'un certain type (ou qu'il ne peut être que l'un de plusieurs types), mais vous ne l'avez pas encore "formellement" identifié. Cela peut être fait via plusieurs méthodes: test de gravure pour les baguettes, test d' évier pour les anneaux, ou, la méthode la plus courante ...

faire défiler le tableau d'identification des prix

... identification des prix ! C'est de cela qu'il s'agit.

En bref, il y a des magasins situés dans les donjons de Doom (oui, les commerçants ont pensé que ce serait une bonne idée de s'installer dans un donjon souterrain; ne demandez pas pourquoi). Dans ces boutiques, vous pouvez acheter et vendre les différents articles que vous rencontrerez lors de vos déplacements. Lors de l'achat ou de la vente d'un article, le commerçant vous indiquera d'abord combien il vous le vendra / vous l'achètera. Étant donné que certains articles sont garantis à des prix spécifiques , vous pouvez l'utiliser pour identifier de manière informelle un certain type d'article.

Certains éléments, comme le rouleau de lumière , sont les seuls à coûter un certain montant, ce qui vous permet de les identifier sans ambiguïté; cependant, la plupart des articles partagent un groupe de prix avec d'autres articles de la même classe, ce qui vous permet uniquement de restreindre les possibilités (ce qui est toujours utile). Cependant, les prix d'achat / vente d'un article sont affectés par un certain nombre de variables (telles que votre stat charisme ). D'où le graphique ci-dessus.

Pourriez-vous dire que j'aime Nethack?

Contribution

L'entrée sera fournie sous la forme d'un jeu (vanilla, 3.4.3) Nethack en cours de lecture:

"For you, most gracious sir; only 177 for this scroll labeled VERR YED HORRE."
--More--

        ------------
        |          .                                        ---------
        |          |                         ----------     |    ^  |
        |          .##       ################.        +#   #.       .#
        |          | #                       |       _|#   #---------#
        |          | ###                   ##.<       |#   ####      #
        |          .#########################----------#      #      #
        ------------   ###     #         ############# #      #      #
           #             #  -----------  #             #      #   ####
         ###             ###|         |###             #      #   #----------
         #                 #.         |#             ### #    #   #|.???????|
        ##                  |         |#             #--------#   #|.??@????|
    ----.----###############.         |#             #|      |#   #-@???????|
    |.......+#              |         |#             #.      |#    ----------
    |.......|               |         .#              |      |#
    |......>|               -----------               |      +#
    ---------                                         --------


Wizard the Evoker         St:12 Dx:14 Co:11 In:16 Wi:12 Ch:10  Chaotic
Dlvl:2  $:0  HP:11(11) Pw:0(8) AC:9  Exp:1 T:11

Cela signifie qu'il est garanti d'avoir plusieurs propriétés:

  • Il comportera toujours 24 lignes.

  • Chaque ligne aura toujours 80 caractères ou moins.

  • L'avant-dernière ligne comprendra les " jetons " suivants: le nom et le titre du joueur (sous la forme de " foo the bar "), la liste des attributs (séparés par un seul espace) et l'alignement du joueur ( Légal, Neutre ou Chaotique). Chaque jeton sera séparé par un nombre variable d'espaces. 1

  • La liste des attributs sera toujours St:* Dx:* Co:* In:* Wi:* Ch:*, où un *caractère représente un entier de 3 à 25. 2 (Le point d'intérêt ici est la dernière statistique, Charisma, dont vous avez besoin pour calculer les prix.)

  • La première ligne sera toujours constituée d'un message lié à la boutique (en particulier, le message qui s'affiche lorsque vous achetez ou vendez un article). De plus, cet article est garanti comme étant un seul parchemin non identifié et sans nom. Pour acheter un article, c'est:

    "For you, {TITLE}; only {PRICE} for this scroll labeled {LABEL}."--More--
    

    et pour la vente, c'est:

    {SHK} offers {PRICE} gold pieces for your scroll labeled {LABEL}.  Sell it? [ynaq] (y)
    

    où les "variables" répertoriées dans {curly braces}sont les suivantes:

    • {TITLE}est toujours l'un des « bons », des « honorés », des « plus gracieux » ou des « estimés », concaténés avec « dame » ou « monsieur ».

    • {PRICE} est toujours un entier.

    • {LABEL}sera toujours l'un des éléments suivants ( source ):

      ZELGO MER       JUYED AWK YACC  NR 9             XIXAXA XOXAXA XUXAXA
      PRATYAVAYAH     DAIYEN FOOELS   LEP GEX VEN ZEA  PRIRUTSENIE
      ELBIB YLOH      VERR YED HORRE  VENZAR BORGAVVE  THARR
      YUM YUM         KERNOD WEL      ELAM EBOW        DUAM XNAHT
      ANDOVA BEGARIN  KIRJE           VE FORBRYDERNE   HACKEM MUCHE
      VELOX NEB       FOOBIE BLETCH   TEMOV            GARVEN DEH
      READ ME
      
    • {SHK}sera toujours l'un des éléments suivants ( source ):

      Skibbereen      Ballingeary     Inishbofin      Annootok        Abitibi
      Kanturk         Kilgarvan       Kesh            Upernavik       Maganasipi
      Rath Luirc      Cahersiveen     Hebiwerie       Angmagssalik    Akureyri
      Ennistymon      Glenbeigh       Possogroenoe    Aklavik         Kopasker
      Lahinch         Kilmihil        Asidonhopo      Inuvik          Budereyri
      Kinnegad        Kiltamagh       Manlobbi        Tuktoyaktuk     Akranes
      Lugnaquillia    Droichead Atha  Adjama          Chicoutimi      Bordeyri
      Enniscorthy     Inniscrone      Pakka Pakka     Ouiatchouane    Holmavik
      Gweebarra       Clonegal        Kabalebo        Chibougamau     Lucrezia
      Kittamagh       Lisnaskea       Wonotobo        Matagami        Dirk
      Nenagh          Culdaff         Akalapi         Kipawa
      Sneem           Dunfanaghy      Sipaliwini      Kinojevis
      

    Ce message peut être divisé sur une autre ligne (mais il ne prendra jamais plus de 2 lignes). 3

  • Mis à part les premières lignes, tous les paris sont désactivés sur ce à quoi ressemble le reste de l'écran. Nethack utilise la majorité du jeu de caractères ASCII . La seule chose que vous pouvez supposer en toute sécurité est que l'entrée sera purement ASCII (mais cela n'aura probablement pas d'importance car vous pouvez de toute façon ignorer les lignes 3-22).

Si l'entrée est considérée comme un argument de fonction, elle sera donnée exactement comme indiqué dans l'exemple ci-dessus (séparé par un saut de ligne). Si vous entrez via STDIN, il sera donné comme 24 lignes d'entrée consécutives (encore une fois, comme indiqué ci-dessus). Vous pouvez choisir si vous souhaitez que l'entrée ait ou non une nouvelle ligne de fin. L'entrée est garantie sans espaces de fin.

Sortie

La sortie doit être fournie comme ce que je devrais #namefaire défiler que je viens d'identifier. Le système de nommage que j'utilise (et que j'ai vu d'autres utiliser) est:

  • Si le parchemin est identifié sans ambiguïté comme un certain parchemin (identifier, allumer, enchanter l'arme), #namec'est ça. C'est le cas pour les parchemins des prix de base suivants (vous verrez comment calculer le prix de base ci-dessous): 20 -> identifier, 50 -> léger, 60 -> enchanter l'arme.

  • Sinon, prenez les trois premières lettres de l'apparence du parchemin ou le premier mot s'il contient moins de 3 caractères. Par exemple, ZELGO MERdevient ZEL, VE FORBRYDERNEdevient VE, etc. Concatène avec ceci (un espace, puis) ​​le prix de base du parchemin. Par exemple ELB 300,.

  • Si le prix de base peut être l'une des deux possibilités, je continue généralement d'essayer d'acheter ou de vendre l'article jusqu'à ce que j'obtienne un prix offert qui le place sans ambiguïté dans une certaine fourchette de prix. Cependant, vous ne pouvez pas faire cela dans ce défi, alors séparez simplement les deux prix de base possibles avec une barre oblique ( /). Par exemple HAC 60/80,.

Voici la formule pour convertir le prix de base d'un article en prix qu'on vous propose de l'acheter:

  • commencer par le prix de base de l'article

  • possibilité d'un éventuel "supplément non identifié" de 33%, calculé via price += price / 3

  • une autre chance de 33% de "majoration de ventouse" (ce n'est pas une chance aléatoire en fait, mais pour les besoins de ce défi, elle l'est), calculée de la même manière

  • un modificateur de charisme, qui est appliqué comme suit:

    Ch    3-5     6-7       8-10      11-15  16-17     18        19-25
    Mod   +100%   +50%      +33%      +0%    -25%      -33%      -50%
    Code  p *= 2  p += p/2  p += p/3  ---    p -= p/4  p -= p/3  p /= 2
    

Et voici la formule du prix de base -> prix de vente:

  • commencer par le prix de base de l'article

  • divisez ceci par 2 ou 3 ("normal" ou "balisage de ventouse" respectivement; encore une fois, pas au hasard, mais c'est aux fins de ce défi)

  • possibilité d'une réduction supplémentaire de 25% 4 , calculée viaprice -= price / 4

La division est une division entière, ce qui signifie que le résultat à chaque étape est arrondi. (Source: wiki , et un peu de fouille de code source. Inverser ces formules est votre travail.)

Enfin, voici un graphique ASCII pratique qui montre les prix d'achat possibles (regroupés par stat charisme) et les prix de vente d'un parchemin avec un certain prix de base:

Base  Ch<6          6-7          8-10         11-15        16-17        18           19-25        Sell
20    40/52/68      30/39/51     26/34/45     20/26/34     15/20/26     14/18/23     10/13/17     5/6/8/10
50    100/132/176   75/99/132    66/88/117    50/66/88     38/50/66     34/44/59     25/33/44     12/16/19/25
60    120/160/212   90/120/159   80/106/141   60/80/106    45/60/80     40/54/71     30/40/53     15/20/23/30
80    160/212/282   120/159/211  106/141/188  80/106/141   60/80/106    54/71/94     40/53/70     20/26/30/40
100   200/266/354   150/199/265  133/177/236  100/133/177  75/100/133   67/89/118    50/66/88     25/33/38/50
200   400/532/708   300/399/531  266/354/472  200/266/354  150/200/266  134/178/236  100/133/177  50/66/75/100
300   600/800/1066  450/600/799  400/533/710  300/400/533  225/300/400  200/267/356  150/200/266  75/100/113/150

(Ceci est identique au graphique sur le wiki, sauf qu'il répertorie tous les prix de vente possibles, tandis que le graphique wiki néglige d'inclure deux des quatre prix de vente possibles. Non, je n'ai pas créé ce graphique manuellement; généré avec ce script Ruby .)

Cas de test

Contribution:

"For you, honored sir; only 80 for this scroll labeled LEP GEX VEN ZEA."
--More--                   #                                          #
                      ----------------                              -----
                      |              |              ------------####+   |
      -----           |              -##############+          .#   |   |
      |   .###########|           >  |#           # |          |  ##.   |
      |   |          #------------.---#           ##.          |  # -----
      -+---          ##################             ----.-------###    #
       ####                     ###                     #       #      #
          #                     #                       #     ###      ###
          ###                 ###                       #     #          #
            #                 #                         #   ###     -----|--
       -----.---            ###                     ----+---#       |...@..|
       |       |            #                       |      |#       |???+??|
       |  <    .#          ##                     ##+      |        |+?????|
       |       |#    ------.-------                 |      |        |??]?@?|
       ---------###  |            |                 |      |        --------
            #     #  |            |                 --------
                  ###|            |                       #
                    #+            |
                     --------------

Wizard the Evoker         St:11 Dx:15 Co:9 In:20 Wi:9 Ch:11  Chaotic
Dlvl:7  $:0  HP:11(11) Pw:1(8) AC:9  Exp:1

Sortie: LEP 60/80


Contribution:

"For you, most gracious sir; only 80 for this scroll labeled DAIYEN FOOELS."
--More--                                                             #
                ------------                         -----      -------
 -----          |          |                         |   |      |     |
 |!)%|          |          |     ---------------     |   |     #-     |
 |*[@|          |          .#####|   <         |#####.   |   ###|     |
 |?(?|          ---------.--    #+             |#    |   |   #  |     |
 |[!(|                  ##       |             |#    |   +#### #.     .#
 |.@.|         ##################.             +#    ---.-     #|     |#
 ---|-                ###        ---------------#       ##     #-------#
    ##                #                    ######        #     #       #
     #              ###                         #        #     #       #
     ##             #                           #        #     #       #
  ------        #####                           #        #     #       #
  |    |       -.----                           #        #     #       #
  |    .#####  |^   |                        ####        #     #       #
  |    |    #  |    |          ----          #-----------.---- #       #------
  |    |    ###|    |          |  |          #.      >       | #       #|    |
  ------      #.    |          |  |           |              .##       #|    |
               |    |          ----           |              |         #.    |
               ------                         ----------------          ------

Wizard the Evoker         St:11 Dx:14 Co:16 In:15 Wi:10 Ch:9  Chaotic
Dlvl:6  $:0  HP:11(11) Pw:9(9) AC:9  Exp:1

Sortie: enchant weapon


Contribution:

Aklavik offers 113 gold pieces for your scroll labeled GARVEN DEH.  Sell it?
[ynaq] (y)

     -----      ------                                 ---------      -------
     |   |      |    |                         #     ##.       |      |.?)%/|
     |   |    ##.    |                       -----   # |       |      |.@!=*|
     |<  |    # |    |            #        ##.   .#####+    >  |#    #-.*?@[|
     |   .##### |    |      ------------   # | { |#    |^      |#    #|.=%)+|
     ---.-      |    |      |          .#### |   |#    ---------##   #-------
       ##       -.----     #.          |     |   |#          # ###   #
       #         ########  #|          .##   |   |#            ##    #
     ###                #  #------------ #   -----#          ####    #
     #                  #######          ##########################  #
     #                    #   #                            ###----.--#
     #                    ### #                            # #|     |#
   --.----       ########################################### #.     |#
   |     |       #----------.-#                               |     |#
   |     |       #|          |#                               -------
   |     |       #|          .#
   |     |########|          |
   -------        ------------
                   #    #
Wizard the Evoker         St:9 Dx:14 Co:11 In:19 Wi:10 Ch:12  Chaotic
Dlvl:4  $:0  HP:11(11) Pw:5(9) AC:9  Exp:1 Satiated

Sortie: GAR 300


Contribution:

"For you, good lady; only 67 for this scroll labeled VE FORBRYDERNE."--More--

                                                 -------
                                               ##|     |
  ------------                                 # |     |
  |+[!/!?%[?)|                               ### |     |          --------
  |[)(!/+]?!@|               #               #   |     |        ##+      |
  |.......@..|            --------------   ###   | <   | ##       |      |
  --------+---           #|            |   #     |     |  #       |    > |
          #            ###|            .####     --.----  ###    #-      |
          #            ###.            |           #        #  ###|      |
          #          #### ---.----------           #        ######.      |
          #          ####    ##                    #         ###  --------
          #        ####       #                    #         #
          #        ####       ########################     ###
        ###      ####                            ----+---- #
        #   #    ####                            |       .##
    ----.------####                              |  ^    |
    |         +####                              |    >  |
    |         |                                  | ^     |
    -----------                                  ---------

Wizard the Evoker         St:18 Dx:18 Co:16 In:20 Wi:20 Ch:18  Chaotic
Dlvl:4  $:150 HP:11(11) Pw:5(7) AC:9  Exp:1

Sortie: VE 100


Contribution:

Droichead Atha offers 5 gold pieces for your scroll labeled XIXAXA XOXAXA
XUXAXA.  Sell it? [ynaq] (y)
                                                ------------
                   -----                        |          .#
                   |   .### -----------        #.       {  |#
       -----       |   |  # |         |      ###|          |#
       |   .#     #.   |  # |         |      #  ---------+--#
       |   |    ###-|---    |         .##  ###          ##  #
       |   |    #   # #     |         | #  #            #   #
       |   -#####   #       |         | #### ############   #
       |>  | ##     #       ---------+-  ## -.----------    # ----------
       |   .####    ###             ## #####|          |    # |.*??/?)*|
       -----   #      #             #  #    |          |    # |@*)%!)]%|
               ###    ###         ######    |          |    # |.=)!%*!!|
                 #      #         #  #      |          |    ##+@*[%)(%?|
                 #####################      |          |      |.]?*?)%%|
                    -----+---.----##########.          |      |.%)%!!!%|
                    |            +##        ------------      ----------
                    |    <       |                  #
                    |            |
                    --------------

Wizard the Digger          St:11 Dx:9 Co:14 In:6 Wi:6 Ch:9  Lawful
Dlvl:3  $:0  HP:15(15) Pw:0(1) AC:9  Exp:1

Sortie: identify

(J'ai dû compiler manuellement Nethack avec tous les autres noms de commerçant supprimés car je n'ai pas trouvé de commerçant qui avait un espace à son nom ...)

Règles

  • Il s'agit de , donc le code le plus court en octets montera gagnant.

1: ce n'est pas nécessairement toujours vrai lors d'un jeu Nethack, mais nous supposons cela pour des raisons de simplicité.

2: encore une fois, pas toujours vrai. La force peut être de 18/01 à 18 / **, mais vous n'avez pas besoin de gérer cela.

3: simplifications excessives plus grossières. Par exemple, il est possible pour un commerçant de vous appeler "écume" ou "créature la plus connue et sacrée", mais vous n'avez rien à faire.

4: qu'un joueur intelligent contourne en proposant à plusieurs reprises de vendre l'article jusqu'à ce qu'il reçoive le prix plus élevé.

Poignée de porte
la source
15
Mur de texte sacré!
orlp

Réponses:

10

Javascript (ES6), 1610 724 601 612 419 405 octets

a=>(b=a.match(/(\d+) (g|f).+d (\w{0,3})[\s\S]+h:(\d+)/m),c=+b[4],d=[20,50,60,80,100,200,300].map(e=>(f=e>>1,g=~~(e/3),[e,b[2]=='g'?[g-(g>>2),g,f-(f>>2),f]:[e,e+g,e+g+~~((e+g)/3)].map(h=>c<6?h*2:c<8?h+h>>1:c<11?h+~~(h/3):c<16?h:c<18?h-(h>>2):c<19?h-~~(h/3):h>>1)])).filter(i=>i[1].includes(+b[1])),j={20:'identify',50:'light',60:'enchant weapon'}[d[0][0]],k=b[3]+' '+d[0][0],d.length==1?j||k:k+'/'+d[1][0])

Grand mur de texte, rencontre grand mur de code.

Non golfé

inp => (
    extraction = inp.match(/(\d+) (g|f).+d (\w{0,3})[\s\S]+h:(\d+)/m),

    charisma = +extraction[4],

    allowed = [20, 50, 60, 80, 100, 200, 300].map(base => (
        tmp1 = base >> 1,
        tmp2 = ~~(base / 3),
        [
            base,
            extraction[2] == 'g' ?
                [tmp2 - (tmp2 >> 2), tmp2, tmp1 - (tmp1 >> 2), tmp1]
            :
                [base, base + tmp2, base + tmp2 + ~~((base + tmp2) / 3)].map(val =>
                    charisma < 6 ?
                        val * 2
                    : charisma < 8 ?
                        val + val >> 1
                    : charisma < 11 ?
                        val + ~~(val / 3)
                    : charisma < 16 ?
                        val
                    : charisma < 18 ?
                        val - (val >> 2)
                    : charisma < 19 ?
                        val - ~~(val / 3)
                    : val >> 1
            )
        ]
    )).filter(key => key[1].includes(+extraction[1])),

    name_ = {
        20: 'identify',
        50: 'light',
        60: 'enchant weapon'
    }[allowed[0][0]],

    tmp3 = extraction[3] + ' ' + allowed[0][0],

    allowed.length == 1 ?
        name_ || tmp3
    :
        tmp3 + '/' + allowed[1][0]
)

Exemple

usandfriends
la source
1
C'est un gros tas de scripts.
Fatalize
1
Woah, quelqu'un a finalement répondu à cela? Nice: D
Poignée de porte
@Doorknob Voulant mettre à jour cela depuis un certain temps, j'ai finalement réussi.
usandfriends