improve doc, exit codes
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
*.pyc
|
*.pyc
|
||||||
|
README.html
|
||||||
|
|||||||
29
README.adoc
29
README.adoc
@@ -2,3 +2,32 @@
|
|||||||
|
|
||||||
This repository contains scripts for calculating probalities and expected
|
This repository contains scripts for calculating probalities and expected
|
||||||
values for rewards and carves in Monster Hunter games.
|
values for rewards and carves in Monster Hunter games.
|
||||||
|
|
||||||
|
== Dependencies
|
||||||
|
|
||||||
|
Tested using Python 2.7, might work with 2.6. Uses sqlite3, which is part of
|
||||||
|
the standard library now but I'm not sure it's always compiled in by default
|
||||||
|
in all Python distributions (e.g. for Windows or Mac OS X).
|
||||||
|
|
||||||
|
== Example usage
|
||||||
|
|
||||||
|
For a list of quests providing the specified monster part:
|
||||||
|
|
||||||
|
./mhrewards.py "Zinogre Jasper"
|
||||||
|
|
||||||
|
This gives expected values for the item from different sources, including
|
||||||
|
quest rewards, carves, capture, and shiny drops. An expected value of
|
||||||
|
8% means that on average, you would get 8 of the item from 100 quests. Note
|
||||||
|
that this is different from the probability of getting at least one, which
|
||||||
|
will be lower and is a pain to calculate when there can be different number
|
||||||
|
of rewards.
|
||||||
|
|
||||||
|
For more manual calculations, mhprob.py can be used directly. The quest
|
||||||
|
"Plain Dangerous" in 3U has 2 fixed rewards in A, one in B. Diablos hardhorns
|
||||||
|
have a 5% chance:
|
||||||
|
|
||||||
|
./mhprop.py 5 2 3 69
|
||||||
|
./mhprop.py 5 1 1 69
|
||||||
|
|
||||||
|
For great luck, you would replace 69 with 90. The output includes both expected
|
||||||
|
value and probability of getting at least one.
|
||||||
|
|||||||
@@ -106,6 +106,11 @@ def quest_reward_p(reward_percent, min_rewards, max_rewards, extend_percent=69):
|
|||||||
|
|
||||||
|
|
||||||
def reward_expected_c(min_rewards, max_rewards, extend_percent):
|
def reward_expected_c(min_rewards, max_rewards, extend_percent):
|
||||||
|
"""
|
||||||
|
Expected value for number of rewards, if @min_rewards are gauranteed
|
||||||
|
and there is an @extend_percent chance of getting one more each time
|
||||||
|
with at most @max_rewards.
|
||||||
|
"""
|
||||||
total_p = 0.0
|
total_p = 0.0
|
||||||
expected_attempts = 0.0
|
expected_attempts = 0.0
|
||||||
for reward_count in xrange(min_rewards, max_rewards + 1):
|
for reward_count in xrange(min_rewards, max_rewards + 1):
|
||||||
@@ -185,6 +190,7 @@ def carve_delta_expected_c(carve_skill):
|
|||||||
return 1
|
return 1
|
||||||
elif carve_skill == CARVING_SKILL_GOD:
|
elif carve_skill == CARVING_SKILL_GOD:
|
||||||
# Description: Increases the number of carving chances by one (maybe more) and prevents knockbacks while carving.
|
# Description: Increases the number of carving chances by one (maybe more) and prevents knockbacks while carving.
|
||||||
|
# TODO: max 2 and 50% extend is a guess, find the actual values
|
||||||
min_c = 1
|
min_c = 1
|
||||||
max_c = 2
|
max_c = 2
|
||||||
extend_p = 50
|
extend_p = 50
|
||||||
|
|||||||
22
mhrewards.py
22
mhrewards.py
@@ -18,30 +18,29 @@ def _format_range(min_v, max_v):
|
|||||||
return "%5.2f%% to %5.2f%%" % (min_v, max_v)
|
return "%5.2f%% to %5.2f%%" % (min_v, max_v)
|
||||||
|
|
||||||
|
|
||||||
def find_item(db, item_name, out):
|
def find_item(db, item_name, err_out):
|
||||||
item_row = db.get_item_by_name(item_name)
|
item_row = db.get_item_by_name(item_name)
|
||||||
if item_row is None:
|
if item_row is None:
|
||||||
print("Item '%s' not found. Listing partial matches:" % item_name,
|
print("Item '%s' not found. Listing partial matches:" % item_name,
|
||||||
file=out)
|
file=err_out)
|
||||||
terms = item_name.split()
|
terms = item_name.split()
|
||||||
for term in terms:
|
for term in terms:
|
||||||
if len(term) < 2:
|
if len(term) < 2:
|
||||||
# single char terms aren't very useful, too many results
|
# single char terms aren't very useful, too many results
|
||||||
continue
|
continue
|
||||||
print("= Matching term '%s'" % term, file=out)
|
print("= Matching term '%s'" % term, file=err_out)
|
||||||
rows = db.search_item_name(term, "Flesh")
|
rows = db.search_item_name(term, "Flesh")
|
||||||
for row in rows:
|
for row in rows:
|
||||||
print(" ", row["name"], file=out)
|
print(" ", row["name"], file=err_out)
|
||||||
return None
|
return None
|
||||||
return item_row
|
return item_row
|
||||||
|
|
||||||
|
|
||||||
def print_quests_and_rewards(db, item_name, out):
|
def print_quests_and_rewards(db, item_row, out):
|
||||||
"""
|
"""
|
||||||
Get a list of the quests for acquiring a given item and the probability
|
Get a list of the quests for acquiring a given item and the probability
|
||||||
of getting the item, depending on cap or kill and luck skills.
|
of getting the item, depending on cap or kill and luck skills.
|
||||||
"""
|
"""
|
||||||
item_row = db.get_item_by_name(item_name)
|
|
||||||
item_id = item_row["_id"]
|
item_id = item_row["_id"]
|
||||||
quests = db.get_item_quest_objects(item_id)
|
quests = db.get_item_quest_objects(item_id)
|
||||||
for q in quests:
|
for q in quests:
|
||||||
@@ -168,21 +167,24 @@ def print_quests_and_rewards(db, item_name, out):
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
print("Usage: %s 'item name'" % sys.argv[0])
|
print("Usage: %s 'item name'" % sys.argv[0])
|
||||||
sys.exit(1)
|
sys.exit(os.EX_USAGE)
|
||||||
|
|
||||||
item_name = sys.argv[1]
|
item_name = sys.argv[1]
|
||||||
|
|
||||||
out = get_utf8_writer(sys.stdout)
|
out = get_utf8_writer(sys.stdout)
|
||||||
|
err_out = get_utf8_writer(sys.stderr)
|
||||||
|
|
||||||
# TODO: doesn't work if script is symlinked
|
# TODO: doesn't work if script is symlinked
|
||||||
db_path = os.path.dirname(sys.argv[0])
|
db_path = os.path.dirname(sys.argv[0])
|
||||||
db_path = os.path.join(db_path, "db", "mh4u.db")
|
db_path = os.path.join(db_path, "db", "mh4u.db")
|
||||||
db = mhdb.MHDB(db_path)
|
db = mhdb.MHDB(db_path)
|
||||||
|
|
||||||
item_row = find_item(db, item_name, out)
|
item_row = find_item(db, item_name, err_out)
|
||||||
if item_row is not None:
|
if item_row is None:
|
||||||
print_quests_and_rewards(db, item_name, out)
|
sys.exit(os.EX_DATAERR)
|
||||||
|
print_quests_and_rewards(db, item_row, out)
|
||||||
|
|||||||
Reference in New Issue
Block a user