vitoco Posted January 30 Share Posted January 30 Home page: https://gkanold.wixsite.com/homeputerium/copy-of-rules Key info: - Deadline: Saturday, March 16, 2024, 18:00 CET - Awards Ceremony: Saturday, April 6, 2024 6 1 Quote Link to comment Share on other sites More sharing options...
Preppie Posted January 30 Share Posted January 30 Cool, guess I'll have to put a pause on learning Defold. Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 4 Share Posted February 4 Just thought I'd add any little tips I find out while making a 10 liner. This may have been posted before but I can't remember. When using boleens in FastBASIC do the boleen test first will give a speed increase. instead of: a=a+(b=c) use: a=(b=c)+a in a 10,000 loop (empty loop times at 102 jiffies) the first took 367-102=265 jiffies and the second took 336-102=234 jiffies. It's only a small increase in speed but sometimes that's the difference between a steady 50fps and dropping frames. 5 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 4 Share Posted February 4 Hi! 4 hours ago, Preppie said: Just thought I'd add any little tips I find out while making a 10 liner. This may have been posted before but I can't remember. When using boleens in FastBASIC do the boleen test first will give a speed increase. instead of: a=a+(b=c) use: a=(b=c)+a in a 10,000 loop (empty loop times at 102 jiffies) the first took 367-102=265 jiffies and the second took 336-102=234 jiffies. It's only a small increase in speed but sometimes that's the difference between a steady 50fps and dropping frames. Note that this will be true fo many expressions, in general "a = some_expression + b" is faster than "a = b + some_expression". Have Fun! 1 1 Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 4 Share Posted February 4 Thx, I figured that would be the case but didn't do full testing. Quote Link to comment Share on other sites More sharing options...
OxC0FFEE Posted February 14 Share Posted February 14 Now that I've got most of my tenliner's game logic and details done, I get to the truly hard part and contemplate a rewrite. TBXL or Fastbasic... FB does offer procedures with arguments, but unless they're local variables inside the procedure (which I suspect they're not) I'm not sure it offers any benefit for writing recursive code. @dmsc? Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 15 Share Posted February 15 Hi! 3 hours ago, OxC0FFEE said: Now that I've got most of my tenliner's game logic and details done, I get to the truly hard part and contemplate a rewrite. TBXL or Fastbasic... FB does offer procedures with arguments, but unless they're local variables inside the procedure (which I suspect they're not) I'm not sure it offers any benefit for writing recursive code. @dmsc? Yes, parameters in procedures are not local, so you can't call a procedure recursively and expect them to retain the value. But of course, you can implement recursion if you save the values in an array, and the parameters are a good way to minimize your program in a tenliner 🙂. Do you have a recursive function that need to implement? This is an example of a recursive QuickSort, using an array as a stack to store the variables that need to be preserved between calls: proc QSort i0 i1 if i1 < i0 + 10 ' Use insertion sort for small arrays for i=i0 to i1-1 temp = p(i+1) for j=i to i0 step -1 if (p(j)) <= (temp) then exit p(j+1) = p(j) next p(j+1) = temp next else ' Set pivot to 'i1', do the partition temp = p(i1) j0 = i0 - 1 j1 = i1 do repeat : inc j0 : until (p(j0)) >= (temp) repeat : dec j1 : if j1 = i0 then exit : until (temp) >= (p(j1)) if j0 >= j1 then exit x = p(j0) : p(j0) = p(j1) : p(j1) = x loop p(i1) = p(j0) : p(j0) = temp ' Recurse over smaller sub-array first stack1(lvl) = j0 if i1 - j0 > j1 - i0 stack0(lvl) = i1 : inc lvl @QSort i0, j0 - 1 : dec lvl @QSort stack1(lvl) + 1, stack0(lvl) else stack0(lvl) = i0 : inc lvl @QSort j0 + 1, i1 : dec lvl @QSort stack0(lvl), stack1(lvl) - 1 endif endif endproc The above can be minimized to: pr.QS i j:ifj<=i t.ex.:t=p(j):k=i-1:m=j:do:r.:inck:u.p(k)>=t:r.:decm:u.m<>i a.t>=p(m):ifk>=m t.ex.:x=p(k):p(k)=p(m):p(m)=x:l.:p(j)=p(k):p(k)=t s1(l)=k:ifj-k>m-i:s0(l)=j:incl:@QS i,k-1:decl:@QS s1(l)+1,s0(l):el.:s0(l)=i:incl:@QS k+1,j:decl:@QS s0(l),s1(l)-1:e.:en. Have Fun! 3 Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 15 Share Posted February 15 Here's a little challenge using FastBASIC I need to expand a byte into a word while doubling the bits. eg. number = 129 10000001 -> 11000000 00000011 Needs to be little endian therefore -> 00000011 11000000 Final decimal would be 960 Here's one solution: n=129:b=n&128/2*3+n&64/4*3+n&32/8*3+n&16/16*3+n&8*6144+n&4*3072+n&2*1536+n&1*768 And here's a similar solution using a loop: n=129:t=128:v=2:f.i=0to3:b=n&t/v*3+n&(t/16)*t*48+b:v=v+v:t=t/2:n. Can anyone do any better? Quote Link to comment Share on other sites More sharing options...
vitoco Posted February 15 Author Share Posted February 15 54 minutes ago, Preppie said: Can anyone do any better? n=129:m=&"0123456789ABCDEF"+1:b=p.(m+n/16)*256+p.(m+n&15) The string actually is this sequence of chars/bytes: $00,$03,$0C,$0F,$30,$33,$3C,$3F,$C0,$C3,$CC,$CF,$F0,$F3,$FC,$FF 1 Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 15 Share Posted February 15 Thanks Vitoco I thought about using a lookup table last night but when I woke up to do a bit of coding I forgot lol Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 15 Share Posted February 15 (edited) Just spotted small error: n=129:m=&"0123456789ABCDEF"+1:b=p.(m+n/16)+p.(m+n&15)*256 Needed to multiply 2nd byte 256 not first Edited February 15 by Preppie Quote Link to comment Share on other sites More sharing options...
vitoco Posted February 15 Author Share Posted February 15 21 minutes ago, Preppie said: Just spotted small error: n=129:m=&"0123456789ABCDEF"+1:b=p.(m+n/16)+p.(m+n&15)*256 Needed to multiply 2nd byte 256 not first That's why I got a negative number!!! 😂 42 minutes ago, Preppie said: I thought about using a lookup table last night but when I woke up to do a bit of coding I forgot lol Sometimes my showers are looooong while I'm trying to solve this kind of problems... 😉 2 Quote Link to comment Share on other sites More sharing options...
rdefabri Posted February 16 Share Posted February 16 Ok - there's a slight chance I'll have an entry, maybe in the PUR-80 category. The game sucks, but it's something, and the big if is IF I can get it down to 10 lines. I don't stand a chance to win based on the entries so far, but it will be a bucket list item completed. Quote Link to comment Share on other sites More sharing options...
thank you Posted February 17 Share Posted February 17 So I saw the problem posed by @Preppie but your solution and the solution by @vitoco didn't make sense to me... I'm not fluent in FastBASIC, especially "10-liner'd". But I was interested so I worked out a potentially clever solution using a spreadsheet and some Python: n = 129 t = [0,192,48,240,12,204,60,252,3,195,51,243,15,207,63,255] print(256*t[n//16]+t[n%16]) So now, I understood vitoco's solution... at least I was on the right track. But then I think maybe the lookup table can be replaced by an expression... n = 129 f = lambda x: (x+1)//2*192-x//2*144-84*(x>3)-84*(x>11)-105*(x>7) print(256*f(n//16)+f(n%16)) Now I'm realizing I'm trying to implement Preppie's solution, but he understands it better I'm done here! We should have a monthly 'code golf' type thing so you and the other experts can show off the chops. @rdefabri good luck with your game, I bet you can make it. 3 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 17 Share Posted February 17 Hi! On 2/15/2024 at 9:23 AM, Preppie said: Can anyone do any better? Here is a version without a table - it is still 2 more characters than the table solution by Vitoco, but it does not use any special symbols: n=x/16+x&15*256:n=n!(n*4)&13107:n=n!(n*2)&21845:n=n*3 The way this works is, starting with the binary number ABCDEFGH: 00000000ABCDEFGH n=x/16+x&15*256 0000EFGH0000ABCD n=n!(n*4)&13107 00EF00GH00AB00CD n=n!(n*2)&21845 0E0F0G0H0A0B0C0D n=n*3 EEFFGGHHAABBCCDD Have Fun! 1 Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 17 Share Posted February 17 thx, I knew you'd have something special for me btw: we can save 2 bytes with that final n=n*3 x=129:n=x/16+x&15*256:n=n!(n*4)&13107:n=(n!(n+n)&21845)*3 I've also changed the n*2 to n+n. This will be faster unless your compiler optimizers for this. Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 17 Share Posted February 17 Also, I realised I made a mistake in my logic. I don't need a single word variable, I need 2 separate bytes. I can of course do this using one of the above techniques, so now I have multiple ways of doing it I can figure out the best solution. What I'm actually using this for is as follows. I have a 2x2 gr.0 character which has a P/M overlay for the outline in a different color. I wanted to merge the character with the background image so it looked better but that would require a lot of mask data but I don't have the space for it. Then it occurred to me that I could transform the P/M data into character data for the mask which is why I needed this little routine. The mistake is that the character data is laid out differently so I can't dpoke the mask data into the character set data, I need to poke the individual bytes. Anyway, thanks for all the help 1 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 17 Share Posted February 17 Hi! 18 minutes ago, Preppie said: thx, I knew you'd have something special for me btw: we can save 2 bytes with that final n=n*3 Indeed! and you don't need the parenthesis, so it is now 2 chars less than the table based one: n=x/16+x&15*256:n=n!(n*4)&13107:n=n!(n*2)&21845*3 Have Fun! 1 Quote Link to comment Share on other sites More sharing options...
rdefabri Posted February 17 Share Posted February 17 This is probably a dumb question, but if you have multiple DATA statements, is there a way to combine them? If so, I'm curious how the corresponding READ statements know which data to select? Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 17 Share Posted February 17 Hi! 37 minutes ago, rdefabri said: This is probably a dumb question, but if you have multiple DATA statements, is there a way to combine them? If so, I'm curious how the corresponding READ statements know which data to select? Which BASIC? For example, FastBasic does not have "READ", the data is defined as an array. You can have DATA statement span more than one line: DATA LongVar() BYTE = 0,1,2,3,4,5,6,7,8, DATA BYTE = 9,10,11,12,13,14,15,16,$C0,$80, DATA BYTE = $FF,7,8,9 ? LongVar(10) For other BASIC dialects in the Atari, you can use RESTORE to assign a line to read DATA from. Have Fun! Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 17 Share Posted February 17 I've just spent an hour trying to figure out exactly what's going on with DMSCs code, it's a fascinating piece of bit manipulation - thx for expanding my knowledge Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 18 Share Posted February 18 (edited) After seeing the beautiful bit manipulation my ape brain realised that all I actually need to do is extract each bit in turn, multiply it by 3 and then put it in the correct position in the word. n=129:n=n/16+n&15*16:w=1:f.i=0to7:x=x+n&w*w*3:w=w+w:n. Brute force beats beauty by 1 char edit: I have to initialize x=0 so it's not shorter Edited February 18 by Preppie 1 Quote Link to comment Share on other sites More sharing options...
dmsc Posted February 18 Share Posted February 18 Hi! 1 hour ago, Preppie said: After seeing the beautiful bit manipulation my ape brain realised that all I actually need to do is extract each bit in turn, multiply it by 3 and then put it in the correct position in the word. n=129:n=n/16+n&15*16:w=1:f.i=0to7:x=x+n&w*w*3:w=w+w:n. Brute force beats beauty by 1 char edit: I have to initialize x=0 so it's not shorter You can use a REPEAT/UNTIL instead of FOR and use one less variable to do the loop, my result is in N, input in X: i=x/16+x&15*16:w=1:n=0:R.:n=n+i&w*w*3:w=w+w:U.w>255 But it is smaller still if you use the same variable to hold the input and the result. This is the same length as my other solution: n=x/16+x&15*16:I=128:R.:n=n*4+n&I/I*3:I=I+I:U.I<0 What kills this kind of loop is the need to invert the nibbles at the start (the "x/16=x&15*16"), without it it is much smaller. Have Fun! 1 Quote Link to comment Share on other sites More sharing options...
Preppie Posted February 18 Share Posted February 18 Yep, swapping those nybbles is a pain, so I did something without having to do the swap n=129:w=1:r.:x=x+n&(w*16)/2*3+n&w*w*768:w=w+w:u.w>8 This save 4 chars over your last one but maybe some of your magic bit manipulation can shrink it even further. Quote Link to comment Share on other sites More sharing options...
rdefabri Posted February 18 Share Posted February 18 I can't imagine how I can get my code down to 10 lines without some sort of magic. I might have to try a different category or language!!! Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.