5 releases (3 breaking)
0.4.0 | Jul 1, 2022 |
---|---|
0.3.1 | Feb 8, 2022 |
0.3.0 | Feb 4, 2022 |
0.2.0 | Jan 3, 2022 |
0.1.0 | Dec 29, 2021 |
#1501 in Parser implementations
26 downloads per month
75KB
1.5K
SLoC
Gcalc
Gcalc is a game probability calculator.
Gcalc is not a gacha simulator but more of a generic probability calculator. Consequently gcalc's goal is not about getting a percentage from given try counts, but calculate expected effects of the "tries". Such expectation can be used to decide how many tries should be given to users, assess the economical effect that game events might occur and so on and so forth.
Usage
# Basic
gcalc <SUBCOMMAND> <OPTIONS>
# SUBCOMMANDS:
# cond Conditional calculation
# qual Conditional calculation but only prints result
# range Prints range of calculations
# reference Create a reference file
# option Create an option file
# For cond and qual
-b, --budget <budget> Budget of total cost
-C, --cost <cost> Cost per try
# For range
-c, --count <count> Counts to execute
-S, --start <start> Starting index to print
# Global option
--constant <constant> Constant value to be added into probability
-f, --format <format> Table format(csv|console|gfm)
--fallback <fallback> Set csv value fallback {rollback|ignore|none} [default: none]
-h, --help Print help information
-l, --column <column> Column mapping
--noheader CSV without header
-o, --out <FILE> File to write output
-O, --option <option> Option file to use
-p, --probability <prob> Basic probability
--value <value> Target goal's value
-P, --precision <precision> Precision
-r, --ref <reference> Reference file
--refin Reference from stdin
-s, --strict Set strict CSV reader mode, every try should be corresponding csv record.
-t, --target <target> Target probability to achieve
-T, --type <probtype> Probability type(percentage|fraction)
--plot Create plot vector graphics named as "out.svg"
Install
binary
cargo install gcalc --features binary --locked
libary
[dependencies]
gcalc = "*"
Demo
# Print records of probability 0.2(20%) with budget of 100 and cost of 20 for each iteration.
# Target probability is 0.6
gcalc cond --probability 0.2 --budget 100 --cost 20 -f console --precision 2 -T percentage -t 0.6
# Print from 0 to 10 as github markdown formatted table, which has a precision of
# 2 digits. Each try has cost of 1000.
gcalc range --probability 0.2 --count 10 --format gfm --precision 2 --cost 1000
# Print probability changes illustrated as csv formatted table, which has a
# precision of 2 digits. Target probability is 0.8.
gcalc cond --probability 0.2 --format csv --precision 2 --target 0.8
# Print how many counts are required to reach 0.99 probability with 0.01 change of each try
# Qual subcommand uses geometric-series formula if no reference was given as an argument
# Which is efficient for very small probability cases
gcalc qual --probability 0.001 -f gfm --target 0.99 --precision 2
# Use reference file
gcalc <SUBCOMMAND> --ref ref.csv
# Use reference from stdin
cat ref.csv | gcalc <SUBCOMMAND> --refin
# Read options from option file
gcalc range --option option.json
Results of prior usages are,
# gcalc cond --probability 0.2 --budget 100 --cost 20 -f console --precision 2 -T percentage -t 0.6
+-------+-------------+------+----------+-------+
| count | probability | cost | constant | value |
+-------+-------------+------+----------+-------+
| 1 | 20.00% | 20 | 0 | 0 |
+-------+-------------+------+----------+-------+
| 2 | 36.00% | 40 | 0 | 0 |
+-------+-------------+------+----------+-------+
| 3 | 48.80% | 60 | 0 | 0 |
+-------+-------------+------+----------+-------+
| 4 | 59.04% | 80 | 0 | 0 |
+-------+-------------+------+----------+-------+
| 5 | 67.23% | 100 | 0 | 0 |
+-------+-------------+------+----------+-------+
# gcalc range --probability 0.2 --count 10 --format gfm --precision 2 --cost 1000
| count | probability | cost | constant | value |
|-------+-------------+-------+----------+-------|
| 1 | 0.20 | 1000 | 0 | 0 |
| 2 | 0.36 | 2000 | 0 | 0 |
| 3 | 0.48 | 3000 | 0 | 0 |
| 4 | 0.59 | 4000 | 0 | 0 |
| 5 | 0.67 | 5000 | 0 | 0 |
| 6 | 0.73 | 6000 | 0 | 0 |
| 7 | 0.79 | 7000 | 0 | 0 |
| 8 | 0.83 | 8000 | 0 | 0 |
| 9 | 0.86 | 9000 | 0 | 0 |
| 10 | 0.89 | 10000 | 0 | 0 |
# gcalc cond --probability 0.2 --format csv --precision 2 --target 0.8
count,probability,cost,constant,value
1,0.20,0,0,0
2,0.36,0,0,0
3,0.48,0,0,0
4,0.59,0,0,0
5,0.67,0,0,0
6,0.73,0,0,0
7,0.79,0,0,0
8,0.83,0,0,0
# gcalc qual --probability 0.001 -f gfm --target 0.99 --precision 2
| count | probability | cost | value |
|-------+-------------+------+-------|
| 4602 | 0.99 | 0 | 0 |
Reference file example
count,probability,constant,cost
1,0.1,0,50
2,0.2,0,40
3,0.3,0,30
4,0.4,0,20
5,0.5,0,10
option file example
{
"count": 10,
"prob_type": "Percentage",
"prob_precision": 2,
"budget": null,
"fallback": "None",
"no_header": false,
"strict": false,
"target": null,
"value": null,
"format": "GFM",
"csv_ref": {
"File": "ref.csv"
},
"out_option": "Console"
}
"csv_ref" is a tuple which has variant of...
"csv_ref" : {
"Raw" : "count,probability,constant,cost
1,0.1,0.0,10"
}
or
"csv_ref" : {
"File": "file_name_in_string"
}
or
"csv_ref" : "None",
Advanced usage
Column mapping
You can read existing csv file without changing the name of original columns with column mapping.
Column that is queried are
- count
- prob
- cost
- constant
# Example csv content...
db,type,count,const,cost,probability
t1,a,1,0.1,30,0.1
t1,b,2,0.1,20,0.1
t1,c,3,0.1,10,0.1
t1,a,4,0.2,30,0.1
t1,b,5,0.2,20,0.2
t1,c,6,0.2,10,0.3
# Example usage
gcalc range --ref ref.csv --count 6 --column prob=probability,constant=const
Strict Read
Gcalc doesn't match every try for corresponding reference's record by default.
# Example csv file
count,probability,constant,cost
1,0.5,0,50
2,0.2,0,40
3,0.3,0,30
4,0.4,0,20
5,0.5,0,10
# Range from 1 to 10
# From 6th try, 5th record values are used
gcalc range --count 10 --ref ref.csv
User can disable this behaviour with strict flag
gcalc range --count 10 --ref ref.csv --strict
# Previous command yields error
Invalid csv error
= Empty row in index: 6
Fallback
Gcalc tries to parse CSV value as intended data type. But user can define fallback behaviour for some undefined situations.
# Example csv file
count,probability,constant,cost
1,0.5,0.2,50
2,0.2,-,40
3,0.3,0.1,30
4,0.4,-,20
5,0.5,-,10
# Default value is 'none'
# Option is case insensitive, btw
gcalc <SUBCOMMAND> --ref ref.csv --constant 0.7 --fallback rollback|ignore|none
On previous example, at the third record which is 3,0.3,0.1,30
- Rollback : Set constant as 0.7 which is an initial value given as argument
- Ignore : Set constant as 0.2 which is the updated value of constant.
- None : Panics and abort a program
Demo plot image
About
Why not use a simple formula?
Well because, real life usages are not clear cut demonstrated geometric sequences. Sometimes there is bonus for a specific gacha stage and there is also a so-called confirmed gacha system, which makes it hard to use geometric series formula.
Ok, why not use other gacha simulators or calculators?
First, simulation is not calculation. The major reasoning of this crate is about expectation and calibration, especially game development in mind.
Second, existing calculators only consider fixed value of probability. However there are plenty of contents that utilize bonus probability on specific steps and there are some gachas that have different probability for different situations.
Third, those are hard to integrate with other systems. Most of them are either simple programs with integrated front end (GUI) which can be only losely connected to other game development tools at the most and automation is nearly impossible.
Goal
- Easily usable binary and library for probability check and calculations
- Easy automation with csv files
- Multi format: cross-platform binary + wasm binary
- Integration with jupyter notebooks
Dependencies
~4.5–8.5MB
~124K SLoC