Hard Light Productions Forums

Modding, Mission Design, and Coding => FS2 Open Coding - The Source Code Project (SCP) => Topic started by: Bobboau on April 27, 2005, 03:54:13 am

Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 03:54:13 am
[edit]new build, handles negitive numbers and beter evaluation[/edit]
http://dynamic4.gamespy.com/~freespace/forums/attachment.php?s=&postid=666534

if you care at all about anything you will run this program and try to break it, you enter any normal mathematical expression (no trig or other type functions yet, just +-*/^) it will evaluate it corectly, if it fails to do so post here describeing what the conditions of failure were (post your expression) I am only going to get two hours of sleep because I stayed up all night working on this FOR YOU the least you could do is test the hell out of it for fifteen minutes. this is for the material and other systems (wouldn't you like user defined variables for the HUD?) it is a simple ugly looking thing but it is crucal that it works flawlessly
testitestittestittestittestitNOWWWW

instructions:
enter a simple (just arithmitic no log or trig (ect...) functions I do intend on implementing them eventualy but not just now) math formula, you may use any number includeing multi-diget and containing decimal points parenthises(ect...), it doesn't quite handle negitive numbers yet but it will.
hit enter
use a calculator to see if it was right.
tell me what happened, whatever the case.

if your not sure weather or not something is suported, try it! godamit!
I realy hope that when I wake up in 2 hours that there's like 40 posts here and not like... none, like there probly will be...
sleep.........

[edit]new build, handles negitive numbers and beter evaluation[/edit]
http://dynamic4.gamespy.com/~freespace/forums/attachment.php?s=&postid=666534
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 27, 2005, 04:14:55 am
Awesome. :) I'll definitely test this tomorrow.
Title: absolutely critical that you play with this small stand alone app
Post by: Ypoknons on April 27, 2005, 04:20:54 am
When I download it I get a PHP file.

Firefox doesn't read that.
Title: absolutely critical that you play with this small stand alone app
Post by: phatosealpha on April 27, 2005, 04:26:09 am
(49*49-49)+((3+3)/3):  Result 2448
(2401-49)+(6/3)
2352+2=2354.




(200/30+20):  Result 6.66667
(200/30)+20)
6.6667 + 20 = 26.6667

10*10+20:  Result 100
50/5+50/10:  Result 10

Also, if you have any two operands together, or if you start an equation with an operand, it crashes the program.  So entering:
+20  causes a crash as does entering 20+/10.
Title: absolutely critical that you play with this small stand alone app
Post by: Col. Fishguts on April 27, 2005, 04:33:49 am
Tested it and it told me that

(1+2)*2+2 = 6

the last "2" isn't evaluated for some reason.
Title: absolutely critical that you play with this small stand alone app
Post by: gonz on April 27, 2005, 05:14:15 am
3/2*3/2 = 2.25
3*2/3 = 2
2*3/2 = 3
3*2*1 = 6
3+2+1 = 6
3*1*1 = 3
3/1/1 = 3
3+1/2 = 3.5
3-(3+1)/2 = 1
3-(3+1)/2+1 = 2
(2+1)*(2+2) = 12
(2+1)*(2+2)-1 = 12 Incorrect
((2+1)+3)*2 = 12
2^2 = 4
2+2^3 = 10
(2+1)^2 = 9
(2+2)^(3-1) = 16
(3+2)/(3-1) = 2.5
(2.5+0.5)*2 = 6
(2.5+.5)*2 = 6

Note the incorrect result above, pretty good basis for a numerical parser/evaluator. Hope you can work out the bugs.
Title: absolutely critical that you play with this small stand alone app
Post by: DaBrain on April 27, 2005, 05:14:49 am
0/5 = 0


Is this really correct?
I think there this shouldn't have any result...

You should get some kind of error if you try to divide 0 with 0.


Everything else I tried worked perfectly. ;)
Title: absolutely critical that you play with this small stand alone app
Post by: Col. Fishguts on April 27, 2005, 05:23:14 am
Quote
Originally posted by DaBrain
0/5 = 0


Is this really correct?
I think there this shouldn't have any result...


Yes, that's correct, since it's equivalent to 0 * 1/5

Quote

You should get some kind of error if you try to divide 0 with 0.


Correct again, and Bob's program gives INF back, when you divide by 0.
Title: absolutely critical that you play with this small stand alone app
Post by: DaBrain on April 27, 2005, 05:37:00 am
Ah, right... Looks like I deserve the mark I got in math... ;)
Title: absolutely critical that you play with this small stand alone app
Post by: tom on April 27, 2005, 05:48:36 am
Quote

Quote


You should get some kind of error if you try to divide 0 with 0.
Correct again, and Bob's program gives INF back, when you divide by 0. [/B]

0/0 = indefinite
I presume the prog calculates that properly.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 09:55:36 am
huh... looks like it doesn't handle higherlevel opperations before lower level ones (ie if you * before you - without parenthises around the * block, it will perform the following subtraction incorectly)
Title: absolutely critical that you play with this small stand alone app
Post by: Inquisitor on April 27, 2005, 10:04:06 am
Aren't there math libraries you could use?
Title: absolutely critical that you play with this small stand alone app
Post by: krisvek on April 27, 2005, 10:40:15 am
Quote
   huh... looks like it doesn't handle higherlevel opperations before lower level ones (ie if you * before you - without parenthises around the * block, it will perform the following subtraction incorectly)


that should be pretty easy to fix though, right?  just throw in a loop checking for the higher levels first

oh, and i couldnt get the thing (firefox), else i'd have run it some too...lemme try with IE
Title: absolutely critical that you play with this small stand alone app
Post by: krisvek on April 27, 2005, 10:59:21 am
ok, i looked a little deeper into one of the Incorrect problems above...

(2+1)*(2+2)-1 = 12     Incorrect

(2+1)-1 = 2                  Correct

2*(2)-1 = 4                  Incorrect

2*2-1 = 4                    Incorrect

2*2-1+2 = 4                Incorrect

(2*2)-1 = 3                  Correct


So...yeah, that's odd.
Title: absolutely critical that you play with this small stand alone app
Post by: redmenace on April 27, 2005, 11:12:34 am
Quote
Originally posted by Inquisitor
Aren't there math libraries you could use?

I think this is a school project that involve trees IIRC back to the days of Data Structures.
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 27, 2005, 11:33:07 am
2^2*2+2=4 MAJOR WRONG

Even if it fubars the operator priority, it should work left-to-right, correct? Then it should do:
2^2*2+2
4*2+2
8+2
10

Also, note in whatever documentation that it wants points, and not commas. (EU vs US rules, or Dutch vs English)

15+5*5=40, nice and correct. (Ergo, it does seem to do some kind of operator preference.)

5*5+15=25.

(5*5)+15=40. So it works well with brackets.

It also exits without error on any NAN entry.


2*4+7=8. Pretty wrong. It seems that if you do x*y+z you will always get something odd. Perhaps it gives you just x*y, and forgets z.

Yup, it does. x*y+z gives you x*y.
Also seems x/y-z gives you x/y.
z+x*y gives you a correct answer. (z+(x*y)).
z-x/y gives you z-(x/y), correct as well.

3^-5 gives an ugly crash. (Want the MS bugreport? Msn at [email protected] )
Seems to reproduce for x^-y.
Ditto for x^(-1*y).
However, x^(y-z), when z>y, works, and gives a correct answer.

BTW, can you make it so it'll take an expression as command line arg, and return the result? I could write a testing thing with random expressions in no time.

I'll test some more after dinner, but an argument thingy would be great.

EDIT: Got source? I might be able to read the C and find the bug, if you'd allow a total beginner to touch the code.....
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 27, 2005, 02:53:00 pm
Also, if I type 1.23456789 I get 1.23457. It seems to round after the 6th decimal, but it rounds correctly.

The only way to create a negative number is to do (1-2)*x, where x is your number.

9\3=9
9/3=3
I know I used the wrong slash, but it might be better to die more graciously.

It seems that if it does not recognise an operator, it returns the value of anything in front of the unknown operator, and ignores the rest. An error return/debug output should be in place to prevent the really odd bugs. (x+y=z gives x+y). It does check for odd stuff at the start of an expression, just not for odd stuff inside the expression.

The ! is not implemented yet.
In the final implentation, e, pi, and any other constants should be replaced by the apropriate value, something that shouldn't be forgotten.

Also, mashing a lot  of keys and adding a few ^operators returns 1.#INF. Anything above 2^127 returns that, actually. Might be worth to add that to docs too. I geuss you're using signed floats, and anything out of bounds is called infinite?

(1-2)*2^127 works as expected.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 27, 2005, 05:19:49 pm
Quote
Originally posted by Inquisitor
Aren't there math libraries you could use?


I don't think so. What Bobb's trying to implement (correct me if I'm wrong) is what I described for the HUD system, but never got working. The idea was to allow one-line equations to be used to control variables on the HUD. That wayyou could combine variables for a variety of gauges. Say if you wanted a HP gauge, you use the variable "self.hull_strength". If you want a HP % gauge, you use "self.hull_strength / self.total_hull_strength * 100". That way, coders only need to define a base set of variables and modders can combine them any way they please.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 27, 2005, 07:50:24 pm
2^3/4 = 8
2^3/2 = 8
2^3/20 = 8
(2^3)/4 = 2
8*6+3 = 48
8*6+90 = 48
(8*6)+3 = 51
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 10:42:27 pm
there is now a new build up, I will be trying all the expressions the last one failed, I'm fairly sure this is at the least better than the last build, it has a totaly reworked expression parser.
Title: absolutely critical that you play with this small stand alone app
Post by: Taristin on April 27, 2005, 10:45:57 pm
I would try, but then I'd actually have to do the math to test if the responses are correct. And I'm not that confident in my own maths skills. :p
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 10:50:40 pm
it's called a calculator.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 27, 2005, 10:54:57 pm
Works good now, I tried mine and a few other equations posted in this thread and all worked.

Doesn't seem to support negative numbers too well:
NOTE: Spacing is important and I tried to be exact, since it seems to break stuff.

Quote
-5 + 3
"3 = 3"

3 + -5
"-5 = -5"

3+-5
"3+-5 = 8"

(3)+(-5)
"(3)+(-5)" = -2

3 + 4
"4 = 4"

4 + 3
"3 = 3"

(3) + (4)
"(4) = 4"


3+4
"3+4 = 7"


The % operator also behaves oddly:
Quote
4%3+7
"4%3+7 = 0"

(4%3)+7
"(4%3)+7 = 4"


Edit: Sent the link to a friend.

Quote
3^-2
"3^-2 = 9"

3^(-2)
"3^(-2) = 0.111111"
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 11:05:08 pm
I don't have modulus in yet, I'm suprized that worked at all.

I should have mentioned only inital rudimentery suport for negitive mumbers has been added, you'd be suprized how complicated it is to figure out weather a '-' means subtract or negate. right now it looks to see if the charicter on the other side of the - sign is a NULL or a ( indicateing that it's at the start of an expression, I guess it should also see if there are any opperateors there.

see if the general mechanisms for positive numbers works corectly while I work on getting this working
Title: absolutely critical that you play with this small stand alone app
Post by: Taristin on April 27, 2005, 11:11:14 pm
Quote
Originally posted by Bobboau
it's called a calculator.


Eh? Whassat?
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 11:15:42 pm
magic

ok and now I have version 3 uploaded, I real realy think I got negitive numbers working now :)
wait a secon I just DLed it and it's weird
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 27, 2005, 11:20:29 pm
First impression (Ignore the cutoffedness, that'd be the stupid dos box):
Code: [Select]
3 + 4

3 = 3
if this is not corect, please tell me and provid

enter another expression or type exit to do so:

+ = 0
if this is not corect, please tell me and provid

enter another expression or type exit to do so:

4 = 4
if this is not corect, please tell me and provid


3+-5 still doesn't work properly...
3^-2 still doesn't work properly...
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 11:20:40 pm
ok, new post new atachment

[note to self]don't modify atachments

use this atachment, it looks like when I changed the old exe it got corupted or something, a fresh upload should work good, I know for a fact those expressions are all working on my machine
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 27, 2005, 11:26:39 pm
Both of the bottom equations work now, although it keeps thinking that a space = a new equation.

*Tests some more*

Edit:

-(2^-(3)+1)-3 = 10
2^-(3) = 8
-(9)-3 = 6
3-(9)-3 = -9
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 11:31:24 pm
"although it keeps thinking that a space = a new equation"
thats a..ehh..... undocumented feature! er..yeah that's it, not a bug...

but seriously, hmm, interesting, that must be doind that at a high level, higher than the classes I'm testing, because its giveing the whole output thing.
seems to indeed be a 'feature' of cin and/or string.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 11:34:52 pm
hmm hadn't thought of that, looks like I'm going to have to make a class of unary operators also.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 27, 2005, 11:44:12 pm
ok, I need to sleep, if you want to play with this tonight, here is the full source for that console app. seems like I'm going to have to pre process the input infix data and find unary '-'s and give them some specal tolken. then add a whole new class of opperators that only have one operand, I was going to need to do this eventualy to suport sin, cos, (ect).
sleepy time :)

Code: [Select]
#include
#include
#include
#include
#include

using namespace std;

struct ship{
float a;
};

class variable{
public:
virtual float value(ship*shipp=NULL) = 0;
};

class constant:public variable{
float val;
public:
constant(float in):val(in){};
float value(ship*shipp=NULL){return val;};
};


class operate:public variable{
protected:
variable *operand1, *operand2;
public:
virtual float value(ship*shipp=NULL) = 0;
operate(variable*op1, variable*op2){operand1 = op1; operand2 = op2;}
~operate(){if(operand1)delete operand1; if(operand2)delete operand2;}
};


class add:public operate{
public:
add(variable*op1, variable*op2):operate(op1,op2){}
float value(ship*shipp=NULL){return operand1->value(shipp) + operand2->value(shipp);}
};

class sub:public operate{
public:
sub(variable*op1, variable*op2):operate(op1,op2){}
float value(ship*shipp=NULL){return operand1->value(shipp) - operand2->value(shipp);};
};

class divide:public operate{
public:
divide(variable*op1, variable*op2):operate(op1,op2){}
float value(ship*shipp=NULL){return operand1->value(shipp) / operand2->value(shipp);};
};

class power:public operate{
public:
power(variable*op1, variable*op2):operate(op1,op2){}
float value(ship*shipp=NULL){return(float)pow(operand1->value(shipp), operand2->value(shipp));};
};

class mult:public operate{
public:
mult(variable*op1, variable*op2):operate(op1,op2){}
float value(ship*shipp=NULL){return operand1->value(shipp) * operand2->value(shipp);};
};


class expression:public variable{
int n_var; //number of variables in the expression
variable *head; //the head of the expression

void postfix(string&);
variable* parse_next(char*&);
variable* get_ship_variable(char**);
public:
expression(char*);
~expression(){for(int i = 0;i float value(ship*shipp=NULL);
};

/*
variable* con = new constant(1.0f);
variable* op = new add(con,con);
*/


expression::expression(char* in_str):n_var(0),head(NULL){
string str = in_str;
postfix(str);
char* is = new char[str.length()+1];
char* os = is;
strcpy(is, str.c_str());
head = parse_next(is);
delete[]os;
}

variable* expression::parse_next(char*&in_str){
//kill any noise
while((*in_str == ' ' || *in_str == ' ') && *in_str != char(0))in_str++;

char ship_idnt[] = "ship:";
char op_char[] = "+-/*^";
if(!strcmp(in_str,ship_idnt)){
(*in_str)+=strlen(ship_idnt);
//it's a ship variable
return get_ship_variable(&in_str);
}else{
//it's a constant, or an opporateor
if(strchr(op_char, *in_str) && *(in_str+1) == ','){
//it must be an operator
char o = *in_str++;
if(*in_str == ',')in_str++;

variable*a = parse_next(in_str);
variable*b = parse_next(in_str);

switch(o){
case '+':return new add(a,b);
case '-':return new sub(a,b);
case '*':return new mult(a,b);
case '/':return new divide(a,b);
case '^':return new power(a,b);
}
}else{
//it must be a constant
char *str = in_str;
while(*(in_str) != ',' && *in_str != 0)in_str++;
if(*in_str == ',')in_str++;
return  new constant(atof(str));
}
}

return NULL;
}

variable* expression::get_ship_variable(char**){
return new constant(0.0f);
}

inline int get_value(char c){
switch(c){
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
default:return -1;
}
}

bool is_value(char c){
if(c >= '0' && c <= '9')return true;
if(c == '.')return true;
return false;
}
void fix_implied_mult(string &str){
for(int i = 1; i< str.length(); i++){
if(str[i] == '('){
if(!get_value(str[i-1]))
str.insert(i,"*");
}
}
}

void reverse(string&s){
string out = "";
int l = s.length();
string temp = "";
for(int i = 0; i for(i; i temp += s[i];
if(!is_value(s[i]) || !is_value(s[i+1]))break;
}
out.insert(0,temp);
temp = "";
}
s = out;
}

void expression::postfix(string& str){
string s = str;
fix_implied_mult(s);
stack op_stack;

string out;
reverse(s);

int i = 0;
while(s[i]){
if(is_value(s[i])){
int sidx = i;

while(is_value(s[i]))out+=s[i++];

if(s[i] == '-' && (s[i+1] == 0 || s[i+1] == '(' || get_value(s[i+1]) != -1)){
out+="-";
i++;
}

out+=',';
}else if(s[i] == ')'){
op_stack.push(s[i++]);
}else if(s[i] == '('){
while(op_stack.top() != ')'){
out+=op_stack.top();
op_stack.pop();
out+=',';
}
op_stack.pop();
i++;
}else{
int v = get_value(s[i]);
if(v){
//it's an opperator
if(op_stack.empty() || op_stack.top() == ')' || get_value(op_stack.top()) <= v){
op_stack.push(s[i++]);
}else{
while(!op_stack.empty() && get_value(op_stack.top()) > v){
out+=op_stack.top();
op_stack.pop();
out+=',';
}
op_stack.push(s[i++]);
}
}
}
}
while(!op_stack.empty()){out+=op_stack.top(); op_stack.pop(); out+=',';}
out.resize(out.length()-1);
reverse(out);

str = out;
}

float expression::value(ship*shipp){
return head->value(shipp);
}


void main(){
string str = "";
// string str = "(1+2)*(3+4)*(5+6)";
// string str = "1+(2+3*4^(5-3)-7)*3";
// string str = "1+2+3*4^5-6-7*8";
// string str = "1+2*3+4";
// string str = "1*(2+3)";
// string str = "2*3/(2-1)+5*(4-1)";
// string str = "49*49-49";

cout << "enter an expression or type exit to do so\n";
cin >> str;
while(str!="exit"){
char test[512];
strcpy(test, str.c_str());
expression exp(test);
// cout << pow(4.0f,5.0f);
cout << "\n" << str << " = " << exp.value() << "\nif this is not corect, please tell me and provide the expression you entered\n\nenter another expression or type exit to do so:\n";
str = "";
cin >> str;
}
cout << "thank you for testing me";
}

Title: absolutely critical that you play with this small stand alone app
Post by: Anaz on April 28, 2005, 12:12:53 am
it is actually a "feature" of cin. cin leaves whatever comes after whitespace in the input stream without removing it. use cin.getline() instead if you want to avoid that particular feature.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 28, 2005, 12:13:53 am
This is one reason why I never use cin, cout, or filestreams. :p
Title: absolutely critical that you play with this small stand alone app
Post by: Drew on April 28, 2005, 12:35:49 am
1-2*2 = -3
wrong
Title: absolutely critical that you play with this small stand alone app
Post by: StratComm on April 28, 2005, 01:06:22 am
Actually Drew that's right.  1-4 is -3.
Title: absolutely critical that you play with this small stand alone app
Post by: Carl on April 28, 2005, 01:26:05 am
Multiplication comes before subtraction in orders of operation, Drew.
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 28, 2005, 08:43:06 am
Bobb: What about doing what the TI calculators do and use a different minus sign for the negative and the substraction? Use an underscore or something for one of them.
Title: absolutely critical that you play with this small stand alone app
Post by: Drew on April 28, 2005, 10:34:09 am
Quote
Originally posted by StratComm
Actually Drew that's right.  1-4 is -3.


not when you work the operations seperate.  whatever.
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 28, 2005, 10:35:06 am
WMC, I hope you don't mind me using your example :p.

-(2^-(3)+1)-3=10 FALSE
-1*(2^(-3)+1)-3=4.125 TRUE

It's all in the way you write the equation.  In basic, low level mathematics, the first statement is invalid.  Understood elements cannot be parsed, because the program doesn't know what understood element it is.  Therefore, direct logical equations must be used.

EDIT:  If I may ask, why are we playing with this calculator?  What is it for?
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 28, 2005, 12:52:10 pm
Quote
Originally posted by kasperl
Bobb: What about doing what the TI calculators do and use a different minus sign for the negative and the substraction? Use an underscore or something for one of them.


It'd be a real pain to do that since you'd have to open up charmap every time you wanted to use a negative.

Although I suppose tilde or something could be subbed in...it'd make the code less readable though.
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 28, 2005, 12:55:46 pm
I know it isn't fun for readability, but it'd save a ****load of coding, and quite a few ambiguities.
Title: absolutely critical that you play with this small stand alone app
Post by: Anaz on April 28, 2005, 04:37:06 pm
or do something like using tilde or another character as your "negative" minus sign rather than subtraction operation.
Title: absolutely critical that you play with this small stand alone app
Post by: Taristin on April 28, 2005, 04:53:40 pm
screw readability, once you get it working once, don't touch it again :p
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 04:54:14 pm
I think I'm going to have any time it finds a '-' without an operand on either side it'll replace it with '-1*', sence -# is working
Title: absolutely critical that you play with this small stand alone app
Post by: StratComm on April 28, 2005, 05:05:48 pm
what about (a)-(b)?
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 05:32:51 pm
this change fixes it I think.

it actualy replaces any '-' that does not have a valid charicter before it with '(-1*' and finds the end of the block it's being multiplyed with and adds a ')'
so -x is replaced with (-1*x)
-(14*5+3) is replaced with (-1*(14*5+3))

Code: [Select]
void fix_implied_mult(string &str){
for(int i = 0; i< str.length(); i++){
if(i && str[i] == '('){
if(!get_value(str[i-1]))
str.insert(i,"*");
}
if(str[i] == '-'){
if((!i || (!is_value(str[i-1]) && str[i-1] != ')') )){
str.insert(i,"(");
int p = 0;
for(int k = i+2; get_value(str[k]) == -1 || p; k++){
if(str[k] == '(')p++;
if(str[k] == ')')p--;
}
str.insert(k,")");
str.insert(i+2,"1*");
i+=3;
}
}
}
}
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 05:33:28 pm
test build!
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 28, 2005, 05:45:38 pm
Code: [Select]
enter an expression or type exit to do so
-(9+11)

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 05:56:44 pm
Code: [Select]
void fix_implied_mult(string &str){
for(int i = 0; i< str.length(); i++){
if(i && str[i] == '('){
if(!get_value(str[i-1]))
str.insert(i,"*");
}
if(str[i] == '-'){
if((!i || (!is_value(str[i-1]) && str[i-1] != ')') )){
str.insert(i,"(");
int p = 0;
for(int k = i+2; (get_value(str[k]) == -1 || p) && str[k]; k++){
if(str[k] == '(')p++;
if(str[k] == ')')p--;
}
str.insert(k,")");
str.insert(i+2,"1*");
i+=3;
}
}
}
}


ok, try again
Title: absolutely critical that you play with this small stand alone app
Post by: Drew on April 28, 2005, 05:58:41 pm
if i put in -1 by itself, the thing crashes
Title: absolutely critical that you play with this small stand alone app
Post by: Drew on April 28, 2005, 05:59:30 pm
-x by itself crashes in general
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 28, 2005, 06:01:09 pm
Code: [Select]
enter an expression or type exit to do so
-(9+11)

-(9+11) = -20
if this is not corect, please tell me and provide the expression you entered

enter another expression or type exit to do so:
2^-(1)

2^-(1) = 0.5
if this is not corect, please tell me and provide the expression you entered
I think you got that part down, bob :).
Title: absolutely critical that you play with this small stand alone app
Post by: Flipside on April 28, 2005, 06:25:35 pm
-((2/4)*3+(2^2)+6)-3 = -14.5

This seems wrong....

=   -((0.5)*3+(4)+6)-3
= -(1.5)+(10)-3
= -8.5

Though my maths brain cells haven't been used in years, so it could be down to my knowledge of BODMAS ;) It was the only calculation that seemed a bit off.

EDIT : This was prefix 5, I'll try 6 now :) Still -14.5. Someone check my maths, I'm still not certain ;)
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 06:25:32 pm
someone pointed out something screwed up, new version better implyed multiplication suport now.
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 28, 2005, 06:48:56 pm
Sorry flip, your math is wrong :p.  You got the first line right, but you will notice how you made your mistake.

= -((0.5*3)+4+6)-3
= -((1.5)+10)-3
= -(11.5)-3
= -14.5

There was your problem.  As my old math teacher said, "the most important part of an equation is the attention to detail".
Title: absolutely critical that you play with this small stand alone app
Post by: Flipside on April 28, 2005, 06:55:45 pm
Ahhh... yes, the -3 is outside the brackets and so applies after the equation has been inversed :) I'd need another set of brackets to get the result I got ;)

Ah well, told ya it'd been a while ;)
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 07:23:28 pm
because I'm on a computer were I can't save, I'm uploading my code
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 28, 2005, 07:37:04 pm
Compiled version (EXE):
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 28, 2005, 07:43:04 pm
I'm going to assume that the silence means no one has found any more errors...
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 28, 2005, 07:56:06 pm
I tried for an hour to try and break this thing, and it isn't letting me fail, so long as I follow standard mathematical procedure.  However, it seems to think that 0.999_=1 :p.

Suggestions, error handling like ending parenthesis should be present.  Also, how about a root function?  Cubic root of 27 could be written as 3r27, and it would ofcourse resolve to 3.
Title: absolutely critical that you play with this small stand alone app
Post by: Drew on April 28, 2005, 11:17:35 pm
x=x = 0 seems kinda strange but i guess = isnt an treated as an operater
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 12:03:02 am
this isn't an algebraic symbol simplifier, it's an arithmitic evaluator, no '='
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 01:09:40 am
yay!
sin sqrt tan log cos ln!!!

also x#y = the x'th root of y

oh, yeah, modulus (%) is working now.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 01:38:40 am
ok,
1)does everything work
2)what else do I need to add
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 29, 2005, 03:48:58 am
1)I don't know the order of the operations for trig/calc (nor do I know trig/calc period :p), so I can't tell you.
2)That all depends on what it's used for.  You still haven't told us, yet.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 07:17:45 am
well I'm developing this for the materia system, but it'll probly end up getting used in a new HUD system and linked animations.

come on now folks were in the home streach, don't quit on me now...
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 29, 2005, 08:58:20 am
Rad/degree?
I do see it is in radians.
You still need to implement ! (3!=1*2*3).
Do we have arctan, arcsin, and arccos?

It doesn't seem to support unreal answers, btw.


We either need constants like pi available, or some kind of accuracy control:
sin(3.1415926) = 1.50996e-007'
(My TI says sin(pi)=0, like it's supposed to.
It does work when not aproaching zero:
cos(3.1415926) = -1.

tan((1/8)3.1415926) = 0.125655
TI:
tan((1/8)pi)=.414213
Perhaps it doesn't  multiply when no char found.
Indeed it doesn't....
tan((1/8)*3.1415926) = 0.414214

It totally dies when you fo
rget to close your bracket.

It still doesn't trow out an error if it doesn't support the operand.
(arcsin(1)=0)

EDIT:
Log and ln work as expected, ditto for #.
We definately need constants though, stuff with e in it just gets odd.)
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 09:14:47 am
try PI and E

"sin(3.1415926) = 1.50996e-007'" that is what's known as a rounding error, that's as close to right as a computer ever gets.

I need to fix implied multiplication for the closeing side of parenthises aparently.

and also added to the todo list, better parenthises error handleing, it shouldn't be too hard to append the corect number of parenthises to the end of an expression, or at the very least handle it without crashing.

will add arc* and hyperbolic trig functions when I get home tonight. any other unary {y=f(x)} functions anyone wants?

I supose a degree(radian_number) and radian(degree_number) should be added.
and I'll add factorial.
and I'm not going to suport imaginary numbers.
Title: absolutely critical that you play with this small stand alone app
Post by: Col. Fishguts on April 29, 2005, 09:27:53 am
Erm...are arcsin(), arccos(), etc. in ?
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 09:30:13 am
not yet, and if you try to use them it will quite likely crash, at the very least it'll give bizar output if anything.
as I said, I will get them in tonight, it'll be a trivial matter to add these.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 10:01:41 am
just thought of something to add, log of a variable base. how's this sound X~B gives you the log(base B) of X
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 29, 2005, 10:19:31 am
Well, log(x)/log(b) works fine....

And any operator or function it doesn't recognise will return zero, it seems. It really should return an error, IMHO.

I'm simply looking at the catalog of functions on my TI and putting anything of which I know what it does and isn't in yet.

abs(x)
(wtf is cosh?)
Degree/Rad conversion
Dec-->Frac might be handy, but I doubt it'll work...
int( ). (I think it'll give the rounded int value of anything it gets)
rand might be a good thing somehow....
That was the TI catalog, anyway, dunno about anything else.

Do you want probability calculations?
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 10:39:39 am
cosh is hyperbolic cosine, I'll be adding all three hyperbolic functions.

the thing with log is, the fewer variables (opperators are counted as variables) used the better, so if I can make an opperator that can do something common with being passed two variables (1 opp + 2 param = 3 variables) rather than useing 6 it'll be twice as fast, the evaluation uses recersive calls to many derived claasses so it is inherently slow as it is.

ipart and fpart would probly come in usefull
abs() definately!
there realy isn't any way to use fractions like that, evaluateing an expression is built from the ground up to return only a floating point value, not another expression. although makeing a function to take a float and display a fraction might be nice to have around in general.
rand() would defenately be useful (I can think of a material for flickering debris would use it right away), two implementations a 'rand' wich returns a number between 0.0 and 1.0 and a range version, I'm thinking 'A?B', returns a value between A and B, though I might want to reserve '?' for posable conditionals later on.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 10:52:09 am
ok so the complete list of functions that are not currently suported but will be a short time after I get home tonight are(is? :wtf:.. anyway):
arcsin(x)
arccos(x)
arctan(x)
hypsin(x)
hypcos(x)
hyptan(x)
degree(x)
radian(x)
!(x)
abs(x)
ipart(x)
fpart(x)
sign(x)
rand {and a binary verion for range, needs to be one charicter long}
~ {log of variable base}
Title: absolutely critical that you play with this small stand alone app
Post by: Col. Fishguts on April 29, 2005, 10:55:18 am
Quote
Originally posted by Bobboau
not yet, and if you try to use them it will quite likely crash, at the very least it'll give bizar output if anything.
as I said, I will get them in tonight, it'll be a trivial matter to add these.


Ah...I overread that. It doesn't crash though, just returns 0.

For other functions:

- Complex numbers (if there's any use for them)
- sign(x) is handy sometimes
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 29, 2005, 11:46:38 am
sign?

Complex numbers, I reallly can't  see any use for those in materials or the HUD....
Same thing with Probability calculation, I geuss.

Some way to do formulas and derivations might be needed somewhere in the HUD thing if you want stuff with distance/speed/accel, but you couldn't do it properly since you don't have a proper formula for anything. I think just doing (f(x)+f(x+h))/h is the only really probably way of working that in. You might want a function for that, if it really saves time.  I can see functions like that being used in the HUD a LOT.

BTW, is there any limit on the number of brackets one can use?
Title: absolutely critical that you play with this small stand alone app
Post by: Col. Fishguts on April 29, 2005, 11:52:52 am
sign(x) =

=  1 for x > 0
=  0 for x = 0
= -1 for x < 0
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 12:08:55 pm
added.

I realy don't think that there is any way to do derivitives/integrals properly, there is no way of getting what the value of something was last frame (though frame time should be available) anything that you'd want the information for it will probly have a hard coded ship variable for it anyway. so I don't think I'm even going to contemplate any calc opperations, so no df/dx.

there is no limit on the size or complexity of the function (in theory) and you should be able to use as many parenthises as you want (so long as you make sure you close them all)
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 29, 2005, 01:43:06 pm
'nother question: Any way at all to do something a bit more permanent then a single frame? It'd be a good thing for the HUD, obviously, and also when you need to do flickering materials you need to record a certain length of time, I would think.
Since framerates can vary greatly, and you don't want to cause a migraine/epiliptic attack for those with a good rig, while those on a slower computer see the flickering once a second. (Gross exeguration, but you get the idea.)

Would SEXP variables be accesable by this part of the code? (I'm thinking HUD here again.)
Title: absolutely critical that you play with this small stand alone app
Post by: StratComm on April 29, 2005, 03:24:23 pm
Like SEXP evaluation or beam damage, this should only be done in fixed intervals.  That's pretty obvious, as you want the effect to be framerate dependent.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 05:02:37 pm
for flickreing you don't need to know anything, you just need to make a simple probablistic formula sign(ipart(rand*(1.0/probability))) will give an out put of 1.0 at the specified probability., it would be constant flickering, so you would do something like sign(ipart(rand*(1.0/(probability*sin(time/10)*sin(time /11)))))

sExp values can be rereived, as well as any global.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 29, 2005, 05:45:09 pm
Bobb, can you (please) make this OO? I have nothing against a probability variable, but something like "math.probability" would make things clearer, and easier to document.

If that seems too long, we could follow with a shorthand system that would allow "m.p", by basically aliasing the command names. sexps could be
Code: [Select]
sexp."variable name" or sx."variable name"
with ships
Code: [Select]
ships."ship".variable or s."ship".variable

I think the OO/shorthand system would let us add mass amounts of variables without running out of names (as often) or having things get disorganized. Whether or not it's true OO or just a string with a dot in it won't matter in the shortterm.

Kasperl: The way that things are handled, if you want to have something flicker half a second, it'll work. FS2 basically increments the mission timer by frametime. If you wanted something to flicker once every two seconds:
Code: [Select]
$Brightness: 255*(mission.time%2)
Freespace would increment the mission.time properly to account for any frame lag, then /2, find the result was either an odd or even number. On an even second, the gauge/texture would be off. On an odd second, the gauge would be on.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 08:55:25 pm
when I said probability in that statement I meant what ever the probability of the light being on was, like if you wanted it to be on half the time then you  would put 0.5 in.
Title: absolutely critical that you play with this small stand alone app
Post by: Setekh on April 29, 2005, 08:59:05 pm
Quote
Originally posted by redmenace

I think this is a school project that involve trees IIRC back to the days of Data Structures.


Hey, that's exactly what I'm learning right now. Abstract data types and stuff - stacks, queues, binary search trees, 2-3 and 2-3-4 trees, heaps... it's fun. :D
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 29, 2005, 10:19:14 pm
Quote
Originally posted by Bobboau
when I said probability in that statement I meant what ever the probability of the light being on was, like if you wanted it to be on half the time then you  would put 0.5 in.


Ohh, alright.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 29, 2005, 11:20:32 pm
though if there is going to be a lot of demand it might be a good idea to make a flicker(x) function, just a thought.

ok, new build I'm prety sure this just about sums everything up, the only thing it lacks is a rand function, because I'm going to use the one in FS already so I need to wait untill I reintegrate, and I've decided on how I'm going to implement it, it will be passed a variable, it will return a number between 0 and the number passed, this will make it simple to implement and generaly flexable.

I haven't done this yet, but it won't matter because it's currently just a stub feature anyway, rather than being passed a ship pointer, I'm going to have it pass an object pointer, and the evaluating functions for each of the ship variables will be able to handle weapons and shock waves and fireballs and any other object type the only place were it won't get a pointer is in the tech room, and in the sky box code.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 30, 2005, 11:14:01 am
ok, once again, I can only assume that the 12 hours of deffoning silence implies that everything is working perfictly, and it's almost tme for me to reintegrate it into the game so I hope there aren't any bugs left.
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 30, 2005, 12:11:39 pm
I couldn't find anything while testing, no. That doesn't mean it's infallible. Especially in the outer bits of the float range the thing will behave oddly.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 30, 2005, 01:06:34 pm
ok, I've worked out the object variable syntax, it's sort of an odd OO style setup, but toaly diferent than any exsisting language (because I already have the '.' defined as part of a number)

all game variables will start off with the ':' charicter, then there will be which groupe of variables you want, currently all I have defined is object (meaning the currently rendered object) but I will likely also have :global, and maybe :player_object and :targeted_object (though this could probly be done via :object{targeted object{whatever}}). after this is a set of {}s with the name of the variable in it so to get the currently rendered object's engine output, you'd type
:object{engine_output}, currently this is being tested with a bunch of stubb data, so it realy isn't anything to test, just look to see if there are any further glareing errors in the last build.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 30, 2005, 01:25:05 pm
Hmm, I dislike that way for a few reasons.
1):object doesn't seam as intuitive as object:
2):object{member objectvar} seems similar enough to functions to be confusing when reading code, and you have to keep track of the number of closing braces...unlike parentheses, they aren't really denoting a section per-se.
3)both the : and the {} characters all require you to hold down shift, which is a little annoying (for me anyway)
4)No other coding language has used that system, as far as I know, unless it's from some shader language...meaning you have to learn + get used to an all new syntax. If we ever implement a full scripting system, it'd add needless confusion as well

Wouldn't it be possible for the parser to do something like this? (this is pseudo-code, as I didn't fully understand how the parser actually parsed the various operators and have to be somewhere in 10 min)
Code: [Select]

if(isletter(currentchar))
{
     while(isletter(currentchar))
     {
           currentchar++;
     }
     if(currentchar=='(')
          return THIS_IS_A_FUNCTION;
     else if(currentchar=='.')
     {
          return THIS_IS_AN_OBJECT_ITEM;
          //Next function does this
          if(currentobject)
               add_object_child(currentparseitem);
     }
     else
     {
          parse_error("Somebody used an invalid thingamabob!");
     }
}


Unless you've got another reason for using the :{} syntax or that'd be really hard to do with the current parser

I still need to test the last build.

Edit: SYNTAX ERROR :p
Title: absolutely critical that you play with this small stand alone app
Post by: kasperl on April 30, 2005, 01:56:19 pm
Disabling smilies might be a good idea BTW....
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 30, 2005, 02:50:31 pm
yeah

and the reason I have a thing to start and end members is because the string gets read backwards so I need something to denote the end of a member as well as the begining of a game variable, when the string is getting converted to postfix notation it is reversed, ans what if by sone twist of fate the end of a mamber variable hapens to end in "log" or "sin" or something that I already have a check for, it's just simpler to go if you fiind '}' copy everything untill you find ':'. '}' isn't currently used by anything so the only posability is that we have a member of an object.
I doubt anyone useing this is going to be a coder, so it doesn't matter if it looks like function syntax.

I supose I could change it to :object.member: everything between two colens gets coppied as a single operand. but I've already started integrateing it into the game again, so I'll just have to wait untill I get the game working with it again, it should be a simple change.
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 30, 2005, 05:02:43 pm
Yeah, I sort of like that better.

Couldn't you check if 'log' actually is the end of a word or a variable? Since all variables would have '.' in 'em, any contiguous string with a '.' should automatically be processed as a variable.

I can try and do that once you've got it into CVS.
Title: absolutely critical that you play with this small stand alone app
Post by: MatthewPapa on April 30, 2005, 08:19:11 pm
20*.3 = 6
??? Since when.
And since when does 9999*.3 = 2999.7
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 30, 2005, 08:28:33 pm
ummm... sence decimal numbers were invented I supose, so... I don't know... 2500 B.C. maybe?

those are corect. at least acording to my $150 calculator, and MScalculator, and google... am I missing something?
Title: absolutely critical that you play with this small stand alone app
Post by: Taristin on April 30, 2005, 08:40:04 pm
Quote
Originally posted by MatthewPapa
20*.3 = 6
??? Since when.
And since when does 9999*.3 = 2999.7


You're thinking division.

.3, 20 times, is 6 ;)
Title: absolutely critical that you play with this small stand alone app
Post by: WMCoolmon on April 30, 2005, 09:36:55 pm
.3 is 3/10.
Title: absolutely critical that you play with this small stand alone app
Post by: Bobboau on April 30, 2005, 10:27:45 pm
well it's good that my code is starting to out think some peaople... probly...
Title: absolutely critical that you play with this small stand alone app
Post by: Scuddie on April 30, 2005, 10:33:02 pm
We don't know that...  Yet :p.
Title: absolutely critical that you play with this small stand alone app
Post by: MatthewPapa on May 01, 2005, 12:36:07 pm
Quote
Originally posted by Raa


You're thinking division.

.3, 20 times, is 6 ;)


Thats what im saying. I was just wondering if that might be a problem.....whatever.