The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: jenxin on October 13, 2011, 10:25:25 PM

Title: Sudoku *Checker*
Post by: jenxin on October 13, 2011, 10:25:25 PM
Hey all.

I'm currently learning assembly language.

My assignment is to make a program that can check a sudoku.

The first code is the assignment, the 2nd is my attempt.

INCLUDE Irvine32.inc
.code


;-------------- BEGIN STUDENT CODE ------------------------------------------------
; (You may replace this block of code with "INCLUDE Test_Sudoku.asm", and then
; edit only that file when developing code.) Only submit code for this procedure:

INCLUDE Test_Sudoku.asm

;-------------- END STUDENT CODE --------------------------------------------------


Main PROC
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester -- Program #2
    ; October 6, 2011


    ; This code draws a Sudoku matrix, allows the user to enter or erase numbers,
    ; and thus helps students debug their procedure "Test_Sudoku" (which is called
    ; by this procedure after each number is entered; an illegal entry causes that
    ; value to flash on the screen a few times and then disappear).
    ;
    ; The Sudoku matrix is stored as a contiguous string of 81 bytes. These bytes
    ; will only contain unsigned codes for values 0-9 (0 is an uninitialized cell).
    ; The bytes are in row-wise (left-to-right, top-to-down) scan format.
    ;
    ; The single parameter passed to procedure "Test_Sudoku" is the starting address
    ; of these 81 bytes in memory, which is passed in register edx.
    ;
    ; Procedure "Test_Sudoku" passes back eax=1 if the matrix is found to be valid
    ; according to Sudoku rules of legality, and eax=0 if not valid.
    ;


    .data
        Sudoku_Matrix BYTE 81 dup(0)
        Cursor_Row   BYTE  ?
        Cursor_Col   BYTE  ?
        Temp_Dword   DWORD ?
    .code


    call Draw_Sudoku_Matrix


    ; Position cursor in upper left cell of the Sudoku grid
    mov Cursor_Row,0
    mov Cursor_Col,0


Get_User_Input:

    ; Redraw the Sudoku matrix values on the display
    call Update_Sudoku_Matrix

    call Update_Cursor

    call ReadChar

    .IF (al=='l')||(al=='L')
        jmp Square_Left
    .ELSEIF (al=='r')||(al=='R')
        jmp Square_Right
    .ELSEIF (al=='u')||(al=='U')
        jmp Square_Up
    .ELSEIF (al=='d')||(al=='D')
        jmp Square_Down
    .ELSEIF (al=='0')||(al==' ')
        ; blank square
        mov al,' '
        call WriteChar
        mov al,0
        call Write_Sudoku_Matrix
        jmp Square_Right
    .ELSEIF (al>='1')&&(al<='9')
        ; a number was entered
        sub al,'0'                 ; convert '1'-'9' to 1-9
        mov ah,al                  ; store the value in ah temporarily
        call Read_Sudoku_Matrix    ; AL returns the previous value at (Row,Col)
        ror ax,8                   ; swap AL and AH contents
        call Write_Sudoku_Matrix   ; AH stores previous value, user input sent to mem.

        pushad                     ; save all doubleword registers on stack
        mov edx,OFFSET Sudoku_Matrix
        call Test_Sudoku           ; EDX sends address of Sudoku_Matrix,
                                   ; EAX returns value of 1 (valid) or 0 (invalid)
        mov Temp_Dword,eax
        popad                      ; restore all doubleword registers
        mov eax,Temp_Dword         ; I had to do this for ease of testing many students' code...

        .IF (eax==1)
            ; legal input
            jmp Square_Right
        .ELSEIF (eax==0)
            ; illegal input
            call Flash_Value           ; flash the illegal input value a few times, then ignore
            mov al,ah
            call Write_Sudoku_Matrix   ; previous value is restored
        .ELSE
            ; eax has returned neither 1 nor 0, so terminate the program
            jmp Quit
        .ENDIF
    .ENDIF

    jmp Get_User_Input


Square_Left:

    .IF (Cursor_Col==0)
        mov Cursor_Col,8
        jmp Square_Up
    .ELSE
        dec Cursor_Col
    .ENDIF
    call Get_User_Input


Square_Right:

    .IF (Cursor_Col==8)
        mov Cursor_Col,0
        jmp Square_Down
    .ELSE
        inc Cursor_Col
    .ENDIF
    call Get_User_Input


Square_Up:

    .IF (Cursor_Row==0)
        mov Cursor_Row,8
    .ELSE
        dec Cursor_Row
    .ENDIF
    call Get_User_Input


Square_Down:

    .IF (Cursor_Row==8)
        mov Cursor_Row,0
    .ELSE
        inc Cursor_Row
    .ENDIF
    jmp Get_User_Input


Quit:
    ;illegal value returned in eax from "Test_Sudoku" -- stop execution
    exit
Main ENDP


Draw_Sudoku_Matrix PROC
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; This procedure draws the grid lines for a Sudoku matrix in the
    ; command window.

    .data
        String1 BYTE 20 dup(' '),0C9h
                BYTE  2 dup(2 dup(3 dup(0CDh),0D1h),3 dup(0CDh),0CBh)
                BYTE        2 dup(3 dup(0CDh),0D1h),3 dup(0CDh),0BBh,0
        String2 BYTE 20 dup(' '),0BAh
                BYTE  2 dup(2 dup(3 dup(020h),0B3h),3 dup(020h),0BAh)
                BYTE        2 dup(3 dup(020h),0B3h),3 dup(020h),0BAh,0
        String3 BYTE 20 dup(' '),0C7h
                BYTE  2 dup(2 dup(3 dup(0C4h),0C5h),3 dup(0C4h),0D7h)
                BYTE        2 dup(3 dup(0C4h),0C5h),3 dup(0C4h),0B6h,0
        String4 BYTE 20 dup(' '),0CCh
                BYTE  2 dup(2 dup(3 dup(0CDh),0D8h),3 dup(0CDh),0CEh)
                BYTE        2 dup(3 dup(0CDh),0D8h),3 dup(0CDh),0B9h,0
        String5 BYTE 20 dup(' '),0C8h
                BYTE  2 dup(2 dup(3 dup(0CDh),0CFh),3 dup(0CDh),0CAh)
                BYTE        2 dup(3 dup(0CDh),0CFh),3 dup(0CDh),0BCh,0
        String6 BYTE "   Cursor control:",0
        String7 BYTE "   U = move up",0
        String8 BYTE "   D = move down",0
        String9 BYTE "   L = move left",0
        StringA BYTE "   R = move right",0
        StringB BYTE "   Enter 1-9,",0
        StringC BYTE "   or 0/space",0
        StringD BYTE "   for blank",0

    .code

    call ClrScr
    call Crlf
    call Crlf
    call Crlf
    mov edx,OFFSET String1
    call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
    call Crlf
    mov edx,OFFSET String3
    call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
    call Crlf
    mov edx,OFFSET String3
    call WriteString
        mov edx,OFFSET StringB
        call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
        mov edx,OFFSET StringC
        call WriteString
    call Crlf
    mov edx,OFFSET String4
    call WriteString
        mov edx,OFFSET StringD
        call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
    call Crlf
    mov edx,OFFSET String3
    call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
        mov edx,OFFSET String6
        call WriteString
    call Crlf
    mov edx,OFFSET String3
    call WriteString
        mov edx,OFFSET String7
        call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
        mov edx,OFFSET String8
        call WriteString
    call Crlf
    mov edx,OFFSET String4
    call WriteString
        mov edx,OFFSET String9
        call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
        mov edx,OFFSET StringA
        call WriteString
    call Crlf
    mov edx,OFFSET String3
    call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
    call Crlf
    mov edx,OFFSET String3
    call WriteString
    call Crlf
    mov edx,OFFSET String2
    call WriteString
    call Crlf
    mov edx,OFFSET String5
    call WriteString
    call Crlf
    ret
Draw_Sudoku_Matrix ENDP


Update_Sudoku_Matrix PROC
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; This procedure updates all of the numbers in the Sudoku matrix that is
    ; displayed in the command window, based on those stored in memory in array
    ; 'Sudoku_Matrix'.

    .data
        Cursor_Row_copy  BYTE  ?
        Cursor_Col_copy  BYTE  ?
    .code

    mov al,Cursor_Row                 ; save copy of the current cursor position
    mov Cursor_Row_copy,al
    mov al,Cursor_Col
    mov Cursor_Col_copy,al

    mov Cursor_Row,0
A1:     mov Cursor_Col,0
A2:         call Read_Sudoku_Matrix   ; AL returns value at (Cursor_Row,Cursor_Col)
            .IF (al==0)
                mov al,' '            ; display space character instead of zero
            .ELSE
                add al,'0'            ; convert 1-9 to '1'-'9'
            .ENDIF
            call Update_Cursor        ; display value inside the grid lines
            call WriteChar
            call Update_Cursor1       ; display value as it appears in linear memory
               .IF (al==' ')
                mov al,'0'            ; display zero instead of space character
            .ENDIF
            call WriteChar
       inc Cursor_Col
       cmp Cursor_Col,9
       jne A2
    inc Cursor_Row
    cmp Cursor_Row,9
    jne A1

    mov al,Cursor_Row_copy            ; restore cursor position
    mov Cursor_Row,al
    mov al,Cursor_Col_copy
    mov Cursor_Col,al
    ret
Update_Sudoku_Matrix ENDP


Read_Sudoku_Matrix PROC USES ecx edx
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; This procedure reads and returns (in al) the Sudoku matrix value
    ; that is stored at location (Cursor_Row,Cursor_Col).  Cursor_Row
    ; and Cursor_Col are existing memory bytes in the range [0,8].
    ; The base address is "Sudoku_Matrix".
    ;
    mov edx,OFFSET Sudoku_Matrix
    mov ecx,0
    mov cl,Cursor_Row
    shl cl,3    ; CL <-- 8*Cursor_Row
    add cl,Cursor_Row  ; CL <-- CL + Cursor_Row = 9*Cursor_Row
    add cl,Cursor_Col  ; CL <-- 9*Cursor_Row + Cursor_Col = matrix offset
                       ;         to desired cell
    mov al,[edx+ecx]
    ret
Read_Sudoku_Matrix ENDP


Write_Sudoku_Matrix PROC USES ecx edx
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; This procedure writes the value that is passed in al to the Sudoku
    ; matrix at location (Cursor_Row,Cursor_Col).  Cursor_Row and Cursor_Col
    ; are existing memory bytes in the range [0,8]. The base address is
    ; "Sudoku_Matrix".
    ;
    mov edx,OFFSET Sudoku_Matrix
    mov ecx,0
    mov cl,Cursor_Row
    shl cl,3    ; CL <-- 8*Cursor_Row
    add cl,Cursor_Row  ; CL <-- CL + Cursor_Row = 9*Cursor_Row
    add cl,Cursor_Col  ; CL <-- 9*Cursor_Row + Cursor_Col = matrix offset
                       ;         to desired cell
    add edx,ecx ; pointer <-- pointer + offset
    mov [edx],al
    ret
Write_Sudoku_Matrix ENDP


Update_Cursor PROC USES edx
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; input parameters: Cursor_Row,Cursor_Col (in memory)
    ; Cursor is moved to Sudoku Matrix location (Cursor_Row,Cursor_Col)
    ;
    mov dh,Cursor_Row
    shl dh,1
    add dh,4         ; dh <-- Yoffset + 2*Cursor_Row  (Yoffset=4)
    mov dl,Cursor_Col
    shl dl,2
    add dl,22        ; dl <-- Xoffset + 4*Cursor_Col  (Xoffset=22)
    call GotoXY
    ret
Update_Cursor ENDP


Update_Cursor1 PROC USES edx
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; input parameters: Cursor_Row,Cursor_Col (in memory)
    ;
    ; Cursor is moved to a spot at left of the matrix grid to a position
    ; corresponding to coordinates (Cursor_Row,Cursor_Col)
    ;
    mov dh,Cursor_Row
    add dh,8             ; dh <-- Yoffset + Cursor_Row  (Yoffset=8)
    mov dl,Cursor_Col
    add dl,5             ; dl <-- Xoffset + Cursor_Col  (Xoffset=5)
    call GotoXY
    ret
Update_Cursor1 ENDP


Flash_Value PROC USES eax ecx
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; This procedure flashes on and off (4 times) the value that is stored at
    ; Sudoku Matrix location (Cursor_Row,Cursor_Col)
    ;
    mov ecx,4
A0:     mov al,' '
        call WriteChar
        call Update_Cursor
        call Wait1
        call Read_Sudoku_Matrix
        add al,'0'
        call WriteChar
        call Update_Cursor
        call Wait1
    loop A0
    ret
Flash_Value ENDP


Wait1 PROC USES eax
    ; Vladimir Goncharoff
    ; ECE 267: Computer Organization I
    ; University of Illinois at Chicago
    ; Fall 2011 Semester
    ; October 6, 2011
    ;
    ; This procedure waits for 1/10 sec
    ;
    mov eax,100
    call Delay
    ret
Wait1 ENDP


END main



Attempt at solution:

Test_Sudoku PROC

mov ecx, 81
mov eax, 0
.code

A0:
mov ebx, [edx]
cmp ebx, 0
jne CheckRow
loop A0
ret

CheckRow:

mov bl,[edx]
.if bl==[edx+0]

.if bl==[edx+1] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1] || bl==[edx+9*2] || bl==[edx+9*3] || bl==[edx+9*4] || bl==[edx+9*5] || bl==[edx+9*6] || bl==[edx+9*7] || bl==[edx+9*8]
jmp Fail
.endif

.if bl==[edx+10] || bl==[edx+11] || bl==[edx+19] || bl==[edx+20]
jmp Fail
.endif
.endif

mov bl,[edx+1]

.if bl==[edx+1]

.if bl==[edx+11]
jmp Fail
.endif

.endif

jmp Pass

Pass:
mov eax,1
ret
Fail:

mov eax,0
ret

Test_Sudoku ENDP


My question is how to check other squares beside the 1st square. It goes bad when I try to implement another square check.

It's due at 12AM tonight, I'd prefer advice in order to understand the language more.

Thanks.

Also, EDX is the pointer which points to memory for value at the squares(so i think).
Title: Re: Sudoku *Checker*
Post by: jenxin on October 13, 2011, 11:01:25 PM
I got it working for the 1st 3 numbers..

The problem is that the 1st box must have a value now. :[

CheckRow:

mov bl,[edx]

.if bl==[edx+1] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1] || bl==[edx+9*2] || bl==[edx+9*3] || bl==[edx+9*4] || bl==[edx+9*5] || bl==[edx+9*6] || bl==[edx+9*7] || bl==[edx+9*8]
jmp Fail
.endif

.if bl==[edx+10] || bl==[edx+11] || bl==[edx+19] || bl==[edx+20]
jmp Fail
.endif

inc bl

.if bl==[edx+0] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif


.if bl==[edx+9*1+1] || bl==[edx+9*2+1] || bl==[edx+9*3+1] || bl==[edx+9*4+1] || bl==[edx+9*5+1] || bl==[edx+9*6+1] || bl==[edx+9*7+1] || bl==[edx+9*8+1]
jmp Fail
.endif

.if bl==[edx+9] || bl==[edx+10]|| bl==[edx+11] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

inc bl

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif


.if bl==[edx+9*1+2] || bl==[edx+9*2+2] || bl==[edx+9*3+2] || bl==[edx+9*4+2] || bl==[edx+9*5+2] || bl==[edx+9*6+2] || bl==[edx+9*7+2] || bl==[edx+9*8+2]
jmp Fail
.endif

.if bl==[edx+9] || bl==[edx+10]|| bl==[edx+11] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 12:04:00 AM
I don't understand why you are using "inc bl" as this isn't loading another value from the next matrix point which you want to be  checking.

Basically you're got to do 81 iterations, and checking the 8 other values in the same row, and 8 other values in the same column.

So wouldn't that first "inc bl" need to be "mov bl,[edx+1]" ?
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 12:29:30 AM
yeah, I recently figured it out.

Currently bruteforcing the solution..

Here's a updated version and so on..
Is there any other way? (easier?) I'm new to assembly. :{

The reason my code wasn't working was because it was checking with a 0 value in bl. :\

Check0:

mov bl,[edx]
.if bl>=1

.if bl>=1 && bl==[edx+1] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl>=1 && bl==[edx+9*1] || bl==[edx+9*2] || bl==[edx+9*3] || bl==[edx+9*4] || bl==[edx+9*5] || bl==[edx+9*6] || bl==[edx+9*7] || bl==[edx+9*8]
jmp Fail
.endif

.if bl>=1 && bl==[edx+10] || bl==[edx+11] || bl==[edx+19] || bl==[edx+20]
jmp Fail
.endif

jmp Check1

.endif

Check1:
mov bl,[edx]+1
.if bl>=1

.if bl==[edx+0] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+1] || bl==[edx+9*2+1] || bl==[edx+9*3+1] || bl==[edx+9*4+1] || bl==[edx+9*5+1] || bl==[edx+9*6+1] || bl==[edx+9*7+1] || bl==[edx+9*8+1]
jmp Fail
.endif

.if bl==[edx+9] || bl==[edx+10]|| bl==[edx+11] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check2

.endif

Check2:
mov bl,[edx]+2
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+2] || bl==[edx+9*2+2] || bl==[edx+9*3+2] || bl==[edx+9*4+2] || bl==[edx+9*5+2] || bl==[edx+9*6+2] || bl==[edx+9*7+2] || bl==[edx+9*8+2]
jmp Fail
.endif

.if bl==[edx+9] || bl==[edx+10]|| bl==[edx+11] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check3

.endif
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 12:34:26 AM
Well if I were going to check every combination in this fashion, I'd probably use a C language app to generate the code stream so I didn't miss a combination. Basically printf() out a bunch of assembler lines for each row/column check.

The way you probably want to attack it is to multiple row/column loops.

If you're familiar with C or Java, try implementing the algorithm in that first, then try and build the equivalent in assembler.
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 12:39:44 AM
Dang.. I shouldhv thought of that. only 4 hours till its due. I'm somewhat familiar with java. But I'm unsure how I would write it.
Would I have a int variable, and ask the input.keyboard for it?

Is there no other way to check ?
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 01:11:56 AM
You could use a bit vector, and confirm that each digit appeared only once as you traverse each row, column, and 3x3 grid.
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 01:46:57 AM
I just realized. My code needs at least 1 square on the top row to be filled, Why is this? assignment due in 2 hours fml.
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 01:57:50 AM
here's what I currently have done..

Test_Sudoku PROC

mov ecx, 81
mov eax, 1

A0:
mov ebx, [edx]
cmp ebx, 0
jne Check0
loop A0
ret

Check0:

mov bl,[edx]
.if bl>=1

.if bl>=1 && bl==[edx+1] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl>=1 && bl==[edx+9*1] || bl==[edx+9*2] || bl==[edx+9*3] || bl==[edx+9*4] || bl==[edx+9*5] || bl==[edx+9*6] || bl==[edx+9*7] || bl==[edx+9*8]
jmp Fail
.endif

.if bl>=1 && bl==[edx+10] || bl==[edx+11] || bl==[edx+19] || bl==[edx+20]
jmp Fail
.endif

jmp Check1

.endif

Check1:
mov bl,[edx]+1
.if bl>=1

.if bl==[edx+0] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+1] || bl==[edx+9*2+1] || bl==[edx+9*3+1] || bl==[edx+9*4+1] || bl==[edx+9*5+1] || bl==[edx+9*6+1] || bl==[edx+9*7+1] || bl==[edx+9*8+1]
jmp Fail
.endif

.if bl==[edx+9] || bl==[edx+10]|| bl==[edx+11] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check2

.endif

Check2:
mov bl,[edx]+2
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+2] || bl==[edx+9*2+2] || bl==[edx+9*3+2] || bl==[edx+9*4+2] || bl==[edx+9*5+2] || bl==[edx+9*6+2] || bl==[edx+9*7+2] || bl==[edx+9*8+2]
jmp Fail
.endif

.if bl==[edx+9] || bl==[edx+10]|| bl==[edx+11] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check3

.endif

Check3:
mov bl,[edx]+3
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+2] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+3] || bl==[edx+9*2+3] || bl==[edx+9*3+3] || bl==[edx+9*4+3] || bl==[edx+9*5+3] || bl==[edx+9*6+3] || bl==[edx+9*7+3] || bl==[edx+9*8+3]
jmp Fail
.endif

.if bl==[edx+12] || bl==[edx+13]|| bl==[edx+14] || bl==[edx+21] || bl==[edx+22]|| bl==[edx+23]
jmp Fail
.endif

jmp Check4

.endif

Check4:
mov bl,[edx]+4
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+2] || bl==[edx+3] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+4] || bl==[edx+9*2+4] || bl==[edx+9*3+4] || bl==[edx+9*4+4] || bl==[edx+9*5+4] || bl==[edx+9*6+4] || bl==[edx+9*7+4] || bl==[edx+9*8+4]
jmp Fail
.endif

.if bl==[edx+12] || bl==[edx+13]|| bl==[edx+14] || bl==[edx+21] || bl==[edx+22]|| bl==[edx+23]
jmp Fail
.endif

jmp Check5

.endif

Check5:
mov bl,[edx]+5
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+3] || bl==[edx+4] || bl==[edx+2] || bl==[edx+6] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+5] || bl==[edx+9*2+5] || bl==[edx+9*3+5] || bl==[edx+9*4+5] || bl==[edx+9*5+5] || bl==[edx+9*6+5] || bl==[edx+9*7+5] || bl==[edx+9*8+5]
jmp Fail
.endif

.if bl==[edx+12] || bl==[edx+13]|| bl==[edx+14] || bl==[edx+21] || bl==[edx+22]|| bl==[edx+23]
jmp Fail
.endif


jmp Check6

.endif

Check6:
mov bl,[edx]+6
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+2] || bl==[edx+7] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+6] || bl==[edx+9*2+6] || bl==[edx+9*3+6] || bl==[edx+9*4+6] || bl==[edx+9*5+6] || bl==[edx+9*6+6] || bl==[edx+9*7+6] || bl==[edx+9*8+6]
jmp Fail
.endif

.if bl==[edx+24] || bl==[edx+25]|| bl==[edx+26] || bl==[edx+15] || bl==[edx+16]|| bl==[edx+17]
jmp Fail
.endif


jmp Check7

.endif

Check7:
mov bl,[edx]+7
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+2] || bl==[edx+6] || bl==[edx+8]
jmp Fail
.endif

.if bl==[edx+9*1+7] || bl==[edx+9*2+7] || bl==[edx+9*3+7] || bl==[edx+9*4+7] || bl==[edx+9*5+7] || bl==[edx+9*6+7] || bl==[edx+9*7+7] || bl==[edx+9*8+7]
jmp Fail
.endif

.if bl==[edx+24] || bl==[edx+25]|| bl==[edx+26] || bl==[edx+15] || bl==[edx+16]|| bl==[edx+17]
jmp Fail
.endif


jmp Check8

.endif

Check8:
mov bl,[edx]+8
.if bl>=1

.if bl==[edx+0] || bl==[edx+1] || bl==[edx+2] || bl==[edx+3] || bl==[edx+4] || bl==[edx+5] || bl==[edx+6] || bl==[edx+7]
jmp Fail
.endif

.if bl==[edx+9*1+8] || bl==[edx+9*2+8] || bl==[edx+9*3+8] || bl==[edx+9*4+8] || bl==[edx+9*5+8] || bl==[edx+9*6+8] || bl==[edx+9*7+8] || bl==[edx+9*8+8]
jmp Fail
.endif

.if bl==[edx+24] || bl==[edx+25]|| bl==[edx+26] || bl==[edx+15] || bl==[edx+16]|| bl==[edx+17]
jmp Fail
.endif


jmp Check9
.endif

Check9:

mov bl,[edx]+9
.if bl>=1

.if bl==[edx+10] || bl==[edx+11] || bl==[edx+12] || bl==[edx+13] || bl==[edx+14] || bl==[edx+15] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1] || bl==[edx+9*2] || bl==[edx+9*3] || bl==[edx+9*4] || bl==[edx+9*5] || bl==[edx+9*6] || bl==[edx+9*7] || bl==[edx+9*8]
jmp Fail
.endif

.if bl==[edx+0] || bl==[edx+1]|| bl==[edx+2] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check10

.endif

Check10:
mov bl,[edx]+10
.if bl>=1


.if bl==[edx+9] || bl==[edx+11] || bl==[edx+12] || bl==[edx+13] || bl==[edx+14] || bl==[edx+15] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+1] || bl==[edx+9*2+1] || bl==[edx+9*3+1] || bl==[edx+9*4+1] || bl==[edx+9*5+1] || bl==[edx+9*6+1] || bl==[edx+9*7+1] || bl==[edx+9*8+1]
jmp Fail
.endif

.if bl==[edx+0] || bl==[edx+1]|| bl==[edx+2] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check11

.endif

Check11:
mov bl,[edx]+11
.if bl>=1


.if bl==[edx+9] || bl==[edx+10] || bl==[edx+12] || bl==[edx+13] || bl==[edx+14] || bl==[edx+15] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+2] || bl==[edx+9*2+2] || bl==[edx+9*3+2] || bl==[edx+9*4+2] || bl==[edx+9*5+2] || bl==[edx+9*6+2] || bl==[edx+9*7+2] || bl==[edx+9*8+2]
jmp Fail
.endif

.if bl==[edx+0] || bl==[edx+1]|| bl==[edx+2] || bl==[edx+18] || bl==[edx+19]|| bl==[edx+20]
jmp Fail
.endif

jmp Check12

.endif

Check12:
mov bl,[edx]+12
.if bl>=1


.if bl==[edx+9] || bl==[edx+10] || bl==[edx+11] || bl==[edx+13] || bl==[edx+14] || bl==[edx+15] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+3] || bl==[edx+9*2+3] || bl==[edx+9*3+3] || bl==[edx+9*4+3] || bl==[edx+9*5+3] || bl==[edx+9*6+3] || bl==[edx+9*7+3] || bl==[edx+9*8+3]
jmp Fail
.endif

.if bl==[edx+3] || bl==[edx+4]|| bl==[edx+5] || bl==[edx+21] || bl==[edx+22]|| bl==[edx+23]
jmp Fail
.endif

jmp Check13

.endif

Check13:
mov bl,[edx]+13
.if bl>=1

.if bl==[edx+9] || bl==[edx+10] || bl==[edx+11] || bl==[edx+12] || bl==[edx+14] || bl==[edx+15] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+4] || bl==[edx+9*2+4] || bl==[edx+9*3+4] || bl==[edx+9*4+4] || bl==[edx+9*5+4] || bl==[edx+9*6+4] || bl==[edx+9*7+4] || bl==[edx+9*8+4]
jmp Fail
.endif

.if bl==[edx+3] || bl==[edx+4]|| bl==[edx+5] || bl==[edx+21] || bl==[edx+22]|| bl==[edx+23]
jmp Fail
.endif

jmp Check14

.endif

Check14:
mov bl,[edx]+14
.if bl>=1

.if bl==[edx+9] || bl==[edx+10] || bl==[edx+11] || bl==[edx+12] || bl==[edx+13] || bl==[edx+15] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+5] || bl==[edx+9*2+5] || bl==[edx+9*3+5] || bl==[edx+9*4+5] || bl==[edx+9*5+5] || bl==[edx+9*6+5] || bl==[edx+9*7+5] || bl==[edx+9*8+5]
jmp Fail
.endif

.if bl==[edx+3] || bl==[edx+4]|| bl==[edx+5] || bl==[edx+21] || bl==[edx+22]|| bl==[edx+23]
jmp Fail
.endif


jmp Check15

.endif

Check15:
mov bl,[edx]+15
.if bl>=1

.if bl==[edx+9] || bl==[edx+10] || bl==[edx+11] || bl==[edx+12] || bl==[edx+13] || bl==[edx+14] || bl==[edx+16] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+6] || bl==[edx+9*2+6] || bl==[edx+9*3+6] || bl==[edx+9*4+6] || bl==[edx+9*5+6] || bl==[edx+9*6+6] || bl==[edx+9*7+6] || bl==[edx+9*8+6]
jmp Fail
.endif

.if bl==[edx+6] || bl==[edx+7]|| bl==[edx+8] || bl==[edx+24] || bl==[edx+25]|| bl==[edx+26]
jmp Fail
.endif


jmp Check16

.endif

Check16:
mov bl,[edx]+16
.if bl>=1

.if bl==[edx+9] || bl==[edx+10] || bl==[edx+11] || bl==[edx+12] || bl==[edx+13] || bl==[edx+14] || bl==[edx+15] || bl==[edx+17]
jmp Fail
.endif

.if bl==[edx+0*1+7] || bl==[edx+9*2+7] || bl==[edx+9*3+7] || bl==[edx+9*4+7] || bl==[edx+9*5+7] || bl==[edx+9*6+7] || bl==[edx+9*7+7] || bl==[edx+9*8+7]
jmp Fail
.endif

.if bl==[edx+6] || bl==[edx+7]|| bl==[edx+8] || bl==[edx+24] || bl==[edx+25]|| bl==[edx+26]
jmp Fail
.endif


jmp Check17

.endif

Check17:
mov bl,[edx]+17
.if bl>=1

.if bl==[edx+9] || bl==[edx+10] || bl==[edx+11] || bl==[edx+12] || bl==[edx+13] || bl==[edx+14] || bl==[edx+15] || bl==[edx+16]
.endif

.if bl==[edx+0*1+8] || bl==[edx+9*2+8] || bl==[edx+9*3+8] || bl==[edx+9*4+8] || bl==[edx+9*5+8] || bl==[edx+9*6+8] || bl==[edx+9*7+8] || bl==[edx+9*8+8]
jmp Fail
.endif

.if bl==[edx+6] || bl==[edx+7]|| bl==[edx+8] || bl==[edx+24] || bl==[edx+25]|| bl==[edx+26]
jmp Fail
.endif

jmp Check18

.endif

Check18:

mov bl,[edx]+18
.if bl>=1

.if bl==[edx+19] || bl==[edx+20] || bl==[edx+21] || bl==[edx+22] || bl==[edx+23] || bl==[edx+24] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1] || bl==[edx+0*2] || bl==[edx+9*3] || bl==[edx+9*4] || bl==[edx+9*5] || bl==[edx+9*6] || bl==[edx+9*7] || bl==[edx+9*8]
jmp Fail
.endif

.if bl==[edx+0] || bl==[edx+1]|| bl==[edx+2] || bl==[edx+9] || bl==[edx+10]|| bl==[edx+11]
jmp Fail
.endif

jmp Check19

.endif

Check19:
mov bl,[edx]+19
.if bl>=1


.if bl==[edx+18] || bl==[edx+20] || bl==[edx+21] || bl==[edx+22] || bl==[edx+23] || bl==[edx+24] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+1] || bl==[edx+0*2+1] || bl==[edx+9*3+1] || bl==[edx+9*4+1] || bl==[edx+9*5+1] || bl==[edx+9*6+1] || bl==[edx+9*7+1] || bl==[edx+9*8+1]
jmp Fail
.endif
.if bl==[edx+0] || bl==[edx+1]|| bl==[edx+2] || bl==[edx+9] || bl==[edx+10]|| bl==[edx+11]
jmp Fail
.endif

jmp Check20

.endif

Check20:
mov bl,[edx]+20
.if bl>=1


.if bl==[edx+18] || bl==[edx+19] || bl==[edx+21] || bl==[edx+22] || bl==[edx+23] || bl==[edx+24] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+2] || bl==[edx+0*2+2] || bl==[edx+9*3+2] || bl==[edx+9*4+2] || bl==[edx+9*5+2] || bl==[edx+9*6+2] || bl==[edx+9*7+2] || bl==[edx+9*8+2]
jmp Fail
.endif
.if bl==[edx+0] || bl==[edx+1]|| bl==[edx+2] || bl==[edx+9] || bl==[edx+10]|| bl==[edx+11]
jmp Fail
.endif

jmp Check21

.endif

Check21:
mov bl,[edx]+21
.if bl>=1


.if bl==[edx+18] || bl==[edx+19] || bl==[edx+20] || bl==[edx+22] || bl==[edx+23] || bl==[edx+24] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+3] || bl==[edx+0*2+3] || bl==[edx+9*3+3] || bl==[edx+9*4+3] || bl==[edx+9*5+3] || bl==[edx+9*6+3] || bl==[edx+9*7+3] || bl==[edx+9*8+3]
jmp Fail
.endif

.if bl==[edx+3] || bl==[edx+4]|| bl==[edx+5] || bl==[edx+12] || bl==[edx+13]|| bl==[edx+14]
jmp Fail
.endif

jmp Check22

.endif

Check22:
mov bl,[edx]+22
.if bl>=1

.if bl==[edx+18] || bl==[edx+19] || bl==[edx+20] || bl==[edx+21] || bl==[edx+23]  || bl==[edx+24] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+4] || bl==[edx+0*2+4] || bl==[edx+9*3+4] || bl==[edx+9*4+4] || bl==[edx+9*5+4] || bl==[edx+9*6+4] || bl==[edx+9*7+4] || bl==[edx+9*8+4]
jmp Fail
.endif

.if bl==[edx+3] || bl==[edx+4]|| bl==[edx+5] || bl==[edx+12] || bl==[edx+13]|| bl==[edx+14]
jmp Fail
.endif

jmp Check23

.endif

Check23:
mov bl,[edx]+23
.if bl>=1

.if bl==[edx+18] || bl==[edx+19] || bl==[edx+20] || bl==[edx+21] || bl==[edx+22] || bl==[edx+24] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+5] || bl==[edx+0*2+5] || bl==[edx+9*3+5] || bl==[edx+9*4+5] || bl==[edx+9*5+5] || bl==[edx+9*6+5] || bl==[edx+9*7+5] || bl==[edx+9*8+5]
jmp Fail
.endif

.if bl==[edx+3] || bl==[edx+4]|| bl==[edx+5] || bl==[edx+12] || bl==[edx+13]|| bl==[edx+14]
jmp Fail
.endif


jmp Check24

.endif

Check24:
mov bl,[edx]+24
.if bl>=1

.if bl==[edx+18] || bl==[edx+19] || bl==[edx+20] || bl==[edx+21] || bl==[edx+22] || bl==[edx+23] || bl==[edx+25] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+6] || bl==[edx+0*2+6] || bl==[edx+9*3+6] || bl==[edx+9*4+6] || bl==[edx+9*5+6] || bl==[edx+9*6+6] || bl==[edx+9*7+6] || bl==[edx+9*8+6]
jmp Fail
.endif

.if bl==[edx+6] || bl==[edx+7]|| bl==[edx+8] || bl==[edx+15] || bl==[edx+16]|| bl==[edx+17]
jmp Fail
.endif


jmp Check25

.endif

Check25:
mov bl,[edx]+25
.if bl>=1

.if bl==[edx+18] || bl==[edx+19] || bl==[edx+20] || bl==[edx+21] || bl==[edx+22] || bl==[edx+23] || bl==[edx+24] || bl==[edx+26]
jmp Fail
.endif

.if bl==[edx+9*1+7] || bl==[edx+0*2+7] || bl==[edx+9*3+7] || bl==[edx+9*4+7] || bl==[edx+9*5+7] || bl==[edx+9*6+7] || bl==[edx+9*7+7] || bl==[edx+9*8+7]
jmp Fail
.endif

.if bl==[edx+6] || bl==[edx+7]|| bl==[edx+8] || bl==[edx+15] || bl==[edx+16]|| bl==[edx+17]
jmp Fail
.endif


jmp Check26
.endif

Check26:
mov bl,[edx]+26
.if bl>=1

.if bl==[edx+18] || bl==[edx+19] || bl==[edx+20] || bl==[edx+21] || bl==[edx+22] || bl==[edx+23] || bl==[edx+24] || bl==[edx+25]
.endif

.if bl==[edx+9*1+8] || bl==[edx+0*2+8] || bl==[edx+9*3+8] || bl==[edx+9*4+8] || bl==[edx+9*5+8] || bl==[edx+9*6+8] || bl==[edx+9*7+8] || bl==[edx+9*8+8]
jmp Fail
.endif

.if bl==[edx+6] || bl==[edx+7]|| bl==[edx+8] || bl==[edx+15] || bl==[edx+16]|| bl==[edx+17]
jmp Fail
.endif


jmp Pass

.endif






























Pass:
mov eax,1
ret
Fail:

mov eax,0
ret

Test_Sudoku ENDP
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 01:59:16 AM
In Chicago midnight is still 3 hours away.

Ok, so is zero the "unfilled" indicator? Should the check ignore zeros as a failing criteria? ie a unfilled line/box will pass as long as the digits 1 thru 9 don't appear more than once in the row/column/3x3.
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 02:01:40 AM
Yes, 0 means it's unfilled. (i think) And, after repeating all these lines, my sense of math is a bit off. haha!

man I seriously thought there was 2 hours left. haha :facepalm:
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 02:05:02 AM
Also its not just any square in top row.. there must be a box filled in one of the first 4.
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 02:23:36 AM
Ok, so a five minute brute force check. It does the row/column traversal, but does not validate individual 3x3 grids

mov bl,[edx+0] ; a[0][0]
or bl,bl
jz @F ; skip empty
cmp bl,[edx+9] ; a[1][0]
jz fail
cmp bl,[edx+18] ; a[2][0]
jz fail
cmp bl,[edx+27] ; a[3][0]
jz fail
cmp bl,[edx+36] ; a[4][0]
jz fail
cmp bl,[edx+45] ; a[5][0]
jz fail
cmp bl,[edx+54] ; a[6][0]
jz fail
cmp bl,[edx+63] ; a[7][0]
jz fail
cmp bl,[edx+72] ; a[8][0]
jz fail
cmp bl,[edx+1] ; a[0][1]
jz fail
cmp bl,[edx+2] ; a[0][2]
jz fail
cmp bl,[edx+3] ; a[0][3]
jz fail
cmp bl,[edx+4] ; a[0][4]
jz fail
cmp bl,[edx+5] ; a[0][5]
jz fail
cmp bl,[edx+6] ; a[0][6]
jz fail
cmp bl,[edx+7] ; a[0][7]
jz fail
cmp bl,[edx+8] ; a[0][8]
jz fail
@@:
mov bl,[edx+1] ; a[0][1]
or bl,bl
jz @F ; skip empty
cmp bl,[edx+10] ; a[1][1]
jz fail
cmp bl,[edx+19] ; a[2][1]
jz fail
cmp bl,[edx+28] ; a[3][1]
jz fail
cmp bl,[edx+37] ; a[4][1]
jz fail
cmp bl,[edx+46] ; a[5][1]
jz fail
cmp bl,[edx+55] ; a[6][1]
jz fail
cmp bl,[edx+64] ; a[7][1]
jz fail
cmp bl,[edx+73] ; a[8][1]
jz fail
cmp bl,[edx+0] ; a[0][0]
jz fail
cmp bl,[edx+2] ; a[0][2]
jz fail
cmp bl,[edx+3] ; a[0][3]
jz fail
cmp bl,[edx+4] ; a[0][4]
jz fail
cmp bl,[edx+5] ; a[0][5]
jz fail
cmp bl,[edx+6] ; a[0][6]
jz fail
cmp bl,[edx+7] ; a[0][7]
jz fail
cmp bl,[edx+8] ; a[0][8]
jz fail
@@:
... crap the forum eats it, will attach

   
Title: Re: Sudoku *Checker*
Post by: drizz on October 14, 2011, 02:28:02 AM
>> I'd probably use a C language app to generate the code stream
We already have a language above asm - macro  :wink

lea esi,Sudoku_Matrix

; BOUNDS CHK
i = 0
repeat 9
j = 0
repeat 9
cmp byte ptr [esi+i*9+j],1
jb @@Fail
cmp byte ptr [esi+i*9+j],9
ja @@Fail
j = j + 1
endm
i = i + 1
endm

; BOX SUM
i = 0
repeat 9
xor eax,eax
j = 0
repeat 9
add al,[esi+i*9+j]
j = j + 1
endm
cmp al,1+2+3+4+5+6+7+8+9
jne @@Fail
i = i + 1
endm

; ROW SUM
i = 0
repeat 9
xor eax,eax
j = 0
repeat 3
add al,[esi+(i/3)*9*3+j*9+0]
add al,[esi+(i/3)*9*3+j*9+1]
add al,[esi+(i/3)*9*3+j*9+2]
j = j + 1
endm
cmp al,1+2+3+4+5+6+7+8+9
jne @@Fail
i = i + 1
endm

; COL SUM
i = 0
repeat 9
xor eax,eax
j = 0
repeat 3
add al,[esi+0*3+j*3*9+(i/3)*9+(i mod 3)]
add al,[esi+1*3+j*3*9+(i/3)*9+(i mod 3)]
add al,[esi+2*3+j*3*9+(i/3)*9+(i mod 3)]
j = j + 1
endm
cmp al,1+2+3+4+5+6+7+8+9
jne @@Fail
i = i + 1
endm

; BOX DUP CHK
i = 0
repeat 9
push 0
push 0
push 0
j = 0
repeat 9
movzx eax, byte ptr [esi+i*9+j]
or byte ptr [esp+eax-1],1
j = j + 1
endm
pop eax
pop edx
pop ecx
and eax,edx
cmp eax,01010101h
jne @@Fail
cmp ecx,01h
jne @@Fail
i = i + 1
endm

; ROW DUP CHK
i = 0
repeat 9
push 0
push 0
push 0
j = 0
repeat 3
movzx eax, byte ptr [esi+(i/3)*9*3+j*9+0]
movzx edx, byte ptr [esi+(i/3)*9*3+j*9+1]
movzx ecx, byte ptr [esi+(i/3)*9*3+j*9+2]
or byte ptr [esp+eax-1],1
or byte ptr [esp+edx-1],1
or byte ptr [esp+ecx-1],1
j = j + 1
endm
pop eax
pop edx
pop ecx
and eax,edx
cmp eax,01010101h
jne @@Fail
cmp ecx,01h
jne @@Fail
i = i + 1
endm

; COL DUP CHK
i = 0
repeat 9
push 0
push 0
push 0
j = 0
repeat 3
movzx eax, byte ptr [esi+0*3+j*3*9+(i/3)*9+(i mod 3)]
movzx edx, byte ptr [esi+1*3+j*3*9+(i/3)*9+(i mod 3)]
movzx ecx, byte ptr [esi+2*3+j*3*9+(i/3)*9+(i mod 3)]
or byte ptr [esp+eax-1],1
or byte ptr [esp+edx-1],1
or byte ptr [esp+ecx-1],1
j = j + 1
endm
pop eax
pop edx
pop ecx
and eax,edx
cmp eax,01010101h
jne @@Fail
cmp ecx,01h
jne @@Fail
i = i + 1
endm

mov eax,1
ret

@@Fail:
xor eax,eax
ret
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 02:30:22 AM
Thanks. Now I'm ultra confused. haha! Why didn't my code work?
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 02:33:26 AM
Also I can only use registers eax,ebx,ecx,and edx. and none of his variables.
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 02:35:36 AM
Also, I have absolutely no clue how to implement that code Clive

EDIT:

I C&P'd it in.. >_>
Title: Re: Sudoku *Checker*
Post by: dedndave on October 14, 2011, 02:37:36 AM
that code is by drizz - not Clive   :P
it looks like he already implemented it for you
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 02:39:32 AM
Quote from: drizz on October 14, 2011, 02:28:02 AM
>> I'd probably use a C language app to generate the code stream
We already have a language above asm - macro  :wink

Indeed, but it's a lot less flexible, and ill suited to some tasks.

MACRO's would work well here, but jenxin has algorithm issues.
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 02:45:30 AM
I haven't learned any C :(
I'll integrate clive's code.. I need to explain a lot of the work, Thanks anyways drizz!

And thanks alot clive, may I ask how you generated that code?
Title: Re: Sudoku *Checker*
Post by: drizz on October 14, 2011, 02:53:14 AM
Quote from: jenxin on October 14, 2011, 02:45:30 AM
I haven't learned any C :(
I'll integrate clive's code.. I need to explain a lot of the work, Thanks anyways drizz!
Your welcome, but it was for the topic, I wanted to seed how short the code would be with macros. I wouldn't use macros and other stuff otherwise.  :U
Title: Re: Sudoku *Checker*
Post by: clive on October 14, 2011, 03:00:49 AM
This was a quick 5 minute hack, coded for a high probability of success first time around.

#include <stdio.h>

int main(int argc, char **argv)
{
int i, j;
int v, w;

for(i=0; i<9; i++)
{
for(j=0; j<9; j++)
{
printf("\tmov\tbl,[edx+%d]\t; a[%d][%d]\n",i*9 + j, i, j);
printf("\tor\tbl,bl\n");
printf("\tjz\t@F\t; skip empty\n");

for(v=0; v<9; v++)
if (v != i)
{
printf("\tcmp\tbl,[edx+%d]\t; a[%d][%d]\n", v*9 + j, v, j);
printf("\tjz\tfail\n");
}

for(w=0; w<9; w++)
if (w != j)
{
printf("\tcmp\tbl,[edx+%d]\t; a[%d][%d]\n", i*9 + w, i, w);
printf("\tjz\tfail\n");
}

printf("@@:\n");
}
}

return(1);
}
Title: Re: Sudoku *Checker*
Post by: jenxin on October 14, 2011, 03:11:27 AM
Is that C? Time for me to start learning hah. I've only taken a intro to Java programming course.
Title: Re: Sudoku *Checker*
Post by: drizz on October 14, 2011, 03:25:30 AM
Pure masm  :P
lea esi,Sudoku_Matrix

; BOUNDS CHK
i = 0
repeat 9*9
cmp byte ptr [esi+i],1
jb @@Fail
cmp byte ptr [esi+i],9
ja @@Fail
i = i + 1
endm

; DUP & SUM CHK
k = 0
repeat 3
i = 0
repeat 9
xor eax,eax
push eax
push eax
push eax
j = 0
repeat 3
if k eq 0;-- BOX
movzx ebx, byte ptr [esi+i*9+j*3+0]
movzx edx, byte ptr [esi+i*9+j*3+1]
movzx ecx, byte ptr [esi+i*9+j*3+2]
elseif k eq 1;-- ROW
movzx ebx, byte ptr [esi+(i/3)*9*3+j*9+0]
movzx edx, byte ptr [esi+(i/3)*9*3+j*9+1]
movzx ecx, byte ptr [esi+(i/3)*9*3+j*9+2]
else;-- COL
movzx ebx, byte ptr [esi+0*3+j*3*9+(i/3)*9+(i mod 3)]
movzx edx, byte ptr [esi+1*3+j*3*9+(i/3)*9+(i mod 3)]
movzx ecx, byte ptr [esi+2*3+j*3*9+(i/3)*9+(i mod 3)]
endif
or byte ptr [esp+ebx-1],1
or byte ptr [esp+edx-1],1
or byte ptr [esp+ecx-1],1
add eax,ebx
add eax,edx
add eax,ecx
j = j + 1
endm
pop ebx
pop edx
pop ecx
and ebx,edx
cmp ebx,01010101h
jne @@Fail
cmp ecx,01h
jne @@Fail
cmp eax,1+2+3+4+5+6+7+8+9
jne @@Fail
i = i + 1
endm
k = k + 1
endm
Title: Re: Sudoku *Checker*
Post by: drizz on October 14, 2011, 03:33:21 AM
Or even better without the stack...
lea esi,Sudoku_Matrix

; BOUNDS CHK
i = 0
repeat 9*9
cmp byte ptr [esi+i],1
jb @@Fail
cmp byte ptr [esi+i],9
ja @@Fail
i = i + 1
endm

; DUP & SUM CHK
k = 0
repeat 3
i = 0
repeat 9
xor eax,eax
xor edi,edi
j = 0
repeat 3
if k eq 0
movzx ebx, byte ptr [esi+i*9+j*3+0]
movzx edx, byte ptr [esi+i*9+j*3+1]
movzx ecx, byte ptr [esi+i*9+j*3+2]
elseif k eq 1
movzx ebx, byte ptr [esi+(i/3)*9*3+j*9+0]
movzx edx, byte ptr [esi+(i/3)*9*3+j*9+1]
movzx ecx, byte ptr [esi+(i/3)*9*3+j*9+2]
elseif k eq 2
movzx ebx, byte ptr [esi+0*3+j*3*9+(i/3)*9+(i mod 3)]
movzx edx, byte ptr [esi+1*3+j*3*9+(i/3)*9+(i mod 3)]
movzx ecx, byte ptr [esi+2*3+j*3*9+(i/3)*9+(i mod 3)]
endif
bts edi,ebx
bts edi,edx
bts edi,ecx
add eax,ebx
add eax,edx
add eax,ecx
j = j + 1
endm
cmp edi,1111111110b
jne @@Fail
cmp eax,1+2+3+4+5+6+7+8+9
jne @@Fail
i = i + 1
endm
k = k + 1
endm



...Ok off I go  :bdg