Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- comment *----------------------------------------
- Esercizio: scacchiera
- Author : Marco 'RootkitNeo'
- ----------------------------------------*
- include c:\masm32\include\masm32rt.inc
- include coords.inc
- ; ==================================
- ; MACRO
- ; ==================================
- ; Calcola l'abs() di un valore passato in number
- ABS_NUMBER MACRO number
- push ebx
- mov ebx, number
- sar ebx, 01Fh
- xor number, ebx
- sub number, ebx
- pop ebx
- ENDM
- ; ==================================
- ; SEZIONI
- ; ========================================================================
- .data
- szWhiteKing db "========= Posizione Re Bianco ======== ",13,10,0
- szBlackKing db 13,10,"========= Posizione Re Nero ======== ",13,10,0
- szBlackQueen db 13,10,"========= Posizione Regina Nera ======== ",13,10,0
- szPossibleState db 13,10,"========= Possibili Mosse Re Bianco ========",13,10,0
- szX db "X: ",0
- szY db "Y: ",0
- szTemp db 7 dup(?) ; Numero letto da tastiera
- ; ========================================================================
- .data?
- coordsWhiteKing COORDS < > ; Re Bianco
- coordsBlackKing COORDS < > ; Re Nero
- coordsBlackQueen COORDS < > ; Regina Nera
- pointerToMemory DWORD ? ; Puntatore DWORD non inizializzato
- ; alloco memoria dinamicamente (non che sia utile)
- ; ========================================================================
- .code
- start:
- ; White King
- ; ------------------------------------------------------
- print offset szWhiteKing
- print offset szX
- invoke StdIn, addr szTemp, 6
- invoke atodw, addr szTemp
- mov coordsWhiteKing.dwX, eax
- print offset szY
- invoke StdIn, addr szTemp, 6
- invoke atodw, addr szTemp
- mov coordsWhiteKing.dwY, eax
- ; ------------------------------------------------------
- ; Black King
- ; ------------------------------------------------------
- print offset szBlackKing
- print offset szX
- invoke StdIn, addr szTemp, 6
- invoke atodw, addr szTemp
- mov coordsBlackKing.dwX, eax
- print offset szY
- invoke StdIn, addr szTemp, 6
- invoke atodw, addr szTemp
- mov coordsBlackKing.dwY, eax
- ; ------------------------------------------------------
- ; Black Queen
- ; ------------------------------------------------------
- print offset szBlackQueen
- print offset szX
- invoke StdIn, addr szTemp, 6
- invoke atodw, addr szTemp
- mov coordsBlackQueen.dwX, eax
- print offset szY
- invoke StdIn, addr szTemp, 6
- invoke atodw, addr szTemp
- mov coordsBlackQueen.dwY, eax
- ; ------------------------------------------------------
- ; Verifico se i Re sono in posizioni adiacenti
- push coordsWhiteKing.dwY
- push coordsWhiteKing.dwX
- call isBlackKingNear
- .IF eax == 1
- print "I Re non possono essere vicini.",13,10
- jmp _exit
- .ENDIF
- ; Verifico se è scacco; se scacco matto restituisce eax=2
- ; in caso contrario restituira' 0
- call checkMateWoman
- .IF eax == 2
- print "Scacco Matto, nessuna mossa disponibile",13,10
- jmp _exit
- .ENDIF
- ; Se ci sono mosse possibili le stampo a video
- print offset szPossibleState
- call printPosition
- _exit:
- call GetProcessHeap
- invoke HeapFree, eax, 0, pointerToMemory
- inkey
- invoke ExitProcess, 0
- ; Restituisce in EAX la distanza tra (x,y) e le relative coordinate
- ; del Re Nero. Se EAX=1 i Re confinano
- ; Distanza di Tchebichev
- ; -------------------------------------------------------------
- isBlackKingNear proc uses ebx edx dwX :DWORD, dwY :DWORD
- mov eax, dwX
- sub eax, coordsBlackKing.dwX
- ABS_NUMBER eax
- push eax
- mov eax, dwY
- sub eax, coordsBlackKing.dwY
- ABS_NUMBER eax
- mov ebx, eax
- pop eax
- cmp eax, ebx
- cmovl eax, ebx
- ret
- isBlackKingNear endp
- ; --------------------------------------------------------------------
- ;
- ; Verifica lo scacco di donna
- ; --------------------------------------------------------------------
- checkMateWoman proc
- call GetProcessHeap
- invoke HeapAlloc, eax, HEAP_ZERO_MEMORY, 40h
- mov pointerToMemory, eax
- mov esi, eax
- assume esi :ptr COORDS
- ; Guardo tutt le 8 posizioni attorno al Re bianco
- mov eax, coordsWhiteKing.dwX
- mov ebx, coordsWhiteKing.dwY
- mov ecx, eax
- mov edx, ebx
- xor ecx, ecx
- ; Cerca attorno al Re Bianco
- dec eax
- dec ebx
- .WHILE ecx < 8
- .IF ecx == 3 || ecx == 5
- inc eax
- mov ebx, edx
- dec ebx
- .ELSEIF ecx == 4
- inc ebx
- .ENDIF
- .IF eax > 0 && eax < 9 && ebx > 0 && ebx <9
- mov edi, eax
- push ebx
- push eax
- call isCheckMateWoman
- .IF eax == 0
- push ebx
- push edi
- call isBlackKingNear
- ; Salvo le posizioni che non sono sotto scacco
- .IF eax != 1
- mov [esi+ecx*8].dwX, edi
- mov [esi+ecx*8].dwY, ebx
- .ENDIF
- .ENDIF
- mov eax,edi
- .ENDIF
- inc ecx
- inc ebx
- .ENDW
- ; Se la memoria puntata da ESI risulta a 0
- ; in corrispondenza del primo elemento, mi fermo;
- ; si tratta di scacco matto, non ci sono mosse
- ; che salvano il Re Bianco
- .IF [esi].dwX == 0 && [esi].dwY == 0
- mov eax, 2
- .ELSE
- mov eax, 0
- .ENDIF
- ret
- checkMateWoman endp
- ; ---------------------------------------------------------------------
- ;Verifico se il Re e' sotto scacco dalla Regina
- ; @return: EAX = 1 in presenza di scacco; 0 se non e' sotto scacco
- ; ---------------------------------------------------------------------
- isCheckMateWoman proc uses ebx ecx edx dwX:DWORD, dwY:DWORD
- mov eax, dwX
- mov ebx, dwY
- ; orizzontale / verticale
- .IF eax == coordsBlackQueen.dwX || ebx == coordsBlackQueen.dwY
- mov eax, 1
- ret
- .ENDIF
- ;Diagonali
- mov ecx, coordsBlackQueen.dwX
- sub ecx, coordsBlackQueen.dwY
- sub eax, ebx
- .IF eax == ecx
- mov eax, 1
- ret
- .ENDIF
- mov ecx, coordsBlackQueen.dwX
- add ecx, coordsBlackQueen.dwY
- mov eax, dwX
- add eax, dwY
- .IF ecx == eax
- mov eax,1
- ret
- .ENDIF
- mov eax,0
- ret
- isCheckMateWoman endp
- ; ------------------------------------------------------------------------
- ;
- ; Stampo le posizioni valide
- ; ------------------------------------------------------------------------
- printPosition proc
- mov esi, pointerToMemory
- assume esi:ptr COORDS
- xor ecx,ecx
- .WHILE ecx < 8
- mov eax, [esi+ecx*8].dwX
- mov ebx, [esi+ecx*8].dwY
- .IF eax > 0
- push ecx
- print str$(eax),32
- print str$(ebx),13,10
- pop ecx
- .ENDIF
- inc ecx
- .ENDW
- ret
- printPosition endp
- ; --------------------------------------------------------------------------
- end start
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement