Skip to content

Instantly share code, notes, and snippets.

@abdullahnaseer
Last active May 22, 2018 08:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abdullahnaseer/facf6db47d4540e28767846074fa7f2e to your computer and use it in GitHub Desktop.
Save abdullahnaseer/facf6db47d4540e28767846074fa7f2e to your computer and use it in GitHub Desktop.
COAL Project
.386
.model flat, stdcall
.stack 1024
GetTickCount PROTO ; get elapsed milliseconds
; since computer turned on
ExitProcess PROTO, ; exit program
dwExitCode:DWORD ; return code
GetStdHandle PROTO, ; get standard handle
nStdHandle:DWORD ; type of console handle
CloseHandle PROTO, ; close file handle
handle:DWORD
ReadConsoleA PROTO,
handle:DWORD, ; input handle
lpBuffer:PTR BYTE, ; pointer to buffer
nNumberOfCharsToRead:DWORD, ; number of chars to read
lpNumberOfCharsRead:PTR DWORD, ; number of chars read
lpReserved:PTR DWORD ; 0 (not used - reserved)
WriteConsoleA PROTO, ; write a buffer to the console
handle:DWORD, ; output handle
lpBuffer:PTR BYTE, ; pointer to buffer
nNumberOfCharsToWrite:DWORD, ; size of buffer
lpNumberOfCharsWritten:PTR DWORD, ; number of chars written
lpReserved:PTR DWORD ; 0 (not used)
CreateFileA PROTO, ; create new file
pFilename:PTR BYTE, ; ptr to filename
accessMode:DWORD, ; access mode
shareMode:DWORD, ; share mode
lpSecurity:DWORD, ; can be NULL
howToCreate:DWORD, ; how to create the file
attributes:DWORD, ; file attributes
htemplate:DWORD ; handle to template file
ReadFile PROTO, ; read buffer from input file
fileHandle:DWORD, ; handle to file
pBuffer:PTR BYTE, ; ptr to buffer
nBufsize:DWORD, ; number bytes to read
pBytesRead:PTR DWORD, ; bytes actually read
pOverlapped:PTR DWORD ; ptr to asynchronous info
SetConsoleTextAttribute PROTO,
nStdHandle:DWORD, ; console output handle
nColor:DWORD ; color attribute
SetConsoleCursorPosition PROTO,
handle:DWORD,
pos:DWORD
GetTimeFormatA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD,:DWORD
.data
seed dword ?
temp byte 30 dup(?)
filepath byte "C:\Users\abdul\source\repos\COALProject\COALProject\words.txt", 0
buffer byte 5000 dup(?)
randomWords byte 200 dup(?)
rightAnswers byte 300 dup(?)
rightAnswered byte 15 dup(0)
enterArray byte 00ah, 00dh
count dword ?
welcomeMessage1 byte " |-------Welcome to the puzzle word-------| ", 00ah, 00dh
welcomeMessage2 byte "You have 10 minutes to complete this puzzle. Your time started at: ", 0
welcomeMessage3 byte "Words to be found: Score: ", 0
completeMessage byte "Congratulations!!! You completed the game!!!", 0
timeoutMessage byte "Times Up!!! 10 minutes are completed!!!", 0
timeMessage byte 15 dup(0), 0
scoreMessage byte 3 dup(0), "0", 0
finalScoreMessage byte "Your final score is: ", 0
score dword 0
startTime dword ?
board byte 4096 dup(0), 0
tempBoard byte 4096 dup(0), 0
userInputMessage byte "Please enter the word, row no, column no, and the direction no (e.g. dummyword 1 2 0): ", 0
userInput byte 20 dup(?), 0
userInputWord byte 16 dup(?)
userInputWordCount byte ?
userInputRow byte ?
userInputColumn byte ?
userInputDirection byte ?
userInputWordLengthError byte "Invalid length of words entered!!!", 0
userInputWordError byte "Invalid input entered!!! Make sure all inputs are valid and in proper format!!!", 0
userInputRowError byte "Invalid row number entered!!!", 0
userInputRowColumn byte "Invalid column number entered!!!", 0
userInputRowDirection byte "Invalid direction number entered!!!", 0
userInputNumericError byte "Invalid input entered!!! Make sure row no, column no and direction no is numeric value and valid!!!", 0
userInputNumericLengthError byte "Invalid input entered!!! Make sure row no, column no and direction no is valid and within the specified range!!!", 0
userInputError byte "Invalid Input!!!", 0
userWrongInput byte "Incorrent Answer!!! -10 Score!!!"
userRightInput byte "Correct Answer!!! +10 Score!!!"
userAlreadyEnteredInput byte "You already entered this input!!!"
spacesArray byte 128 dup(' ')
responseMessageOffset dword ?
responseMessageCount dword 0
;; Global Vars
spaces dword 2
noOfRandomWords dword 8
noOfRows dword 15
noOfColumns dword 15
minWordLength dword 6
maxWordLength dword 10
timeAllowed dword 600000 ;; 10mins = 10 * 60 sec = 600sec = 600000 msec
spider byte "Possible Directions:, 1 2 3, \ | /, \|/,0----O----4, /|\, / | \, 7 6 5"
nullChar byte 0
spaceChar byte ' '
.code
main proc
call displaySpider
invoke GetTickCount
mov seed, eax
invoke GetTimeFormatA, 0, 0, 0, 0, offset timeMessage, lengthof timeMessage ; get current time
push offset filepath
push noOfRandomWords
push offset randomWords
call generateRandomWords
add esp, 12
push offset board
push noOfRandomWords
push offset randomWords
push spaces
call insertRandomWordsInBoard
add esp, 16
push offset board
call insertRandomCharactersInBoard
add esp, 4
call displayWelcomeAndScoreMessage
call displayRandomWords
;call displayRightAnswers
call displayBoard
invoke GetTickCount
mov startTime, eax
linputLoop:
call displayInputMessage
call checkTime
call processInput
call checkIfAllEntered
jmp linputLoop
lendInputLoop:
invoke ExitProcess, 0
main endp
;@param noOfRandomWords
;@param rightAnswered
;@param completeMessage
checkIfAllEntered proc uses eax ebx ecx edx esi edi ebp
mov esi, 0
lloop:
cmp esi, noOfRandomWords
je lendLoop
cmp rightAnswered[esi], 0
je lend
inc esi
jmp lloop
lendLoop:
call displayWelcomeAndScoreMessage
call displayRightAnswers
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
mov eax, 4
add eax, noOfRandomWords
add eax, noOfRows
push eax
call displayBreakLines
push 3
call displayBreakLinesWithSpaces
add esp, 4
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
call displayBreakLines
add esp, 4
mov ebx, 2 ;; green foreground color
shl ebx, 4
or ebx, 0 ;; black text color
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset completeMessage, lengthof completeMessage, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
push 1
call displayBreakLines
add esp, 4
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset finalScoreMessage, lengthof finalScoreMessage, offset count, 0
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset scoreMessage, lengthof scoreMessage, offset count, 0
push 1
call displayBreakLines
add esp, 4
invoke ExitProcess, 0
lend:
ret
checkIfAllEntered endp
checkTime proc uses eax ebx ecx edx
invoke GetTickCount
sub eax, startTime
cmp eax, timeAllowed
jnge lcontinue
call endProgramTimeOut
lcontinue:
ret
checkTime endp
endProgramTimeOut proc uses eax ebx ecx edx
call displayWelcomeAndScoreMessage
call displayRightAnswers
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
mov eax, 4
add eax, noOfRandomWords
add eax, noOfRows
push eax
call displayBreakLines
push 3
call displayBreakLinesWithSpaces
add esp, 4
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
call displayBreakLines
add esp, 4
mov ebx, 4 ;; green foreground color
shl ebx, 4
or ebx, 0 ;; black text color
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset timeoutMessage, lengthof timeoutMessage, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
push 1
call displayBreakLines
add esp, 4
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset finalScoreMessage, lengthof finalScoreMessage, offset count, 0
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset scoreMessage, lengthof scoreMessage, offset count, 0
push 1
call displayBreakLines
add esp, 4
invoke ExitProcess, 0
ret
endProgramTimeOut endp
;@param spider
displaySpider proc uses eax ebx ecx edx esi edi
push 3
call displayBreakLines
add esp, 4
push 50
call displaySpaces
add esp, 4
mov esi, 0
lloop:
cmp esi, lengthof spider
jae lendLoop
mov cl, spider[esi]
cmp cl, ','
jne lnotComma
push 1
call displayBreakLines
add esp, 4
push 55
call displaySpaces
add esp, 4
jmp lcomma
lnotComma:
mov temp[0], cl
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset temp, 1, offset count, 0
lcomma:
inc esi
jmp lloop
lendLoop:
ret
displaySpider endp
displayWelcomeAndScoreMessage proc uses eax ebx ecx edx
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
;; Display welcomeMessage1
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset welcomeMessage1, lengthof welcomeMessage1, offset count, 0
;; Display welcomeMessage2
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset welcomeMessage2, lengthof welcomeMessage2, offset count, 0
;; Display timeMessage
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset timeMessage, lengthof timeMessage, offset count, 0
push 1
call displayBreakLines
add esp, 4
;; Display welcomeMessage3
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset welcomeMessage3, lengthof welcomeMessage3, offset count, 0
;; Display scoreMessage
call convertAndSaveScore
mov ebx, 7
shl ebx, 4
or ebx, 0
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset scoreMessage, lengthof scoreMessage, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
push 1
call displayBreakLines
add esp, 4
ret
displayWelcomeAndScoreMessage endp
; @param randomWords
displayRandomWords proc uses eax ebx ecx edx esi edi ebp
mov esi, 0
mov edi, 0 ;; no of character
mov ebp, 0 ;; no of word
lloop:
cmp esi, lengthof randomWords
jge lendLoop
mov bl, randomWords[esi]
cmp bl, 0
je lendLoop
mov temp[edi], bl
cmp word ptr randomWords[esi], 00a0dh
jne lnotEnter
mov word ptr temp[edi], 00a0dh
add esi, 1
add edi, 2
cmp rightAnswered[ebp], 1
je lElse
lIf:
;; Display word in temp
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset temp, edi, offset count, 0
jmp lEndIf
lElse:
mov ebx, 7
shl ebx, 4
or ebx, 0
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset temp, edi, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
lEndIf:
inc ebp
mov edi, -1
lnotEnter:
inc edi
inc esi
jmp lloop
lendLoop:
ret
displayRandomWords endp
; @param rightAnswers
displayRightAnswers proc uses eax ebx ecx edx esi edi ebp
mov esi, 0
mov edi, 0 ;; no of character
mov ebp, 0 ;; no of word
lloop:
cmp esi, lengthof rightAnswers
jge lendLoop
mov bl, rightAnswers[esi+ebp]
cmp bl, 0
je lendLoop
mov temp[edi], bl
cmp word ptr rightAnswers[esi+ebp], 00a0dh
jne lnotEnter
mov word ptr temp[edi], 00a0dh
add esi, 1
add edi, 2
cmp rightAnswered[ebp], 1
je lElse
lIf:
;; Display word in temp
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset temp, edi, offset count, 0
jmp lEndIf
lElse:
mov ebx, 7
shl ebx, 4
or ebx, 0
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset temp, edi, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
lEndIf:
inc ebp
mov edi, -1
lnotEnter:
inc edi
inc esi
jmp lloop
lendLoop:
ret
displayRightAnswers endp
displayInputMessage proc uses eax ebx esi edi ebp
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
mov eax, 4
add eax, noOfRandomWords
add eax, noOfRows
push eax
call displayBreakLines
push 3
call displayBreakLinesWithSpaces
add esp, 4
invoke GetStdHandle, -11
invoke SetConsoleCursorPosition, eax, 0
call displayBreakLines
add esp, 4
mov eax, responseMessageOffset
cmp eax, offset userRightInput
je lsuccessResponse
lerrorMessage:
mov ebx, 4 ;; red foregound color
shl ebx, 4
or ebx, 0 ;; black text color
jmp lendResponse
lsuccessResponse:
mov ebx, 2 ;; green foregound color
shl ebx, 4
or ebx, 0 ;; black text color
lendResponse:
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, responseMessageOffset, responseMessageCount, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
push 1
call displayBreakLines
add esp, 4
;; Display input message
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset userInputMessage, lengthof userInputMessage, offset count, 0
;; Read input message
invoke GetStdHandle, -10 ; Input handle
invoke ReadConsoleA, eax, offset userInput, lengthof userInput, offset count, 0
ret
displayInputMessage endp
;@param spider
displayBoard proc uses eax ebx ecx edx esi edi
mov esi, 0
lloop:
cmp esi, lengthof board
jae lendLoop
mov eax, esi
cdq
mov ecx, noOfColumns
div ecx
cmp edx, 0
jne lnotBreakLine
push 1
call displayBreakLines
add esp, 4
lnotBreakLine:
movzx ecx, tempBoard[esi]
cmp ecx, 0
je lnotAlreadyEnteredWord
;; if this word is already entered and scored
cmp rightAnswered[ecx-1], 1
jne lnotAlreadyEnteredWord
mov cl, board[esi]
cmp cl, 0
je lendLoop
mov temp[0], cl
mov ebx, 7
shl ebx, 4
or ebx, 0
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
invoke GetStdHandle,- 11
invoke WriteConsoleA, eax, offset temp, 1, offset count, 0
mov ebx, 0
shl ebx, 4
or ebx, 7
invoke GetStdHandle,- 11
invoke SetConsoleTextAttribute, eax, ebx
jmp alreadyEntered
lnotAlreadyEnteredWord:
mov cl, board[esi]
cmp cl, 0
je lendLoop
mov temp[0], cl
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset temp, 1, offset count, 0
alreadyEntered:
push spaces
call displaySpaces
add esp, 4
inc esi
jmp lloop
lendLoop:
ret
displayBoard endp
; @param noOfLines from stack
displayBreakLines proc uses eax ecx esi
mov esi, [esp+16]
lloop:
cmp esi, 0
jle lendLoop
;; Display enter -> break line
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset enterArray, lengthof enterArray, offset count, 0
dec esi
jmp lloop
lendLoop:
ret
displayBreakLines endp
; @param noOfLines from stack
displayBreakLinesWithSpaces proc uses eax ecx esi
mov esi, [esp+16]
lloop:
cmp esi, 0
jle lendLoop
;; Display spaces
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset spacesArray, lengthof spacesArray, offset count, 0
dec esi
jmp lloop
lendLoop:
ret
displayBreakLinesWithSpaces endp
;@param spaceChar
displaySpaces proc uses eax ebx ecx
mov ecx, [esp+16]
lloop:
push ecx
invoke GetStdHandle, -11 ; Output handle
invoke WriteConsoleA, eax, offset spaceChar, lengthof spaceChar, offset count, 0
pop ecx
loop lloop
ret
displaySpaces endp
;; @param userInput
;; @param count
processInput proc uses eax ebx esi edi ebp
call parseInputWord
cmp eax, 0
je lendProcessInput
mov eax, noOfRows
mov edx, offset userInputRow
call parseInputNumeric
cmp eax, 0
je lendProcessInput
mov eax, noOfColumns
mov edx, offset userInputColumn
call parseInputNumeric
cmp eax, 0
je lendProcessInput
mov eax, 8 ;; directions
mov edx, offset userInputDirection
call parseInputNumeric
cmp eax, 0
je lendProcessInput
lprocessInput:
call processParsedInput
lendProcessInput:
call resetInputs
ret
processInput endp
;; @param randomWords
;; @param userInputWord
;; @param userInputRow
;; @param userInputColumn
;; @param userInputDirection
processParsedInput proc uses ebx esi edi ebp
;; check if userInputWord exists in random words
mov eax, 0
mov ecx, count ;-> M
mov ebp, 0
mov esi, 0
lvalidateInputloop:
push ebp
mov ebp, lengthof rightAnswers ;-> N
sub ebp, ecx ; n - m
cmp esi, ebp
pop ebp
jnle lendValidateInputloop
mov edi, 0
lvalidateInputInnerloop:
cmp edi, ecx
jnl lendValidateInputInnerloop
mov bh, rightAnswers[esi][edi]
mov bl, userInput[edi]
cmp word ptr rightAnswers[esi][edi], 00a0dh
jne l1
inc ebp
l1:
cmp bl, bh
jne lendValidateInputInnerloop
inc edi
jmp lvalidateInputInnerloop
lendValidateInputInnerloop:
cmp edi, ecx ;; j == M
jne lcontinue
mov eax, 1
jmp lendValidateInputloop
lcontinue:
inc esi
jmp lvalidateInputloop
lendValidateInputloop:
mov ecx, 0 ;; use for output response offset
mov edx, 0 ;; use for output response length
cmp word ptr rightAnswers[esi][edi-2], 00a0dh
jne lwordNotFound
cmp byte ptr rightAnswers[esi][edi], 1
je lalreadyEntered
cmp eax, 1
jne lwordNotFound
jmp lendWordNotFound
lwordNotFound:
sub score, 10
mov ecx, offset userWrongInput
mov edx, lengthof userWrongInput
jmp lendRightInput
lendWordNotFound:
jmp lendAlreadyEntered
lalreadyEntered:
mov ecx, offset userAlreadyEnteredInput
mov edx, lengthof userAlreadyEnteredInput
jmp lendRightInput
lendAlreadyEntered:
lrightInput:
mov rightAnswers[esi][edi], 1
mov rightAnswered[ebp-1], 1
add score, 10
mov ecx, offset userRightInput
mov edx, lengthof userRightInput
lendRightInput:
mov responseMessageOffset, ecx
mov responseMessageCount, edx
call displayWelcomeAndScoreMessage
call displayRandomWords
call displayBoard
mov eax, 2
add eax, noOfRows
push eax
call displayBreakLines
add esp, 4
ret
processParsedInput endp
convertAndSaveScore proc uses eax ebx ecx esi ebp
mov eax, score
mov ebx, 10
mov cl, 0 ;; default positive number
mov esi, lengthof scoreMessage
sub esi, 2
lresetScoreMessage:
cmp esi, 0
jle lendResetScoreMessage
mov scoreMessage[esi], 0
dec esi
jmp lresetScoreMessage
lendResetScoreMessage:
cmp eax, 0
jnl notNegative
imul eax, eax, -1 ;; make number positive
mov cl, 1 ;; negative number
notNegative:
mov temp[0], 0
inc esi
lstart:
;; conversion loop
mov esi, 0
cmp eax, 0
jne lloop
mov temp[0], '0'
inc esi
lloop:
cmp eax, 0
je lendLoop
cdq
div ebx
add edx, '0'
mov temp[esi], dl
inc esi
jmp lloop
lendLoop:
;; conversion loop end
cmp cl, 1
jne lnotNegative1
mov byte ptr temp[esi], '-'
inc esi
lnotNegative1:
mov edx, lengthof scoreMessage
sub edx, esi
dec esi
;; insert in reverse loop
linsertLoop:
cmp esi, 0
jl lendInsertLoop
mov ah, temp[esi]
mov scoreMessage[edx], ah
inc edx
dec esi
jmp linsertLoop
lendInsertLoop:
;; insert in reverse loop end
lend:
ret
convertAndSaveScore endp
;; @param offset userInput -> edx
;; @param dword startIndex -> ecx
;; @param maxValue -> eax (al)
;; @return add no of bytes of numeric input in (offset userInput) -> aka ecx
parseInputNumeric proc uses ebx edx esi edi ebp
push eax
mov bl, userInput[ecx]
cmp bl, 32 ;; starting with space
je lerrorParseUserInputNumeric
cmp bl, 13 ;; enter (carriage return)
je lerrorParseUserInputNumeric
mov eax, 0
mov esi, 0
lloop:
mov bl, userInput[ecx]
cmp bl, 32 ;; space
je lendLoop
cmp bl, 13 ;; enter (carriage return)
je lendLoop
mov [edx], al
sub bl, '0'
add [edx], bl
mov eax, 10
mul byte ptr [edx]
;; validate if input is < maxValue (eax)
mov bl, [esp]
cmp [edx], bl
jae lerrorLengthParseUserInputNumeric
inc ecx
inc esi
jmp lloop
lendLoop:
add esp, 4
mov eax, 1
inc ecx
ret
lerrorLengthParseUserInputNumeric:
mov esi, offset userInputNumericLengthError
mov responseMessageOffset, esi
mov esi, lengthof userInputNumericLengthError
mov responseMessageCount, esi
jmp lendErrorParseUserInputNumeric
lerrorParseUserInputNumeric:
mov esi, offset userInputNumericError
mov responseMessageOffset, esi
mov esi, lengthof userInputNumericError
mov responseMessageCount, esi
lendErrorParseUserInputNumeric:
add esp, 4
mov eax, 0
ret
parseInputNumeric endp
;; @param userInput
;; @param count
parseInputWord proc uses ebx edx esi edi ebp
mov eax, 1
mov ecx, 0
mov bl, userInput[ecx]
cmp bl, 32 ;; starting with space
je lerrorParseUserInputWord
lloop:
cmp ecx, count
jge lendLoop
mov bl, userInput[ecx]
lparseUserInputWord:
cmp bl, 97
jnge notSmallAlpha
cmp bl, 122
jnle notSmallAlpha
jmp isAlpha
notSmallAlpha:
cmp bl, 65
jnge notAlpha
cmp bl, 90
jnle notAlpha
isAlpha:
cmp ecx, maxWordLength
jge lerrorLengthParseUserInputWord
jmp processAlpha
notAlpha:
cmp bl, 32 ;; is space
jne parseWordNotComplete ;; bl is not space also not alpha
parseWordLengthCheck:
cmp ecx, maxWordLength
jg lerrorLengthParseUserInputWord
parseWordComplete:
mov ebp, 0
;jmp lendParseUserInputWord
jmp lendLoop
parseWordNotComplete:
jmp lerrorParseUserInputWord
processAlpha:
cmp bl, 'a'
jnge notConvertToUpper
sub bl, 32
notConvertToUpper:
mov userInputWord[ecx], bl
mov userInput[ecx], bl
jmp lendParseUserInputLoop
lerrorLengthParseUserInputWord:
mov esi, offset userInputWordLengthError
mov responseMessageOffset, esi
mov esi, lengthof userInputWordLengthError
mov responseMessageCount, esi
jmp lendErrorParseUserInputWord
lerrorParseUserInputWord:
mov esi, offset userInputWordError
mov responseMessageOffset, esi
mov esi, lengthof userInputWordError
mov responseMessageCount, esi
lendErrorParseUserInputWord:
mov eax, 0
jmp lendLoop
lendParseUserInputWord:
lendParseUserInputLoop:
inc ecx
jmp lloop
lendLoop:
mov userInputWordCount, cl
inc ecx
ret
parseInputWord endp
resetInputs proc uses ecx
mov ecx, lengthof userInput
lloop1:
mov userInput[ecx-1], 0
loop lloop1
mov ecx, lengthof userInputWord
lloop2:
mov userInputWord[ecx-1], 0
loop lloop2
mov userInputRow, 0
mov userInputColumn, 0
mov userInputDirection, 0
ret
resetInputs endp
;; @param offset board
insertRandomCharactersInBoard proc uses eax ebx ecx edx
mov eax, noOfRows
mul noOfColumns
mov ecx, eax
dec ecx
mov ebx, [esp+20]
lloop:
cmp ecx, 0
jl lendLoop
mov al, [ebx][ecx]
cmp al, 0
jne lcontinue
mov eax, 25
call generaterandom
add al, 65
mov [ebx][ecx], al
lcontinue:
dec ecx
jmp lloop
lendLoop:
ret
insertRandomCharactersInBoard endp
;; @return ebx -> random column no [0,7]
generateRandomDirection proc uses eax
;; 0 -> Left
;; 1 -> Left Up
;; 2 -> Up
;; 3 -> Up Right
;; 4 -> Right
;; 5 -> Right Down
;; 6 -> Down
;; 7 -> Down Left
mov eax, 7
call generaterandom
mov ebx, eax ;; COLUMN
ret
generateRandomDirection endp
;; @return esi -> random column no [0,14]
;; @return edi -> random row no [0,14]
generateRandomPosition proc uses eax
mov eax, noOfRows
call generaterandom
mov esi, eax ;; COLUMN
mov eax, noOfColumns
call generaterandom
mov edi, eax ;; ROW
ret
generateRandomPosition endp
;; @param offset file
;; @param dword noOfWordsToGenerate
;; @param offset randomWords
generateRandomWords proc uses eax ebx ecx edx esi edi
mov edi, [esp+28]
mov eax, [esp+36] ;; offset filepath
invoke CreateFileA, eax, 1, 0, 0, 3, 128, 0 ;; 3 for already created file
;; eax => handler
invoke ReadFile, eax, offset buffer, lengthof buffer, offset count, 0
mov esi, 0
lloop:
cmp esi, [esp+32]
jge lendLoop
mov eax, count
sub eax, 12
call generaterandom
;; Read the next word from random number
lsubLoop:
mov bx, word ptr buffer[eax] ;; some random error here -> check it, possibly because of file
cmp bx, 00a0dh ;; if 'enter'
je lendSubLoop
inc eax
jmp lsubLoop
lendSubLoop:
add eax, 2
linsertWordLoop:
mov bx, word ptr buffer[eax]
mov [edi], bx
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
;; conversion to uppercase
cmp bl, 'a'
jnge lcontinue
sub bl, 32
mov [edi], bx
lcontinue:
inc edi
inc eax
jmp linsertWordLoop
lendInsertWordLoop:
add edi, 2
inc esi
jmp lloop
lendLoop:
ret
generateRandomWords endp
; Generate a random number in the range [0, n-1]
; Expect one parameter that is 'n' in EAX
; returns random number in EAX
; seed is a dword type variable global variable initialized with positive number
; (It’s not a good practice though to use global variables inside the procedure)
generaterandom proc uses ebx edx
mov ebx, eax ; maximum value
mov eax, 343FDh
imul seed
add eax, 269EC3h
mov seed, eax ; save the seed for the next call
ror eax,8 ; rotate out the lowest digit
mov edx,0
div ebx ; divide by max value
mov eax, edx ; return the remainder
ret
generaterandom endp
;; @param offset randomWords
;; @param dword noOfWordsToInsert OR countRandomWords
;; @param offset board
;; @param spaces
insertRandomWordsInBoard proc uses eax ebx ecx edx esi edi ebp
mov ecx, [esp+36]
mov edx, 0
mov ebp, 1
lloop:
cmp ebp, [esp+40]
ja lendLoop
mov eax, 0
lcountLengthWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCountLengthWordLoop
inc ecx
inc eax
jmp lcountLengthWordLoop
lendCountLengthWordLoop:
sub ecx, eax
push eax
jmp lnotAgain
lagain:
add esp, 16
lnotAgain:
call generateRandomDirection
call generateRandomPosition
push [esp+40] ;; offset board
push [esp+36] ;; spaces
push ecx ;; offset wordToInsert
push [esp+12] ;; count wordToInsert
;mov ebx, 0
cmp ebx, 0
jne lpoint1
;; Left
call handleLeftInsertRandomWordsInBoard
jmp lcheckPoint
lpoint1:
cmp ebx, 1
jne lpoint2
;; Left Up
call handleLeftUpInsertRandomWordsInBoard
jmp lcheckPoint
lpoint2:
cmp ebx, 2
jne lpoint3
;; Up
call handleUpInsertRandomWordsInBoard
jmp lcheckPoint
lpoint3:
cmp ebx, 3
jne lpoint4
;; Up Right
call handleUpRightInsertRandomWordsInBoard
jmp lcheckPoint
lpoint4:
cmp ebx, 4
jne lpoint5
;; Right
call handleRightInsertRandomWordsInBoard
jmp lcheckPoint
lpoint5:
cmp ebx, 5
jne lpoint6
;; Right Down
call handleRightDownInsertRandomWordsInBoard
jmp lcheckPoint
lpoint6:
cmp ebx, 6
jne lpoint7
;; Down
call handleDownInsertRandomWordsInBoard
jmp lcheckPoint
lpoint7:
cmp ebx, 7
jne lcheckPoint
;; Down Left
call handleDownLeftInsertRandomWordsInBoard
lcheckPoint:
cmp eax, 1
jne lagain
push ebx
linsertRightAnswerLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertRightAnswerLoop
mov rightAnswers[edx], bl
inc ecx
inc edx
jmp linsertRightAnswerLoop
lendInsertRightAnswerLoop:
pop ebx
mov rightAnswers[edx], ' '
inc edx
mov ecx, esi
call convertIntToString
mov rightAnswers[edx], ' '
inc edx
mov ecx, edi
call convertIntToString
mov rightAnswers[edx], ' '
inc edx
mov ecx, ebx
call convertIntToString
mov word ptr rightAnswers[edx], 00a0dh
add edx, 3
pop eax
pop ecx
add ecx, eax
add ecx, 2
add esp, 12
inc ebp
jmp lloop
lendLoop:
ret
insertRandomWordsInBoard endp
; @param number -> ecx
; @param offset scale rightAnswers -> edx
convertIntToString proc uses eax ebx ecx esi ebp
mov ebp, edx
mov eax, ecx
mov bl, 10
cmp eax, 0
jne lstart
mov rightAnswers[edx], '0'
inc edx
jmp lend
lstart:
;; conversion loop
mov esi, 0
lloop:
cmp al, 0
je lendLoop
cbw
div bl
add ah, '0'
mov temp[esi], ah
inc esi
jmp lloop
lendLoop:
;; conversion loop end
dec esi
;; insert in reverse loop
linsertLoop:
cmp esi, 0
jl lendInsertLoop
mov ah, temp[esi]
mov rightAnswers[edx], ah
inc edx
dec esi
jmp linsertLoop
lendInsertLoop:
;; insert in reverse loop end
lend:
ret
convertIntToString endp
; @param dword offset board
; @param dword spaces
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword row -> esi
; @param dword column -> edi
handleLeftInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, edi
sub ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, 0
jge lcheckPoint
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
dec edi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
dec edi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleLeftInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword column
; @param dword row -> esi
; @param dword column -> edi
handleLeftUpInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, edi
sub ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, 0
jnge lfailPoint
mov ecx, esi
sub ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, 0
jge lcheckPoint
lfailPoint:
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
dec esi
dec edi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
dec esi
dec edi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleLeftUpInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword row -> esi
; @param dword column -> edi
handleUpInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, esi
sub ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, 0
jge lcheckPoint
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
dec esi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
dec esi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleUpInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword row -> esi
; @param dword column -> edi
handleUpRightInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, edi
add ecx, [esp+28] ;; add (count wordToInsert)
cmp ecx, noOfRows
jnl lfailPoint
mov ecx, esi
sub ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, 0
jge lcheckPoint
lfailPoint:
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
dec esi
inc edi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
dec esi
inc edi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleUpRightInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword row -> esi
; @param dword column -> edi
handleRightInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, edi
add ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, noOfRows
jl lcheckPoint
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
inc edi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
inc edi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleRightInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword row -> esi
; @param dword column -> edi
handleRightDownInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, edi
add ecx, [esp+28] ;; add (count wordToInsert)
cmp ecx, noOfRows
jnl lfailPoint
mov ecx, esi
add ecx, [esp+28] ;; add (count wordToInsert)
cmp ecx, noOfRows
jl lcheckPoint
lfailPoint:
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
inc esi
inc edi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
inc esi
inc edi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleRightDownInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword row -> esi
; @param dword column -> edi
handleDownInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, esi
add ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, noOfRows
jl lcheckPoint
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
inc esi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
inc esi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleDownInsertRandomWordsInBoard endp
; @param dword offset wordToInsert
; @param dword count wordToInsert
; @param dword offset board
; @param dword spaces
; @param dword row -> esi
; @param dword column -> edi
handleDownLeftInsertRandomWordsInBoard proc uses ebx ecx edx esi edi ebp
mov ecx, edi
sub ecx, [esp+28] ;; subtract (count wordToInsert)
cmp ecx, 0
jnge lfailPoint
mov ecx, esi
add ecx, [esp+28] ;; add (count wordToInsert)
cmp ecx, noOfRows
jl lcheckPoint
lfailPoint:
mov eax, 0
ret
lcheckPoint:
;; Validate no of spaces in board
mov ecx, [esp+32]
push esi
push edi
lcheckSpaceWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendCheckSpaceWordLoop
mov eax, esi
mul noOfRows
add eax, edi
cmp board[eax], bl
je lpassCheckSpaceWordLoop
cmp board[eax], 0
jne lfailCheckSpaceWordLoop
jmp lpassCheckSpaceWordLoop
lfailCheckSpaceWordLoop:
mov eax, 0
add esp, 8
ret
lpassCheckSpaceWordLoop:
inc esi
dec edi
inc ecx
jmp lcheckSpaceWordLoop
lendCheckSpaceWordLoop:
pop edi
pop esi
mov ecx, [esp+32]
linsertWordLoop:
mov bx, word ptr [ecx]
cmp bx, 00a0dh ;; if 'enter'
je lendInsertWordLoop
mov eax, esi
mul noOfRows
add eax, edi
mov board[eax], bl
mov ebx, ebp
mov tempBoard[eax], bl
inc esi
dec edi
inc ecx
jmp linsertWordLoop
lendInsertWordLoop:
mov eax, 1
ret
handleDownLeftInsertRandomWordsInBoard endp
end main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment