Modifier eval: Difference between revisions

From Kolmafia
Jump to navigation Jump to search
imported>Heeheehee
m "special" no longer true -- div-by-zero now throws an error instead of generating NaN (or possibly +/- infinity).
imported>Zarqon
m updated from documentation in mafia source
 
(One intermediate revision by one other user not shown)
Line 15: Line 15:
}}|
}}|


function_description= Evaluates an expression in the format used by variable modifiers:
function_description= Evaluates an expression in the format used by variable modifiers.  The following was copied from http://sourceforge.net/p/kolmafia/code/HEAD/tree/src/data/modifiers.txt :


* No spaces are allowed within the expression, except as part of a zone/location name.
* No spaces are allowed within the expression, except as part of a zone/location name.
* + - * / ( ) have their usual mathematical meaning and precedence.
* + - * / ( ) have their usual mathematical meaning and precedence.
* ^ is exponentiation, with the highest precedence.
* ^ is exponentiation, with the highest precedence.
* Functions available: ceil(x) floor(x) sqrt(x) min(x,y) max(x,y)
* Functions available:
* Location functions: loc(text) zone(text)
** ceil(x) floor(x) sqrt(x) min(x,y) max(x,y) abs(x)
** These have a value of 1 if the current adventure location or zone contains the specified text, 0 elsewhere.
* Location functions: loc(text) zone(text) env(text)
** These have a value of 1 if the current adventure location, zone, or environment contains the specified text, 0 elsewhere.
* Path function: path(text)
** This has a value of 1 if the player's path matches the text.
* Familiar function: fam(text)
* Familiar function: fam(text)
** This has a value of 1 if the player's familiar type contains the text, else 0.
** This has a value of 1 if the player's familiar type contains the text, else 0.
* Weapon function: mainhand(text)
** This has a value of 1 if the player's mainhand weapon class (sword, club, etc.) contains the text.
* Preferences function: pref(text)
* Preferences function: pref(text)
** This must be used on preferences with a float value ONLY - merely retrieving an integer pref will corrupt it!
** Returns the value of the specified preference
* There could be at most one of each text function in an expression.
*            function: pref(text,compare)
** This is no longer the case however and multiple of the same text functions should now work properly.
** Returns 1 if the specified preference is equal to "compare", otherwise 0
* All upper-case letters are reserved for internally-used variables. The available variables are:
* Effect function: effect(text)
** A - number of Ascensions
** This returns the number of turns remaining of the effect uniquely matching text.
** B - Blood of Wereseal effect
* Resistance function: res(text)
** C - Clancy's level
** This returns the number of resistance levels for the listed element
** D - Drunkenness
* Class function: class(text)
** E - active (nonintrinsic) Effects
** This has a value of 1 if the player's class matches the text.
** F - Fullness
* Skill function: skill(text)
** G - Grimace darkness (0..5)
** This has a value of 1 if the player has the skill matching the text.
** H - Hobo Power
* Upper-case letters are varying values:
** J - 1 on Festival of Jarlsberg, 0 otherwise
** A - number of Ascensions
** L - player Level
** B - Blood of Wereseal effect
** M - total Moonlight (0..9)
** C - Clancy's level
** R - Reagent potion duration
** D - Drunkenness
** S - Spleenness
** E - active (nonintrinsic) Effects
** T - Turns remaining of this effect
** F - Fullness
** U - telescope Upgrades
** G - Grimace darkness (0..5)
** W - familiar Weight
** H - Hobo Power
** X - gender (-1=male, 1=female)
** I - Disco Momentum
** J - 1 on Festival of Jarlsberg, 0 otherwise
** K - Smithsness
** L - player Level
** M - total Moonlight (0..9)
** N - AudieNce
** P - Pasta Thrall level
** R - Reagent potion duration
** S - Spleenness
** T - Turns remaining of this effect
** U - telescope Upgrades
** W - familiar Weight
** X - gender (-1=male, 1=female)
** Y - furY
 
* This wrapper allows user-defined variables to be used as well, which must have names starting with a lower-case letter (or underscore) to distinguish them from built-in variables.  Variables are supplied as a float[string] map.
* This wrapper allows user-defined variables to be used as well, which must have names starting with a lower-case letter (or underscore) to distinguish them from built-in variables.  Variables are supplied as a float[string] map.
 |
 |
Line 52: Line 71:
code1={{CodeSample|
code1={{CodeSample|
title=Code Sample|
title=Code Sample|
description=This script expands modifier_eval() to include support for user-defined variables. It is extremely complex, but it is extremely useful to anyone who wants to use modifier_eval().|
description=This script expands modifier_eval() to include support for user-defined variables. It is a bit complex, but it is extremely useful to anyone who wants to use modifier_eval().|
code=
code=
<syntaxhighlight>
<syntaxhighlight>

Latest revision as of 16:01, 5 June 2015

Function Syntax

float modifier_eval(string expression )

  • expression is a mathematical expression to be solved.

Evaluates an expression in the format used by variable modifiers. The following was copied from http://sourceforge.net/p/kolmafia/code/HEAD/tree/src/data/modifiers.txt :

  • No spaces are allowed within the expression, except as part of a zone/location name.
  • + - * / ( ) have their usual mathematical meaning and precedence.
  • ^ is exponentiation, with the highest precedence.
  • Functions available:
    • ceil(x) floor(x) sqrt(x) min(x,y) max(x,y) abs(x)
  • Location functions: loc(text) zone(text) env(text)
    • These have a value of 1 if the current adventure location, zone, or environment contains the specified text, 0 elsewhere.
  • Path function: path(text)
    • This has a value of 1 if the player's path matches the text.
  • Familiar function: fam(text)
    • This has a value of 1 if the player's familiar type contains the text, else 0.
  • Weapon function: mainhand(text)
    • This has a value of 1 if the player's mainhand weapon class (sword, club, etc.) contains the text.
  • Preferences function: pref(text)
    • Returns the value of the specified preference
  • function: pref(text,compare)
    • Returns 1 if the specified preference is equal to "compare", otherwise 0
  • Effect function: effect(text)
    • This returns the number of turns remaining of the effect uniquely matching text.
  • Resistance function: res(text)
    • This returns the number of resistance levels for the listed element
  • Class function: class(text)
    • This has a value of 1 if the player's class matches the text.
  • Skill function: skill(text)
    • This has a value of 1 if the player has the skill matching the text.
  • Upper-case letters are varying values:
    • A - number of Ascensions
    • B - Blood of Wereseal effect
    • C - Clancy's level
    • D - Drunkenness
    • E - active (nonintrinsic) Effects
    • F - Fullness
    • G - Grimace darkness (0..5)
    • H - Hobo Power
    • I - Disco Momentum
    • J - 1 on Festival of Jarlsberg, 0 otherwise
    • K - Smithsness
    • L - player Level
    • M - total Moonlight (0..9)
    • N - AudieNce
    • P - Pasta Thrall level
    • R - Reagent potion duration
    • S - Spleenness
    • T - Turns remaining of this effect
    • U - telescope Upgrades
    • W - familiar Weight
    • X - gender (-1=male, 1=female)
    • Y - furY
  • This wrapper allows user-defined variables to be used as well, which must have names starting with a lower-case letter (or underscore) to distinguish them from built-in variables. Variables are supplied as a float[string] map.

 

Code Sample

This script expands modifier_eval() to include support for user-defined variables. It is a bit complex, but it is extremely useful to anyone who wants to use modifier_eval().

float eval(string expr, float[string] vars) {
   buffer b;
   matcher m = create_matcher( "\\b[a-z_][a-zA-Z0-9_]*\\b", expr );
   while (m.find()) {
      string var = m.group(0);
      if (vars contains var) {
         m.append_replacement(b, vars[var].to_string());
      }
      // could implement functions, pref access, etc. here
   }
   m.append_tail(b);
   return modifier_eval(b.to_string());
}

# Everything below this line shows how to make use of eval().
# TESTING:

float[string] v;
v["pi"] = 3.14159265;
v["ten"] = 10;
print(eval("2+3", v));
print(eval("max(pi^ten,ten^pi)", v));
print(eval("sqrt(pi)*L", v));
print(eval("undefined/2", v));