Qbasicnews.com

Full Version: Drunken-man screensaver
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I was fooling around in the IDE and came up with a little screensaver. It simulates a drunken man (he walks randomly in the four directions) with a great memory (he never walks where he already has walked). It's interesting to see how fast he get's stuck - that is, if he makes a circle for himself that he can't get out of.
Note that he drank so much that he's urinating wherever he steps (hence the trail :wink: ).
Here's the code. Note: you'll have to load QB.exe with the /ah command-line option for this to work - I needed an array the size of the screen (there's gotta be a better way to do that... :-? ).
Code:
SCREEN 13
TYPE Dot
   x AS INTEGER
   y AS INTEGER
clr AS INTEGER
END TYPE
'$DYNAMIC
DIM ScrMap(320, 200) AS INTEGER
DIM Dots(0) AS Dot
FOR i = 0 TO 0
   RANDOMIZE TIMER
   Dots(i).x = CINT(RND * 320)
   Dots(i).y = CINT(RND * 200)
   Dots(i).clr = CINT(RND * 16)
NEXT
CONST LEFT = 0
CONST RIGHT = 1
CONST UP = 2
CONST DOWN = 3
T! = TIMER
DO WHILE INKEY$ = ""
IF TIMER - T! >= .001 THEN
   FOR i = 0 TO 0
      RANDOMIZE TIMER
      Direction = CINT(RND * 5)
      IF ((Direction = LEFT AND Dots(i).x <> 1) OR (Direction = 5 AND Dots(i).x <> 1)) AND ScrMap(Dots(i).x - 1, Dots(i).y) = 0 THEN
        
         Dots(i).x = Dots(i).x - 1
         PSET (Dots(i).x, Dots(i).y), Dots(i).clr
         ScrMap(Dots(i).x, Dots(i).y) = 1
      END IF
      IF (Direction = RIGHT AND Dots(i).x <> 319) AND ScrMap(Dots(i).x + 1, Dots(i).y) = 0 THEN
        
         Dots(i).x = Dots(i).x + 1
         PSET (Dots(i).x, Dots(i).y), Dots(i).clr
         ScrMap(Dots(i).x, Dots(i).y) = 1
      END IF
      IF (Direction = UP AND Dots(i).y <> 1) AND ScrMap(Dots(i).x, Dots(i).y - 1) = 0 THEN
        
         Dots(i).y = Dots(i).y - 1
         PSET (Dots(i).x, Dots(i).y), Dots(i).clr
         ScrMap(Dots(i).x, Dots(i).y) = 1
      END IF
      IF (Direction = DOWN AND Dots(i).y <> 199) AND ScrMap(Dots(i).x, Dots(i).y + 1) = 0 THEN
        
         Dots(i).y = Dots(i).y + 1
         PSET (Dots(i).x, Dots(i).y), Dots(i).clr
         ScrMap(Dots(i).x, Dots(i).y) = 1
      END IF
   NEXT
   T! = TIMER
END IF
LOOP
Note: I posted this exact thing at QBNZ - The Wall. Tongue
Very cool. Reminds me of a cellular automaton that I made. It's called Langton's ant. It's an ant that moves either only left or right. Every step it makes it puts a pixel. If it touches a pixel that was drawn previously, it changes direction and clears that pixel back to black. It creates very interresting effects. Here's a link to a java applet:
http://users.libero.it/acnard/ant.html
(wait until the ant reaches around 10000 moves. He'll start building this "highway".

About your code, I don't undertstand why you have FOR:NEXT loops that start with 0 and ends with 0. :???: There's no point of putting one. Also, instead of holding an array that large, you can just use the POINT to detect if there's a color at your next movement location. If there is, you don't move there.
purple pee?

hmmm..

Isn't very realistic.

You could minimize the cost by...uh...storing 16 X values instead of 1, so make it:

(19, 199) 'unless you want to use OPTION BASE 1

So the first 16 (1, 1), (2, 1), (3, 1)... etc. are in the first integer, etc.
You don't need an array. Use POINT to detect if the next pixel has color.
Quote:purple pee?

hmmm..

Isn't very realistic.

You could minimize the cost by...uh...storing 16 X values instead of 1, so make it:

(19, 199) 'unless you want to use OPTION BASE 1

So the first 16 (1, 1), (2, 1), (3, 1)... etc. are in the first integer, etc.
Purple pee...um...drank lots of red wine, he did.
R@dioman: yeah, thanks. The FOR loop is just there if you ever want to add a group of other drunk guys walking with him.
[edit]Whoa, nice Java applet there, R@dioman@ I think I'll mod this screensaver to be a little more complex, like yours.
Oh sorry, I didn't make that java applet. I made a version like that in QB. I know, the way I said made it seem like I made it.
Zack: Thats almost exactly how I made a maze generator. It was pretty cool, it had hundreds of passages, each one acessible, and only by one route. It works pretty cool, but you have to leave it a few minutes to get a big maze.
R@dioman: how about a peek at that QB proggie, then?
Dark: Yeah, I was thinking about maze generation while I was making it...
Zack: Don't have it anymore. That was years ago in my programming adolescence. It's quite simple to make though. Give it a try
This code is ancient, but gets the work done:

Code:
1010 KEY OFF
1020 DEFINT A-Z
1030 X.MAX=95
1040 Y.MAX=49
1050 DIM DELTA.X(6,720)
1060 DIM DELTA.Y(6,720)
1070 DIM PAGE(Y.MAX,X.MAX)
1080 DIM R.N(8)
1090 DIM STACK.1(Y.MAX*X.MAX)
1100 DIM STACK.2(Y.MAX*X.MAX)
1110 CLS
1120 PRINT "                                 Maze Generator"
1130 PRINT
1140 PRINT
1150 PRINT
1160 PRINT "     Random number seed?  ";
1170 LINE INPUT SEED$
1180 R.N.INDEX.1=1
1190 FOR R.N.INDEX.2=1 TO LEN(SEED$)
1200   TEM.INT=ASC(MID$(SEED$,R.N.INDEX.2,1))
1210   R.N(R.N.INDEX.1)=TEM.INT
1220   R.N.INDEX.1=R.N.INDEX.1+1
1230 NEXT R.N.INDEX.2
1240 R.N.INDEX.2=8
1250 WHILE (R.N.INDEX.1 > 1)
1260   R.N.INDEX.1=R.N.INDEX.1-1
1270   R.N(R.N.INDEX.2)=R.N(R.N.INDEX.1)
1280   R.N.INDEX.2=R.N.INDEX.2-1
1290 WEND
1300 WHILE (R.N.INDEX.2 >= 1)
1310   R.N(R.N.INDEX.2)=367
1320   R.N.INDEX.2=R.N.INDEX.2-1
1330 WEND
1340 DELTA.Y(1,1)=-1
1350 DELTA.X(1,1)=-2
1360 DELTA.Y(2,1)=1
1370 DELTA.X(2,1)=-2
1380 DELTA.Y(3,1)=-2
1390 DELTA.X(3,1)=0
1400 DELTA.Y(4,1)=2
1410 DELTA.X(4,1)=0
1420 DELTA.Y(5,1)=-1
1430 DELTA.X(5,1)=2
1440 DELTA.Y(6,1)=1
1450 DELTA.X(6,1)=2
1460 DELTA.INDEX.2=0
1470 FOR DELTA.INDEX.1A=1 TO 6
1480   FOR DELTA.INDEX.1B=1 TO 6
1490     IF DELTA.INDEX.1A = DELTA.INDEX.1B THEN 1850
1500       FOR DELTA.INDEX.1C=1 TO 6
1510         IF DELTA.INDEX.1A = DELTA.INDEX.1C THEN 1840
1520         IF DELTA.INDEX.1B = DELTA.INDEX.1C THEN 1840
1530           FOR DELTA.INDEX.1D=1 TO 6
1540             IF DELTA.INDEX.1A = DELTA.INDEX.1D THEN 1830
1550             IF DELTA.INDEX.1B = DELTA.INDEX.1D THEN 1830
1560             IF DELTA.INDEX.1C = DELTA.INDEX.1D THEN 1830
1570               FOR DELTA.INDEX.1E=1 TO 6
1580                 IF DELTA.INDEX.1A = DELTA.INDEX.1E THEN 1820
1590                 IF DELTA.INDEX.1B = DELTA.INDEX.1E THEN 1820
1600                 IF DELTA.INDEX.1C = DELTA.INDEX.1E THEN 1820
1610                 IF DELTA.INDEX.1D = DELTA.INDEX.1E THEN 1820
1620                   FOR DELTA.INDEX.1F=1 TO 6
1630                     IF DELTA.INDEX.1A = DELTA.INDEX.1F THEN 1810
1640                     IF DELTA.INDEX.1B = DELTA.INDEX.1F THEN 1810
1650                     IF DELTA.INDEX.1C = DELTA.INDEX.1F THEN 1810
1660                     IF DELTA.INDEX.1D = DELTA.INDEX.1F THEN 1810
1670                     IF DELTA.INDEX.1E = DELTA.INDEX.1F THEN 1810
1680                         DELTA.INDEX.2=DELTA.INDEX.2+1
1690                         DELTA.X(DELTA.INDEX.1A,DELTA.INDEX.2)=DELTA.X(1,1)
1700                         DELTA.Y(DELTA.INDEX.1A,DELTA.INDEX.2)=DELTA.Y(1,1)
1710                         DELTA.X(DELTA.INDEX.1B,DELTA.INDEX.2)=DELTA.X(2,1)
1720                         DELTA.Y(DELTA.INDEX.1B,DELTA.INDEX.2)=DELTA.Y(2,1)
1730                         DELTA.X(DELTA.INDEX.1C,DELTA.INDEX.2)=DELTA.X(3,1)
1740                         DELTA.Y(DELTA.INDEX.1C,DELTA.INDEX.2)=DELTA.Y(3,1)
1750                         DELTA.X(DELTA.INDEX.1D,DELTA.INDEX.2)=DELTA.X(4,1)
1760                         DELTA.Y(DELTA.INDEX.1D,DELTA.INDEX.2)=DELTA.Y(4,1)
1770                         DELTA.X(DELTA.INDEX.1E,DELTA.INDEX.2)=DELTA.X(5,1)
1780                         DELTA.Y(DELTA.INDEX.1E,DELTA.INDEX.2)=DELTA.Y(5,1)
1790                         DELTA.X(DELTA.INDEX.1F,DELTA.INDEX.2)=DELTA.X(6,1)
1800                         DELTA.Y(DELTA.INDEX.1F,DELTA.INDEX.2)=DELTA.Y(6,1)
1810                   NEXT DELTA.INDEX.1F
1820               NEXT DELTA.INDEX.1E
1830           NEXT DELTA.INDEX.1D
1840       NEXT DELTA.INDEX.1C
1850   NEXT DELTA.INDEX.1B
1860 NEXT DELTA.INDEX.1A
1870 Y.OUT.MOD.4=1
1880 FOR Y.OUT=1 TO Y.MAX
1890   IF Y.OUT.MOD.4 <> 1 THEN 2030
1900     X.OUT.MOD.8=1
1910     FOR X.OUT=1 TO X.MAX
1920       IF ((X.OUT.MOD.8 = 0) AND (Y.OUT <> 1) AND (Y.OUT <> Y.MAX)) THEN 1980
1930       IF X.OUT.MOD.8 = 3 THEN 1980
1940       IF X.OUT.MOD.8 = 4 THEN 1980
1950       IF X.OUT.MOD.8 = 5 THEN 1980
1960         PAGE(Y.OUT,X.OUT)=0
1970       GOTO 1990
1980         PAGE(Y.OUT,X.OUT)=1
1990       X.OUT.MOD.8=X.OUT.MOD.8+1
2000       IF X.OUT.MOD.8 >= 8 THEN X.OUT.MOD.8=0
2010     NEXT X.OUT
2020   GOTO 2260
2030     IF ((Y.OUT.MOD.4 <> 0) AND (Y.OUT.MOD.4 <> 2)) THEN 2140
2040       X.OUT.MOD.8=1
2050       FOR X.OUT=1 TO X.MAX
2060         IF ((X.OUT.MOD.8 = 2) OR (X.OUT.MOD.8 = 6)) THEN 2090
2070           PAGE(Y.OUT,X.OUT)=0
2080         GOTO 2100
2090           PAGE(Y.OUT,X.OUT)=1
2100         X.OUT.MOD.8=X.OUT.MOD.8+1
2110         IF X.OUT.MOD.8 >= 8 THEN X.OUT.MOD.8=0
2120       NEXT X.OUT
2130     GOTO 2260
2140       X.OUT.MOD.8=1
2150       FOR X.OUT=1 TO X.MAX
2160         IF X.OUT.MOD.8 = 0 THEN 2220
2170         IF X.OUT.MOD.8 = 1 THEN 2220
2180         IF X.OUT.MOD.8 = 4 THEN 2220
2190         IF X.OUT.MOD.8 = 7 THEN 2220
2200           PAGE(Y.OUT,X.OUT)=0
2210         GOTO 2230
2220           PAGE(Y.OUT,X.OUT)=1
2230         X.OUT.MOD.8=X.OUT.MOD.8+1
2240         IF X.OUT.MOD.8 >= 8 THEN X.OUT.MOD.8=0
2250       NEXT X.OUT
2260   Y.OUT.MOD.4=Y.OUT.MOD.4+1
2270   IF Y.OUT.MOD.4 >= 4 THEN Y.OUT.MOD.4=0
2280 NEXT Y.OUT
2290 X=4
2300 Y=Y.MAX-2
2310 PAGE(Y,X)=0
2320 STACK.HEAD=-1
2330   DELTA.INDEX.1A=1
2340     DELTA.INDEX.2=R.N(1)
2350     R.N.INDEX.1=1
2360     FOR R.N.INDEX.2=2 TO 8
2370       TEM.INT=R.N(R.N.INDEX.2)
2380       R.N(R.N.INDEX.1)=TEM.INT
2390       DELTA.INDEX.2=DELTA.INDEX.2+TEM.INT
2400       IF DELTA.INDEX.2 > 727 THEN DELTA.INDEX.2=DELTA.INDEX.2-727
2410       R.N.INDEX.1=R.N.INDEX.2
2420     NEXT R.N.INDEX.2
2430     R.N(8)=DELTA.INDEX.2
2440   IF DELTA.INDEX.2 > 720 THEN 2340
2450   PASSAGE.FOUND=0
2460   SEARCH.COMPLETE=0
2470   WHILE (SEARCH.COMPLETE = 0)
2480     WHILE ((DELTA.INDEX.1A <= 6) AND (PASSAGE.FOUND = 0))
2490       X.NEXT=X+2*DELTA.X(DELTA.INDEX.1A,DELTA.INDEX.2)
2500       IF X.NEXT > 0 THEN 2530
2510         DELTA.INDEX.1A=DELTA.INDEX.1A+1
2520       GOTO 2670
2530         IF X.NEXT < X.MAX THEN 2560
2540           DELTA.INDEX.1A=DELTA.INDEX.1A+1
2550         GOTO 2670
2560           Y.NEXT=Y+2*DELTA.Y(DELTA.INDEX.1A,DELTA.INDEX.2)
2570           IF Y.NEXT > 0 THEN 2600
2580             DELTA.INDEX.1A=DELTA.INDEX.1A+1
2590           GOTO 2670
2600             IF Y.NEXT < Y.MAX THEN 2630
2610               DELTA.INDEX.1A=DELTA.INDEX.1A+1
2620             GOTO 2670
2630               IF PAGE(Y.NEXT,X.NEXT) = 0 THEN 2660
2640                 PASSAGE.FOUND=-1
2650               GOTO 2670
2660                 DELTA.INDEX.1A=DELTA.INDEX.1A+1
2670     WEND
2680     IF PASSAGE.FOUND <> 0 THEN 2760
2690       IF STACK.HEAD < 0 THEN 2760
2700         DELTA.INDEX.1A=STACK.1(STACK.HEAD)
2710         DELTA.INDEX.2=STACK.2(STACK.HEAD)
2720         X=X-2*DELTA.X(DELTA.INDEX.1A,DELTA.INDEX.2)
2730         Y=Y-2*DELTA.Y(DELTA.INDEX.1A,DELTA.INDEX.2)
2740         STACK.HEAD=STACK.HEAD-1
2750         DELTA.INDEX.1A=DELTA.INDEX.1A+1
2760     IF PASSAGE.FOUND = 0 THEN 2790
2770       SEARCH.COMPLETE=-1
2780     GOTO 2810
2790       IF ((STACK.HEAD >= 0) OR (DELTA.INDEX.1A <= 6)) THEN 2810
2800         SEARCH.COMPLETE=-1
2810   WEND
2820   IF PASSAGE.FOUND = 0 THEN 2900
2830     STACK.HEAD=STACK.HEAD+1
2840     STACK.1(STACK.HEAD)=DELTA.INDEX.1A
2850     STACK.2(STACK.HEAD)=DELTA.INDEX.2
2860     PAGE(Y.NEXT,X.NEXT)=0
2870     PAGE((Y+Y.NEXT)\2,(X+X.NEXT)\2)=0
2880     X=X.NEXT
2890     Y=Y.NEXT
2900 IF STACK.HEAD <> -1 THEN 2330
2910 PAGE(2,2)=0
2920 PAGE(Y.MAX-1,X.MAX-1)=0
2930 SCREEN 1
2940 COLOR 0,0
2950 CLS
2960 Y.PREVIOUS=0
2970 Y.NEXT=2
2980 FOR Y.OUT=1 TO Y.MAX
2990   X.OUT=1
3000   FOR X.NEXT=2 TO X.MAX
3010     IF PAGE(Y.OUT,X.OUT) = 0 THEN 3100
3020       IF PAGE(Y.OUT,X.NEXT) = 0 THEN 3040
3030         LINE (3*(X.OUT-1),4*(Y.OUT-1))-(3*(X.NEXT-1),4*(Y.OUT-1)),1
3040       IF Y.PREVIOUS <= 0 THEN 3070
3050         IF PAGE(Y.PREVIOUS,X.NEXT) = 0 THEN 3070
3060           LINE (3*(X.OUT-1),4*(Y.OUT-1))-(3*(X.NEXT-1),4*(Y.PREVIOUS-1)),1
3070       IF Y.NEXT > Y.MAX THEN 3100
3080         IF PAGE(Y.NEXT,X.NEXT) = 0 THEN 3100
3090           LINE (3*(X.OUT-1),4*(Y.OUT-1))-(3*(X.NEXT-1),4*(Y.NEXT-1)),1
3100     X.OUT=X.NEXT
3110   NEXT X.NEXT
3120   Y.PREVIOUS=Y.OUT
3130   Y.NEXT=Y.NEXT+1
3140 NEXT Y.OUT
3150 BEEP
3160 WHILE (INKEY$ = "")
3170 WEND
3180 NUM.DEAD.ENDS=0
3190   FOR Y.OUT=3 TO Y.MAX STEP 4
3200     FOR X.OUT=4 TO X.MAX STEP 8
3210       NUM.WALLS=PAGE(Y.OUT-1,X.OUT-2)
3220       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT+1,X.OUT-2)
3230       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT+2,X.OUT)
3240       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT+1,X.OUT+2)
3250       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT-1,X.OUT+2)
3260       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT-2,X.OUT)
3270       IF NUM.WALLS <> 5 THEN 3510
3280         NUM.DEAD.ENDS=NUM.DEAD.ENDS+1
3290         IF PAGE(Y.OUT-1,X.OUT-2) <> 0 THEN 3330
3300           LINE (3*(X.OUT-4),4*(Y.OUT-1))-(3*(X.OUT-2),4*(Y.OUT-3)),2
3310           PAGE(Y.OUT-1,X.OUT-2)=1
3320         GOTO 3510
3330           IF PAGE(Y.OUT-2,X.OUT) <> 0 THEN 3370
3340             LINE (3*(X.OUT-2),4*(Y.OUT-3))-(3*X.OUT,4*(Y.OUT-3)),2
3350             PAGE(Y.OUT-2,X.OUT)=1
3360           GOTO 3510
3370             IF PAGE(Y.OUT-1,X.OUT+2) <> 0 THEN 3410
3380               LINE (3*X.OUT,4*(Y.OUT-3))-(3*(X.OUT+2),4*(Y.OUT-1)),2
3390               PAGE(Y.OUT-1,X.OUT+2)=1
3400             GOTO 3510
3410               IF PAGE(Y.OUT+1,X.OUT+2) <> 0 THEN 3450
3420                 LINE (3*(X.OUT+2),4*(Y.OUT-1))-(3*X.OUT,4*(Y.OUT+1)),2
3430                 PAGE(Y.OUT+1,X.OUT+2)=1
3440               GOTO 3510
3450                 IF PAGE(Y.OUT+2,X.OUT) <> 0 THEN 3490
3460                   LINE (3*X.OUT,4*(Y.OUT+1))-(3*(X.OUT-2),4*(Y.OUT+1)),2
3470                   PAGE(Y.OUT+2,X.OUT)=1
3480                 GOTO 3510
3490                   LINE (3*(X.OUT-2),4*(Y.OUT+1))-(3*(X.OUT-4),4*(Y.OUT-1)),2
3500                   PAGE(Y.OUT+1,X.OUT-2)=1
3510     NEXT X.OUT
3520   NEXT Y.OUT
3530   Y.LIMIT=Y.MAX-1
3540   FOR Y.OUT=5 TO Y.LIMIT STEP 4
3550     FOR X.OUT=8 TO X.MAX STEP 8
3560       NUM.WALLS=PAGE(Y.OUT-1,X.OUT-2)
3570       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT+1,X.OUT-2)
3580       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT+2,X.OUT)
3590       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT+1,X.OUT+2)
3600       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT-1,X.OUT+2)
3610       NUM.WALLS=NUM.WALLS+PAGE(Y.OUT-2,X.OUT)
3620       IF NUM.WALLS <> 5 THEN 3860
3630         NUM.DEAD.ENDS=NUM.DEAD.ENDS+1
3640         IF PAGE(Y.OUT-1,X.OUT-2) <> 0 THEN 3680
3650           LINE (3*(X.OUT-4),4*(Y.OUT-1))-(3*(X.OUT-2),4*(Y.OUT-3)),2
3660           PAGE(Y.OUT-1,X.OUT-2)=1
3670         GOTO 3860
3680           IF PAGE(Y.OUT-2,X.OUT) <> 0 THEN 3720
3690             LINE (3*(X.OUT-2),4*(Y.OUT-3))-(3*X.OUT,4*(Y.OUT-3)),2
3700             PAGE(Y.OUT-2,X.OUT)=1
3710           GOTO 3860
3720             IF PAGE(Y.OUT-1,X.OUT+2) <> 0 THEN 3760
3730               LINE (3*X.OUT,4*(Y.OUT-3))-(3*(X.OUT+2),4*(Y.OUT-1)),2
3740               PAGE(Y.OUT-1,X.OUT+2)=1
3750             GOTO 3860
3760               IF PAGE(Y.OUT+1,X.OUT+2) <> 0 THEN 3800
3770                 LINE (3*(X.OUT+2),4*(Y.OUT-1))-(3*X.OUT,4*(Y.OUT+1)),2
3780                 PAGE(Y.OUT+1,X.OUT+2)=1
3790               GOTO 3860
3800                 IF PAGE(Y.OUT+2,X.OUT) <> 0 THEN 3840
3810                   LINE (3*X.OUT,4*(Y.OUT+1))-(3*(X.OUT-2),4*(Y.OUT+1)),2
3820                   PAGE(Y.OUT+2,X.OUT)=1
3830                 GOTO 3860
3840                   LINE (3*(X.OUT-2),4*(Y.OUT+1))-(3*(X.OUT-4),4*(Y.OUT-1)),2
3850                   PAGE(Y.OUT+1,X.OUT-2)=1
3860     NEXT X.OUT
3870   NEXT Y.OUT
3880 IF NUM.DEAD.ENDS <> 0 THEN 3180
3890 BEEP
3900 WHILE (INKEY$ = "")
3910 WEND
3920 SCREEN 0
3930 WIDTH 80
3940 END

Unknown authors, probably circa 1984 and for BASCOM Tongue
Pages: 1 2