--- title: "Concentration" id: 53791 type: "computer_media" slug: "concentration" url: "http://localhost/computer_media/concentration/" markdown_url: "http://localhost/computer_media/concentration.md" published_at: "2024-05-13T18:56:52+00:00" modified_at: "2026-03-30T21:41:32+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/05/concentration-sincus-101-1.png" excerpt: "A two-player memory card game hides nine letter pairs across a 6×6 grid, challenging players to find all matches before their opponent does." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Game" slug: "game" taxonomy: "genre" url: "http://localhost/type/game/" media_contents: - id: 53877 title: "SINCUS Exchange Tape 101 – Entertainment" type: "computer_media" url: "http://localhost/computer_media/sincus-exchange-tape-101-entertainment/" media_type: "Program" images: - url: "http://localhost/wp-content/uploads/2024/05/concentration-sincus-101-1.png" - url: "http://localhost/wp-content/uploads/2024/05/concentration-sincus-101-2.png" media_type_tags: "Game" --- # Concentration 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–559 | The 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, 520 | After 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. | | 630 | The 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, 465 | The 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. | ## 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" ```