3-D TicTacToe

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

This program implements a three-dimensional Tic-Tac-Toe game on a 3×3×3 grid, where players designate moves by entering a layer letter (A, B, or C) followed by a position number (1–9). The board is rendered using block graphics to depict three overlapping grids in isometric-style perspective, representing front, middle, and rear planes. Cell coordinates for display are packed into strings X$ and Y$ and decoded at startup by extracting two-character substrings and converting them with VAL, an efficient data-storage technique for position tables. Win detection works by summing A() array values (1 for X, −1 for O) along 13 center-based symmetrical axes and 18 additional non-center lines defined by offset tables C() and R(), scoring accumulated wins in SX and SO rather than halting play after the first three-in-a-row. The first move is restricted from the center square (position 14, the cube’s center), and entering “R” resets the game.


Program Structure

The program is organized into a main loop with several subroutines:

  • Lines 1–4: Introduction and instructions display
  • Lines 5–90: Array and data initialization (dimensions, coordinate tables, win-line tables)
  • Lines 100–120: Game state reset
  • Lines 170–280: Main game loop (display, input, move processing)
  • Lines 390–395: Illegal move handler
  • Lines 500–580: Win-detection and scoring subroutine
  • Lines 800–810: Score incrementing helper
  • Line 900–905: Screen color setup subroutine
  • Lines 1000–1090: Board drawing subroutine
  • Lines 9997–9999: Stop, SAVE, and VERIFY

Data Encoding in Strings

A compact data-packing technique is used for screen coordinates and win-line definitions. X$ and Y$ (line 30–35) each hold 54 characters encoding 27 two-digit decimal numbers representing screen column and row positions for each of the 27 board cells. Similarly, C$ and R$ (lines 60–65) encode 18 two-digit values each, defining the center cell and offset for additional win-line checks. All values are decoded with VAL X$(2*Z-1 TO 2*Z), a standard Sinclair BASIC string-slicing idiom that avoids the need for DATA/READ statements and saves memory.

Board Representation

The 3×3×3 cube is mapped to a flat array A(27). Layers are addressed as offsets: A=cells 1–9, B=cells 10–18, C=cells 19–27. Player input converts a letter (A/B/C) to a base offset (0, 9, or 18) and adds the digit entered, producing a direct index into A(). Cell 14 is the geometric center of the cube; the program explicitly forbids occupying it on the first move (line 245).

Win Detection Algorithm

Win detection (lines 500–565) operates in two passes rather than checking all 49 lines explicitly:

  1. Center-symmetric lines (lines 515–530): For Z=1 to 13, it sums A(14-Z) + A(14) + A(14+Z). Because the center cell is always included and the 13 offsets cover all lines passing through the cube’s center, this elegantly handles all center-passing three-in-a-rows.
  2. Non-center lines (lines 535–565): Uses C(Z) as the middle cell and R(Z) as the step offset. It checks both the line and its mirror (V = 28 - C(Z)) to cover symmetric non-center lines on the cube’s faces and diagonals.

Rather than stopping at the first win, scoring accumulates into SX (X wins) and SO (O wins) across all 27 turns, and totals are printed after every move. This means the game is effectively a full-game scoring variant rather than a stop-at-first-win game.

Notable Bugs and Anomalies

  • Line 540 double-add bug: LET W=A(C(Z))+A(C(Z))+A(C(Z)+R(Z)) adds the middle cell twice instead of using A(C(Z)-R(Z))+A(C(Z))+A(C(Z)+R(Z)). This means the non-center line check is incorrect — it tests 2×middle + one neighbor rather than left + middle + right. This is a genuine bug that would cause missed or false win detections on non-center lines.
  • No input validation beyond occupancy: If the player enters an invalid layer letter or non-numeric digit, VAL Z$(2) may produce 0 or cause an error. No guard against single-character input for the digit is present.
  • Center restriction only on move 1: Line 245 prevents the center square on N=1, but the center is otherwise playable from move 2 onward. The instructions describe this rule correctly.
  • Game does not end on a win: Play always continues until all 27 cells are filled (N=28 triggers a reset at line 205), at which point the game restarts without displaying final scores prominently.

Board Drawing

The subroutine at lines 1000–1090 draws an isometric-perspective three-layer board using block graphic characters. The three grids (A front, B middle, C rear) are overlaid with connecting lines rendered via block graphic escape sequences, giving visual depth. Cell labels 1–9 appear on each layer and layer letters A, B, C are shown on the right edge. The drawing is purely static — moves are plotted individually by printing “X” or “O” at precomputed AT Y(Z),X(Z) positions from the coordinate arrays.

Screen and Color Setup

Line 900 sets PAPER 6 (yellow), INK 1 (blue), and BORDER 6 at the start of each redraw. The FLASH attribute is used for feedback: FLASH 1 is applied to the illegal-move warning at line 390, and FLASH 0 is reset before each INPUT at line 200.

Variable Summary

VariablePurpose
A(27)Board state: 0=empty, 1=X, -1=O
X(27), Y(27)Screen column/row for each cell
C(18), R(18)Center cell and step for non-center win lines
SCurrent player: 1=X, -1=O
NMove counter (1–27)
SX, SOAccumulated win-line counts for X and O
Z$Player input string (e.g., “A5”)
WSum of three cells for win-line check

Content

Appears On

Related Products

Related Articles

Related Content

Image Gallery

Source Code

    1 REM 3-D TIC TAC TOE:GO SUB 900
    2 PRINT AT 3,0;"  INITIALIZING-PLEASE STANDBY":POKE 23658,8
    3 PRINT ,,"THE OBJECT IS TO GET AS MANY 3- IN-A-ROW LINES AS POSIBLE.",,,"REMEMBER: A IS THE FRONT- B IS  THE MIDDLE AND C IS THE REAR."
    4 PRINT ,,"THE FIRST PLAY MAY NOT BE THE   CENTER SQUARE, ENTER LETTER 1ST.(A,B OR C) THEN A NUMBER (1-9)." :PAUSE 400
    5 DIM A(27)
   10 DIM C(18)
   15 DIM R(18)
   20 DIM X(27)
   25 DIM Y(27)
   30 LET X$="020814020814020814061218061218061218101622101622101622"
   35 LET Y$="060606121212181818040404101010161616020202080808141414"
   40 FOR Z=1 TO 27
   45 LET X(Z)= VAL X$(2*Z-1 TO 2*Z)
   50 LET Y(Z)= VAL Y$(2*Z-1 TO 2*Z)
   55 NEXT Z
   60 LET C$="020405050505060810111111111213131313"
   65 LET R$="010301020304030109010809100903060912"
   70 FOR Z=1 TO 18
   75 LET C(Z)= VAL C$(2*Z-1 TO 2*Z)
   80 LET R(Z)= VAL R$(2*Z-1 TO 2*Z)
   90 NEXT Z
  100 FOR Z=1 TO 27
  105 LET A(Z)=0
  110 NEXT Z
  115 LET S=1
  120 LET N=1
  170 CLS 
  172 GO SUB 900
  175 GO SUB 1000
  180 IF S=1 THEN PRINT AT 2,24;" X TO GO"
  185 IF S=-1 THEN PRINT AT 2,24;" O TO GO"
  200 FLASH 0:INPUT Z$
  205 IF N=28 THEN GO TO 100
  210 IF Z$(1)="R" THEN GO TO 100
  215 IF Z$(1)="A" THEN LET Z=0
  220 IF Z$(1)="B" THEN LET Z=9
  225 IF Z$(1)="C" THEN LET Z=18
  235 LET Z=Z+ VAL Z$(2)
  240 IF A(Z) <>0 THEN GO TO 390
  245 IF N=1 AND Z=14 THEN GO TO 390
  250 LET A(Z)=S
  255 LET N=N+1
  260 IF S=1 THEN PRINT AT Y(Z),X(Z);"X"
  265 IF S=-1 THEN PRINT AT Y(Z),X(Z);"O"
  270 GO SUB 500
  275 LET S=-S
  280 GO TO 180
  390 FLASH 1:PRINT AT 20,14;"ILLEGAL-TRY AGAIN"
  395 GO TO 200
  500  
  505 LET SX=0
  510 LET SO=0
  515 FOR Z=1 TO 13
  520 LET W=A(14-Z)+A(14)+A(14+Z)
  525 IF ABS W=3 THEN GO SUB 800
  530 NEXT Z
  535 FOR Z=1 TO 18
  540 LET W=A(C(Z))+A(C(Z))+A(C(Z)+R(Z))
  545 IF ABS W=3 THEN GO SUB 800
  550 LET V=28-C(Z)
  555 LET W=A(V-R(Z))+A(V)+A(V+R(Z))
  560 IF ABS W=3 THEN GO SUB 800
  565 NEXT Z
  570 PRINT AT 20,0;"X=";SX;," O=";SO
  580 RETURN 
  800 IF W=3 THEN LET SX=SX+1
  803 IF W=-3 THEN LET SO=SO+1
  810 RETURN 
  900 PAPER 6:INK 1 :BORDER 6
  905 RETURN 
 1000 PRINT AT 0,6;"3-D TIC TAC TOE"
 1004 PRINT AT 2,10;"1\''\''\''\''\''2\''\''\''\''\''3"
 1006 PRINT AT 3,7;"\..\::\''         \..\::\''\ :" 
 1008 PRINT AT 4,6;"1  /  2     3   \ :"
 1010 PRINT AT 5,3;"\..\::\''   /      \..\::\''   \ :" 
 1012 PRINT AT 6,2;"1\''\''\''\''\''2\''\''\''\''\''3       \ :"
 1014 PRINT AT 7,2;"\:       /    \ :       \ :" 
 1016 PRINT AT 8,2;"\:        4   \ : 5     6        C"
 1018 PRINT AT 9,2;"\:       /    \ :       \ :" 
 1020 PRINT AT 10,2;"\:    4  /  5 \ :   6   \ :    B"     
 1022 PRINT AT 11,2;"\:       /    \ :       \ :"
 1024 PRINT AT 12,2;"4     5/    6       \ :A"
 1026 PRINT AT 13,2;"\:       /    \ :       \ :"
 1028 PRINT AT 14,2;"\:        7///\ :/8/////9"
 1030 PRINT AT 15,2;"\:     ///    \ :    \..\::\''" 
 1032 PRINT AT 16,2;"\:    7     8 \ :   9"
 1034 PRINT AT 17,2;"\: ///        \ :\..\::\''"
 1036 PRINT AT 18,2;"7\..\..\..\..\..8\..\..\..\..\..9"
 1090 RETURN 
 9997 STOP 
 9998 SAVE "3D TIC-TAC" LINE 1
 9999 CLS :PRINT AT 10,8;"REWIND TO VERIFY":PAUSE 200:VERIFY "3D TIC-TAC"

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

People

No people associated with this content.

Scroll to Top