Author Topic: BASIC programming tips  (Read 26626 times)

0 Members and 1 Guest are viewing this topic.

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #100 on: 02:38, 07 April 18 »
I'm not really sure if it's necessary to use REMAIN with AFTER, though I don't know the circumstances for which what you're using AFTER in, I suppose if AFTER was in a Loop you may need REMAIN in that situation. What I found with AFTER, is a single jump to a subroutine. I used one in my short game Find Red to clear the mosaic grid, which seemed to work fine in that situation, I don't recall having any REMAIN statements in that program, though all that is, is a single jump to clear the mosaic AFTER that time had elapsed.
* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)

Offline skylas

  • CPC464
  • **
  • Posts: 47
  • Country: gr
  • Liked: 76
Re: BASIC programming tips
« Reply #101 on: 14:43, 07 April 18 »
Yes, generally REMAIN is not necessary to be used with AFTER. It is necessary when, depending on player choices in the game, you want to stop the execution of AFTER subroutine.
Imagine for example that (for your game) you give 30 seconds to the player to make his choice. For this, you can use AFTER, and after 30 seconds print <you lose!>. In this case, AFTER has to be disabled by REMAIN in most cases, in which the player has made the choice before 30 seconds. If it is not, then <You lose> will appear in the next turn

Another problem i had has to do with where the program goes after calling the AFTER subroutine, as it doesn't seem to go in the same line every time (as i wanted to send the execution back to the next turn). Using GOTO in the subroutine wasn't the best choice, because the end of the subroutine by RETURN will not be recognized. What i did is setting a variable to 1 in the AFTER subroutine, and then using IF/THEN commands in 2-3 lines in different places in the list i send the program back to the next turn. Hopefully, this works

Nice game in only 10 lines! Well done! Needing careful observing!

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #102 on: 07:07, 08 April 18 »
Yes, generally REMAIN is not necessary to be used with AFTER. It is necessary when, depending on player choices in the game, you want to stop the execution of AFTER subroutine.
Imagine for example that (for your game) you give 30 seconds to the player to make his choice. For this, you can use AFTER, and after 30 seconds print <you lose!>. In this case, AFTER has to be disabled by REMAIN in most cases, in which the player has made the choice before 30 seconds. If it is not, then <You lose> will appear in the next turn


I see, so in your situation you need to cancel the countdown and reinitialize for the next choice. That will need a REMAIN.

Quote
Another problem i had has to do with where the program goes after calling the AFTER subroutine, as it doesn't seem to go in the same line every time (as i wanted to send the execution back to the next turn). Using GOTO in the subroutine wasn't the best choice, because the end of the subroutine by RETURN will not be recognized. What i did is setting a variable to 1 in the AFTER subroutine, and then using IF/THEN commands in 2-3 lines in different places in the list i send the program back to the next turn. Hopefully, this works


Not quite sure I follow, the AFTER statement is a condition where by when it's set, that will initiate after the time has elapsed from within anywhere in the program, it's possible that if your program is doing something else with variables which might interfere with variables within your programs AFTER subroutine, that may cause problems. Normally what happens in that case is if you have areas of code you need protected from the Event Jump from AFTER, you can use DI to Disable Interrupts & EI to Enable Interrupts.

Quote
Nice game in only 10 lines! Well done! Needing careful observing!


Thanks! :)
* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)

Offline skylas

  • CPC464
  • **
  • Posts: 47
  • Country: gr
  • Liked: 76
Re: BASIC programming tips
« Reply #103 on: 16:54, 08 April 18 »

Not quite sure I follow, the AFTER statement is a condition where by when it's set, that will initiate after the time has elapsed from within anywhere in the program, it's possible that if your program is doing something else with variables which might interfere with variables within your programs AFTER subroutine, that may cause problems. Normally what happens in that case is if you have areas of code you need protected from the Event Jump from AFTER, you can use DI to Disable Interrupts & EI to Enable Interrupts.
I looked again to what i had done, as it couldn't remember exactly. We are talking about the situation when player loses, because he has not made the choice and we want to go to the next turn.
So, in that case, AFTER subroutine has been runned. I create a new unused variable in the subroutine, and define A=1. So, in case the subroutine has been runned, A=1.
Then, in the area of inputing, just after X$=inkey$ and before the input choices i entered a line <if A=1 then GOTO> (go the next turn). Of course, A is set to 0 in the start of each turn.
In that way, the game does not wait for inputing of the player choice, and goes to next turn. If not done, after displaying <you lose>, the game will continue the same turn, not the next turn

Offline ZbyniuR

  • 464 Plus
  • *****
  • Posts: 300
  • Country: pl
  • 6128 A1230 PSX Win7
    • Jedyne polskie forum o CPC. :)
  • Liked: 294
Re: BASIC programming tips
« Reply #104 on: 06:23, 09 April 18 »
Short Basic Screensaver with frames. :)

10 MODE 1:INK 0,0:BORDER 0:DEFINT a-z:a$=CHR$(150):b$=CHR$(156):c$=CHR$(147):d$=CHR$(153):e$=CHR$(154):f$=CHR$(149):g$=CHR$(9)
20 INK RND*2+1,RND*26:PEN RND*15 MOD 3+1:x=RND*29+1:y=RND*22+1:s=RND*10+2:w=RND*6+2:LOCATE x,y:PRINT a$STRING$(s,e$)b$:y=y+1:FOR a=1 TO w:LOCATE x,y:PRINT f$STRING$(s,g$)f$:y=y+1:NEXT:LOCATE x,y:PRINT c$STRING$(s,e$)d$;:GOTO 20
« Last Edit: 20:21, 10 April 18 by ZbyniuR »
TREK is better than WARS.

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #105 on: 11:45, 09 April 18 »
I looked again to what i had done, as it couldn't remember exactly. We are talking about the situation when player loses, because he has not made the choice and we want to go to the next turn.
So, in that case, AFTER subroutine has been runned. I create a new unused variable in the subroutine, and define A=1. So, in case the subroutine has been runned, A=1.
Then, in the area of inputing, just after X$=inkey$ and before the input choices i entered a line <if A=1 then GOTO> (go the next turn). Of course, A is set to 0 in the start of each turn.
In that way, the game does not wait for inputing of the player choice, and goes to next turn. If not done, after displaying <you lose>, the game will continue the same turn, not the next turn


I'm not quite sure I follow, but it sounds like the A=1 needs to be in the <You Win> subroutine to take it to the next turn, with the <You Lose> routine to clear variables and restart (RUN) the program.
* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)

Offline skylas

  • CPC464
  • **
  • Posts: 47
  • Country: gr
  • Liked: 76
Re: BASIC programming tips
« Reply #106 on: 19:51, 09 April 18 »
No, maybe my english is not so good and i could't make it clear.
imagine that we expect for an answer from the player.
10 A=0:REM DEFINING VARIABLES, GIVING CHOICES-TURN STARTS
20 AFTER 250 GOSUB 100
30 A$=inkeys
35 if A=1 then goto 10
40 if a$=""A""  then..... etc
50 goto 30
100 PRINT '' YOU LOSE'': A=1:RETURN

In the case of a later answer, LINE 100 IS CALLED. Player loses, but program is still between 30 and 50, and waiting for a player choice.
So, we added line 35 to send the programme to the next turn

Many thx for your interest AMSDOS!

Offline EgoTrip

  • 6128 Plus
  • ******
  • Posts: 1.049
  • Country: gl
    • http://egochip.blogspot.co.uk/
  • Liked: 673
Re: BASIC programming tips
« Reply #107 on: 20:07, 09 April 18 »
Wouldn't it be better to have a WHILE A=0 on line 10, and WEND on line 35, instead of the GOTO?
EgoTrip&#39;s Stuff
EgoTrip's Stuff

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #108 on: 03:10, 10 April 18 »
No, maybe my english is not so good and i could't make it clear.


No I think I'm misreading. Thought you had a problem, when in fact you've found a solution.



* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)

Offline skylas

  • CPC464
  • **
  • Posts: 47
  • Country: gr
  • Liked: 76
Re: BASIC programming tips
« Reply #109 on: 04:58, 10 April 18 »
Maybe WHILE can work too. Due to my very limited knowledge, i use mostly very few commands
Yes, AMSDOS, hopefully is working!

Offline skylas

  • CPC464
  • **
  • Posts: 47
  • Country: gr
  • Liked: 76
Re: BASIC programming tips
« Reply #110 on: 04:36, 16 April 18 »
One more simple question!
When we have an INPUT question of an a$ variable, is there a way to specify that characters must not be over a specific number? (for example i want a$ variable to be not more than 15 characters).
I found LEN, but i wonder if there is a quicker way

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #111 on: 10:07, 16 April 18 »
One more simple question!
When we have an INPUT question of an a$ variable, is there a way to specify that characters must not be over a specific number? (for example i want a$ variable to be not more than 15 characters).
I found LEN, but i wonder if there is a quicker way


As far as I know, INPUT only accepts up to the 255 characters, you could have in your program (15 characters max) and then do some MID$, with something like this (I hope):


Code: [Select]
1000 if LEN(a$)>15 THEN r=15 ELSE r=LEN(a$)
1010 w$=MID$(a$,1,r)


A couple of years ago, I wrote this silly little Condensed Text Name selector using Cursor keys to force the amount of areas to let the user select. It works, but it's a bit cumbersome to use.


EDIT: LEFT$ could also be used, which may have a speed advantage to MID$, so:


Code: [Select]
1010 w$=LEFT$(a$,r)

will do the same job as MID$ in this case.
« Last Edit: 12:32, 16 April 18 by AMSDOS »
* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)

Offline skylas

  • CPC464
  • **
  • Posts: 47
  • Country: gr
  • Liked: 76
Re: BASIC programming tips
« Reply #112 on: 14:06, 16 April 18 »
Many thx AMSDOS! I think LEFT$ is fine!!! I just did'nt know it!

Offline Urusergi

  • CPC6128
  • ****
  • Posts: 159
  • Country: es
  • Liked: 241
Re: BASIC programming tips
« Reply #113 on: 20:54, 29 April 18 »
*** Prime numbers from 2 to 997 in ~5 seconds in one Basic line ***

Code: [Select]
10 MODE 2:ZONE 6:DEFINT a-y:z=TIME:p=3:m=1000:c=SQR(m+1):DIM s(m+1):PRINT 2,:WHILE p<c:PRINT p,:FOR i=p+p*2 TO m STEP p*2:s(i)=1:NEXT:p=p+2:WHILE s(p):p=p+2:WEND:WEND:WHILE p<m:PRINT p,:p=p+2:WHILE s(p):p=p+2:WEND:WEND:PRINT:PRINT(TIME-z)/300;"seconds"
The table is reusable. For example, adding this line:

Code: [Select]
20 CALL &BB18:MODE 2:z=TIME:p=3:PRINT 2,:WHILE p<m:PRINT p,:p=p+2:WHILE s(p):p=p+2:WEND:WEND:PRINT:PRINT(TIME-z)/300;"seconds"
it takes only 4 seconds to show the same prime numbers.
« Last Edit: 21:00, 29 April 18 by Urusergi »

Offline mr_lou

  • 6128 Plus
  • ******
  • Posts: 2.751
  • Country: dk
    • index.php?action=treasury
    • 8-bit Memoirs - a Blu-ray diskmag-like eBook about the 8-bit era
  • Liked: 977
Re: BASIC programming tips
« Reply #114 on: 09:28, 13 October 18 »
I think this question has been asked before, but:

Is there anyway to (from BASIC) fetch the character or character-code currently on the screen on a certain position?

This would require a character-memory-map of some kind, which I don't think the CPC has?

Something like CHARCODE(x,y)

Or what about using PEEKS?

Offline ervin

  • Supporter
  • 6128 Plus
  • *
  • Posts: 1.233
  • Country: au
    • index.php?action=treasury
  • Liked: 908
Re: BASIC programming tips
« Reply #115 on: 10:19, 13 October 18 »
I think this question has been asked before, but:

Is there anyway to (from BASIC) fetch the character or character-code currently on the screen on a certain position?

This would require a character-memory-map of some kind, which I don't think the CPC has?

Something like CHARCODE(x,y)

Or what about using PEEKS?

Not sure if it's what you're after, but COPYCHR$ might be worth a look:
http://www.cpcwiki.eu/index.php/Locomotive_BASIC#COPYCHR.24_.28st.29

I don't think it works on a 464, but I seem to remember a discussion on cpcwiki a few years ago about a 464 equivalent.
(I could be remembering incorrectly though).
My (cancelled) entry for the CPCRetroDev 2017 Competition http://www.cpcwiki.eu/forum/programming/my-cpcretrodev-2017-entry/
FAST line drawing in CPCtelera http://www.cpcwiki.eu/forum/programming/drawing-lines-with-cpctelera-sdcc/
RUNCPC My entry for the CPCRetroDev 2015 Competition http://www.cpc-power.com/index.php?page=detail&num=12494

Offline mr_lou

  • 6128 Plus
  • ******
  • Posts: 2.751
  • Country: dk
    • index.php?action=treasury
    • 8-bit Memoirs - a Blu-ray diskmag-like eBook about the 8-bit era
  • Liked: 977
Re: BASIC programming tips
« Reply #116 on: 10:31, 13 October 18 »
Not sure if it's what you're after, but COPYCHR$ might be worth a look:
http://www.cpcwiki.eu/index.php/Locomotive_BASIC#COPYCHR.24_.28st.29

I don't think it works on a 464, but I seem to remember a discussion on cpcwiki a few years ago about a 464 equivalent.
(I could be remembering incorrectly though).
Interesting. Will take a closer look. But it would be nice with something for the 464, since that's the one I'm using for this. (Small enough to be on the same desk as my PC).
EDIT: found this in another thread:
10 FOR a=1 TO 17:POKE 39999+a,VAL("&"+MID$("DD7E00CDB4BBF5CD60BB320000F1C3B4BB",a*2-1,2)):NEXT
20 LOCATE x,y:CALL 40000,0:PRINT CHR$(PEEK(0)) '  this works as COPYCHR$ in any CPC

I used to found this in some magazine. :)

And remember about TEST command, could be usefull to detect pixel color. :)
http://www.cpcwiki.eu/forum/programming/basic-efficient-collision-detection-routine/
« Last Edit: 11:00, 13 October 18 by mr_lou »

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #117 on: 14:19, 13 October 18 »
I think this question has been asked before, but:

Is there anyway to (from BASIC) fetch the character or character-code currently on the screen on a certain position?

This would require a character-memory-map of some kind, which I don't think the CPC has?

Something like CHARCODE(x,y)

Or what about using PEEKS?


Would have to know more about how that character onscreen got there. If it's a program placing and removing characters onscreen, using an array is faster than copychr$(#0) or it's TXT RD CHAR (#BB60) counterpart.
If you were gathering information from a Disk Catalog (#BC9B) through, the firmware can be told where to place that information with the DE register being the address to where the buffer is to go.
* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)

Offline mr_lou

  • 6128 Plus
  • ******
  • Posts: 2.751
  • Country: dk
    • index.php?action=treasury
    • 8-bit Memoirs - a Blu-ray diskmag-like eBook about the 8-bit era
  • Liked: 977
Re: BASIC programming tips
« Reply #118 on: 15:30, 13 October 18 »
Would have to know more about how that character onscreen got there. If it's a program placing and removing characters onscreen, using an array is faster than copychr$(#0) or it's TXT RD CHAR (#BB60) counterpart.
If you were gathering information from a Disk Catalog (#BC9B) through, the firmware can be told where to place that information with the DE register being the address to where the buffer is to go.

Well the idea is to draw levels for a game, using normal PRINT commands. But these levels only contain very little data - as in most of it would be empty spaces. Therefor I figure an array (or map) would only take up unnecessary much space. Hence why I thought it would be better to be able to simply check what's on the screen.

Of course, speed matters too, so..... dunno.

EDIT:Did a short test. First 1000 checks using the PEEK method above. Took 26,44 seconds. Then 1000 outputs from an array. Took 23,92 seconds. So it's not like a huge difference. 2½ seconds for 1000 cycles. So that's 2½ ms slower per cycle to use PEEK rather than an array. I can live with that.
« Last Edit: 15:52, 13 October 18 by mr_lou »

Offline AMSDOS

  • Supporter
  • 6128 Plus
  • *
  • Posts: 3.506
  • Country: au
    • index.php?action=treasury
    • Programs for Turbo Pascal 3
  • Liked: 759
Re: BASIC programming tips
« Reply #119 on: 23:20, 13 October 18 »
Sorry I got the impression that it was 2.5 seconds (not microseconds), which sounds like a lot if the game is running through a cycle of checks.

I converted this game earlier this year, which had a lot of copychr$(#0) in it. The game is also MODE 1, so I setup a Memory array with a Function pointing to it, which gave me the advantage of having a byte sized array from BASIC, even on a MODE 1 screen I was able to have some redefined characters and the Array situated at &A000. I'm unsure what happened to the original program, though may have somewhere, actually I think the program maybe within this attached file with this message.
« Last Edit: 23:23, 13 October 18 by AMSDOS »
* Using some of the hardly used Amstrad compilers :D
* I use Firmware in my Assembly code :P
* Have interpreted some BASIC 1.1 programs for BASIC 1.0. :)