Concentration

This file is part of and SINCUS Exchange Tape 101 - Entertainment. Download the collection to get this file.
Type: Program
Platform(s): TS 2068
Tags: Game

This program implements the card-matching memory game Concentration for two players on a 6×6 grid, using letters A through I (each appearing four times) as the hidden card values. The shuffling routine at lines 50–120 uses a rejection-sampling method, filling a 6×6 DIM A array by picking random coordinates and retrying if the cell is already occupied. Cards are displayed as filled block graphics (█) and revealed by printing the corresponding letter from the string X$; matched pairs are cleared by setting their array entries back to zero and printing a space. Player scores are tracked in P1 and P2, and the game detects completion when P1+P2 equals 18, representing all nine pairs found.


Program Analysis

Program Structure

The program divides into four logical phases:

  1. Initialization (lines 5–48): Dimensions the 6×6 array A, sets player scores to zero, displays a “shuffling” splash screen.
  2. Card placement (lines 50–120): Randomly fills A with values 1–9, each placed exactly four times, via a rejection-sampling loop.
  3. Board display (lines 125–195): Draws the grid of covered cards using the block graphic \:: (█) and prints column/row labels and score areas.
  4. Game loop (lines 200–630): Alternates turns between players, accepts two card coordinates, reveals letters, checks for a match, updates scores, and detects game over.

Data Representation

The 6×6 array A holds integer values 1–9, representing nine card pairs (each value placed four times, filling all 36 cells). The string X$="ABCDEFGHI" maps these values to display characters via X$(f) — a one-character slice using Spectrum BASIC’s substring notation. When a matched pair is cleared, both cells are set to zero; the zero value also serves as a sentinel for “already matched” cells, triggering the error message at lines 415 and 465.

Shuffling Algorithm

Lines 50–120 use a nested loop: the outer loop iterates over the nine letter values (I = 1 to 9), the inner loop places four copies of each (J = 1 to 4). Random coordinates X, Y are generated, and if A(X,Y) is already nonzero the inner loop retries via GO TO 70. This is a classic rejection-sampling approach. It is statistically correct but can be slow near the end of placement when few empty cells remain.

Turn Management

The variable Z tracks the current player (1 or 2). On a mismatch, lines 482–486 toggle Z using an explicit if-chain rather than arithmetic (e.g., LET Z=3-Z). On a match, Z is deliberately not toggled, allowing the matching player to take another turn — consistent with standard Concentration rules.

Screen Layout

The grid is drawn with row I placed at AT 2*I+3, 10, giving one blank row between each card row. Column positions are spaced two characters apart. Score display for Player 1 appears at column 3, Player 2 at column 27, keeping them in the side margins outside the 6×6 grid area.

Notable Techniques

  • Block graphic \:: (█) is used as the card-back symbol; this is a Spectrum block graphic character (code 143), not a special PRINT token.
  • FLASH 1 is used inline within PRINT statements for “ERROR MADE”, “OK”, and “GAME OVER” to draw attention without any separate flashing loop.
  • A short BEEP fanfare (lines 553) plays five ascending notes on a successful match using semitone offsets 0, 4, 7, 12, 9, 12.
  • The subroutine at line 300 handles card-entry for the first card; the second card entry re-uses the same flow via GO TO 430 rather than a second subroutine, keeping code compact.
  • PAUSE 100 at line 475 gives players about two seconds to view both revealed cards before the mismatch branch executes.

Bugs and Anomalies

Line(s)Issue
558–559The condition IF f=s is checked redundantly — control only reaches line 558 via line 550 which is itself branched to only when f=s (line 480). The double check is harmless but unnecessary.
510, 520After a match (line 550 branch), Y$=" " is set at line 555, but lines 510 and 520 still execute (fallen through from the mismatch path at line 500). On the match path, control arrives at line 510 after the score update at lines 570–610 via GO TO 510, printing a space over the matched card positions — this is intentional erasure of matched cards but shares code with the mismatch display path in a non-obvious way.
630The final IF p1+p2=18 condition is always true at that point (line 620 only falls through when the sum equals 18), so the IF is redundant. The game also does not restart or offer a replay option after printing “GAME OVER”.
415, 465The already-matched cell error uses GO TO 300 / GO TO 430 to restart entry, but does not restore the display of the first revealed card before re-prompting, which could confuse players.

Content

Related Products

Related Articles

Related Content

Image Gallery

Concentration

Source Code

    5 REM concentration
    6 CLS 
   10 DIM A(6,6)
   15 BORDER 4
   20 LET P1=0
   30 LET P2=0
   40 LET X$="ABCDEFGHI"
   42 PRINT : PRINT 
   45 PRINT "   Please standby . . .",,," cards being shuffled"
   48 PRINT AT 11,2;"\::C O N C E N T R A T I O N\  "
   50 FOR i=1 TO 9
   60 FOR j=1 TO 4
   70 LET X=INT (RND*6+1)
   80 LET Y=INT (RND*6+1)
   90 IF A(X,Y)<>0 THEN GO TO 70
  100 LET A(X,Y)=I
  110 NEXT J
  120 NEXT I
  125 CLS 
  130 PRINT AT 1,10;"CONCENTRATION"
  140 PRINT AT 3,12;"1 2 3 4 5 6"
  150 FOR I=1 TO 6
  160 PRINT AT 2*i+3,10;i;
  170 PRINT " \:: \:: \:: \:: \:: \::"
  180 NEXT I
  185 PRINT AT 7,2;"Score";AT 7,26;"Score"
  190 PRINT AT 9,0;"Player 1";AT 9,24;"Player 2"
  195 PRINT AT 21,1;"Enter row no. then column no."
  200 LET z=1
  230 PRINT AT 17,10;"Player ";Z;" goes"
  280 GO SUB 300
  290 GO TO 230
  300 PRINT AT 19,12;"1st card"
  310 INPUT x
  315 PRINT AT 19,0;"          ";AT 20,0;"           "
  320 INPUT y
  410 LET f=a(X,Y)
  415 IF A(x,y)=0 THEN PRINT AT 19,0; FLASH 1;"ERROR MADE";AT 20,0;"ENTER AGAIN": GO TO 300
  420 PRINT AT 2*X+3,2*Y+10;X$(f)
  430 PRINT AT 19,12;"2nd"
  440 INPUT r
  445 PRINT AT 19,0;"          ";AT 20,0;"           "
  450 INPUT t
  460 LET s=a(R,T)
  465 IF a(r,t)=0 THEN PRINT AT 19,0; FLASH 1;"ERROR MADE";AT 20,0;"ENTER AGAIN": GO TO 430
  470 PRINT AT 2*R+3,2*T+10;X$(s)
  475 PAUSE 100
  480 IF f=s THEN GO TO 550
  482 IF Z=1 THEN GO TO 486
  483 LET z=1
  484 GO TO 490
  486 LET z=2
  490 LET Y$="\::"
  500 PRINT AT 15,3;"No "
  510 PRINT AT 2*X+3,2*Y+10;Y$
  520 PRINT AT 2*R+3,2*T+10;Y$
  530 RETURN 
  550 PRINT AT 15,3; FLASH 1;"OK"
  553 BEEP .15,0: BEEP .1,4: BEEP .1,7: BEEP .2,12: BEEP .1,9: BEEP .3,12
  555 LET Y$=" "
  558 IF f=s THEN LET A(x,y)=0
  559 IF f=s THEN LET A(r,t)=0
  560 IF Z=1 THEN GO TO 600
  570 LET p2=p2+1
  580 PRINT AT 11,27;p2
  590 GO TO 620
  600 LET p1=p1+1
  610 PRINT AT 11,3;p1
  620 IF p1+p2<>18 THEN GO TO 510
  630 IF p1+p2=18 THEN PRINT AT 19,22; FLASH 1;"GAME OVER"

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

People

No people associated with this content.

Scroll to Top