raffitz
5 years ago
commit
4a5654c2c1
2 changed files with 217 additions and 0 deletions
@ -0,0 +1,150 @@ |
|||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <string.h> |
||||||
|
#include <math.h> |
||||||
|
#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,"<span title=\"%dd%d=%d,", (*root).roll.count, (*root).roll.type, values[i]); |
||||||
|
}else if (j == 1){ |
||||||
|
sprintf(result.text,"%s%d\">%d</span>", 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; |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
#ifndef WEBDICE_EXPRESSION |
||||||
|
#define WEBDICE_EXPRESSION |
||||||
|
|
||||||
|
#include <stdint.h> |
||||||
|
|
||||||
|
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 |
Loading…
Reference in new issue