Squash 1

Date: 198x
Type: Program
Platform(s): TS 2068
Tags: Game

Squash 1 is a single-player squash/paddle game in which a ball bounces around the screen and the player moves a bat (displayed as CHR$ 95, the underscore character) along a fixed horizontal row using keys 5 and 8. The ball is represented by a period character and travels diagonally, reflecting off the top edge and side walls, with a BEEP sounded on each bounce. The bat is positioned at row 20 and the ball is lost when it reaches row 22 without being intercepted, triggering a new serve via GO TO 20. A subroutine at line 100 handles both reading the bat position from INKEY$ and redrawing the bat on every iteration of the main loop, giving responsive but polling-based control. The SAVE line stores the program with an auto-run directive at LINE 0.


Program Structure

The program is organized into a tight main loop and a single subroutine:

  • Lines 5–15: Initialization — screen attributes and starting values for bat position (a=20, b=15), and a “wall-hit” flag w.
  • Line 20: New-serve setup — ball position (x, y), vertical direction (ud=1), and random horizontal direction (lr set to ±1).
  • Lines 25–70: Main game loop — draws the ball, calls the bat subroutine, computes next position, checks wall/bat collisions, and redraws.
  • Lines 100–115: Bat subroutine — reads INKEY$, moves and redraws the bat.

Ball Movement and Collision Logic

The ball moves one cell per loop iteration in both axes. Direction variables ud (up/down, ±1) and lr (left/right, ±1) are negated on wall hits. The top edge reflection is detected when nx=0 (line 40); side wall reflections trigger when ny=0 OR ny=31 (line 50). Bat contact is checked at line 55: if the ball’s next row equals a (row 20) and its column equals b, vertical direction is reversed and a higher-pitched BEEP is played. No reflection is performed for the bat’s horizontal position — only an exact column match triggers a return.

A wall-hit flag w is set to 1 whenever the ball reflects off a wall, causing a BEEP at line 25 on the following iteration. This deferred sound avoids sound calls inside position update logic and separates audio from movement cleanly.

Bat Subroutine (Lines 100–115)

The subroutine at line 100 is called twice per loop: once before computing the next position (line 30) and once more at line 45, giving the player two opportunities per frame to move the bat. This is a straightforward way to improve responsiveness without restructuring the loop.

The bat movement expression on line 100 uses a Boolean arithmetic idiom common in Sinclair BASIC:

LET n=b+(INKEY$="8" AND b<31)-(INKEY$="5" AND b>0)

The relational expressions evaluate to 1 (true) or 0 (false), so n is incremented when “8” is pressed and decremented when “5” is pressed, with boundary clamping built in. The bat is only redrawn if its position actually changed (line 105), reducing flicker.

Screen and Display Techniques

The ball is erased by printing CHR$ 32 (space) at its old position before moving (line 60). The bat is drawn as CHR$ 95 (underscore), which visually resembles a horizontal paddle. There is no use of graphics characters or pixel-level drawing; everything is character-cell based.

PAPER 4 sets a green background and INK 9 selects bright default ink, giving a colored court effect. BRIGHT 1 applies globally at initialization.

Loss Condition and Restart

If the ball reaches row 22 (x=22, line 65), a low BEEP is played and the program jumps back to line 20 for a new serve. There is no score tracking — the game loops indefinitely with no win condition.

Bugs and Anomalies

  • The bat collision check (line 55) only tests for an exact column match (ny=b). The bat visually occupies only one character cell, so this is consistent, but it makes the target very small.
  • The ball is not erased at line 25 before the subroutine call — the print at line 25 draws the ball dot, then at line 60 it is erased. This ordering means the ball is visible during the subroutine call delay, which is the intended display behavior.
  • When the ball’s next position matches the bat (line 55), only ud is reversed; w is not set, so no wall-bounce BEEP fires — but a separate higher-pitched BEEP (note 50) is played instead, correctly distinguishing bat hits from wall hits.
  • There is no check preventing the ball from passing through the bat if it approaches from below row 20, though the ball starts moving downward (ud=1) and the loss condition triggers at row 22, so this situation cannot arise in normal play.

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    5 BORDER 4:PAPER 4:BRIGHT 1:INK 9
   10 CLS 
   15 LET a=20:LET b=15:LET w=0
   20 LET x=0:LET y= INT (RND*31):LET ud=1:LET lr= INT (RND*2):IF lr=0 THEN LET lr=-1
   25 PRINT AT x,y;".":IF w THEN BEEP .01,30:LET w=0
   30 GO SUB 100
   35 LET nx=x+ud
   40 IF nx=0 THEN LET ud=-ud:LET w=1
   45 GO SUB 100
   50 LET ny=y+lr:IF ny=0 OR ny=31 THEN LET lr=-lr:LET w=1
   55 IF nx=a AND ny=b THEN LET ud=-ud:BEEP .01,50
   60 PRINT AT x,y; CHR$ 32:LET x=nx:LET y=ny
   65 IF x=22 THEN BEEP .3,0:GO TO 20
   70 GO TO 25
  100 LET n=b+(INKEY$="8" AND b<31)-(INKEY$="5" AND b>0)
  105 IF n <>b THEN PRINT AT a,b; CHR$ 32:LET b=n
  110 PRINT AT a,b; CHR$ 95
  115 RETURN 
 9000 SAVE "PRACTICE"\{16}\{3}\{16}\{3} LINE 0

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.

People

No people associated with this content.

Scroll to Top