From 4a5654c2c11bf830b1264cb8c29f036530f6b083 Mon Sep 17 00:00:00 2001 From: raffitz Date: Tue, 12 Mar 2019 21:08:29 +0000 Subject: [PATCH] Add data structure and resolving function --- expression.c | 150 +++++++++++++++++++++++++++++++++++++++++++++++++++ expression.h | 67 +++++++++++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 expression.c create mode 100644 expression.h diff --git a/expression.c b/expression.c new file mode 100644 index 0000000..e5c353f --- /dev/null +++ b/expression.c @@ -0,0 +1,150 @@ +#include +#include +#include +#include +#include "expression.h" + +union expression* webdice_const(int64_t value){ + union expression* aux = (union expression*) malloc(sizeof(union expression*)); + + (*aux).constant.id = WEBDICE_CONST; + (*aux).constant.value = value; + + return aux; +} + +union expression* webdice_roll(int64_t count, int64_t roll){ + union expression* aux = (union expression*) malloc(sizeof(union expression*)); + + (*aux).roll.id = WEBDICE_ROLL; + (*aux).roll.count = count; + (*aux).roll.type = roll; + + return aux; +} + +union expression* webdice_binary(enum binary_type type, union expression* left, union expression* right){ + union expression* aux = (union expression*) malloc(sizeof(union expression*)); + + (*aux).binary.id = WEBDICE_BINARY; + (*aux).binary.operation = type; + (*aux).binary.left = left; + (*aux).binary.right = right; + + return aux; +} + +union expression* webdice_mul(union expression* left, union expression* right){ + return webdice_binary(WEBDICE_MUL,left,right); +} + +union expression* webdice_div(union expression* left, union expression* right){ + return webdice_binary(WEBDICE_DIV,left,right); +} + +union expression* webdice_add(union expression* left, union expression* right){ + return webdice_binary(WEBDICE_ADD,left,right); +} + +union expression* webdice_sub(union expression* left, union expression* right){ + return webdice_binary(WEBDICE_SUB,left,right); +} + +struct expression_result resolve(union expression* root){ + struct expression_result result,left,right; + + int i, j; + int64_t *values; + int64_t total; + long double size; + int64_t length = 1; + + switch((*root).id.id){ + case WEBDICE_CONST: + size = log10l((*root).constant.value); + length += (int64_t) ceill(size); + result.min = (*root).constant.value; + result.max = (*root).constant.value; + result.expected = (*root).constant.value; + result.actual = (*root).constant.value; + result.text = (char*) malloc(length * sizeof(char)); + sprintf(result.text, "%d",(*root).constant.value); + break; + case WEBDICE_ROLL: + size = (*root).roll.count * ceill(15+log10l((*root).roll.count * (*root).roll.type)); + length += (int64_t) size; + result.min = (*root).roll.count; + result.max = (*root).roll.count * (*root).roll.type; + result.expected = (*root).roll.count * ((*root).roll.type + 1) / 2; + result.text = (char*) malloc(length * sizeof(char)); + values = (int64_t*) malloc((*root).roll.count * sizeof(int64_t)); + for (i = 0, j = (*root).roll.count, total = 0; i < (*root).roll.count; i++, j--){ + values[i] = 1 + (rand() % (*root).roll.type); + total += values[i]; + if (i == 0){ + sprintf(result.text,"%d", result.text, values[i], total); + }else{ + sprintf(result.text,"%s%d,", result.text, values[i]); + } + } + free(values); + result.actual = total; + break; + case WEBDICE_BINARY: + left = resolve((*root).binary.left); + right = resolve((*root).binary.right); + length += 5 + strlen(left.text) + strlen(right.text); + result.text = (char*) malloc(length * sizeof(char)); + switch((*root).binary.operation){ + case WEBDICE_MUL: + result.min = left.min * right.min; + result.max = left.max * right.max; + result.expected = left.expected * right.expected; + result.actual = left.actual * right.actual; + sprintf(result.text,"(%s * %s)",left.text,right.text); + break; + case WEBDICE_DIV: + result.min = left.min / right.max; + result.max = left.max / right.min; + result.expected = left.expected / right.expected; + result.actual = left.actual / right.actual; + sprintf(result.text,"(%s / %s)",left.text,right.text); + break; + case WEBDICE_ADD: + result.min = left.min + right.min; + result.max = left.max + right.max; + result.expected = left.expected + right.expected; + result.actual = left.actual + right.actual; + sprintf(result.text,"(%s + %s)",left.text,right.text); + break; + case WEBDICE_SUB: + result.min = left.min - right.max; + result.max = left.max - right.min; + result.expected = left.expected - right.expected; + result.actual = left.actual - right.actual; + sprintf(result.text,"(%s - %s)",left.text,right.text); + break; + default: + free(result.text); + result.text = NULL; + result.min = 0; + result.max = 0; + result.expected = 0; + result.actual = 0; + break; + } + free(left.text); + free(right.text); + break; + default: + result.text = NULL; + result.min = 0; + result.max = 0; + result.expected = 0; + result.actual = 0; + break; + } + return result; +} diff --git a/expression.h b/expression.h new file mode 100644 index 0000000..0a422fe --- /dev/null +++ b/expression.h @@ -0,0 +1,67 @@ +#ifndef WEBDICE_EXPRESSION +#define WEBDICE_EXPRESSION + +#include + +enum expression_type{ + WEBDICE_CONST, + WEBDICE_ROLL, + WEBDICE_BINARY +}; + +enum binary_type{ + WEBDICE_MUL, + WEBDICE_DIV, + WEBDICE_ADD, + WEBDICE_SUB +}; + +struct expression_id{ + enum expression_type id; +}; + +struct expression_const{ + enum expression_type id; + int64_t value; +}; + +struct expression_roll{ + enum expression_type id; + int64_t count; + int64_t type; +}; + +struct expression_binary{ + enum expression_type id; + enum binary_type operation; + union expression* left; + union expression* right; +}; + +union expression{ + struct expression_id id; + struct expression_const constant; + struct expression_roll roll; + struct expression_binary binary; +}; + +struct expression_result{ + char* text; + long double min; + long double max; + long double expected; + long double actual; +}; + +union expression* webdice_const(int64_t value); +union expression* webdice_roll(int64_t count, int64_t roll); + +union expression* webdice_mul(union expression* left, union expression* right); +union expression* webdice_div(union expression* left, union expression* right); +union expression* webdice_add(union expression* left, union expression* right); +union expression* webdice_sub(union expression* left, union expression* right); + +union expression* webdice_binary(enum binary_type type, union expression* left, union expression* right); + +struct expression_result resolve(union expression* root); +#endif