Angband Forums Blows tables
 Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 September 20, 2018, 19:26 #1 wobbly Veteran   Join Date: May 2012 Location: Adelaide, Australia Posts: 1,608 Blows tables Someone asked, so here they are. These are all from player-calcs.c, the multipliers & minimum weight are in class.txt As you can see there are instructions to read it, though how easy they are to follow... Code: ```/** * This table is used to help calculate the number of blows the player can * make in a single round of attacks (one player turn) with a normal weapon. * * This number ranges from a single blow/round for weak players to up to six * blows/round for powerful warriors. * * Note that certain artifacts and ego-items give "bonus" blows/round. * * First, from the player class, we extract some values: * * Warrior --> num = 6; mul = 5; div = MAX(30, weapon_weight); * Mage --> num = 4; mul = 2; div = MAX(40, weapon_weight); * Priest --> num = 4; mul = 3; div = MAX(35, weapon_weight); * Rogue --> num = 5; mul = 4; div = MAX(30, weapon_weight); * Ranger --> num = 5; mul = 4; div = MAX(35, weapon_weight); * Paladin --> num = 5; mul = 5; div = MAX(30, weapon_weight); * (all specified in class.txt now) * * To get "P", we look up the relevant "adj_str_blow[]" (see above), * multiply it by "mul", and then divide it by "div", rounding down. * * To get "D", we look up the relevant "adj_dex_blow[]" (see above). * * Then we look up the energy cost of each blow using "blows_table[P][D]". * The player gets blows/round equal to 100/this number, up to a maximum of * "num" blows/round, plus any "bonus" blows/round. */ static const int blows_table[12][12] = { /* P */ /* D: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11+ */ /* DEX: 3, 10, 17, /20, /40, /60, /80, /100,/120,/150,/180,/200 */ /* 0 */ { 100, 100, 95, 85, 75, 60, 50, 42, 35, 30, 25, 23 }, /* 1 */ { 100, 95, 85, 75, 60, 50, 42, 35, 30, 25, 23, 21 }, /* 2 */ { 95, 85, 75, 60, 50, 42, 35, 30, 26, 23, 21, 20 }, /* 3 */ { 85, 75, 60, 50, 42, 36, 32, 28, 25, 22, 20, 19 }, /* 4 */ { 75, 60, 50, 42, 36, 33, 28, 25, 23, 21, 19, 18 }, /* 5 */ { 60, 50, 42, 36, 33, 30, 27, 24, 22, 21, 19, 17 }, /* 6 */ { 50, 42, 36, 33, 30, 27, 25, 23, 21, 20, 18, 17 }, /* 7 */ { 42, 36, 33, 30, 28, 26, 24, 22, 20, 19, 18, 17 }, /* 8 */ { 36, 33, 30, 28, 26, 24, 22, 21, 20, 19, 17, 16 }, /* 9 */ { 35, 32, 29, 26, 24, 22, 21, 20, 19, 18, 17, 16 }, /* 10 */ { 34, 30, 27, 25, 23, 22, 21, 20, 19, 18, 17, 16 }, /* 11+ */ { 33, 29, 26, 24, 22, 21, 20, 19, 18, 17, 16, 15 }, /* DEX: 3, 10, 17, /20, /40, /60, /80, /100,/120,/150,/180,/200 */``` Code: ```/** * Stat Table (STR) -- help index into the "blow" table */ const int adj_str_blow[STAT_RANGE] = { 3 /* 3 */, 4 /* 4 */, 5 /* 5 */, 6 /* 6 */, 7 /* 7 */, 8 /* 8 */, 9 /* 9 */, 10 /* 10 */, 11 /* 11 */, 12 /* 12 */, 13 /* 13 */, 14 /* 14 */, 15 /* 15 */, 16 /* 16 */, 17 /* 17 */, 20 /* 18/00-18/09 */, 30 /* 18/10-18/19 */, 40 /* 18/20-18/29 */, 50 /* 18/30-18/39 */, 60 /* 18/40-18/49 */, 70 /* 18/50-18/59 */, 80 /* 18/60-18/69 */, 90 /* 18/70-18/79 */, 100 /* 18/80-18/89 */, 110 /* 18/90-18/99 */, 120 /* 18/100-18/109 */, 130 /* 18/110-18/119 */, 140 /* 18/120-18/129 */, 150 /* 18/130-18/139 */, 160 /* 18/140-18/149 */, 170 /* 18/150-18/159 */, 180 /* 18/160-18/169 */, 190 /* 18/170-18/179 */, 200 /* 18/180-18/189 */, 210 /* 18/190-18/199 */, 220 /* 18/200-18/209 */, 230 /* 18/210-18/219 */, 240 /* 18/220+ */ };``` Code: ```/** * Stat Table (DEX) -- index into the "blow" table */ static const int adj_dex_blow[STAT_RANGE] = { 0 /* 3 */, 0 /* 4 */, 0 /* 5 */, 0 /* 6 */, 0 /* 7 */, 0 /* 8 */, 0 /* 9 */, 1 /* 10 */, 1 /* 11 */, 1 /* 12 */, 1 /* 13 */, 1 /* 14 */, 1 /* 15 */, 1 /* 16 */, 2 /* 17 */, 2 /* 18/00-18/09 */, 2 /* 18/10-18/19 */, 3 /* 18/20-18/29 */, 3 /* 18/30-18/39 */, 4 /* 18/40-18/49 */, 4 /* 18/50-18/59 */, 5 /* 18/60-18/69 */, 5 /* 18/70-18/79 */, 6 /* 18/80-18/89 */, 6 /* 18/90-18/99 */, 7 /* 18/100-18/109 */, 7 /* 18/110-18/119 */, 8 /* 18/120-18/129 */, 8 /* 18/130-18/139 */, 8 /* 18/140-18/149 */, 9 /* 18/150-18/159 */, 9 /* 18/160-18/169 */, 9 /* 18/170-18/179 */, 10 /* 18/180-18/189 */, 10 /* 18/190-18/199 */, 11 /* 18/200-18/209 */, 11 /* 18/210-18/219 */, 11 /* 18/220+ */ };```
 September 23, 2018, 15:22 #2 gglibertine Adept     Join Date: Dec 2007 Location: Chesterfield, UK Age: 51 Posts: 132 Thanks for posting. I'm going to enlist my husband (who does code) to help me decipher this.
September 23, 2018, 20:19   #3
AnonymousHero
Veteran

Join Date: Jun 2007
Posts: 1,365
Quote:
 Originally Posted by gglibertine Thanks for posting. I'm going to enlist my husband (who does code) to help me decipher this.
I hope he has the patience of a saint because it's infuriatingly indirect. Yes, it's "only" two levels at first sight, but then you realize that there are the two dimensions of STR/DEX... The quickest way (for me) was honestly just putting DEX+STR + the tables into a spreadsheet and doing the weird "indexing dance" from there. (That doesn't help you optimize, directly, but at least you can do hypotheticals pretty easily.)

This mess could really stand to be simplified, especially given that these numbers seem quite arbitrary. (Of course, it might have been originally derived from a function, but saved as concrete numbers. Even if it happened in the 1980s I'm not sure if there's any excuse for not just having that in the code and pre-computing the tables on startup, so this parenthetical hypothesis seems kind of dubious...)

September 27, 2018, 11:37   #4
Werbaer

Join Date: Aug 2014
Posts: 101
Quote:
 Originally Posted by AnonymousHero This mess could really stand to be simplified, especially given that these numbers seem quite arbitrary. (Of course, it might have been originally derived from a function, but saved as concrete numbers.
Edit: Disregard this comment. As wobbly pointed out, i looked at the wrong table.

Comment from an old version:
Code:
``` * This table allows quick conversion from "speed" to "energy"
* The basic function WAS ((S>=110) ? (S-110) : (100 / (120-S)))
* Note that table access is *much* quicker than computation.
*
* Note that the table has been changed at high speeds.  From
* "Slow (-40)" to "Fast (+30)" is pretty much unchanged, but
* at speeds above "Fast (+30)", one approaches an asymptotic
* effective limit of 50 energy per turn.```

Last edited by Werbaer; September 27, 2018 at 11:56.

 September 27, 2018, 11:46 #5 wobbly Veteran   Join Date: May 2012 Location: Adelaide, Australia Posts: 1,608 That's the speed tables isn't it? A different table for showing how much energy you gain/turn at various speeds.
 September 27, 2018, 15:31 #6 Derakon Prophet     Join Date: Dec 2009 Posts: 8,469 Ahh, the days when the performance implications of table lookup vs. doing division was an issue that deserved serious consideration.
 September 27, 2018, 19:28 #7 wobbly Veteran   Join Date: May 2012 Location: Adelaide, Australia Posts: 1,608 Perhaps an example is helpful? A human warrior with recommended stats: 18/20 str 18/20 dex dagger weight is 12 deci-pounds, however Min warrior weight for calculations is 30. warrior class multiplier = 5 Looking up 18/20 dex in the 3rd table (dex index) we get 3. That is the column number. Looking at table 1, column 3 you will see it's actually got 18/20 dex written on it. Looking up 18/20 str in the 2nd table we get 40. 40 x 5 = 200 ( adj_str x class multiplier) 200 / 30 = 6.66 (adj_str x class multiplier / weapon weight) we round down - row 6 reading column 3, row 6 we get 33. This is energy/blow. 3 blows would take 99 energy. You get your turn when energy reaches 100 (You & all monsters gain energy every "game tick" depending on speed, this is the table Werbaer mentioned). So our warrior gets 3 blows spending 99 energy then waits for his/her energy to reach 100 again. If he/she kills something with 2 blows he/she spends 66 energy instead (I believe you don't get the final blow till you reach 100 again but would have to check) Note 1.5 blows (66 energy/turn) technically means 1 blow costing 66 energy. If you were dead on 100 energy, you'd hit once and spend 66 leaving 34 energy. You would then reach 100 energy (your next turn) sooner. Last edited by wobbly; September 27, 2018 at 19:37.
September 27, 2018, 23:13   #8
Pete Mack
Prophet

Join Date: Apr 2007
Location: Seattle, WA
Posts: 4,909
Donated: \$40
I am not convinced that floating point would be better here: integer arithmetic has no pesky round-off issues, and working by percentages is certainly no real problem conceptually.

Quote:
 Originally Posted by Derakon Ahh, the days when the performance implications of table lookup vs. doing division was an issue that deserved serious consideration.

 Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 Thread Tools Display Modes Linear Mode

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is Off Forum Rules
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home Angband     AAR     Vanilla     Development     ToME     Sil     Variants     Competition The real world     Idle chatter     Oook! Obsolete     v4

 Similar Threads Thread Thread Starter Forum Replies Last Post Sky Vanilla 3 December 18, 2017 00:42 Therem Harth Development 3 January 20, 2015 13:09 Old Coach v4 8 January 30, 2012 15:16 dhegler Development 3 April 21, 2011 21:46 buzzkill Vanilla 25 February 22, 2011 18:58

All times are GMT +1. The time now is 07:33.