/element.c
https://bitbucket.org/shadwick/alchemy · C · 159 lines · 113 code · 30 blank · 16 comment · 18 complexity · fba9105d37f05e24e10126b4a431181b MD5 · raw file
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <assert.h>
- #include "element.h"
- /* ==================== Static Data ==================== */
- BuiltinElement builtin_elements[] = {
- {"Aquasoothius", 1, ATTR_CONSTANT}, /* #1286 */
- {"Falsium", 0, ATTR_CONSTANT}, /* #721 */
- {"Periphius", 3.14159265, ATTR_CONSTANT}, /* #953 */
- {"Aquaphidium", 1.61803399, ATTR_CONSTANT}, /* #1144 */
- {"Eulerius", 2.71828182, ATTR_CONSTANT}, /* #846 */
- {"Quantifius", 0, ATTR_PRODUCT}, /* #1065 */
- {"Inquirium", 0, ATTR_PRODUCT}, /* #963 */
- {"Elucidium", 0, ATTR_PRODUCT}, /* #929 */
- {"Scribius", 0, ATTR_PRODUCT} /* #836 */
- };
- /* ==================== External Data ==================== */
- /* Allocate and return a new Element after initializing it.
- * If it breaks naming conventions, NULL is returned instead.
- */
- Element *element_create(const char *name) {
- Element *element;
- element = malloc(sizeof(Element));
- if (!element_init(element, name)) {
- free(element);
- return NULL;
- }
- return element;
- }
- /* Initialize a given Element - naming it and computing its other properties.
- * If it breaks naming conventions, 0 is returned; 1 otherwise.
- */
- int element_init(Element *element, const char *name) {
- unsigned int i;
- assert(element);
- assert(name && name[0] != '\0');
-
- /* Copy name and compute substance number */
- element->value = 0;
- element->subnum = 0;
- for (i = 0; i < NAME_MAX; i++) {
- element->name[i] = name[i];
- element->subnum += name[i];
- }
- element->name[i] = '\0';
-
- /* Determine if dry/wet, if the name is valid, and aqueous */
- i = strlen(element->name);
- if (strcmp(element->name + i - 3, "ius") == 0)
- element->dry = 1;
- else if (strcmp(element->name + i - 3, "ium") == 0)
- element->dry = 0;
- else
- return 0;
- element->aqueous = strncmp(element->name, "Aqua", 4) == 0;
- element->initialized = 0;
- element->attributes = 0;
- return 1;
- }
- void element_destroy(Element *element) {
- assert(element);
- free(element);
- }
- void element_set_value(Element *element, double value) {
- assert(element);
- element->value = value;
- if (!element->initialized)
- element->initialized = 1;
- }
- Reagents *reagents_create() {
- Reagents *reagents;
- reagents = malloc(sizeof(Reagents));
- reagents_clear(reagents);
- reagents_set_solvent(reagents, ALKAHEST, 0);
- return reagents;
- }
- void reagents_destroy(Reagents *reagents) {
- assert(reagents);
- free(reagents->elements);
- free(reagents->amounts);
- free(reagents);
- }
- void reagents_add_element(Reagents *reagents, Element *element,
- uint32_t amount) {
- assert(reagents);
- assert(reagents->count < MAX_REAGENTS);
- reagents->elements[reagents->count] = element;
- reagents->amounts[reagents->count] = amount;
- reagents->count++;
- }
- void reagents_clear(Reagents *reagents) {
- reagents->count = 0;
- memset(reagents->elements, 0, sizeof(Element *) * MAX_REAGENTS);
- memset(reagents->amounts, 0, sizeof(uint32_t) * MAX_REAGENTS);
- }
- void reagents_set_solvent(Reagents *reagents, Solvent solvent,
- uint32_t amount) {
- assert(reagents);
- reagents->solvent = solvent;
- reagents->solvent_amount = amount;
- }
- /* Return the amount of solvent that is needed to perform a reaction, given the
- * list of elements, their respective amounts, and the desired solvent type.
- */
- uint32_t reagents_needed_solvent(Reagents *reagents) {
- unsigned int i, base, amount;
- assert(reagents);
- base = 1;
- if (reagents->solvent == WATER)
- base++;
- for (i = 0, amount = 0; i < reagents->count; i++) {
- if (reagents->elements[i]->dry)
- amount += base * reagents->amounts[i];
- else
- amount += (base + 1) * reagents->amounts[i];
- }
- return amount;
- }
- /* Return 1 if the all elements in the list are aqeuous.
- * If any are not, 0 is returned.
- */
- int reagents_are_soluble(Reagents *reagents) {
- unsigned int i;
- assert(reagents);
- for (i = 0; i < reagents->count; i++) {
- if (reagents->elements[i]->aqueous == 0)
- return 0;
- }
- return 1;
- }