Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 21:51 27 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Classic Amazing.Bas modified for MMBasic with Maze's solution

Author Message
EDNEDN
Senior Member

Joined: 18/02/2023
Location: United States
Posts: 118
Posted: 09:06pm 10 Sep 2023
Copy link to clipboard 
Print this post

The classic Amazing.Bas program modified to run on MMBasic.   And also modified to print the maze's solution:

  Quote  
 230 Print "THIS PROGRAM WILL PRINT A DIFFERENT MAZE EACH TIME IT IS"
 240 Print "RUN.  THERE WILL BE A UNIQUE PATH THROUGH THE MAZE.  YOU"
 250 Print "CAN CHOOSE ANY DIMENSIONS FOR THE MAZE UP TO 100 SQUARES"
 260 Print "LONG AND 100 SQUARES WIDE."
 270 Print
 280 Print "WHAT ARE YOUR LENGTH AND WIDTH (E. G. 13,10)";
 290 Input R9, C9
 300 Dim W(65,65)=0, V(65,65)=0, S(65,65)=0
 301 Dim Direction(4)
 302 Const LEFT=1, RIGHT=2, UP=3, DOWN=4
 310 N9 = R9*C9

 340 B = 0                           'FLAG NO EXIT TO BOTTOM YET
 350 Rem                FIND SQUARE IN WHICH TO START
 360 F = Int(Rnd*C9+1)
 370 Print                            'PRINT TOP BORDER
 450 R = 1                           'START IN FIRST ROW
 460 C = F                           'AND COLUMN UNDER HOLE IN BORDER
 470 N = 1                           'COUNT OF SQUARES VISITED
 480 W(R,C) = N
 490 '
 500 '  A CORRIDOR IS CONSTRUCTED BY MOVING IN A RANDOM DIRECTION FROM
 510 '  THE CURRENT SQUARE TO SOME SQUARE THAT HAS NOT BEEN VISITED
 520 '  YET AND ERASING THE WALL BETWEEN THE TWO SQUARES.  IF NO SUCH
 530 '  MOVE IS POSSIBLE, A SIDE CORRIDOR IS STARTED IN SOME SQUARE
 540 '  ALREADY VISITED WHICH IS ADJACENT TO AN UNVISITED SQUARE.  ONLY
 550 '  ONE EXIT TO THE BOTTOM OF THE MAZE IS ALLOWED.
 560 '
 570 Rem                MAKE LIST OF UNBLOCKED DIRECTIONS
 580 D = 0
 590 Rem                CAN WE GO LEFT
 600 If C = 1 Then 640                   'NO, ON BORDER
 610 If W(R,C-1) > 0 Then 640            'NO, SQUARE USED ALREADY
 620 D = D+1                         'YES, ADD "LEFT" TO LIST
 630 Direction(D) = 1
 640 Rem                CAN WE GO RIGHT
 650 If C = C9 Then 690                  'NO, ON BORDER
 660 If W(R,C+1) > 0 Then 690            'NO, SQUARE USED ALREADY
 670 D = D+1                         'YES, ADD "RIGHT" TO LIST
 680 Direction(D) = 2
 690 Rem                CAN WE GO UP
 700 If R = 1 Then 740                   'NO, ON BORDER
 710 If W(R-1,C) > 0 Then 740            'NO, SQUARE USED ALREADY
 720 D = D+1                         'YES, ADD "UP" TO LIST
 730 Direction(D) = 3
 740 Rem                CAN WE GO DOWN
 750 If R < R9 Then 780                  'MAYBE, NOT ON BORDER
 760 If B = 1 Then 810                   'NO, ALREADY HAVE EXIT TO BOTTOM
 770 GoTo 790                            'YES, ALLOW EXIT TO BOTTOM
 780 If W(R+1,C) > 0 Then 810            'NO, SQUARE USED ALREADY
 790 D = D+1                         'YES, ADD "DOWN" TO LIST
 800 Direction(D) = 4
 810 Rem                CHOOSE DIRECTION
 820 If D = 0 Then 1090                  'ALL DIRECTIONS BLOCKED
 830 X = Int(D*Rnd+1)                'PICK RANDOM DIRECTION
 840 On Direction(X) GoTo 850,890,930,970
 850 Rem                GO LEFT
 860 C = C-1
 870 V(R,C) = 2                      'NEW SQUARE HAS ONLY BOTTOM WALL
 880 GoTo 1030
 890 Rem                GO RIGHT
 900 V(R,C) = V(R,C) + 2             'ERASE RIGHT WALL OF THIS SQUARE
 910 C = C+1
 920 GoTo 1030
 930 Rem                GO UP
 940 R = R-1
 950 V(R,C) = 1                      'NEW SQUARE HAS ONLY RIGHT WALL
 960 GoTo 1030
 970 Rem                GO DOWN
 980 V(R,C) = V(R,C) + 1             'ERASE BOTTOM WALL OF THIS SQUARE
 990 R = R+1
 1000 If R <= R9 Then 1030            'STILL IN MAZE
 1010 B = 1                           'FLAG EXIT TO BOTTOM
 1011 C0 = C
 1012 R0 = R-1
 1020 GoTo 1140                           'AND GO VISIT OTHER SQUARES
 1030 Rem                MARK SQUARE AS USED
 1040 N = N+1
 1050 W(R,C) = N
 1060 If N < N9 Then 570
 1070 Rem               DONE
 1080 GoTo 1180
 1090 Rem                RESTART IN USED SQUARE ADJACENT TO UNUSED SQUARE
 1100 C = C+1
 1110 If C <= C9 Then 1160
 1120 R = R+1
 1130 If R <= R9 Then 1150
 1140 R = 1
 1150 C = 1
 1160 Rem      print "attempting restart at ("; c;","; r;")"
 1161 If W(R,C) > 0 Then 570
 1170 GoTo 1100
 1175 Rem
 1176 Rem
 1180 Rem        *******************   PRINT OUT MAZE   ********************
 1181 Rem
 1182 Rem
 1183 Print                            'PRINT TOP BORDER
 1184 For C = 1 To C9
 1185    If C = F Then  Print ":  "; Else  Print ":--";
 1187 Next C
 1188 Print ":"
 1189 Rem
 1190 For R = 1 To R9
 1200    Print "|";
 1210    For C = 1 To C9
 1220       If V(R,C) < 2 Then 1250
 1230       Print "   ";
 1240       GoTo 1260
 1250       Print "  |";
 1260    Next C
 1270    Print
 1280    For C = 1 To C9
 1291       If (v(r,c) Mod 2) = 0 Then 1320
 1300       Print ":  ";
 1310       GoTo 1330
 1320       Print ":--";
 1330    Next C
 1340    Print ":"
 1350 Next R
 1351 Print
 1352 Print
 2175 Rem
 2176 Rem
 2180 Rem        *******************   PRINT OUT ORDER of Cell Usage  ********************
 2181 Rem
 2182 Rem
 2185 Rem   For C = 1 To C9
 2186 Rem       Print "   ";c;
 2187 Rem   Next C
 2188 Rem   Print
 2189 Rem   Print "--------------------------------------------------------"
 2190 Rem   For R = 1 To R9
 2210 Rem      For C = 1 To C9
 2231 Rem         print3 w(r,c)
 2260 Rem      Next C
 2270 Rem      Print " ---";r
 2350 Rem   Next R
 2351 Rem   Print
 2352 Rem   Print
 2400 Rem
 2410 Rem
 2420 Rem       *********************  Print out solution for maze *************************
 2430 Rem
 2440 Rem
 2441 Rem       ****** first, find the solution *****
 2442 Rem
 2500 s(r0,c0) = 1
 2520 r = r0
 2530 c = c0
 2545 nn = w(r,c)
 2550 If c<=1  GoTo 2600     ' skip if we can't check to the left
 2551 If w(r,c-1) <> nn-1 Then 2600
 2555    c = c-1
 2560    s(r,c) = 1
 2580    GoTo 2545
 2599 Rem
 2600 If c>=c9 GoTo 2700     ' skip if we can't check to the right
 2610 If w(r,c+1) <> nn-1 Then 2700
 2620    c = c+1
 2630    s(r,c) = 1
 2640    GoTo 2545
 2650 Rem
 2700 If r<=1 GoTo 2800      ' skip if we can't check upward
 2710 If w(r-1,c) <> nn-1 Then 2800
 2720    r = r-1
 2730    s(r,c) = 1
 2740    GoTo 2545
 2751 Rem
 2800 If r>=r9 GoTo 2900     ' skip if we can't check downward
 2810    If w(r+1,c) <> nn-1 Then 2900
 2820    r = r+1
 2830    s(r,c) = 1
 2840 GoTo 2545
 2850 Rem
 2851 Rem      nn-1 square not available.    look for smallest number
 2852 Rem
 2900 If nn = 1 GoTo 2990
 2901 nnn = nn
 2902 r8 = r
 2903 c8 = c
 2904 Rem   current_solution
 2905 Rem   Print "Broken path at (";c;",";r;")  nnn=";nnn
 2906 Rem   Input a$
 2908 If Can_Go_To(LEFT, c, r) = 0 Then GoTo 2920
 2910    Rem   Print "Left -> "; w(r,c-1)
 2911    If w(r,c-1) >= nnn Then GoTo 2920
 2912    nnn = w(r,c-1)
 2914    r8 = r
 2915    c8 = c-1
 2920 If Can_Go_To(RIGHT, c, r) = 0 Then GoTo 2932
 2921    Rem   Print "RIGHT -> "; w(r,c+1)
 2922    If w(r,c+1) >= nnn Then GoTo 2932
 2923    nnn = w(r,c+1)
 2924    r8 = r
 2925    c8 = c+1
 2932 If Can_Go_To(UP, c, r) = 0 Then GoTo 2945
 2933    Rem   Print "UP -> "; w(r-1,c)
 2935    If w(r-1,c) >= nnn Then GoTo 2945
 2936    nnn = w(r-1,c)
 2938    r8 = r-1
 2940    c8 = c
 2945 If Can_Go_To(DOWN, c, r) = 0 Then GoTo 2956
 2946    Rem   Print "DOWN -> "; w(r+1,c)
 2947    If w(r+1,c) >= nnn Then GoTo 2956
 2948    nnn = w(r+1,c)
 2949    r8 = r+1
 2950    c8 = c
 2955 Rem
 2956 r = r8
 2957 c = c8
 2962 Rem   Print "   Next cell is (";c;",";r;")  nnn=";nnn
 2965 s(r,c) = 1
 2970 GoTo 2545
 
 2990 Rem
 2991 current_solution
 2993 Memory
 2995 GoTo 9999
 2996 Rem
 2997 Rem
 2999 Sub current_solution
 3000 For C7 = 1 To C9
 3002    If c7<10 Then Print " ";C7; Else Print c7;
 3004 Next C7
 3010 Print                            'PRINT TOP BORDER of solution
 3011 For C7 = 1 To C9
 3012   If C7 = F Then  Print "+  "; Else  Print "+--";
 3013 Next C7
 3004 Rem
 3005 Print "|"
 3010 Rem
 3020 For R7= 1 To R9
 3030    Print "|";
 3040    For C7 = 1 To C9
 3050       If V(R7,C7) < 2 Then 3080
 3060       If s(r7,c7)=0 Then Print "   "; Else Print " # ";
 3070       GoTo 3090
 3080       If s(r7,c7)=0 Then Print "  |"; Else Print " #|";
 3090    Next C7
 3200    Print r7
 3210    For C7 = 1 To C9
 3220       If (v(r7,c7) Mod 2) = 0 Then 3250
 3230       Print "+  ";
 3240       GoTo 3260
 3250       Print "+--";
 3260    Next C7
 3270    Print "|"
 3280 Next R7
 3299 Print
 3300 End Sub
 4990 Rem
 4991 Rem
 4992 Rem      ********************* 3 character print of number ***********************
 4993 Rem
 4999 Rem
 5000 Sub print3 arg1
 5010 If arg1 > 9 Then 5050
 5020 Print "   "; arg1;
 5030 Exit Sub
 5050 If arg1 > 99 Then 5100
 5050 Print "  "; arg1;
 5070 Exit Sub
 5100 If arg1 > 999 Then 5200
 5110 Print  " ";arg1;
 5112 Exit Sub
 5200 Print  arg1;
 5999 End Sub
 6000 Rem
 6001 Rem
 6002 Rem
 6003 Rem
 6010 Function Can_Go_To(dir%, x%, y%) As INTEGER
 6020 If dir%<>LEFT Then GoTo 6100
 6030    If x%<2 GoTo 6499
 6040    If v(y%,x%-1) >=2 Then Can_Go_To=1 Else Can_Go_To=0
 6050    Exit Function
 6099 Rem
 6100 If dir%<>RIGHT Then GoTo 6200
 6110    If x%>=c9 GoTo 6499
 6120    If v(y%,x%) >=2 Then Can_Go_To=1 Else Can_Go_To=0
 6130    Exit Function
 6199 Rem
 6200 If dir%<>UP Then GoTo 6300
 6210    If y%<2 GoTo 6499
 6220    If v(y%-1,x%)=1 Or  v(y%-1,x%)=3 Then Can_Go_To=1 Else Can_Go_To=0
 6230    Exit Function
 6299 Rem
 6300 If dir%<>DOWN Then GoTo 6395
 6310    If y%>=r9 GoTo 6499
 6320    If v(y%,x%)=1 Or  v(y%,x%)=3 Then Can_Go_To=1 Else Can_Go_To=0
 6330    Exit Function
 6394 Rem
 6395 Print "Illegal direction in function Can_Go_To(";dir%;")"
 6396 stop
 6499 Can_Go_To = 0
 6500 End Function
 6510 Rem
 9999 End
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 09:50pm 10 Sep 2023
Copy link to clipboard 
Print this post

Very good Ednedn. :) Welcome to the forum!

How do you like working in MMBasic?

If you want to set yourself a challenge, go over it again doing it without line numbers, GOTO or GOSUB and using SUB / END SUB and FUNCTION / END FUNCTION. It can be quite an eye-opener as you really have to understand how the program is working.
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
EDNEDN
Senior Member

Joined: 18/02/2023
Location: United States
Posts: 118
Posted: 10:42pm 10 Sep 2023
Copy link to clipboard 
Print this post

I converted Amazing.bas to MMBasic just to see how well the Pico version would run.   And to get familiar with the tools and such.   Mostly I used the embedded Edit command connected to a Tera-Terminal.    But now I'm mostly using the Maximite Control program paired with MMEdit.

I kind of did what you suggest with ditching the line numbers.    I needed a signal generator to send pulse trains at different frequencies to calibrate an electronic tachometer for an old car that is getting restored.     The code is below:

MMBasic on a Raspberry Pi RP2040 is impressive.   The speed is good and provides a reliable platform for whatever the user has in mind.    In the signal generator case, I was able to turn a $3 Raspberry Pi Zero into a precision calibration tool.  

  Quote  
dim t%, t1%, t2%, n%, e%, y%
SetPin GP17, DOUT

y% = 57
e% = 1000

next_cycle:
          n% = 0
          t% = timer
timeing_loop:
          PIN(gp17) = 1
         
          for x = 1 to 3
            c = x  +  1
          next x

          PIN(gp17) = 0
         
          for x = 1 to y%
            c = x  +   1
          next x
         
          n% = n% + 1
          if n% < e% then goto timeing_loop
         
         
          t1% = timer
          h = e%/((t1%-t%)/1000)
          f$ = str$(h)+".0"
          l  = instr(1,f$,".")
          f$ = left$(f$, l+1)
         
          r$ = str$(15*h)+".0"
          l  = instr(1,r$,".")
          r$ = left$(r$, l+1)
         
          print  f$;" Hz.  "; r$ ;" RPM       "; chr$(13);

freq_adjust:          
          i$ = inkey$
          if i$ = "" then goto next_cycle
          print
         
          if i$ = "=" or i$="+" then
              y% = y% -1
              print y%
              goto freq_adjust
          endif
             
          if i$ = "_" or i$="-" then
              y% = y% +1
              print y%
              goto freq_adjust
          endif
         
          if i$ = "8" then
              y% = 487
              e% = 200
              print y%;" for 800 RPM"
              goto freq_adjust
          endif
                     
          if i$ = "1" then
              y% = 388
              e% = 250
              print y%;" for 1000 RPM"
              goto freq_adjust
          endif
         
          if i$ = "2" then
              y% = 189
              e% = 400
              print y%;" for 2000 RPM"
              goto freq_adjust
          endif
                 
          if i$ = "3" then
              y% = 123
              e% = 600
              print y%;" for 3000 RPM"
              goto freq_adjust
          endif
                       
          if i$ = "4" then
              y% = 90
              e% = 750
              print y%;" for 4000 RPM"
              goto freq_adjust
          endif
                             
          if i$ = "5" then
              y% = 70
              e% = 800
              print y%;" for 5000 RPM"
              goto freq_adjust
          endif
                                       
          if i$ = "6" then
              y% = 57
              e% = 1000
              print y%;" for 6000 RPM"
              goto freq_adjust
          endif
         
          goto next_cycle
     

Edited 2023-09-11 08:43 by EDNEDN
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 11:52pm 10 Sep 2023
Copy link to clipboard 
Print this post

You may be able to shorten your signal generator a little. The PicoMite has a lot of useful features to do that. This method doesn't even need a program, just the command prompt will do.
eg.
> option cpuspeed 64000 'reduce the CPU speed to use PWM at low frequencies
PicoMite MMBasic Version 5.07.08b15
Copyright 2011-2023 Geoff Graham
Copyright 2016-2023 Peter Mather

> setpin gp17,pwm 'GP17 is PWM channel 0B
> rpm = 1000  'engine speed
> cyls = 8 'number of cylinders
> pps = rpm * cyls / 2 / 60 'pulses per second
> pw = rpm / 500 'pulse width, change 500 to get the right pulse width
> pwm 0,pps,,pw 'the extra coma skips channel A to output on B


Using PULSE in a SETTICK interrupt subroutine is another way.
 
EDNEDN
Senior Member

Joined: 18/02/2023
Location: United States
Posts: 118
Posted: 11:57pm 10 Sep 2023
Copy link to clipboard 
Print this post

Wow!  

That is impressive!   MMBasic on a Pico is definitely a good foundation for home projects!
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 12:23am 11 Sep 2023
Copy link to clipboard 
Print this post

The command prompt has a line editor so to change the RPM use the up arrow to get to that line and change the value. Then re-run the other lines. CYLS won't change so that doesn't need to be repeated.
Even that can be simplified, putting the lot on one line.
rpm = 1000 :pps = rpm * cyls / 2 / 60 :pps = rpm * cyls / 2 / 60 :pw = rpm / 500 :pwm 0,pps,,pw
 
EDNEDN
Senior Member

Joined: 18/02/2023
Location: United States
Posts: 118
Posted: 02:06am 11 Sep 2023
Copy link to clipboard 
Print this post

While that would work...   Maybe it can be optimized a little bit:

  Quote  rpm = 1000 :pps = rpm * cyls / 2 / 60 :pw = rpm / 500 :pwm 0,pps,,pw


(I think you might have fat fingered the keyboard and got an extra calculation for the pulses/sec in there....)

THANKS!!!!!
Edited 2023-09-11 12:21 by EDNEDN
 
Mixtel90

Guru

Joined: 05/10/2019
Location: United Kingdom
Posts: 6798
Posted: 06:27am 11 Sep 2023
Copy link to clipboard 
Print this post

The PicoMite has a command, BITSTREAM PULSEOUT that will produce custom pulse trains with very high precision. It's not relevant to this application as it's way too fast, but it gives an example of the sort of things that can be done.

Triggering a PULSE command from a SETTICK interrupt is another way, but most of the interrupts in MMBasic are not precision as they are scanned at the end of each line. It's still a useful technique though, especially for short pulses with long periods between them.

You usually find that there are several ways to skin a cat in MMBasic. :)
Mick

Zilog Inside! nascom.info for Nascom & Gemini
Preliminary MMBasic docs & my PCB designs
 
EDNEDN
Senior Member

Joined: 18/02/2023
Location: United States
Posts: 118
Posted: 01:20pm 11 Sep 2023
Copy link to clipboard 
Print this post

I appreciate the pointers to different ways to accomplish the task.

I need to understand the Chanel A and Chanel B thing on the pwm command.  I haven't pulled up the documentation or code yet to check it out, but I'm guessing there are only two pins that can be put under control with the pwm command and that is why there is a Chanel A and a Chanel B.     I'll get that fully understood first.

Then I'll learn about the BITSTREAM PULSEOUT command.  And see what can be done with that as well as how it is implemented in the firmware.   If it is utilizing hardware timer support in the chip it is very possible only certain pins can be controlled.   I'll get that understood next.

And then I'll check out the SETTICK interrupt stuff.   It will be interesting to see how that is implemented in the firmware.

Thanks again people for help getting up the learning curve!
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2136
Posted: 01:48pm 11 Sep 2023
Copy link to clipboard 
Print this post

Page 9 of the latest PicoMite manual has a pin diagram showing what functions can be assigned to each pin.
There are 8 PWM channels (0 to 7) that can each have a unique frequency. Each of those can drive 2 pins with different mark-space ratios (A and B).
A full description is on page 121.

The manual is an excellent resource.
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024