--- title: "Paqman" id: 72968 type: "computer_media" slug: "paqman" url: "http://localhost/computer_media/paqman/" markdown_url: "http://localhost/computer_media/paqman.md" published_at: "2026-10-27T21:30:07+00:00" modified_at: "2026-10-27T21:30:07+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/10/paqman-1.png" excerpt: "A Pac-Man style maze game in SuperBASIC: eat the dots, dodge up to three ghosts and clear nineteen screens to earn the title of Grand Master." post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "QL" slug: "ql" taxonomy: "post_tag" url: "http://localhost/tag/ql/" model: - name: "Sinclair QL" slug: "sinclair-ql" taxonomy: "model" url: "http://localhost/model/sinclair-ql/" indiv: - name: "S. N. Deary" slug: "s-n-deary" taxonomy: "indiv" url: "http://localhost/indiv/s-n-deary/" genre: - name: "Arcade" slug: "arcade" taxonomy: "genre" url: "http://localhost/type/arcade/" media_type: "Diskette" programmers: - name: "S. N. Deary" slug: "s-n-deary" taxonomy: "indiv" url: "http://localhost/indiv/s-n-deary/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Paqman%20%281985%29%28Deary%2C%20S.%20N.%29%28Sinclair%20QL%29%28UK%29%28Program%29.zip" mediadate: "1985" images: - url: "http://localhost/wp-content/uploads/2026/10/paqman-1.png" media_type_tags: "Arcade" license: false --- # Paqman Paqman is a Pac-Man style maze game. You steer the paqman around a red and blue maze eating dots while ghosts chase you; you have three lives, each cleared screen earns a bonus, more ghosts join as the screens go on, and clearing nineteen screens wins the title of Grand Master. The REMs read “QL USER 1985” and credit S N Deary BSc, so it was a type-in from *QL User* magazine. ## Program Analysis The main loop draws the maze with user-defined characters, then repeats `move_man` and `move_ghost`; the chance of a ghost moving rises with the screen number (`handicap`). ### Potential Issues - The bonus is built as a string (`Screen&'000'`) and added to the score; SuperBASIC coerces it, so it works. It came from a QL owner’s floppy copies of QUANTA and IQLUG library material, imaged double-stepped so that only half of each disk survived; this file read back complete. The download holds the files exactly as recovered and a QL5A floppy image, *Paqman.img*, with the same files and their QDOS headers. Mount the image as FLP1_ (drop it on the QLRun page, or use it as a floppy image in sQLux, QPC2 or Q-emuLator) and type `lrun flp1_paqman_bas`. Tested in QLRun with the JS ROM: the maze and the start screen. ## Source Code ``` 10 REMark **** QL USER 1985 **** 20 REMark **** PAQMAN : Author SN Deary Bsc **** 100 initialise 110 REPeat forever 120 score=0 : lives=3 : Screen=1 130 REPeat screens 140 ghosts=Screen-1 : IF ghosts > 2 : ghosts=2 150 drawmaze 160 handicap=Screen+4 170 REPeat moves 180 move_man 190 IF RND(30)< handicap:move_ghost(RND(ghosts)) 200 IF end_of_screen:EXIT moves 210 END REPeat moves 220 IF max = 0 230 CLS : AT 5,12 : FLASH 1 240 PRINT 'Bonus ';Screen;'000' 250 score=score+(Screen&'000') 260 FLASH 0 : FOR i=1 TO 300 : i=i : REMark delay 270 Screen=Screen+1 280 END IF 290 IF lives < 1 : EXIT screens 300 IF Screen > 19 : EXIT screens 310 END REPeat screens 320 CLS 330 IF Screen > 19 340 PRINT 'You have won the title of Grand Master' 350 PRINT 'Too good for this game. I concede!!' 360 STOP 370 END IF 380 AT 5,10 : FLASH 1 390 PRINT 'G A M E O V E R' 400 FLASH 0 : FOR i=1 TO 1000: i=i: REMark delay 410 IF score > top_score:top_score=score 420 END REPeat forever 430 : 440 DEFine PROCedure move_man 450 INK 2 460 key=KEYROW(1) 470 row=man_row : col=man_col 480 IF key && 2 : col=col-1 : IF col < 0:IF row=5:col=18:ELSE col=0 490 IF key && 16 : col=col+1 : IF col > 18 : IF row=5 : col=0:ELSE col=18 500 IF key && 4 : row=row-1 : IF row <0 : IF col=9 : row=10 : ELSE row=0 510 IF key &&128 : row=row+1 : IF row > 10 : IF col = 9 : row=0 : ELSE row=10 520 prize=maze(row,col) 530 IF (prize&&1) OR key=0:RETurn 540 IF prize&&16:gotcha:RETurn 550 AT man_row,man_col*2:PRINT " "; 560 INK 6:AT row,col*2:PRINT man$; 570 BEEP 200,max 580 maze(row,col)=0 590 IF prize 600 score=score+prize 610 max=max-1 : IF max < 1 : end_of_screen=true 620 AT #4,0,6:PRINT #4,score; 630 END IF 640 man_row=row : man_col=col 650 END DEFine 660 : 670 DEFine PROCedure move_ghost(x) 680 row=ghost_row(x):col=ghost_col(x) 690 not_moved=true 700 IF ABS(man_row-row) < ABS(man_col-col) 710 horizontal:IF not_moved:col=ghost_col(x):vertical 720 ELSE vertical: IF not_moved:row=ghost_row(x):horizontal 730 END IF 740 END DEFine 750 : 760 DEFine PROCedure vertical 770 IF row=man_row : RETurn 780 IF man_row < row 790 row=row-1 : IF row >=0 : moveit 800 ELSE 810 row=row+1: IF row <=10 : moveit 820 END IF 825 END DEFine 830 : 840 DEFine PROCedure horizontal 850 IF col=man_col:RETurn 860 IF man_col=0:moveit 880 ELSE 890 col=col+1:IF col <=18:moveit 900 END IF 910 END DEFine 920 : 930 DEFine PROCedure moveit 940 IF (maze(row,col)&&17) : RETurn 950 INK 4:OVER -1 960 not_moved=false 970 AT ghost_row(x),2*ghost_col(x):PRINT ghost$ 980 maze(ghost_row(x),ghost_col(x))=maze(ghost_row(x),ghost_col(x))-16 990 AT row,2*col:PRINT ghost$ 1000 maze(row,col)=maze(row,col)+16 1010 ghost_row(x)=row:ghost_col(x)=col 1020 OVER 0 1030 IF row=man_row AND col=man_col:gotcha 1040 END DEFine 1050 : 1060 DEFine PROCedure gotcha 1070 end_of_screen=true 1080 lives=lives-1 1090 BEEP 30000,1,255,200,4,2 1100 END DEFine 1110 : 1120 DEFine PROCedure initialise 1130 set_up_user_defined_chars 1140 MODE 8 1150 true=1:false=0 1160 top_score=0 1170 CSIZE 2,1 1180 OPEN #3,scr_512x256a0x0 1190 PAPER #3,0:CLS #3 1200 SCALE #3,256,0,0 1210 OPEN #4,scr_456x10a32x14 1220 WINDOW 476,230,23,26 1230 BORDER 5,2 1240 BLOCK #3,24,5,248,26,1 1250 BLOCK #3,24,5,248,251,1 1260 BLOCK #3,10,20,23,131,1 1270 BLOCK #3,10,20,489,131,1 1280 DIM maze(10,18),man$(2),maze$(2,2) 1290 DIM ghost$(2),ghost_row(2),ghost_col(2) 1300 man$=CHR$(131)&CHR$(132) 1310 ghost$=CHR$(128)&CHR$(129) 1320 maze$(0)=CHR$(133)&' ' 1330 maze$(1)=CHR$(134)&CHR$(134) 1340 maze$(2)=CHR$(130)&' ' 1350 END DEFine 1360 : 1370 DEFine PROCedure set_up_user_defined_chars 1380 start_address=RESPR(100) 1390 register_a0=65537 1400 register_a2=start_address+6 1410 RESTORE 1440 1420 FOR i=0 TO 70: READ byte:POKE start_address+i,byte 1430 CALL start_address,0,0,255,37,0,0,0,register_a0,0,register_a2 1440 DATA 32,4,78,67,78,117 1450 DATA 128,6 1460 DATA 4,8,16,44,76,64,84,84,0 1470 DATA 64,32,16,104,100,4,84,84,0 1480 DATA 0,0,0,0,4,0,0,0,0 1490 DATA 124,60,36,60,124,24,24,56,0 1500 DATA 124,120,72,120,192,48,48,56,0 1510 DATA 0,40,16,56,124,124,124,56,0 1520 DATA 40,56,56,124,124,124,124,40,108 1530 END DEFine 1540 : 1550 DEFine PROCedure drawmaze 1560 max=139:end_of_screen=false 1570 RESTORE 1600 1580 READ man_row,man_col 1590 FOR i=0 TO 2:READ ghost_row(i),ghost_col(i) 1600 DATA 5,0,5,8,5,9,5,10 1610 IF Screen MOD 4 : PAPER 2 : ELSE PAPER 1 1620 CLS : CLS #4 1630 RESTORE 1950 1640 PAPER 1 : INK 4 1650 FOR row=0 TO 5 1660 opposite_row=10-row 1670 FOR col=0 TO 9 1680 opposite_col=18-col 1690 READ prize: maze(row,col)=prize 1700 maze(row,opposite_col)=prize 1710 maze(opposite_row,col)=prize 1720 maze(opposite_row,opposite_col)=prize 1730 IF prize > 1 1740 IF prize = 2 1750 chars$=maze$(2) 1760 ELSE IF prize =6 : chars$=maze$(0):ELSE chars$=maze$(1) 1770 END IF 1780 AT row,col*2: PRINT chars$; 1790 AT opposite_row,col*2:PRINT chars$; 1800 AT opposite_row,opposite_col*2:PRINT chars$; 1810 AT row,opposite_col*2:PRINT chars$; 1815 END IF 1820 END FOR col 1830 END FOR row 1840 AT 5,16:OVER -1:INK 4 1850 FOR i=0 TO ghosts:PRINT ghost$;:maze(5,8+i)=17 1860 AT man_row,2*man_col:OVER 0 1870 maze(man_row,man_col)=0 1880 INK 6 : PRINT man$ 1890 key=KEYROW(1) 1900 PRINT #4,"Press any key to start"; 1910 a$=INKEY$(-1):CLS #4 1920 AT #4,0,0:PRINT #4;'SCORE:';score; 1930 AT #4,0,13:PRINT #4;'TOP SCORE:';top_score; 1940 AT #4,0,31:PRINT #4;'LIVES:';lives 1950 DATA 2,2,2,2,2,2,2,2,1,2 1960 DATA 6,1,2,1,1,2,1,2,2,2 1970 DATA 2,1,2,2,2,2,2,2,1,1 1980 DATA 1,1,1,2,1,2,1,2,1,8 1990 DATA 1,2,2,2,1,2,2,2,2,2 2000 DATA 2,2,1,2,2,2,1,2,1,1 2010 END DEFine ```