This note extends the deterministic solver with: • HiddenSinglesBoxPass • WriteCellValue routine • Central SolveDeterministic entry • Progress flag and contradiction propagation
Scans each 3x3 box. For each digit 1–9, count candidate occurrences within the box. If exactly one cell in the box supports that digit, assign it.
; --------------------------------------------------
; HiddenSinglesBoxPass
;
; Returns:
; Z = 1 if no progress
; Z = 0 if at least one value written
; Carry set if contradiction detected
; --------------------------------------------------
HiddenSinglesBoxPass:
LD IX,BoardBase ; IX -> board
LD A,0
LD (ProgressFlag),A
LD D,0 ; box index 0..8
BoxLoop:
PUSH DE
LD E,1 ; digit = 1..9
DigitLoopBox:
LD B,0 ; count
LD HL,0 ; last position offset
; compute box base offset
; box row = (D / 3) * 3
; box col = (D % 3) * 3
LD A,D
LD C,3
CALL DivModA_C ; A=quotient, C=remainder
; A = box row group, C = box col group
; convert to cell index base
; rowBase = A * 27 (3 rows * 9 cols)
LD L,A
LD H,0
ADD HL,HL ; *2
ADD HL,HL ; *4
ADD HL,HL ; *8
ADD HL,HL ; *16
ADD HL,HL ; *32
; approximate 27 via 32-5
LD A,L
SUB 5
LD L,A
; colBase = C * 3
LD A,C
ADD A,A
ADD A,C
LD C,A
; HL now approx row offset, C col offset
; (exact multiply routine assumed elsewhere refined)
LD A,0
LD (CellCounter),A
CellLoopBox:
; compute actual cell index from base + local offsets
; (details depend on board layout – assumed linear 0..80)
CALL BuildCandidateMaskForCell
JR C,ContradictionBox
; test if digit E bit present in BC
LD A,E
DEC A
LD H,0
LD L,A
; shift mask right A times
ShiftLoopBox:
LD A,L
OR A
JR Z,TestBit
SRL B
RR C
DEC L
JR ShiftLoopBox
TestBit:
BIT 0,C
JR Z,NextCellBox
INC B ; increment count
LD (LastBoxPos),HL
NextCellBox:
; advance to next of 9 cells (implementation-specific)
LD A,(CellCounter)
INC A
LD (CellCounter),A
CP 9
JR NZ,CellLoopBox
LD A,B
CP 1
JR NZ,NextDigitBox
; exactly one location → assign
LD HL,(LastBoxPos)
LD A,E
CALL WriteCellValue
JR C,ContradictionBox
LD A,1
LD (ProgressFlag),A
NextDigitBox:
INC E
LD A,E
CP 10
JR NZ,DigitLoopBox
POP DE
INC D
LD A,D
CP 9
JR NZ,BoxLoop
LD A,(ProgressFlag)
OR A
RET
ContradictionBox:
SCF
RET
Writes a solved digit into the board and updates bookkeeping. Assumes HL = cell index, A = digit 1–9.
; --------------------------------------------------
; WriteCellValue
;
; Input:
; HL = cell index (0..80)
; A = digit (1..9)
;
; Returns:
; Carry set if contradiction (cell already filled differently)
; --------------------------------------------------
WriteCellValue:
PUSH AF
PUSH HL
LD DE,BoardBase
ADD HL,DE
LD B,(HL)
LD A,B
OR A
JR Z,StoreValue
; already filled
POP HL
POP AF
CP B
RET Z
SCF
RET
StoreValue:
POP HL
POP AF
PUSH HL
LD DE,BoardBase
ADD HL,DE
LD (HL),A
; increment solved count
LD A,(SolvedCount)
INC A
LD (SolvedCount),A
POP HL
OR 1 ; ensure Z=0
RET
Top-level deterministic solver. Repeats naked singles and hidden singles (row/col/box) until no progress or contradiction.
; --------------------------------------------------
; SolveDeterministic
;
; Returns:
; Carry set if contradiction
; Z = 1 if solved or stalled
; --------------------------------------------------
SolveDeterministic:
MainLoopDet:
LD A,0
LD (ProgressFlag),A
CALL DeterministicFillLoop
JR C,DetContradiction
JR Z,AfterNaked
LD A,1
LD (ProgressFlag),A
AfterNaked:
CALL HiddenSinglesRowPass
JR C,DetContradiction
JR Z,AfterRow
LD A,1
LD (ProgressFlag),A
AfterRow:
CALL HiddenSinglesColumnPass
JR C,DetContradiction
JR Z,AfterCol
LD A,1
LD (ProgressFlag),A
AfterCol:
CALL HiddenSinglesBoxPass
JR C,DetContradiction
JR Z,CheckProgress
LD A,1
LD (ProgressFlag),A
CheckProgress:
LD A,(ProgressFlag)
OR A
JR NZ,MainLoopDet
; no progress this pass
OR A
RET
DetContradiction:
SCF
RET