Jump to content

Photo

This should be a simple question


18 replies to this topic

#1 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • 965 posts
  • Location:Charlton, MA

Posted Fri Sep 14, 2018 4:34 PM

1 CALL CLEAR
10 T=180
20 PRINT INT(T/30)*100;T/30*100
30 IF T=0 THEN END
40 T=T-1
50 GOTO 20
 

Okay,  I am trying to trigger an event every 30 seconds.

In XB it is easy enough.  However, when I compile, the results are integers

 

I think in the past I just shifted the decimal by multiplying by 10.   I tried that and by 100 but it does not work.

 

I am certain this is easy, I just cannot see it right now....

 

Thanks in advance!

.



#2 senior_falcon ONLINE  

senior_falcon

    Stargunner

  • 1,276 posts
  • Location:Lansing, NY, USA

Posted Fri Sep 14, 2018 6:35 PM

Multiply T*100 first:

20 PRINT INT(T*100/30);T*100/30    (you can simplify to 10/3)

 

When using integers, you get the most accuracy when they are as large as possible, so in the example above multiplying by 100 first gives an answer much closer to the floating point value


Edited by senior_falcon, Fri Sep 14, 2018 6:46 PM.


#3 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • Topic Starter
  • 965 posts
  • Location:Charlton, MA

Posted Fri Sep 14, 2018 8:40 PM

Hey senior_falcon,

I guess I still don't get it?

 

I made a quick change to the sample:

1 CALL CLEAR
10 T=180
15 TIMER=INT(T*10/300)
17 COMP=T*10/300
18 IF TIMER<>COMP THEN 20
19 PRINT T;TIMER;COMP
20 PRINT "NO MATCH"
30 IF T=0 THEN END
40 T=T-1
50 GOTO 15
 

Here is a little of the output from XB:

180  6  6

NO MATCH

NO MATCH

NO MATCH

...

150  5  5

 

 

COMPLIED OUTPUT:

180  6  6

NO MATCH

179  5  5

NO MATCH

178  5  5

NO MATCH

177  5  5

NO MATCH

176  5  5

 

So, in XB, I only trigger the event every 30 seconds  ( iteration in this case )

But Compiled, It triggers every second.

 

For now I am doing IF T=30 or T-60 ....

This is fine for testing, But the idea would be, at hire levels, the time decreases between triggers. 

 

I guess I could do IF T=31-level or T=61-level....  But that seems a bit cheesy.  Also, time per round increases with levels.  I don't want 20 OR's

 

Anyway...  I'll put this aside for tonight, maybe it will hit me in the morning?

 

PS  Your 8Queens demo...  It may be a template to my recursive question I asked earlier.   I get the concept, but I cannot quite grasp this in TI Basic... 

 

Be well.



#4 Asmusr OFFLINE  

Asmusr

    River Patroller

  • 2,943 posts
  • Location:Denmark

Posted Fri Sep 14, 2018 9:03 PM

Perhaps use could use two variables: one for the major ticks and one for the minor? Then you would't need division at all. 



#5 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 821 posts
  • Location:The Great White North

Posted Sat Sep 15, 2018 7:04 AM

Something you might try in compiled BASIC is reading the 1 byte timer that is spinning at address >8378

 

This requires that the interrupts are enabled in the compiled program, so check to see if that is true.

The timer is incrementing every 1/60 of a second so  I think compiled BASIC could  do this.

10   T0=CALL PEEK(33656)
20   T1=CALL PEEK(33656)
40    IF T1=T0 GOTO 20 

This could guarantee a 1/60 second delay.

So put this in a loop 60 times and you get about 1 sec delay.

Wrap it all up in a sub-routine and you have a simple timer.

 

It is also possible to set T1 = T0+X. Then you subtract T1-T0 them in a loop until ABS of the result =0

This way you could get bigger delays in the timer loop.

1 REM 1 second delay ??
10   T0=CALL PEEK(33656)
20   T1=CALL PEEK(33656)+60
40   IF ABS(T1-T0)<>0 GOTO 20
50   RETURN

None of this is tried in BASIC, but it works in that strange language I use. :-)

 

B



#6 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • Topic Starter
  • 965 posts
  • Location:Charlton, MA

Posted Sat Sep 15, 2018 8:51 AM

Thanks TheBF,

I am already using peek to get the 1 second timer working great.

 

So, what is happening is..I start a game round at 180 seconds.  It ticks down to zero.  Every 30 seconds a new game piece is randomly added to the play field.

 

This works great in XB.  However when we compile XB, floating point is lost.  So I cannot compare 179.9 to 180   it becomes 180 to 180.

Triggering the event every cycle.

 

So, I must ask,  What language are you using?



#7 Airshack OFFLINE  

Airshack

    Dragonstomper

  • 855 posts
  • Location:Phoenix, AZ

Posted Sat Sep 15, 2018 8:59 AM

Multiply T*100 first:
20 PRINT INT(T*100/30);T*100/30    (you can simplify to 10/3)
 
When using integers, you get the most accuracy when they are as large as possible, so in the example above multiplying by 100 first gives an answer much closer to the floating point value



Or... Since you’re trying to trigger an event every 30 seconds why not use the CALL DELAY function from XB256 which works hand-in-hand with the compiler?

#8 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,350 posts
  • HarmlessLion
  • Location:BUR

Posted Sat Sep 15, 2018 3:01 PM

Or... Since you’re trying to trigger an event every 30 seconds why not use the CALL DELAY function from XB256 which works hand-in-hand with the compiler?

 

Wouldn't that block the rest of the program?

 

I wanted to second the idea of using two variables, a minor counter and a major counter. That's the simplest integer way to deal with fractional values, and it makes it easy to have any fraction you want. ;)



#9 senior_falcon ONLINE  

senior_falcon

    Stargunner

  • 1,276 posts
  • Location:Lansing, NY, USA

Posted Sat Sep 15, 2018 4:53 PM

This does the same thing as your example in post #3 and works the same when compiled:
 
1 CALL CLEAR
10 T=180
15 TIMER=30*INT(T/30)
18 IF TIMER<>T THEN 20
19 PRINT T;TIMER;COMP
20 PRINT "NO MATCH"
30 IF T=0 THEN END
40 T=T-1
50 GOTO 15


#10 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • Topic Starter
  • 965 posts
  • Location:Charlton, MA

Posted Sat Sep 15, 2018 7:07 PM

TIMER=30*INT(T/30)

 

Yup, that did the trick!   I knew it would be simple.  For someone else!

 

Thank you senior_falcon Again!

 

I will also play with the multiple timers, just as a test.  This solution falls right in place with my game loop.

 

Thanks to all!



#11 Bones-69 OFFLINE  

Bones-69

    Chopper Commander

  • 206 posts
  • Location:Australia

Posted Sun Sep 16, 2018 2:22 AM

.

Edited by Bones-69, Sun Sep 16, 2018 2:37 AM.


#12 Bones-69 OFFLINE  

Bones-69

    Chopper Commander

  • 206 posts
  • Location:Australia

Posted Sun Sep 16, 2018 2:38 AM

As another idea (something I have been experimenting with) - You could put an invisible sprite in motion and use its Position to trigger events. The good thing about this is you can go about your business and as long as you check the position occasionally the "timer" will keep ticking along without any ongoing maintenance.... 

 

This example will fire approximately every 30 seconds, give or take...

100 CALL CLEAR
110 CALL SPRITE(#1,32,1,8,1,0,1)
120 CALL POSITION(#1,A,B):: DISPLAY AT(10,1):"SECONDS";INT(B/3.8)
130 IF B<117 THEN 120 :: CALL SOUND(100,200,0):: GOTO 110

Edited by Bones-69, Sun Sep 16, 2018 2:45 AM.


#13 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • Topic Starter
  • 965 posts
  • Location:Charlton, MA

Posted Sun Sep 16, 2018 5:22 AM

That is interesting.

 

Maybe it would be cool to show the sprite as a visual to when the next event will fire?

Also, It could be used as kind of a random number.  Wen the position is polled.  Though it would be in a rolling range,  which also could be useful.

 

I am very happy with the current method I am using, But I will keep this in mind.



#14 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,350 posts
  • HarmlessLion
  • Location:BUR

Posted Sun Sep 16, 2018 1:10 PM

 

As another idea (something I have been experimenting with) - You could put an invisible sprite in motion and use its Position to trigger events. The good thing about this is you can go about your business and as long as you check the position occasionally the "timer" will keep ticking along without any ongoing maintenance.... 

 

This example will fire approximately every 30 seconds, give or take...

100 CALL CLEAR
110 CALL SPRITE(#1,32,1,8,1,0,1)
120 CALL POSITION(#1,A,B):: DISPLAY AT(10,1):"SECONDS";INT(B/3.8)
130 IF B<117 THEN 120 :: CALL SOUND(100,200,0):: GOTO 110

 

That's a trick I've liked for a long time! I first saw it in Cavern Quest for XB (at least I think it was Cavern Quest). It was a typical XB "CALL COINC(ALL)" affair, and it created a timer by setting up two sprites at the top of the screen, one moving towards the other. When they collided, you'd die due to the COINC, making a very clever and free timer. ;)



#15 Bones-69 OFFLINE  

Bones-69

    Chopper Commander

  • 206 posts
  • Location:Australia

Posted Sun Sep 16, 2018 3:34 PM

 

That's a trick I've liked for a long time! I first saw it in Cavern Quest for XB (at least I think it was Cavern Quest). It was a typical XB "CALL COINC(ALL)" affair, and it created a timer by setting up two sprites at the top of the screen, one moving towards the other. When they collided, you'd die due to the COINC, making a very clever and free timer. ;)

 

And here I was thinking this was my fantastic and original idea..... 



#16 Tursi OFFLINE  

Tursi

    Quadrunner

  • 5,350 posts
  • HarmlessLion
  • Location:BUR

Posted Sun Sep 16, 2018 5:28 PM

 

And here I was thinking this was my fantastic and original idea..... 

 

The author /clearly/ traveled forward in time to steal your idea. Keep the credit, it's yours! ;)



#17 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 821 posts
  • Location:The Great White North

Posted Sun Sep 16, 2018 6:28 PM

Thanks TheBF,

I am already using peek to get the 1 second timer working great.

 

So, what is happening is..I start a game round at 180 seconds.  It ticks down to zero.  Every 30 seconds a new game piece is randomly added to the play field.

 

This works great in XB.  However when we compile XB, floating point is lost.  So I cannot compare 179.9 to 180   it becomes 180 to 180.

Triggering the event every cycle.

 

So, I must ask,  What language are you using?

 

I play with Forth and everything is integers so from that perspective it a little easier to do these low level things.

Like working in Assembler.

 

One that is commonly done in integer math is to scale numbers to get fractional values.

For example you cannot compare 179.9 and 180, but you CAN compare 1799 to 1800, or 17990 to 18000 as long as you know the multiplication factor.

 

Forth a nice operator that does a multiply and divide.

It multiplies giving 32 bit result and then divides that result with a 16 bit int.

This handy for scaling integers to fractional values.



#18 1980gamer OFFLINE  

1980gamer

    Dragonstomper

  • Topic Starter
  • 965 posts
  • Location:Charlton, MA

Posted Sun Sep 16, 2018 7:02 PM

I think part of the problem is...  I don't have to be as clever in modern languages or even scripting languages.

You can easily convert or cast data types or use % MOD etc.

 

I know I handled this in the past,  but I stayed away from the TI and compiler for 18-24 months.  At this age... You flush info faster.  LOL

 

But I was recently inspired and had several ideas to work on.  So, I have been plugging away with the help of the friendly community here.

 

I am hoping to squeeze some memory and finish this up.  But it is getting tight and I may need to scrap a few pieces?



#19 TheBF OFFLINE  

TheBF

    Dragonstomper

  • 821 posts
  • Location:The Great White North

Posted Mon Sep 17, 2018 7:08 AM

I think part of the problem is...  I don't have to be as clever in modern languages or even scripting languages.

You can easily convert or cast data types or use % MOD etc.

 

I know I handled this in the past,  but I stayed away from the TI and compiler for 18-24 months.  At this age... You flush info faster.  LOL

 

But I was recently inspired and had several ideas to work on.  So, I have been plugging away with the help of the friendly community here.

 

I am hoping to squeeze some memory and finish this up.  But it is getting tight and I may need to scrap a few pieces?

 

Yes modern languages do pretty good job of hiding the low level details so you can get work done. 

 

I am not sure how tight the code is from the compiler, but sometimes a solution for size is to replace a key routine, preferably one that is used more than once, with an assembler version.

 

If you hit the wall, perhaps a collaboration with some of the excellent Assembly language talent here could help shoe-horn everything in. ?

 

Keep plugging on it. These things keep us young. 






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users