optimize.h 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. /*
  2. * This file is part of RuneOptimizer.
  3. *
  4. * RuneOptimizer is free software: you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation, either version 3 of the License, or (at your option)
  7. * any later version.
  8. *
  9. * RuneOptimizer is distributed in the hope that it will be useful, but WITHOUT
  10. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12. * more details.
  13. *
  14. * You should have received a copy of the GNU General Public License along with
  15. * RuneOptimizer. If not, see <https://www.gnu.org/licenses/>.
  16. */
  17. /**
  18. * @file optimize.h
  19. *
  20. * Declarations of the functions and data typer related to the optimixe command.
  21. *
  22. * This file declares all the functions and data types used by the optimize
  23. * command implemented in {@link optimize.c}.
  24. */
  25. #pragma once
  26. #include "../runeoptimizer.h"
  27. /**
  28. * Hard limit on the number of results
  29. */
  30. #define MAX_RESULTS 5000
  31. /**
  32. * Limit on runes per slot for the optimizations.
  33. *
  34. * Number format.
  35. */
  36. #define LIMIT_RUNES_PER_SLOT 500
  37. /**
  38. * Hard limit on the number of teams or units that can be excluded from
  39. * optimization.
  40. */
  41. #define MAX_EXCLUSIONS 128
  42. /**
  43. * Maximum number of sets.
  44. *
  45. * Maximum for the requested sets option.
  46. */
  47. #define MAX_SETS 3
  48. /**
  49. * A rune.
  50. *
  51. * Contains usefull information to operate with runes.
  52. */
  53. typedef struct Rune {
  54. /**
  55. * The rune ID.
  56. *
  57. * Unit ID, as given by Com2Us.
  58. */
  59. unsigned char id[RUNE_ID_LEN];
  60. /**
  61. * The slot of the rune
  62. *
  63. * Can be [1-6].
  64. */
  65. unsigned char slot;
  66. /**
  67. * Rune set id.
  68. *
  69. * Identifier of the set the rune belongs to.
  70. */
  71. unsigned char set;
  72. /**
  73. * ID of the unit the rune is assigned to.
  74. *
  75. * NULL if the rune is not assigned.
  76. */
  77. unsigned char unit[UNIT_ID_LEN];
  78. /**
  79. * HP% stat.
  80. *
  81. * HP% given by the rune, in any of it's stats.
  82. */
  83. unsigned char hp_percent;
  84. /**
  85. * ATK% stat.
  86. *
  87. * ATK% given by the rune, in any of it's stats.
  88. */
  89. unsigned char atk_percent;
  90. /**
  91. * DEF% stat.
  92. *
  93. * DEF% given by the rune, in any of it's stats.
  94. */
  95. unsigned char def_percent;
  96. /**
  97. * HP stat.
  98. *
  99. * HP given by the rune, in any of it's stats.
  100. */
  101. unsigned short hp_flat;
  102. /**
  103. * ATK stat.
  104. *
  105. * ATK given by the rune, in any of it's stats.
  106. */
  107. unsigned char atk_flat;
  108. /**
  109. * DEF stat.
  110. *
  111. * DEF given by the rune, in any of it's stats.
  112. */
  113. unsigned char def_flat;
  114. /**
  115. * SPD stat.
  116. *
  117. * SPD given by the rune, in any of it's stats.
  118. */
  119. unsigned char spd;
  120. /**
  121. * CRR stat.
  122. *
  123. * CRR given by the rune, in any of it's stats.
  124. */
  125. unsigned char crr;
  126. /**
  127. * CRD stat.
  128. *
  129. * CRD given by the rune, in any of it's stats.
  130. */
  131. unsigned char crd;
  132. /**
  133. * RES stat.
  134. *
  135. * RES given by the rune, in any of it's stats.
  136. */
  137. unsigned char res;
  138. /**
  139. * ACC stat.
  140. *
  141. * ACC given by the rune, in any of it's stats.
  142. */
  143. unsigned char acc;
  144. } Rune;
  145. /**
  146. * Stats of a unit.
  147. *
  148. * Can be used for base stats or for current stats.
  149. */
  150. typedef struct Stats {
  151. /**
  152. * HP stat.
  153. *
  154. * Unit health. Unit gets defeated in battle when it reaches 0.
  155. */
  156. unsigned int hp;
  157. /**
  158. * ATK stat.
  159. *
  160. * Unit attack power. Retermines how much damage it does.
  161. */
  162. unsigned short atk;
  163. /**
  164. * DEF stat.
  165. *
  166. * Unit defense. Reduces incoming damage.
  167. */
  168. unsigned short def;
  169. /**
  170. * SPD stat.
  171. *
  172. * Unit speed. Determines turn order.
  173. */
  174. unsigned short spd;
  175. /**
  176. * CRR stat.
  177. *
  178. * Chance of landing a critical hit. Capped at 100.
  179. */
  180. unsigned short crr;
  181. /**
  182. * CRD stat.
  183. *
  184. * Extra damage done when landing a critical hit.
  185. */
  186. unsigned short crd;
  187. /**
  188. * RES stat.
  189. *
  190. * Chance of resisting a harmful effect. Cant be lower than 15.
  191. */
  192. unsigned short res;
  193. /**
  194. * ACC stat.
  195. *
  196. * Chance of landing a harmfull effect. Effective cap is 85.
  197. */
  198. unsigned short acc;
  199. /**
  200. * EHP stat.
  201. *
  202. * EHP is a complex stat that depends on {@link hp} and {@link def}. See
  203. * {@link calculate_ehp} for more details.
  204. */
  205. unsigned int ehp;
  206. /**
  207. * DMG stat.
  208. *
  209. * DMG is a complex stat that depends on {@link atk} and {@link crr} and
  210. * {@link crr}. See {@link calculate_ehp} for more details.
  211. */
  212. unsigned short dmg;
  213. } Stats;
  214. /**
  215. * Indicates ponderations for stats.
  216. *
  217. * Ponderations are used to give more or less weight to a stat when calculating
  218. * a {@link Result}.rating.
  219. *
  220. * @todo Implement ponderations.
  221. */
  222. typedef struct Stat_Ponderation {
  223. /**
  224. * HP ponderation.
  225. *
  226. * Weight given to the HP stat.
  227. */
  228. float hp;
  229. /**
  230. * ATK ponderation.
  231. *
  232. * Weight given to the ATK stat.
  233. */
  234. float atk;
  235. /**
  236. * DEF ponderation.
  237. *
  238. * Weight given to the DEF stat.
  239. */
  240. float def;
  241. /**
  242. * SPD ponderation.
  243. *
  244. * Weight given to the SPD stat.
  245. */
  246. float spd;
  247. /**
  248. * CRR ponderation.
  249. *
  250. * Weight given to the CRR stat.
  251. */
  252. float crr;
  253. /**
  254. * CRD ponderation.
  255. *
  256. * Weight given to the CRD stat.
  257. */
  258. float crd;
  259. /**
  260. * RES ponderation.
  261. *
  262. * Weight given to the RES stat.
  263. */
  264. float res;
  265. /**
  266. * ACC ponderation.
  267. *
  268. * Weight given to the ACC stat.
  269. */
  270. float acc;
  271. } Stat_Ponderation;
  272. /**
  273. * A result of the optimization.
  274. *
  275. * {@link optimize_thread} loads one for each combination that match all the
  276. * criteria passed to the optimizer.
  277. */
  278. typedef struct Result {
  279. /**
  280. * Runes.
  281. *
  282. * The runes that compose the result.
  283. */
  284. unsigned char rune_ids[RUNE_SLOTS][RUNE_ID_LEN];
  285. /**
  286. * The rating of the result.
  287. *
  288. * Calculated by comparing each stat (except EHP and DMG) with the unit
  289. * current stats.
  290. */
  291. signed int rating;
  292. /**
  293. * Result stats.
  294. *
  295. * The stats the unit would have with the result runes equipped.
  296. */
  297. struct Stats stats;
  298. } Result;
  299. typedef struct Optimizer_Output{
  300. // TODO: Document, maybe separate
  301. unsigned char verbose;
  302. unsigned char quiet;
  303. unsigned char debug;
  304. unsigned char format;
  305. unsigned char output;
  306. } Optimizer_Output;
  307. typedef struct Optimizer_Options{
  308. // TODO: Document, maybe separate
  309. unsigned char help;
  310. unsigned char threads;
  311. } Optimizer_Options;
  312. /**
  313. * Options for the optimizer.
  314. *
  315. * The options that can be passed to the optimizer via arguments. Default values
  316. * are assigned in {@link optimize_set_default_options}, and the argument values
  317. * are set in {@link optimize_parse_arguments}.
  318. */
  319. typedef struct Optimizer_Filters {
  320. /**
  321. * Unit ID.
  322. *
  323. * Mandatory, has no default value. Must be de first parameter passed to the
  324. * optimizer. For a while, it may contain a Unit name so the size is
  325. * increased.
  326. */
  327. unsigned char id[UNIT_NAME_LEN];
  328. /**
  329. * Rune to consider the levels at during optimization.
  330. *
  331. * The level option argument is -l or --level, and the value can be
  332. * 'current', '12', or '15', for {@link LVCURR}, {@link LV12}, or
  333. * {@link LV15}, respectively. If not specifier, the default value is
  334. * {@link LVCURR}.
  335. *
  336. * At current level, the optimization will be done considering the rune as
  337. * is, but at levels 12 or 15, if the rune is currently in a lower level,
  338. * the main stat will be considered to have the value it would have if the
  339. * rune was at that level.
  340. */
  341. unsigned char level;
  342. /**
  343. * Sets of runes that the unit must have.
  344. *
  345. * These are the sets of runes that the unit must have after optimization.
  346. * Any combination of runes that doesn't conform at least these sets will
  347. * be discarded.
  348. *
  349. * The parameter to set this option is -e or --sets, and the sets have to be
  350. * passed by name, lowercase, separated by commas. This option is mandatory
  351. * and at least one set needs to be passed. Sets can be repeated, but the
  352. * sum of runes in every set cant be more than 6. Only the first three sets
  353. * passed will be read, the rest will be ignored.
  354. *
  355. * Some examples:
  356. *
  357. * @code
  358. * --sets violent,energy :OK, optimize for violent,energy
  359. * --sets violent,rage :ERROR, too many runes.
  360. * --sets shield :OK, optimize for at least one blade
  361. * set.
  362. * --sets will,will,will :OK, optimize for three will sets.
  363. * --sets VioLenT :ERROR, unrecognized set (lowercase!)
  364. * --sets will,rage,blade,swift: :OK, check for will,rage,blade (swift
  365. * is ignored!)
  366. * @endcode
  367. */
  368. unsigned char sets[MAX_SETS];
  369. /**
  370. * Indicates if the sets in {@link sets} amount for 6 runes.
  371. *
  372. * This is not a configurable option, but a handy flag. The default value is
  373. * {@link FALSE} and will be checked in {@link optimize}.
  374. */
  375. unsigned char full_set;
  376. /**
  377. * Other sets of runes that can be used.
  378. *
  379. * When the sets passed in th eoption {@link sets} don't amount to 6 runes,
  380. * more sets can be indicated here. If so, only runes of the selected sets
  381. * will be used to fill the remaining slots, but unless {@link broken_sets}
  382. * is set, its not guaranteed that full sets will be formed.
  383. *
  384. * The parameter to set this option is -i or --opt-sets, and the sets have
  385. * to be passed by name, lowercase, separated by commas. This option is
  386. * optional, but if used, at least one set needs to be passed. Repeated sets
  387. * are ignored, and setting the same that in {@link sets} will have no
  388. * effect. It can take as many as rune sets are, but optimization times
  389. * increase exponencially for every set.
  390. */
  391. unsigned char optional_sets[DIFFERENT_SETS];
  392. /**
  393. * Stats allowed in the even slots.
  394. *
  395. * Use this option to indicate wich stats are allowed to be used in slots 2,
  396. * 4 and 6. Only the runes with a main stat in this list will be considered
  397. * during the optimization. The parameter is -t or --stats, and the stats
  398. * have to be passed separated by commas.
  399. *
  400. * Accepted values are 'hp',
  401. * 'hpflat', 'atk', 'atkflat', 'def', 'defflat', 'spd', 'crr', 'crd', 'res'
  402. * and 'acc'. As many as the user want can be passed, and repeated ones will
  403. * be ignored.
  404. */
  405. unsigned char stats[DIFFERENT_STATS];
  406. /**
  407. * Min stats for the unit.
  408. *
  409. * During optimization, only the runes that leave the unit with at least
  410. * this stats will be considered a match. These are optional parameters and,
  411. * except min EHP and min DMG, which default to 0, the rest of stat
  412. * minimum default to the unit's current values.
  413. *
  414. * The parameters to set these valuesare:
  415. *
  416. * <pre>
  417. * -h | --min_hp N
  418. * -a | --min_atk N
  419. * -d | --min_def N
  420. * -s | --min_spd N
  421. * -c | --min_crr N
  422. * -d | --min_crd N
  423. * -r | --min_res N
  424. * -f | --min_acc N
  425. * -p | --min_ehp N
  426. * -m | --min_dmg N
  427. * </pre>
  428. */
  429. Stats *min_stats;
  430. /**
  431. * Option to format the optput for the GUI.
  432. *
  433. * This is not intended to be used by the user. It changes the output format
  434. * to be consumed by the GUI. To set it, the parameter -g or --gui must be
  435. * passed (it takes no options).
  436. */
  437. unsigned char gui;
  438. /**
  439. * Flag to use only unassigned runes.
  440. *
  441. * If this option is set to {@link TRUE}, only runes in storage (i.e. not
  442. * assigned to any unit will be considered during optimization). Runes
  443. * assigned to the unit being currently optimizad will of course be
  444. * considered even with this option.
  445. *
  446. * The parameter to set this option is -o or --storage, and it takes no
  447. * options.
  448. */
  449. unsigned char storage;
  450. /**
  451. * List of teams to ignore during optimization.
  452. *
  453. * For every team indicated here, no rune of it's units will be considered
  454. * during optimization. If the unit currently being optimized is in one of
  455. * these teams, the unit's runes will still be considered.
  456. *
  457. * The parameter for this option is -x or --no-teams, followed by a comma
  458. * separated list of team IDs (not names). If more teams that
  459. * {@link MAX_EXCLUSIONS} are indicated, the last ones wil be ignored.
  460. */
  461. unsigned char excluded_teams[MAX_EXCLUSIONS][TEAM_ID_LEN];
  462. /**
  463. * Indicates how many teams are excluded.
  464. *
  465. * This is not a configurable option, but a handy counter. The default value
  466. * is 0, and will be set when {@link excluded_teams} is populated.
  467. */
  468. unsigned char total_excluded_teams;
  469. /**
  470. * List of units to ignore during optimization.
  471. *
  472. * For every unit indicated here, it's units will be considered during
  473. * optimization. If the unit currently being optimized is in the list, it's
  474. * runes will still be considered.
  475. *
  476. * The parameter for this option is -u or --no-units, followed by a comma
  477. * separated list of unit IDs (not names). If more units that
  478. * {@link MAX_EXCLUSIONS} are indicated, the last ones wil be ignored. If is
  479. * not enough, consider making a team and exclude with
  480. * {@link excluded_teams}.
  481. */
  482. unsigned char excluded_units[MAX_EXCLUSIONS][UNIT_ID_LEN];
  483. /**
  484. * Indicates how many units are excluded.
  485. *
  486. * This is not a configurable option, but a handy counter. The default value
  487. * is 0, and will be set when {@link excluded_units} is populated.
  488. */
  489. unsigned char total_excluded_units;
  490. /**
  491. * Option to enable broken sets.
  492. *
  493. * If {@link sets} doesn't amount for six runes, this option will discard
  494. * any result that is not formed by complete sets. The default value is
  495. * {@link FALSE}. To set it, use the parameter -k or --broken (it takes no
  496. * options).
  497. */
  498. unsigned char broken_sets;
  499. /**
  500. * Number of thread to be used during optimization.
  501. *
  502. * Calculation of rune combinations can be done in separateed threads. Each
  503. * thread shares the same amount of work as the others, so the more threads,
  504. * the faster the optimzation is! The default value is 1, and can be set
  505. * passing the parameter -b or --threads, followed by a numeric value. No
  506. * more than 8 threads can be used.
  507. */
  508. unsigned char threads;
  509. /**
  510. * Weights for each stat.
  511. *
  512. * To calculate the rating of a results, different stats can be weighted
  513. * differently. The higher the ponderation of a stat, the more effect will
  514. * it have in the rating. Default values are 1 for every stat, and the value
  515. * can be a float between 0 and 2.
  516. *
  517. * @todo Implement
  518. * @todo Once implemented, document the argument ot use.
  519. * @todo Once implemented, document here if EHP and DMG can be weighted.
  520. */
  521. Stat_Ponderation ponderation;
  522. /**
  523. * Output mode for the optimization data.
  524. */
  525. unsigned char output_mode;
  526. } Optimizer_Filters;
  527. /**
  528. * Data package used by the optimizer.
  529. *
  530. * This is the data that {@link optimize_thread} takes. Each thread must have
  531. * it's own data package.
  532. */
  533. typedef struct Optimizer_Data {
  534. /**
  535. * Numeric ID of the thread.
  536. *
  537. * Usually, the spawing order.
  538. */
  539. unsigned int thread_id;
  540. /**
  541. * List of runes.
  542. *
  543. * These are the runes to test during optimization. The 0 index is not used
  544. * and can be empty or have garbage.
  545. */
  546. Rune runes[RUNE_SLOTS + 1][LIMIT_RUNES_PER_SLOT];
  547. /**
  548. * Runes counter for each slot.
  549. *
  550. * Indicates the size of each {@link runes}. Index 0 is not used.
  551. */
  552. unsigned int count[RUNE_SLOTS + 1];
  553. /**
  554. * List of results.
  555. *
  556. * The thread saves every succesfull combination here.
  557. */
  558. Result results[MAX_RESULTS];
  559. /**
  560. * Number of results.
  561. *
  562. * The total number of results the thread has found.
  563. */
  564. unsigned int total_results;
  565. /**
  566. * The options passed to the optimizer. *
  567. */
  568. Optimizer_Options *options;
  569. /**
  570. * The filters passed to the optimizer.
  571. *
  572. * The threads also needs to know some of these options.
  573. */
  574. Optimizer_Filters *filters;
  575. /**
  576. * The output options passed to the optimizer.
  577. *
  578. * The threads also needs to know some of these options.
  579. */
  580. Optimizer_Output *output;
  581. /**
  582. * Max testable combinations.
  583. *
  584. * Not just for this thread, but the sum of combinations to test by every
  585. * thread.
  586. */
  587. unsigned long long max_combinations;
  588. /**
  589. * Tested combinations.
  590. *
  591. * Number of tested combinations at any given point in time.
  592. */
  593. unsigned long long tested_combinations;
  594. /**
  595. * Set count calculated from the options passed to the optimizer.
  596. *
  597. * A set count to compare every rune combination against.
  598. */
  599. Rune_Set_Count requested_set_count;
  600. /**
  601. * The optimized unit
  602. *
  603. * The unit being optimized, with all the info previously loaded.
  604. */
  605. Unit *unit;
  606. /**
  607. * Optimization start time
  608. *
  609. * The time the optimization started in ISO format:
  610. * YYYY-MM-DDTHH:MM:SS
  611. */
  612. char start_time[20];
  613. } Optimizer_Data;
  614. /**
  615. * Starts the optimization process.
  616. *
  617. * Validates the arguments, gets the neccessary runes and starts the
  618. * optimization process. On error, it will print a message to stderr.
  619. *
  620. * @param[in] argc Number of argument passed to the optimizer command. As a
  621. * rule, it must me two less than the argc received by the {@link main}
  622. * function of the program.
  623. * @param[in] argv Arguments passed to the optimizer. As a rule, they must be
  624. * the same than the argv received by the {@link main} function of the program
  625. * without the first two. The first of them must be a unit ID or name. Apart
  626. * from that, only two of them are mandatory: --stats / -t and --sets / -e.
  627. * @return {@link SUCCESS} if the optimization was done coreclty, or an error
  628. * defined in {@link error.h} if there were problems with any of them.
  629. */
  630. int optimize(int argc, char *argv[]);