game maker
Gebruikersnaam:
Wachtwoord:
Home Info Forums Help
Welkom, Gast. Alsjeblieft inloggen of registreren.
De activerings e-mail gemist?
+  Forums
|-+  Werken met Game Maker
| |-+  Experts
| | |-+  Berekenen van wiskundige formules
Pagina's: [1]
« vorige volgende »
Print
Advertenties

Yambam
Gebruiker


Offline Offline

Berichten: 70


WWW
« Gepost op: 21 Juni 2016, 14:26:20 »

Ik heb een simpele script gemaakt om de uitkomst te berekenen uit wiskundige formules:

GML:
/* infix_evaluate(infix,ret_fromstack,constants)
 * Evalute infix expression.
 */

var str,ret_fromstack,i,j,k,d,len,newstr,newstr2,op,push,do_push;
str=argument0

push=0
do_push=0

if argument3=0
{
  pcount=string_count('^',str)+2*(string_count('*',str)+string_count('/',str))+3*(string_count('+',str)+string_count('-',str))
  str=pcount*'('+string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(str,'(','((((('),')',')))))'),'^',')^('),'*','))*(('),'/','))/(('),'+',')))+((('),'-',')))-(((')+pcount*')'
  argument3=50
  argument4=ds_stack_create()
  global.ret_stack=argument4
  ret_fromstack=1 //argument1
}
else
  ret_fromstack=0

if string_char_at(str,1)!="("
{
  //show_message('Pushed on stack: '+str)
  if ds_map_exists(argument2,str)
    ds_stack_push(argument4,ds_map_find_value(argument2,str))
  else
    ds_stack_push(argument4,real(str))
  return str;
}

if argument3=1
  return "";

newstr=""
newstr2=""
i=1
j=1
for(k=0;k<2;k+=1)
{
  if string_char_at(str,i)="("
  {
    i+=1
    j=i
    d=1
    len=string_length(str)
    while(d&&i<=len)
    {
      char=string_char_at(str,i)
      if char="("
        d+=1
      if char=")"
        d-=1
      i+=1
    }
  }
  //else if k=0
  //  ds_stack_push(argument4,real(string_copy(str,j,i-1-j)))
  op[k]=string_char_at(str,i)
  //if k=0
  //  show_message('Operator: '+op[k])
  newstr+=infix_evaluate(string_copy(str,j,i-1-j),argument1,argument2,argument3-1,argument4)+" "
  if string_pos(op[k],'^*/+-')&&k=0
  {
    newstr2=" "+op[k]
    //show_message('Operator correct: '+op[k])
   
    do_push=1
    i+=1
  }
  else
  {
    while(string_count('  ',newstr))
      newstr=string_replace_all(newstr,'  ',' ')
    if do_push
    {
      //exec='return '+string(ds_stack_pop(argument4))+op[0]+string(ds_stack_pop(argument4))
      //push=execute_string(exec)
      //show_message(exec)
      b=ds_stack_pop(argument4)
      a=ds_stack_pop(argument4)
      if op[0]='^'
        push=power(a,b)
      else if op[0]='*'
        push=a*b
      else if op[0]='/'
        push=a/b
      else if op[0]='+'
        push=a+b
      else if op[0]='-'
        push=a-b
      //show_message('Pushed operation '+op[0]+' result: '+string(push))
      ds_stack_push(argument4,push)
    }
    if ret_fromstack
      return ds_stack_pop(argument4);
    return newstr+newstr2;
  }
}

Je kunt ervoor kiezen om het eindresultaat uit de stack te krijgen. Of je kunt ervoor kiezen om de (infix)expressie gewoon te converteren naar prefix, dan krijg je bijvoorbeeld i.p.v. "4*(5+3)" "5 3 + 4 *".

Voorbeelden van gebruik:
  • Initialiseren:
GML:
map=ds_map_create()
ds_map_add('pi',pi)

GML:
show_message(infix_evaluate("10*10+5*4",1,map))
  • Resultaat: 154
GML:
show_message(infix_evaluate("3*10^2",1,map))
  • Resultaat: 300
GML:
show_message(infix_evaluate("3*(1+2)",1,map))
  • Resultaat: 9
GML:
show_message(infix_evaluate("2*pi",1,map))
  • Resultaat: 6.28
GML:
show_message(infix_evaluate("10*10+5*4",0,map))
  • Resultaat: 10 10 * 5 4 * +
GML:
show_message(infix_evaluate("3*(1+2)",0,map))
  • Resultaat: 3 1 2 + *

« Laatste verandering: 21 Juni 2016, 18:35:07 door Yambam »



Als je wilt meehelpen met het maken van deze website, stuur mij dan een PM. Blij
Naar boven Gelogd

ShroomProductions
Gebruiker


Offline Offline

Berichten: 1374


« Antwoord #1 Gepost op: 21 Juni 2016, 17:27:21 »

Dat kan best handig zijn. Hoe formuleer je de infix, gewoon als een string?
edit: ik zie het al, maar misschien is het handig om iets uitgebreider uit te leggen hoe je dit gebruikt aangezien dit ook heel nuttig kan zijn voor mensen die het script zelf (nog) niet begrijpen

« Laatste verandering: 21 Juni 2016, 17:33:27 door ShroomProductions »

Naar boven Gelogd

Yambam
Gebruiker


Offline Offline

Berichten: 70


WWW
« Antwoord #2 Gepost op: 21 Juni 2016, 17:31:52 »

Dat kan best handig zijn. Hoe formuleer je de infix, gewoon als een string?
Ja dus je doet bijvoorbeeld infix_evaluate("1+1",1) en dan krijg je 2.

EDIT: Ik heb wat voorbeelden toegevoegd aan de topic.

« Laatste verandering: 21 Juni 2016, 17:40:34 door Yambam »



Als je wilt meehelpen met het maken van deze website, stuur mij dan een PM. Blij
Naar boven Gelogd

ShroomProductions
Gebruiker


Offline Offline

Berichten: 1374


« Antwoord #3 Gepost op: 21 Juni 2016, 17:43:29 »

GML:
//graph
for(i=0; i<300; i++) {
    var val = infix_evaluate(ingewikkelde_berekening_met_i,ret_fromstack) // <-------
    draw_set_color(c_red);
    var xoff, yoff;
    xoff = 332;
    yoff = 16;
    draw_line(xoff+i, yoff+100, xoff+i, yoff+100-val);
};

draw_set_color(c_black);
draw_line(xoff, yoff, xoff+300, yoff);
draw_line(xoff+300, yoff, xoff+300, yoff+100);
draw_line(xoff, yoff+100, xoff+300, yoff+100);

dit tekent een grafiekje, moet je wel even schalen naar je hoogste verwachte uitkomst (even snel uit een project geplukt)

Doe dit trouwens wel op een surface of maak er een sprite van ofzo als je het ingame gaat gebruiken, elke step zo veel lijnen drawen is niet bevorderlijk voor je fps

« Laatste verandering: 21 Juni 2016, 18:08:57 door ShroomProductions »

Naar boven Gelogd

Yambam
Gebruiker


Offline Offline

Berichten: 70


WWW
« Antwoord #4 Gepost op: 21 Juni 2016, 17:50:57 »

Ja dat werkt inderdaad. Gemoedelijk

GML:
//graph
for(i=0; i<300; i+=1) {
    val = infix_evaluate('('+string(i)+'-40)^2-20',1) // <-------
    draw_set_color(c_red);
    xoff = 332;
    yoff = 16;
    draw_line(xoff+i, yoff+100, xoff+i, yoff+100-val);
};

draw_set_color(c_black);
draw_line(xoff, yoff, xoff+300, yoff);
draw_line(xoff+300, yoff, xoff+300, yoff+100);
draw_line(xoff, yoff+100, xoff+300, yoff+100);

Ik zou eigenlijk een systeem voor variables moeten toevoegen.




Als je wilt meehelpen met het maken van deze website, stuur mij dan een PM. Blij
Naar boven Gelogd

ShroomProductions
Gebruiker


Offline Offline

Berichten: 1374


« Antwoord #5 Gepost op: 21 Juni 2016, 18:23:09 »

bij mij doet 'ie  het trouwens niet

Citaat
Final Compile...Error : gml_Object_object0_DrawEvent_1(3) : function "infix_evaluate" expects 4 arguments, 2 provided

als ik twee tijdelijke variabelen mee geef als argument2 en argument3 werkt het ook niet
Citaat
############################################################################################
FATAL ERROR in
action number 1
of Draw Event
for object object0:

DoAdd :: Execution Error
 at gml_Script_infix_evaluate (line 13) -   str=pcount*'('+string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(str,'(','((((('),')',')))))'),'^',')^('),'*','))*(('),'/','))/(('),'+',')))+((('),'-',')))-(((')+pcount*'
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_infix_evaluate (line 13)
called from - gml_Object_object0_DrawEvent_1 (line 6) -     val = infix_evaluate('('+string(i)+'-40)^2-20',1, a, b) // <-------


Naar boven Gelogd

Yambam
Gebruiker


Offline Offline

Berichten: 70


WWW
« Antwoord #6 Gepost op: 21 Juni 2016, 18:26:57 »

Voor die extra arguments geef je in Studio gewoon twee keer 0. In Studio bestaat vermenigvuldigen met tekst niet meer, dus dan moet je regel 13 met dit vervangen:

GML:
str=string_repeat('(',pcount)+string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(str,'(','((((('),')',')))))'),'^',')^('),'*','))*(('),'/','))/(('),'+',')))+((('),'-',')))-(((')+string_repeat(')',pcount)




Als je wilt meehelpen met het maken van deze website, stuur mij dan een PM. Blij
Naar boven Gelogd

R1ckx
Gebruiker


Offline Offline

Berichten: 668

I'm a ghost, and I'm Red. Voeg me toe op steam :D


WWW
« Antwoord #7 Gepost op: 21 Juni 2016, 18:27:37 »

Heel erg handig! Kan je ook doen dat 'pi' veranderd naar 3.1415 en functies zoals wortels of sin/cos/tan toevoegen?


Naar boven Gelogd

ShroomProductions
Gebruiker


Offline Offline

Berichten: 1374


« Antwoord #8 Gepost op: 21 Juni 2016, 18:35:53 »

Voor die extra arguments geef je in Studio gewoon twee keer 0. In Studio bestaat vermenigvuldigen met tekst niet meer, dus dan moet je regel 13 met dit vervangen:

GML:
str=string_repeat('(',pcount)+string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(string_replace_all(str,'(','((((('),')',')))))'),'^',')^('),'*','))*(('),'/','))/(('),'+',')))+((('),'-',')))-(((')+string_repeat(')',pcount)

Nice, nu werkt het  Blij


Naar boven Gelogd

Yambam
Gebruiker


Offline Offline

Berichten: 70


WWW
« Antwoord #9 Gepost op: 21 Juni 2016, 18:36:39 »

Heel erg handig! Kan je ook doen dat 'pi' veranderd naar 3.1415 en functies zoals wortels of sin/cos/tan toevoegen?
Ik heb constanten toegevoegd, nu moet ik alleen nog functies laten werken. Gemoedelijk

Nice, nu werkt het  Blij
Gelukkig. Blij




Als je wilt meehelpen met het maken van deze website, stuur mij dan een PM. Blij
Naar boven Gelogd

Advertenties
« vorige volgende »
Pagina's: [1]
Print


Topic Informatie
0 geregistreerde leden en 1 gast bekijken dit topic.

Ga naar:  

Powered by SMF 1.1.21 | SMF © 2006-2007, Simple Machines
www.game-maker.nl © 2003-2020 Nederlandse Game Maker Community