OH GODS NO!! You can't leave us here with Doorknob! It'll be nethack everywhere! - 1d ago by Geobits
Well, couldn't disappoint...
Introduction
(you can skip this section if you don't care about exposition and/or if you have Tab Explosion Syndrome)
One of the characteristic mechanics of Nethack (and Rogue, and similar games in the same roguelike genre) is its identification system. At the beginning of the game, only items in your starting inventory are "formally identified." The vast majority of other objects start out unknown; for example, a "shield of reflection" will initially display as a "polished silver shield" before it's identified.
A "polished silver shield" can only be a shield of reflection, but this has interesting consequences in two other cases.
Some items are different from each other, but have the same "appearance." For example, if you find a "gray stone," it could be one of four things: A flint stone (useless), a touchstone (can be useful), a loadstone (which will severely encumber you because it weighs a ton and you can't drop it), or a luckstone (extremely helpful, almost necessary for winning the game).
Many items (scrolls, wands, rings, spellbooks, some armor, etc.) have a randomized appearance. What this means is that there is a set list of possible apperances, say, potions could have; for example, [golden potion, swirly potion, fizzy potion, purple-red potion, etc.]. These appearances are then randomly assigned to what they actually are (potion of healing, potion of paralysis, potion of see invisible, potion of polymorph, etc.).
Which means that a hexagonal amulet could save your life in one game (amulet of life saving), and choke you to death the next (amulet of strangulation).
Naturally, this makes identifying items a critical part of the game. Items can be "formally identified," meaning that they will unambiguously show up as definitely being a certain item (ex. all the jeweled wands you find will show up as wands of create monster); this is done primarily via scrolls or spellbooks of identify. Typically those are in short supply, though, which brings us to...
Informal identification. This means that you're pretty sure (or certain) that a certain unidentified item is of a certain type (or that it can only be one of several types), but you haven't "formally" identified it yet. This can be done via several methods: engrave-testing for wands, sink-testing for rings, or, the most common method...
... price identification! Which is what this challenge is about.
In a nutshell, there are shops located throughout the Dungeons of Doom (yes, the shopkeepers thought it'd be a good idea to set up shop in some underground dungeon; don't ask why). In these shops, you can buy and sell the various items that you come across during your travels. When buying or selling an item, the shopkeeper will first tell you how much he would sell it to you / buy it from you for. Since certain items are guaranteed to have specific prices, you can use this to informally identify a certain type of item.
Some items, such as the scroll of light, are the only items to cost a certain amount, which allows you to unambiguously identify them; however, most items share a price group with other items of the same class, which only lets you narrow down the possibilities (which is still useful). However, the buy/sell prices of an item are affected by a number of variables (such as your Charisma stat). Hence the chart above.
Could you tell I like Nethack?
Input
Input will be provided as a (vanilla, 3.4.3) Nethack game currently being played:
"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
This means that it is guaranteed to have several properties:
It will always be 24 lines long.
Each line will always be 80 characters or less in length.
The second-to-last line will consist of the following "tokens": the player's name and title (in the form of "foo the bar"), the list of attributes (separated by a single space), and the player's alignment (Lawful, Neutral, or Chaotic). Each token will be separated by a variable number of spaces.1
The list of attributes will always be
St:* Dx:* Co:* In:* Wi:* Ch:*
, where a*
character represents an integer from 3 to 25.2 (The point of interest here is the last stat, Charisma, which you need to calculate prices.)The first line will always consist of a shop-related message (specifically, the message that is displayed when you are buying or selling an item). Furthermore, this item is guaranteed to be a single, unidentified, unnamed scroll. For buying an item, this is:
"For you, {TITLE}; only {PRICE} for this scroll labeled {LABEL}."--More--
and for selling, it is:
{SHK} offers {PRICE} gold pieces for your scroll labeled {LABEL}. Sell it? [ynaq] (y)
where the "variables" listed in
{curly braces}
are the following:{TITLE}
is always one of "good", "honored", "most gracious", or "esteemed", concatenated with either "lady" or "sir".{PRICE}
is always an integer.{LABEL}
will always be one of the following (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}
will always be one of the following (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
This message may be split onto another line (but it will never take up more than 2 lines).3
Aside from the first few lines, all bets are off as to what the rest of the screen looks like. Nethack uses the majority of the ASCII character set. The only thing that you can safely assume is that the input will be purely ASCII (however this probably won't matter because you can discard lines 3-22 anyway).
If the input is taken as a function argument, it will be given exactly as shown in the example above (newline separated). If you input via STDIN, it will be given as 24 consecutive lines of input (again, as shown above). You may choose whether you want the input to have a trailing newline or not. The input is guaranteed to have no trailing spaces.
Output
Output should be provided as what I should #name
the scroll that I just price-ID'd. The naming system I use (and that I have seen others use) is:
If the scroll is unambiguously identified as a certain scroll (identify, light, enchant weapon),
#name
it that. This is the case for scrolls of the following base prices (you will see how to calculate base price below): 20 -> identify, 50 -> light, 60 -> enchant weapon.Otherwise, take the first three letters of the scroll's appearance, or the first word if it is less than 3 characters. For example,
ZELGO MER
becomesZEL
,VE FORBRYDERNE
becomesVE
, etc. Concatenate with this (a space, and then) the base price of the scroll. For example,ELB 300
.If the base price can be one of two possibilities, I usually keep trying to buy or sell the item until I get an offered price that unambiguously places it into a certain price slot. However, you can't do that in this challenge, so just separate the two possible base prices with a slash (
/
). For example,HAC 60/80
.
Here's the formula for converting the base price of an item into the price you are offered to buy it:
start with the base price of the item
chance of a possible 33% "unidentified surcharge," calculated via
price += price / 3
another chance of a 33% "sucker markup" (this isn't random chance actually, but for the purposes of this challenge it is), calculated the same way
a charisma modifier, which is applied as follows:
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
And here's the formula for base price -> sell price:
start with the base price of the item
divide this by either 2 or 3 ("normal" or "sucker markup" respectively; again, not random, but it is for the purposes of this challenge)
chance of a further 25% reduction4, calculated via
price -= price / 4
The division is integer division, which means the result at each step is rounded down. (Source: wiki, and a bit of source code digging. Reversing these formulas is your job.)
Finally, here's a handy-dandy ASCII chart that shows the possible buy prices (grouped by Charisma stat) and sell prices of a scroll with a certain base price:
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
(This is identical to the chart on the wiki except that it lists all possible sell prices, while the wiki chart neglects to include two of the four possible sell prices. No, I didn't manually make that chart; generated with this Ruby script.)
Test cases
Input:
"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
Output: LEP 60/80
Input:
"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
Output: enchant weapon
Input:
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
Output: GAR 300
Input:
"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
Output: VE 100
Input:
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
Output: identify
(I had to manually compile Nethack with all the other shopkeeper names removed because I couldn't find a shopkeeper who had a space in his name...)
Rules
1: this isn't necessarily always true during a Nethack game, but we assume this for the sake of simplicity.
2: again, not always true. Strength can be 18/01 through 18/**, but you don't need to handle that.
3: more gross oversimplifications. For example, it is possible for a shopkeeper to call you "scum" or "most renowned and sacred creature," but you don't have to handle any of that.
4: which a smart player gets around by repeatedly offering to sell the item until given the higher price.