Browse Source

Add data structure and resolving function

main
raffitz 5 years ago
commit
4a5654c2c1
Signed by: raffitz
GPG Key ID: 0224483A6E6AC710
  1. 150
      expression.c
  2. 67
      expression.h

150
expression.c

@ -0,0 +1,150 @@ @@ -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;
}

67
expression.h

@ -0,0 +1,67 @@ @@ -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…
Cancel
Save