Deterministic Solver Core – Phase 2

This note extends the deterministic solver with: • HiddenSinglesBoxPass • WriteCellValue routine • Central SolveDeterministic entry • Progress flag and contradiction propagation

HiddenSinglesBoxPass

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

WriteCellValue

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

SolveDeterministic Entry

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