AndorraDotNet

Comunitat d'usuaris .NET del pais dels pirineus
¿No perteneces a AndorraDotNet? ¡Regístrate y sé un miembro!
Iniciar sesión | REGÍSTRATE AQUÍ | Ayuda
en Buscar

Andorra Net User Group Blog

January 2008 - Artículos

  • Primer event del grup - Divendres 1 de Febrer de 2008

    :-)
    Hola a tots,

    Ja tenim data! El primer event del grup esdevindrà el proper 1 de Febrer a les 18h00, a la sala polivalent de FIMARGE dins el centre de negoci MONTCLAR (Bonaventura Armengol 10 Edifici2 5º Planta, Andorra la vella). La entrada és lliure (mentre no tinguem problema d’aforament).

    1Event

    Agenda:

    • Presentació del grup (objectiu, finalitat)
    • Sessions de treball
    • Conclusions i planificació del proper event
    • Sopar (qui s’animi :-D)

    Sessions:

    • Introducció a SharePoint com a plataforma col·laborativa
    • Diferencies entre WSS 3.0 i MOSS 2007
    • Instal·lació, configuració i administració
    • Publicació de continguts (Llistes vs. Biblioteques)
    • Tipus de contingut
    • Gestió de versions
    • Integració amb Microsoft Office 2003 i 2007
    • Disseny de Workflows
    • Plataforma de serveis per al desenvolupador
    • WebParts (demo)
    • Model d’objectes (demo)
    • SharePoint Designer (demo)
    • Creació de WorkFlows personalitzants (demo)

    Totes les sessions seran impartides per Lluís Franco, Microsoft MVP fundador de AndorraDotNet.

    Pot semblar que hi ha molta cosa per 2 o 3 hores, oi? Pot ser si, però jo crec que podem arribar a fer-ho tot, i si no sempre podem deixar alguna cosa per més endavant.

    Fins aviat, us esperem!

  • Sudoku en Assembler

    :-)

    Tal i com sona. Acabo de llegir-ho en el blog de Carlos Fouz a Geeks.ms, i la veritat es que trobo que és una frikada increíble. Per veure el codi formatejat es recomana el programa ConText que es freeware.

    logocontext

    Us deixo una captura i el codi font per si algú es tan friki de provar-ho:

    sudoku

    Codi:

    ;SuDoKu
    ;Carlos A. Fouz Rodríguez (base - UOC)
    
    .model small         ;modell de memòria SMALL
    .stack 1024
    
    DOSSERVICE  EQU  21H	; serveis DOS
    BIOSSERVICE EQU  10H	; serveis BIOS
    
    .data 
     Board db '   - S U D O K U -  ' ;Tauler de joc que es mostra a l'inici del programa
            db '  1 2 3 4 5 6 7 8 9 '
            db ' ÉÍÍÍÍÍËÍÍÍÍÍËÍÍÍÍÍ»'
            db '1º ³ ³ º ³ ³ º ³ ³ º'
            db ' ºÄÅÄÅĺÄÅÄÅĺÄÅÄÅĺ'
            db '2º ³ ³ º ³ ³ º ³ ³ º'
            db ' ºÄÅÄÅĺÄÅÄÅĺÄÅÄÅĺ'
            db '3º ³ ³ º ³ ³ º ³ ³ º'
            db ' ÌÍÍÍÍÍÎÍÍÍÍÍÎÍÍÍÍ͹'
            db '4º ³ ³ º ³ ³ º ³ ³ º'
            db ' ºÄÅÄÅĺÄÅÄÅĺÄÅÄÅĺ'
            db '5º ³ ³ º ³ ³ º ³ ³ º'
            db ' ºÄÅÄÅĺÄÅÄÅĺÄÅÄÅĺ'
            db '6º ³ ³ º ³ ³ º ³ ³ º'
            db ' ÌÍÍÍÍÍÎÍÍÍÍÍÎÍÍÍÍ͹'
            db '7º ³ ³ º ³ ³ º ³ ³ º'
            db ' ºÄÅÄÅĺÄÅÄÅĺÄÅÄÅĺ'
            db '8º ³ ³ º ³ ³ º ³ ³ º'
            db ' ºÄÅÄÅĺÄÅÄÅĺÄÅÄÅĺ'
            db '9º ³ ³ º ³ ³ º ³ ³ º'
            db ' ÌÍÍÍÍÍÊÍÍÍÍÍÍÍÍÍÍ͹'
            db ' º                 º'
            db ' ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ'
            
    
      ;Matriu 9x9 amb els valors inicials ; Possible solució
      Sudoku  db '123456789' ; 123456789
      	  db '456789123' ; 456789123
      	  db '789123456' ; 789123456 
      	  db '9123456  ' ; 912345678
      	  db '345678   ' ; 345678912
      	  db '67891    ' ; 678912345
      	  db '8912     ' ; 891234567
      	  db '234    9 ' ; 234567891
      	  db '567      ' ; 567891234
    
      ;Matriu 9x9 on posarem els números
      Play   db '         '
      	 db '         '
      	 db '         '
      	 db '         '
      	 db '         '
      	 db '         '
      	 db '         '
      	 db '         '
      	 db '         '
    
    
      State     db 1  ; 0: Sortir, hem pitjat la tecla 'q' per sortir o s'ha acabat el temps.
                      ; 1: Continuem jugant.
                      ; 2: Guanyador, hem omplert la matriu Play correctament.
    
      ;Variables per indicar la posició del cursor dins la matriu Sodoku i Play.
      ;No les utilitzeu per indicar la posici¢ del cursor a la pantalla.
      RowCur    db 4  ; [0-8] Val 0:Fila 1,    val 8:Fila 9    (posició inicial:4 = Fila 5)
      ColCur    db 4  ; [0-8] Val 0:Columna 1, val 8:Column 9  (posició inicial:4 = Columna 5)
    
      RowIni    db ?  ;Fila inicial pel procediment CheckPos
      ColIni    db ?  ;Columna inicial pel procediment CheckPos
      BoxIni    db ?  ;Casella on comença la regió on està la posició que estem mirant.
     
      ;Variables amb els missatges que sortiran per pantalla.
      MsgHelpVacio  db '          ','$'
      MsgExit   db 'Oh! No has pogut acabar!','$'
      MsgWinner db 'Enhorabona!  Has acabat.','$'
      Numeros db '0$1$2$3$4$5$6$7$8$9$'
    
    
    .code
    
    
    ;*******************************************************************************
    ; Esborra la pantalla completament escrivint espais en blanc
    ; Parametres d'entrada: Cap
    ; Parametres de sortida: Cap
    ;*******************************************************************************
    ClearScreen:
    
      push AX
      push BX
      push CX
      push DX
    
      ;Inicialització per posicionar el cursor
      mov bh,00h        ;pàgina
      mov dh,00h        ;fila inicial
      mov dl,00h        ;columna inicial
      mov ah,02h        ;servei per posicionar el cursor
      int BIOSSERVICE
    
      mov bh,00h        ;pàgina
      mov bl,07h        ;atribut
      mov cx,2000       ;80*25nombre de caràcters a escriure
      mov al,' '        ;caràcter
      mov ah,09h        ;servei per escriure caràcter.
      int BIOSSERVICE
    
      pop DX
      pop CX
      pop BX
      pop AX
    
    ret
    
    ;*******************************************************************************
    ; Mostra el Tauler de joc sense Dades, és a dir, mostra la matriu Board
    ; Paràmetres d'entrada: Cap
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    PrintBoard:
    
      push AX
      push BX
      push CX
      push DX
      push SI
    
      ;Inicialitzar registres
      mov bh,00h        ;pagina  
      mov dh,00         ;fila inicial a pantalla on mostraurem el Tauler.
      mov dl,24         ;columna inicial a pantalla on mostrarem el Tauler.
    
      mov bl,07h        ;atribut
      mov cx,1          ;escriurem 1 caràcters cada cop
      
      mov si,0          ;índex per accedir al tauler
      
    LoopPB:
      mov ah,02h        ;servei per posicionar el cursor
      int BIOSSERVICE
    
      mov al,BOARD[SI]  ;caràcter
      mov ah,09h        ;servei per escriure caràcter.
      int BIOSSERVICE
    
      inc si            ;incrementem l'índex per accedir a les dades
    		    ;Actualitzem posició del cursor (fila i columna)
      inc dl            ;columna 
      cmp dl, 44
      jl LoopPB
      mov dl, 24
      inc dh            ;fila
      cmp dh, 23 
      jl LoopPB
    
      ;Posar el cursor a la posició inicial (5,5)
      mov al,2          ;multipliquem per 2 per saltarnos les ratlles del tauler.
      mul RowCur
      mov dh,al
      add dh,03         ;03: fila a pantalla de la posició (1,1)
      mov al,2
      mul ColCur
      mov dl,al
      add dl,26         ;26: columna a pantalla de la posició (1,1)
    
      mov ah,02h        ;servei per posicionar el cursor
      mov bh,00h        ;pagina
      int BIOSSERVICE
    
      pop SI
      pop DX
      pop CX
      pop BX
      pop AX
    
      ret
    
    ;*******************************************************************************
    ; Verifica quins números no es poden posar en una casella de la matriu Play
    ;
    ; Paràmetres d'entrada: SI: Index dins la matriu Play (posició que volem mirar)
    ; SI: pot pendre valors de 0 a 80.
    ;
    ; Paràmetres de sortida: AX: Registre on el bit 'i' indica que en aquella 
    ; posició NO podem posar-hi el nombre 'i'. AX (bit 15 - bit 0) només utilitzarem
    ; del (bit 9 - bit 1). EX: 0000 0000 0001 0110 vol dir que a la posició indicada 
    ; per SI de la matriu Play no podem posar els nombres 1,2 i 4
    ;*******************************************************************************
    CheckPos:
    
      push BX
      push CX
      push DX
      push SI
    
      mov ch,Play[SI]   ;agafem la posició que estem verificant, la guardem a la pila
      mov Play[SI],' '  ;i la posem en blanc per no verificar-la.
    
      mov bl,9          ;Determinal la posició inicial de la fila i columna.
      mov AX,SI         ;SI és la posició dins la matriu Play.
      	    
      div bl            ;dividim SI entre 9
      mov ColIni,ah     ;AH:(reste):columna, AL(quocient): fila
      mov RowIni,al     ;RowIni: fila inicial dins de Play.
                        ;ColIni: columna inicial dins de Play.
      
      mov bl,3          ;Calculem la casella on comanença el quadrant de la posició  
      mov AX,0          ;que estem mirant.
      mov al,ColIni         
      div bl            ;AL(quocient): 
      mov ah,0          ;AH:(reste): no el volem.
      mul bl            
      mov cl,al  
    
      mov AX,0          
      mov al,RowIni     
      div bl            ;AL(quocient): 
      mov ah,0          ;AH:(reste): no ens cal.
      mov bl,27
      mul bl
      add al,cl
      mov BoxIni,al  
    
      mov AX,0
      mov al,RowIni
      mov bl,9
      mul bl            ;multipliquem AL(fila)*9
      mov SI,AX         ;SI: Índex de la matriu Play
      add AX,9
      mov BX,AX         ;BX: Índex de la matriu Play on hem de parar.
      mov AX,0          ;AX: Màscara on acumulem els numeros que anem trobant.
    
    CheckRow:
      
      cmp Play[SI],' '
      je ContRow
    
      mov DX,0000000000000001b  ;DX: Màscara on indicarem el número trobat
      mov Cl,Play[SI]
      sub cl,48
      shl DX,cl          ;posem el 1 a la posició del número que tenim a Play.
      or  AX,DX          ;actualitzarem la màscara AX.
      
    ContRow:  
      add SI,1
      cmp SI,BX
      jl  CheckRow
    
    
      mov BX,0          
      mov bl,ColIni         
      mov SI,BX         ;SI: Índex de la matriu Play
      
    CheckColumm:
    
      cmp Play[SI],' '
      je ContColumm
    
      mov DX,0000000000000001b  ;DX: Màscara on indicarem el número trobat
      mov Cl,Play[SI]
      sub cl,48
      shl DX,cl         ;posem el 1 a la posició del número que tenim a Play.
      or  AX,DX          ;actualitzarem la màscara AX.
      
    ContColumm:  
      add SI,9
      cmp SI,81
      jl  CheckColumm
    
      mov BX,0          
      mov bl,BoxIni         
      mov SI,BX         ;SI: Índex de la matriu Play on comença el quadrant.
      add BX,20         ;BX: Índex de la matriu Play on hem de parar. 
    
    CheckBox:
    
      cmp Play[SI],' '
      je ContBox1
    
      mov DX,0000000000000001b  ;DX: Màscara on indicarem el número trobat
      mov Cl,Play[SI]
      sub cl,48
      shl DX,cl          ;posem el 1 a la posició del número que tenim a Play.
      or  AX,DX          ;actualitzarem la màscara AX.
      
    ContBox1:
      add SI,1
    
      cmp Play[SI],' '
      je ContBox2
    
      mov DX,0000000000000001b  ;DX: Màscara on indicarem el número trobat
      mov Cl,Play[SI]
      sub cl,48
      shl DX,cl          ;posem el 1 a la posició del número que tenim a Play.
      or  AX,DX          ;actualitzarem la màscara AX.
      
    ContBox2:  
      add SI,1
    
      cmp Play[SI],' '
      je ContBox3
    
      mov DX,0000000000000001b  ;DX: Màscara on indicarem el número trobat
      mov Cl,Play[SI]
      sub cl,48
      shl DX,cl          ;posem el 1 a la posició del número que tenim a Play.
      or  AX,DX          ;actualitzarem la màscara AX.
      
    ContBox3:
    
      add SI,7
      cmp SI,BX
      jl  CheckBox
    
      pop SI
    
      mov Play[SI],ch  ;restaurem el valor de la matriu Play.
    
      pop DX
      pop CX
      pop BX
      ;AX té la màscara amb el números que no es poden posar a la posició SI de Play
    
      ret
    
    ;*******************************************************************************
    ; Copia els valors inicials de la matriu Sudoku a la matriu Play.
    ; Paràmetres d'entrada: Cap
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    IniPlay:
    
      mov si,0            ;Índex per anar copiant la informació.
     
      ;Iniciem el bucle per fer la cópia.
    LoopIP:
    
      mov cl,Sudoku[SI]   ;Agafem el valor de la matriu Sudoku
      mov Play[SI],cl     ;Posem el valor a la matriu Play.
    
      inc si              ;incrementem l'índex per accedir a la següent posició
      cmp si, 81          ;matriu de 9x9 posicions (0-80)
      jl LoopIP
      ret
    
    ;*******************************************************************************
    ; Mostra quins números es poden escriura a la casella del cursor.
    ; S'ha de tenir en compte que si és casella d'un dels valors inicals no s'hi pot
    ; escriure res.
    ; Paràmetres d'entrada: Cap
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    PrintHelp:
    
      ;eliminem missatge de ajuda anterior pintant la variable MsgHelpVacio
      mov dh,21             ;fila
      mov dl,26             ;columna
      push DX
      lea dx,MsgHelpVacio
      push DX
      call PrintMessage
      add sp,4
    
      ;POSICIO CURSOR AL ARRAY : Multipliquem per 9 el RowCur + el valor del ColCur
      mov ax,9
      mul RowCur
      mov dx,0
      mov dl,ColCur
      add ax, dx
      mov si, ax         ; si indica la posicio del digit al array
    
      ;controlem que aquesta posicio es una de las que pot escriure l'usuari
      cmp SUDOKU[ si ],' '
      jne noHelp
    
      Call CheckPos      ; si es el parametre d´entrada que indica la posicio en l´array
                         ; Paràmetres de sortida: AX: Registre on el bit 'i' indica que en aquella
                         ; posició NO podem posar-hi el nombre 'i'. AX (bit 15 - bit 0) només utilitzarem
                         ; del (bit 9 - bit 1). EX: 0000 0000 0001 0110 vol dir que a la posició indicada
                         ; per SI de la matriu Play no podem posar els nombres 1,2 i 4
      jmp helpCheck1
    
    noHelp:
      mov ax, 0000001111111110b ;si no pot escriure generem la nostre propia AX
    helpCheck1:
      ;AX tenim els possibles valors
      mov bl,26             ;columna on escriurem el missatge
      ;verifiquem si pot escriure el 1
      mov dx, ax
      and dx, 0000000000000010b
      cmp dx, 0000000000000010b
      je helpCheck2
      mov dh,21             ;fila
      mov dl,bl             ;columna
      push DX
      lea dx,Numeros[ 2 ]
      push DX
      call PrintMessage     ;pintem el numero 1
      add sp,4
      inc bl                ;incrementem columna per escriure més numeros
    
    helpCheck2:
      ;verifiquem si pot escriure el 2
      mov dx, ax
      and dx, 0000000000000100b
      cmp dx, 0000000000000100b
      je helpCheck3
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 4 ]
      push DX
      call PrintMessage    ;pintem el numero 2
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck3:
      ;verifiquem si pot escriure el 3
      mov dx, ax
      and dx, 0000000000001000b
      cmp dx, 0000000000001000b
      je helpCheck4
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 6 ]
      push DX
      call PrintMessage    ;pintem el numero 3
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck4:
      ;verifiquem si pot escriure el 4
      mov dx, ax
      and dx, 0000000000010000b
      cmp dx, 0000000000010000b
      je helpCheck5
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 8 ]
      push DX
      call PrintMessage    ;pintem el numero 4
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck5:
      ;verifiquem si pot escriure el 5
      mov dx, ax
      and dx, 0000000000100000b
      cmp dx, 0000000000100000b
      je helpCheck6
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 10 ]
      push DX
      call PrintMessage    ;pintem el numero 5
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck6:
      ;verifiquem si pot escriure el 6
      mov dx, ax
      and dx, 0000000001000000b
      cmp dx, 0000000001000000b
      je helpCheck7
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 12 ]
      push DX
      call PrintMessage
      add sp,4             ;pintem el numero 6
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck7:
      ;verifiquem si pot escriure el 7
      mov dx, ax
      and dx, 0000000010000000b
      cmp dx, 0000000010000000b
      je helpCheck8
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 14 ]
      push DX
      call PrintMessage    ;pintem el numero 7
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck8:
      ;verifiquem si pot escriure el 8
      mov dx, ax
      and dx, 0000000100000000b
      cmp dx, 0000000100000000b
      je helpCheck9
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 16 ]
      push DX
      call PrintMessage    ;pintem el numero 8
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    helpCheck9:
      ;verifiquem si pot escriure el 9
      mov dx, ax
      and dx, 0000001000000000b
      cmp dx, 0000001000000000b
      je finHelp
      mov dh,21            ;fila
      mov dl,bl            ;columna
      push DX
      lea dx,Numeros[ 18 ]
      push DX
      call PrintMessage    ;pintem el numero 9
      add sp,4
      inc bl               ;incrementem columna per escriure més numeros
    
    finHelp:
      ret
    
    ;*******************************************************************************
    ; Actualitza el contingut del Tauler de Joc amb les dades de la matriu indicada
    ; per BX. Si a la matriu Sudoku hi ha un espai en blanc en aquella posició s'ha
    ; d'escriure el número de diferent color.
    ; Paràmetres d'entrada: BX: Adreça inicial de les dades a mostrar en el tauler.
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    UpdateBoard:
      push AX
      push CX
      push DX
      push SI
    
      push BX           ; el tractem a apart perque ‚s on tenim l'adreca de la matriu.
                        ; el guardem perque tambe‚ l'hem d'utilitzar en els serveis BIOS
    
      ;Inicialitzar registres
      mov bh,00h        ;pagina
      mov dh,03         ;fila inicial on podem escriure en el tauler.
      mov dl,26         ;columna inicial on podem escriure en el tauler.
    
      mov cx,1          ;escriurem 1 caràcters cada cop
    
      mov si,0          ;índex per a les dades de Sudoku
    
    LoopUB:
      mov ah,02h        ;servei per posicionar el cursor
      int BIOSSERVICE
    
      pop BX
      mov al,[BX][SI]  ;caràcter
      push BX
    
      ;Si a la matriu un espai en blanc s'ha d'escriure de diferent color.
      cmp Sudoku[SI],' '
      je diferentColor
    
      mov bl,09h        ;atribut (blau mar¡ amb intensitat)
      jmp printUpdate
    
    diferentColor:
      mov bl,0Bh        ;atribut (blau clar amb intensitat)
    
    printUpdate:
      mov ah,09h        ;servei per escriure caràcter.
      mov bh,00h        ;pagina
      int BIOSSERVICE
    
      inc si            ;incrementem l'índex per accedir a les dades
      
      ;Actualitzem posició del cursor (fila i columna)
      inc dl            ;columna ( dos salts per les linees del tauler )
      inc dl
      ;en cas que la columna sigui 44 a la seguent fila (fila + 2)e init la columna a 26
      cmp dl, 44        
      jl LoopUB
      mov dl, 26        ;columna inicial on podem escriure en el tauler.
      inc dh            ;fila  ( dos salts per les linees del tauler )
      inc dh
      cmp dh, 20        ;en cas que la fila sigui 20 ja hem finalitzat d'escriure la matriu.
      jl LoopUB
    
      ;Posar el cursor a la posició inicial (5,5)
      mov al,2          ;multipliquem per 2 per saltarnos les ratlles del tauler.
      mul RowCur
      mov dh,al
      add dh,03         ;03: fila a pantalla de la posició (1,1)
      mov al,2
      mul ColCur
      mov dl,al
      add dl,26         ;26: columna a pantalla de la posició (1,1)
    
      mov ah,02h        ;servei per posicionar el cursor
      mov bh,00h        ;pagina
      int BIOSSERVICE
    
      pop SI
      pop DX
      pop CX
      pop BX
      pop AX
    
      ret
    
    ;*******************************************************************************
    ; Llegim una tecla utilitzant el servei 08h de les crides al DOS. 
    ; Segons la tecla llegida cridarem al procediment corresponent.
    ;  [‘i’,’j’,’k’ o ’l’] cridar al procediment MoveCursor
    ;  [‘1’,‘2’,‘3’,‘4’,‘5’,‘6’,‘7’,‘8’,‘9’ o ‘’] cridar al procediment ChangeNum
    ;  ‘q’ posa Estat=0.
    ; (per la lectura de teclat utilitzeu només crides als serceis del DOS).
    ; Paràmetres d'entrada: Cap
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    ReadKey:
    
      mov ah, 07h		; demanem un digit
      int DOSSERVICE	
    
      ;SORTIDA DEL PROGRAMA
      cmp al,'q'
      je SalidaReadKey
      cmp al,'Q'
      je SalidaReadKey
    
      ;MOVIMIENT DEL CURSOR
      cmp al,'i'
      je MoveCursor
      cmp al, 'I'
      je MoveCursor
      cmp al,'j'
      je MoveCursor
      cmp al, 'J'
      je MoveCursor
      cmp al,'k'
      je MoveCursor
      cmp al, 'K'
      je MoveCursor
      cmp al,'l'
      je MoveCursor
      cmp al, 'L'
      je MoveCursor
    
      ;PETICIO DE CANVI DE NUMERO
      cmp al, ' '
      je ChangeNum
      cmp al, 49    ;si el codigo ASCI de la tecla es menor a 49 ('1') finalitzar
      jb finReadKey
      cmp al, 57    ;si el codigo ASCI de la tecla es mayor a 49 ('9') finalitzar
      jg finReadKey
      jmp ChangeNum ; si arriba aqui es que correspon a 1-9
    
    
      ;si no es cap tecla d´aquestes finalitzar en finReadKey
      jmp finReadKey
    
    SalidaReadKey:
      mov State , 0   ;actualitzar State perque el bucle del main finalitzi execució
    
    finReadKey:
    
      ret
    
    ;*******************************************************************************
    ; Segons la direcció indicada per AL i actualitza RowCur i ColCur 
    ; segons la direcció que s’hagi seleccionat. No s'ha de posicionar el cursor a 
    ; pantalla, hi un altre subrutina per fer-ho.
    ; Paràmetres d'entrada: AL conté la direcció del moviment ('i', 'j', 'k' o 'l')
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    MoveCursor:
    
      ;seleccionar el moviment que ha demanat el user.
      cmp al,'i'
      je moveCursorUp
      cmp al,'I'
      je moveCursorUp
      cmp al,'k'
      je moveCursorDown
      cmp al,'K'
      je moveCursorDown
      cmp al,'j'
      je moveCursorLeft
      cmp al,'J'
      je moveCursorLeft
      cmp al,'l'
      je moveCursorRight
      cmp al,'L'
      je moveCursorRight
    
    moveCursorUp:        ; moviment cap amunt
      cmp RowCur,0
      je finMoveCursor
      dec RowCur
      jmp finMoveCursor
    moveCursorDown:      ; moviment cap abaix
      cmp RowCur,8
      je finMoveCursor
      inc RowCur
      jmp finMoveCursor
    moveCursorLeft:      ; moviment cap esquerre
      cmp ColCur,0
      je finMoveCursor
      dec ColCur
      jmp finMoveCursor
    moveCursorRight:     ; moviment cap dreta
      cmp ColCur,8
      je finMoveCursor
      inc ColCur
    
    finMoveCursor:
      call PosCurScreen
    
      ret
    
    ;*******************************************************************************
    ; Escriu / Esborra Número
    ; Posar el caràcter a la matriu Play. No s'ha de mostrar res.
    ; Només s'ha de posar el caràcter si no és un número de la matriu Sodoku.
    ; (la matriu actualitzada es mostrarà en un altre subrutina)
    ; Paràmetres d'entrada: AL conté el símbol que volem escriure a la matriu.
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    ChangeNum:
    
      push dx
      push ax
    
      ;POSICIO CURSOR AL ARRAY : Multipliquem per 9 el RowCur + el valor del ColCur
      mov ax,9
      mul RowCur
      mov dx,0
      mov dl,ColCur
      add ax, dx
      mov si, ax  ;si indica la posicio del digit al array
    
      cmp Sudoku[si],' '  ;verifiquem que a aquesta posicio el user pot escriure
      jne noPotChangeNum
    
      pop ax
      mov Play[si], al   ;guardem el valor a la array PLAY
      push ax
    
    noPotChangeNum:
      pop ax
      pop dx
    
      ret
    
    ;*******************************************************************************
    ; Verifica si hem omplert totes les caselles (no hi ha cap posició de la matriu 
    ; Play que sigui un espai en blanc) i que els valors escrits siguin correctes 
    ; si és així canvia State a 2 (Guanyador).
    ; Paràmetres d'entrada: Cap
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    CheckEnd:
    push ax
    push cx
       ;initzialitzem valors
       mov si,0
       mov cx,0
       mov bx,0
    bucleCheckEnd:              ; recorrem totes les posicions
    
       cmp SUDOKU[si],' ' ;mirem si es una posicio que el user pot escriure, sino no la validem
       jne noCheckPos
       
       mov ax, si         ;guardem si en ax perque s´utilitza dintre de CheckEndPos
    
       call CheckEndPos
    
       cmp bx,1                ;verifiquem el retorn de CheckEndPos ( bx )
       jne noCheckPos
       mov cx,bx                ;si dona alguna possicio incorrecte la guardem
    
    noCheckPos:
       inc si                  ;incrementem index
       cmp si,81
       jne bucleCheckEnd
    
       cmp cx,0                ; si val 0 es tot correcte
       jne errorcheckend
       mov State,2             ;Actualitzem State a 2 perque el bucle del main finalitzi execucio
    
    errorcheckend:
    
    pop cx
    pop ax
      ret
    
    ;*******************************************************************************
    ; Verifica si el valor indicat per parametre (Posicio) es correcte o no
    ; Paràmetres d'entrada: ax indica la posicio del digit al array
    ; Paràmetres de sortida: bx 1 si no validem la posicio com a correcte
    ;*******************************************************************************
    CheckEndPos:
      push cx
    
      mov si, ax         ; si indica la posicio del digit al array
    
      Call CheckPos      ; si es el parametre d´entrada que indica la posicio en l´array
                         ; Paràmetres de sortida: AX: Registre on el bit 'i' indica que en aquella
                         ; posició NO podem posar-hi el nombre 'i'. AX (bit 15 - bit 0) només utilitzarem
                         ; del (bit 9 - bit 1). EX: 0000 0000 0001 0110 vol dir que a la posició indicada
                         ; per SI de la matriu Play no podem posar els nombres 1,2 i 4
    
    
      ;verifiquem si ha d'escriure el 1
      mov dx, ax
      and dx, 0000000000000010b
      cmp dx, 0000000000000010b
      je CheckEndCheck2
      cmp Play[si],'1'
      je CheckEndCheck2
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck2:
      ;verifiquem si pot escriure el 2
      mov dx, ax
      and dx, 0000000000000100b
      cmp dx, 0000000000000100b
      je CheckEndCheck3
      cmp Play[si],'2'
      je CheckEndCheck3
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck3:
      ;verifiquem si pot escriure el 3
      mov dx, ax
      and dx, 0000000000001000b
      cmp dx, 0000000000001000b
      je CheckEndCheck4
      cmp Play[si],'3'
      je CheckEndCheck4
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck4:
      ;verifiquem si pot escriure el 4
      mov dx, ax
      and dx, 0000000000010000b
      cmp dx, 0000000000010000b
      je CheckEndCheck5
      cmp Play[si],'4'
      je CheckEndCheck5
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck5:
      ;verifiquem si pot escriure el 5
      mov dx, ax
      and dx, 0000000000100000b
      cmp dx, 0000000000100000b
      je CheckEndCheck6
      cmp Play[si],'5'
      je CheckEndCheck6
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck6:
      ;verifiquem si pot escriure el 6
      mov dx, ax
      and dx, 0000000001000000b
      cmp dx, 0000000001000000b
      je CheckEndCheck7
      cmp Play[si],'6'
      je CheckEndCheck7
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck7:
      ;verifiquem si pot escriure el 7
      mov dx, ax
      and dx, 0000000010000000b
      cmp dx, 0000000010000000b
      je CheckEndCheck8
      cmp Play[si],'7'
      je CheckEndCheck8
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck8:
      ;verifiquem si pot escriure el 8
      mov dx, ax
      and dx, 0000000100000000b
      cmp dx, 0000000100000000b
      je CheckEndCheck9
      cmp Play[si],'8'
      je CheckEndCheck9
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    CheckEndCheck9:
      ;verifiquem si pot escriure el 9
      mov dx, ax
      and dx, 0000001000000000b
      cmp dx, 0000001000000000b
      je finalCheckEnd
      cmp Play[si],'9'
      je finalCheckEnd
      mov bx, 1          ;si no es correcte actualitzem a 1 bx
    
    finalCheckEnd:
      pop cx
      ret
    
    ;*******************************************************************************
    ; Mostra un missatge a la posició indicada de la pantalla.
    ; L'adreça del missatge i la posició es passen per la pila. 
    ; Paràmetres d'entrada: Adreça del missatge [bp+4] i posició (fila,columna) [bp+6]
    ; Paràmetres de sortida: Cap
    ;*******************************************************************************
    PrintMessage:
         push bp
         mov bp,sp
         push ax           ;salvem a la pila els registres que utilitzem
         push bx
         push dx
         push si
    
         mov ah,02h        ;servei per posicionar el cursor
         mov bh,00h        ;p…gina
         mov dx,[bp+6]     ;Posem a dh la fila i a dl la columna per escriure
         int BIOSSERVICE
    
         mov dx,[bp+4]	    ;posem l'adre‡a del missatge al registre DX.
         mov ah,09h
         int DOSSERVICE
    
         pop si            ;restaurem els registre amb els valor inicials.
         pop dx
         pop bx
         pop ax
         pop bp
      ret
    
    ;*******************************************************************************
    ; Posiciona cursor a la pantalla en base a les variables RowCur i ColCur.
    ; Paràmetres d'entrada: Cap
    ; Paràmetres de sortida: cap 
    ;*******************************************************************************
    PosCurScreen:
      push ax
      push dx
      push bx
    
      ;RowCur  [0-8] Val 0:Fila 1,    val 8:Fila 9    (posició inicial:4 = Fila 5)
      ;control de la fila
      mov al,2          ;multipliquem per 2 per saltarnos les ratlles del tauler.
      mul RowCur        ;el resultat a al
      add al, 3         ;augmentem 3 a al que es el valor incial per aribar a la primera fila del tauler.
      mov dh,al
    
       ;ColCur  [0-8] Val 0:Columna 1, val 8:Column 9  (posició inicial:4 = Columna 5)
       ;control de la columna
      mov al,2          ;multipliquem per 2 per saltarnos les ratlles del tauler.
      mul ColCur        ;el resultat a al
      add al, 26        ;augmentem 26 a al que es el valor incial per aribar a la primera columna del tauler.
      mov dl,al
    
      mov bh,00h        ;pàgina
      mov ah,02h        ;servei per posicionar el cursor
      int BIOSSERVICE
    
    errorPosCurScreen:
    
      pop ax
      pop dx
      pop bx
    
      ret
    
    
    ;*******************************************************************************
    ; Programa Principal
    ;*******************************************************************************
    Main:
      STARTUPCODE
    
      Call ClearScreen   ; netegem la pantalla
    
      Call PrintBoard    ; mostra el tauler de jov buit ( mostra les línies del tauler)
    
      push BX
      lea BX , Sudoku   ; cargem les dades de inici del sudoku de l'array Sudoku2
      Call UpdateBoard   ; mostra es numeros que es donen inicialment ( matriu Sudoku )
      pop BX
    
      Call IniPlay       ; initialitzem la matriu Play amb els valors inicials de la matriu Sudoku
    
    
    bucle:
    
      Call PrintHelp      ;Mostrar l'ajuda
    
      call PosCurScreen   ;Posicionar el cursor al tauler
    
      call ReadKey        ;llegir una tecla i fer els canvis corresponents a la matriu de dades
    
      push BX
      lea BX , Play
      Call UpdateBoard   ;Actualitzar el Tauler mostra es numeros  matriu play
      pop BX
        
      call CheckEnd;Verificar si el tauler ja s´ha complert completament
    
    ;CONDICIO SORTIDA DEL BUCLE ( STATE != 1 )
    cmp State, 1
    je bucle
    
      ;mirem el motiu de la sortida del bucle i mostrem missatge.
      mov dh,24             ;fila
      mov dl,23             ;columna
      push DX
    
      cmp State, 0
      je stateMessage               
      lea dx,MsgWinner     ; 2: Guanyador, hem omplert la matriu Play correctament.
      jmp fin
    
    stateMessage:
      lea dx,MsgExit       ; 0: Sortir, hem pitjat la tecla 'q' per sortir o s'ha acabat el temps.
    
    fin:
      push DX
      call PrintMessage    ;pintem per pantalla el missatge de finalització d'execució
      add sp,4
      EXITCODE 0           ;finalitzem l'execució
    
    end Main
Ofrecido por Community Server (Commercial Edition)