Identificazione automatica dei prezzi delle pergamene in Nethack


21

OH DIO NO !! Non puoi lasciarci qui con Doorknob! Sarà nethack dappertutto! - 1 giorno fa di Geobits

Beh, non potevo deludere ...

introduzione

(puoi saltare questa sezione se non ti interessa l'esposizione e / o se hai la sindrome da esplosione di tabulazione )

Uno dei meccanismi caratteristici di Nethack (e Rogue, e giochi simili nello stesso genere roguelike) è il suo sistema di identificazione . All'inizio del gioco, solo gli oggetti nell'inventario iniziale vengono "identificati formalmente". La stragrande maggioranza degli altri oggetti inizia sconosciuta; ad esempio, uno "scudo di riflessione" verrà inizialmente visualizzato come uno "scudo d'argento lucido" prima di essere identificato.

Uno "scudo d'argento lucido" può essere solo uno scudo di riflessione , ma ciò ha conseguenze interessanti in altri due casi.

  1. Alcuni oggetti sono diversi l'uno dall'altro, ma hanno lo stesso "aspetto". Ad esempio, se trovi una " pietra grigia ", potrebbe essere una delle quattro cose: una pietra focaia (inutile), una pietra di paragone (può essere utile), una pietra da carico (che ti graverebbe pesantemente perché pesa una tonnellata e tu non posso lasciarlo cadere) o una pietra della fortuna (estremamente utile, quasi necessaria per vincere la partita).

  2. Molti oggetti (pergamene, bacchette, anelli, libri degli incantesimi, alcune armature, ecc.) Hanno un aspetto casuale. Ciò significa che esiste un elenco prestabilito di possibili apparizioni, diciamo, pozioni potrebbero avere; per esempio, [ pozione d'oro , pozione swirly , pozione gassata , pozione viola-rosso , ecc]. Queste apparenze vengono quindi assegnate casualmente a ciò che sono realmente ( pozione di guarigione , pozione di paralisi , pozione di vedere invisibile , pozione di polimorfo , ecc.).

    Il che significa che un amuleto esagonale potrebbe salvarti la vita in un gioco (amuleto del salvavita) , e soffocarti a morte il successivo (amuleto di strangolamento) .

Naturalmente, ciò rende l'identificazione degli oggetti una parte fondamentale del gioco. Gli oggetti possono essere "identificati formalmente", nel senso che appariranno inequivocabilmente come un certo oggetto (es. Tutte le bacchette ingioiellate che trovi appariranno come bacchette per creare mostri ); questo viene fatto principalmente tramite pergamene o libri degli incantesimi di identificazione. In genere quelli sono scarsi, tuttavia, il che ci porta a ...

Identificazione informale. Ciò significa che sei abbastanza sicuro (o certo) che un determinato oggetto non identificato è di un certo tipo (o che può essere solo uno di diversi tipi), ma non l'hai ancora "formalmente" identificato. Questo può essere fatto attraverso diversi metodi: test di incisione per bacchette, test di affondamento per anelli o, il metodo più comune ...

scorrere il grafico ID prezzo

... identificazione del prezzo ! Questa è la sfida.

In breve, ci sono negozi situati nei sotterranei del destino (sì, i negozianti hanno pensato che sarebbe stata una buona idea aprire un negozio in un sotterraneo sotterraneo; non chiedere perché). In questi negozi, puoi acquistare e vendere i vari articoli che incontri durante i tuoi viaggi. Al momento dell'acquisto o della vendita di un articolo, il negoziante ti dirà per primo quanto lo venderebbe per te. Poiché è garantito che determinati articoli abbiano prezzi specifici , è possibile utilizzarlo per identificare in modo informale un determinato tipo di articolo.

Alcuni oggetti, come il rotolo di luce , sono gli unici elementi che costano un determinato importo, il che consente di identificarli in modo inequivocabile; tuttavia, la maggior parte degli articoli condivide un gruppo di prezzi con altri articoli della stessa classe, il che consente solo di restringere le possibilità (che è ancora utile). Tuttavia, i prezzi di acquisto / vendita di un articolo sono influenzati da una serie di variabili (come la tua statistica Carisma ). Da qui la tabella sopra.

Potresti dire che mi piace Nethack?

Ingresso

L'input verrà fornito come gioco Nethack (vaniglia, 3.4.3) attualmente in corso:

"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

Ciò significa che è garantito avere diverse proprietà:

  • Sarà sempre lungo 24 righe.

  • Ogni riga avrà sempre 80 caratteri o meno di lunghezza.

  • La penultima riga sarà composta dai seguenti " token ": il nome e il titolo del giocatore (nella forma di " foo the bar "), l'elenco degli attributi (separati da un singolo spazio) e l'allineamento del giocatore ( Legale, neutrale o caotico). Ogni token sarà separato da un numero variabile di spazi. 1

  • L'elenco degli attributi sarà sempre St:* Dx:* Co:* In:* Wi:* Ch:*, in cui un *personaggio rappresenta un numero intero compreso tra 3 e 25. 2 (Il punto di interesse qui è l'ultimo stat, Charisma, di cui è necessario calcolare i prezzi.)

  • La prima riga sarà sempre costituita da un messaggio relativo al negozio (in particolare, il messaggio che viene visualizzato quando si acquista o si vende un articolo). Inoltre, questo articolo è garantito per essere un singolo scorrimento, non identificato, senza nome. Per l'acquisto di un articolo, questo è:

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

    e per la vendita, è:

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

    dove le "variabili" elencate in {curly braces}sono le seguenti:

    • {TITLE}è sempre uno di " buono ", " onorato ", " molto gentile " o " stimato ", concatenato con " signora " o " signore ".

    • {PRICE} è sempre un numero intero.

    • {LABEL}sarà sempre uno dei seguenti ( fonte ):

      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}sarà sempre uno dei seguenti ( fonte ):

      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
      

    Questo messaggio può essere diviso su un'altra riga (ma non occuperà mai più di 2 righe). 3

  • A parte le prime righe, tutte le scommesse sono spente su come appare il resto dello schermo. Nethack utilizza la maggior parte del set di caratteri ASCII . L'unica cosa che puoi tranquillamente presumere è che l'ingresso sarà puramente ASCII (tuttavia questo probabilmente non importerà perché puoi comunque scartare le linee 3-22).

Se l'input viene preso come argomento di funzione, verrà fornito esattamente come mostrato nell'esempio sopra (riga separata separata). Se si immette tramite STDIN, verrà fornito come 24 righe consecutive di input (di nuovo, come mostrato sopra). È possibile scegliere se si desidera che l'input abbia una nuova riga finale o meno. È garantito che l'input non abbia spazi finali.

Produzione

L'output dovrebbe essere fornito come quello che dovrei #namescorrere e ho appena identificato il prezzo. Il sistema di denominazione che uso (e che ho visto usare da altri) è:

  • Se la pergamena viene identificata in modo inequivocabile come una certa pergamena (identifica, illumina, incanta l'arma), #nameè quella. Questo è il caso delle pergamene dei seguenti prezzi base (vedrai come calcolare il prezzo base di seguito): 20 -> identifica, 50 -> luce, 60 -> incanta l'arma.

  • Altrimenti, prendi le prime tre lettere dell'aspetto della pergamena o la prima parola se contiene meno di 3 caratteri. Ad esempio, ZELGO MERdiventa ZEL, VE FORBRYDERNEdiventa VE, ecc. Concatena con questo (uno spazio, quindi) il prezzo base della pergamena. Ad esempio ELB 300,.

  • Se il prezzo di base può essere una delle due possibilità, di solito continuo a cercare di acquistare o vendere l'oggetto fino a quando non ottengo un prezzo offerto che lo colloca in modo univoco in una determinata fascia di prezzo. Tuttavia, non puoi farlo in questa sfida, quindi separa i due possibili prezzi base con una barra ( /). Ad esempio HAC 60/80,.

Ecco la formula per convertire il prezzo base di un articolo nel prezzo che ti viene offerto di acquistarlo:

  • inizia con il prezzo base dell'articolo

  • possibilità di un possibile "supplemento non identificato" del 33% calcolato tramite price += price / 3

  • un'altra possibilità di un "markup ventosa" del 33% (questa in realtà non è una casualità, ma ai fini di questa sfida lo è), calcolata allo stesso modo

  • un modificatore di carisma, che viene applicato come segue:

    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
    

Ed ecco la formula per il prezzo base -> prezzo di vendita:

  • inizia con il prezzo base dell'articolo

  • dividerlo per 2 o 3 (rispettivamente "normale" o "markup ventosa"; di nuovo, non casuale, ma è ai fini di questa sfida)

  • possibilità di un'ulteriore riduzione del 25% 4 , calcolata tramiteprice -= price / 4

La divisione è divisione intera, il che significa che il risultato di ogni passaggio viene arrotondato per difetto. (Fonte: wiki e un po 'di ricerca del codice sorgente. Invertire queste formule è il tuo lavoro.)

Infine, ecco un grafico ASCII a portata di mano che mostra i possibili prezzi di acquisto (raggruppati per statistica Carisma) e i prezzi di vendita di una pergamena con un determinato prezzo di 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

(Questo è identico al grafico sul wiki tranne per il fatto che elenca tutti i possibili prezzi di vendita, mentre il grafico del wiki trascura di includere due dei quattro possibili prezzi di vendita. No, non ho creato manualmente quel grafico; generato con questo script Ruby .)

Casi test

Ingresso:

"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

Produzione: LEP 60/80


Ingresso:

"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

Produzione: enchant weapon


Ingresso:

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

Produzione: GAR 300


Ingresso:

"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

Produzione: VE 100


Ingresso:

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

Produzione: identify

(Ho dovuto compilare manualmente Nethack con tutti gli altri nomi di negozianti rimossi perché non riuscivo a trovare un negoziante che avesse uno spazio nel suo nome ...)

Regole


1: questo non è necessariamente sempre vero durante un gioco Nethack, ma assumiamo questo per motivi di semplicità.

2: di nuovo, non sempre vero. La forza può essere dal 18/01 al 18 / **, ma non è necessario gestirla.

3: semplificazioni eccessive più grossolane. Ad esempio, è possibile che un negoziante ti chiami "feccia" o "creatura più rinomata e sacra", ma non devi gestire nulla di tutto ciò.

4: che un giocatore intelligente aggira offrendo ripetutamente di vendere l'oggetto fino a quando non viene dato il prezzo più alto.


15
Sacra parete di testo!
orlp,

Risposte:


10

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

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])

Grande muro di testo, incontra grande muro di codice.

Ungolfed

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]
)

Esempio


1
Questa è una grande pila di sceneggiatura.
Fatalizza il

1
Woah, qualcuno ha finalmente risposto a questo? Bello: D
Maniglia della porta

@Doorknob Volevo aggiornarlo da un po ', finalmente ci sono riuscito.
usandfriends
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.