| ECE 291 | Computer Engineering II | Lockwood, Fall 1998 |
| Assigned | Tuesday 9/8/98 |
| Due Date | Wednesday 9/17/98 |
| Purpose | Loops, Array manipulation |
| Points | 50 |
For this machine problem, you will write the algorithm to automate the game of 'Word Find'. This type of game, typically found in newspaper or a TV guide, requires locating words in a matrix of letters. Words may appear in any direction, and (for this game) may even wrap around the edges.
Your code, if written properly, should be able to locate a word in such a game in a sub-millisecond, and thus easily beat any human player. As an optimized assembly-language program, the fastests program written for this class will become known as 'Deep 291'.
(OrigMatrix) for the first letter
of the word that you specify. Once a matching first letter is
found, calls are made to check the entire word in all four directions
(right, down, left, and up). When an entire word is found that matches,
the replace routine is called to copy that word from
OrigMatrix to EndMatrix. The
PrintMatrix routine is called to print the resulting
EndMatrix after all searches have completed.
The word to search for is entered on the command line.
If you want to search for ECE291, for example, type MP1 ECE291.
A sample run from the program is shown below:
W:\MP1>MP1 ECE291 ------------- Original matrix ------------ EHUBBELQMI TI9ABCPUSS ADUSLEAAAT LDPSE2TKME LECE291EER LNHMK1UKTA ADDBINARYM CAILLIX3BU COLYLDOOWK OOEDIVHEXR MOODNIBBLE MENTIMESEG -------------- Final matrix -------------- .....E.... .....C.... .....E.... .....2.... .ECE291... .....1.... .......... .......... .......... .......... .......... .......... LIBMP1 Ver 1.0 Calls: -PrintMatrix -CheckLetter -CheckUp -CheckDown -ReplaceDown -CheckLeft -CheckRight -ReplaceRight |
Run the program a few times to learn how it operates. Try searching for other words like: 'BINARY', 'NIBBLE', 'SEGMENT', 'VIDEO', 'REGISTER', and the number '9' (case matters). Note that words my wrap around the matrix. Also note that multiple words are found if they appear more than once.
Next, look through the given source code and rebuild
the executable from source code by typing
NMAKE CLEAN then NMAKE.
Now run
the program under CodeView. Choose your search word
by a click to open the (R)un menu then (S)et Runtime Arguments.
Step through the code
as you did in MP1. Use the function keys to trace (F8) through
your code, step (F10) over library calls, and go (F5) between breakpoints.
Review MP0 if you need help with CodeView.
This assignment has eighteen procedures. You will receive credit by replacing each of these eighteen procedures listed below with your own code.
origMatrix (an offset from the beginning)
offset origMatrix
or to offset EndMatrix before the routine
is called).
origMatrix
from that position to see if the entire word is a match
in the direction given.
; Word Search Data File
; (Feel free to invent your own test cases as well)
; Your program must work for arbitrary data.
NumRows EQU 12
NumCols EQU 10
OrigMatrix db 'EHUBBELQMI',
'TI9ABCPUSS',
'ADUSLEAAAT',
'LDPSE2TKME',
'LECE291EER',
'LNHMK1UKTA',
'ADDBINARYM',
'CAILLIX3BU',
'COLYLDOOWK',
'OOEDIVHEXR',
'MOODNIBBLE',
'MENTIMESEG'
PAGE 75, 132
TITLE Deep291 - Your Name - Current Date
COMMENT %
WordFind
--------------------
ECE291: MP1 - Deep 291
Prof. John W. Lockwood
Unversity of Illinois, Dept. of Electrical & Computer Engineering
Assistant Guest Authors: Pat Spizzo, Neil Kumar
Fall 1998
Revision 1.0
%
;====== Constants =========================================================
CR EQU 13
LF EQU 10
;====== Externals =========================================================
; -- LIB291 Routines (free) --
extrn dspout:near ; See your lab manual for a full description
extrn dspmsg:near ; of the ECE291 lib291 functions
extrn dosxit:near ; Quit to DOS
; -- LIB291 Routines (free) --
extrn mp1xit:near ; Terminate MP1
;====== Stack Segment =====================================================
stkseg segment stack
db 64 dup ('STACK ')
stkseg ends
;====== Code/Data segment =================================================
cseg segment public 'CODE'
assume cs:cseg, ds:cseg, ss:stkseg, es:nothing
;====== Variables =========================================================
INCLUDE wordfile.asm ; Define NumRows & NumCols; Create OrigMatrix
EndMatrix db NumRows*NumCols dup ('.')
RowSize dw NumRows
ColSize dw NumCols
CommandErrorMessage db 'Usage: mp1 WordToFind',CR,LF,'$'
StartMessage db '------------- Original matrix ------------',CR,LF,'$'
EndMessage db '-------------- Final matrix --------------',CR,LF,'$'
crlf db CR,LF,'$' ; Carriage Return / Line Feed String
WordLength dw ? ; Length of search word
RowPos dw ?
ColPos dw ?
offsetPos dw ?
PUBLIC OrigMatrix,RowSize,ColSize,EndMatrix ; Variables visible to LIBMP1
PUBLIC WordLength,RowPos,ColPos,offsetPos ;
; ======== Your Code ======================================================
; -- Write the code for your subroutines below --
; To use your own code,
; comment out the 'extrn' routine from above and
; uncomment your procedure declaration
extrn PrintMatrix:near
; Inputs:
; si = index to matrix to print
; PrintMatrix proc NEAR
; For all letters in origMatrix {
; ..
; MOV DL,[si]
; ..
; Print character to screen
; ..
; }
; PrintMatrix ENDP
extrn CheckLetter:near
; Inputs:
; offsetPos = position of letter in OrigMatrix to check
; Outputs:
; zf = zero if letter matches
; zf = one if letter does not match
extrn CheckRight:near
; Inputs:
; offsetPos = RowPos*NumCols + ColPos
; RowPos = current row position
; ColPos = current column position
; WordLength = length of word to find
; Outputs
; zf = zero if word matches
; zf = one if any letter mismatches
extrn ReplaceRight:near
; Inputs:
; offsetPos = RowPos*NumCols + ColPos
; RowPos = current row position
; ColPos = current column position
; WordLength = length of word to find
; Output
; EndMatrix
extrn CheckDown:near
; Inputs/Ouputs: Same as CheckRight
extrn ReplaceDown:near
; Inputs/Ouputs: Same as ReplaceRight
; Remaining Directions..
extrn CheckLeft:near
extrn ReplaceLeft:near
extrn CheckUp:near
extrn ReplaceUp:near
;====== Main procedure ====================================================
main proc far
; The Main body of the program parses the command
; line and invokes each subroutine. You are given this code.
; Command line arguments can be set in Codeview
; by selecting the (R)un menu, then (S)et args.
mov ax, ds ; DOS reads command line arguments from the PSP
mov es, ax ; (See: Hyde, Section 13.3.11 for details)
mov ax, cseg
mov ds, ax ; set DS=CS
mov cl, byte ptr es:[80h] ; Read Length of Command Line
cmp cl, 1
jbe CommandLineError ; Terminate program for no input
mov ch,0
dec CX
mov SI,0
CheckNextArgumentLetter:
CMP BYTE PTR ES:[82h+SI],' '
JE CommandLineDone ; Determine length of first argument
INC SI ; by scanning for a space
LOOP CheckNextArgumentLetter
CommandLineDone: ; Start MP0
mov WordLength,SI
mov dx, offset StartMessage
call dspmsg
mov si, offset OrigMatrix
call PrintMatrix
mov offsetPos, 0 ; Start scanning at top-left
mov RowPos, 0 ; corner of OrigMatrix.
mov ColPos, 0
LetterScanLoop:
call CheckLetter
jne ProcessNextLetter
; First Letter matches, now check for word match in all four directions
call CheckRight ; Scan for words going right
jne RightChecked
call ReplaceRight ; Copy word to EndMatrix if it matches
RightChecked:
call CheckDown ; Scan for words going down
jne DownChecked
call ReplaceDown
DownChecked:
call CheckLeft ; Scan for words going right
jne LeftChecked
call ReplaceLeft
LeftChecked:
call CheckUp
jne UpChecked ; Scan for words going up
call ReplaceUp
UpChecked:
ProcessNextLetter:
inc offsetPos ; advance to next position
inc ColPos ; advance to next column
cmp ColPos, NumCols
jb LetterScanLoop
ProcessNextRow:
mov ColPos,0
inc RowPos ; advance to next row
cmp RowPos, NumRows
jb LetterScanLoop
; Search has completed
mov dx, offset CRLF
call dspmsg
mov dx, offset EndMessage
call dspmsg
mov si, offset EndMatrix
call PrintMatrix
call mp1xit
commandLineError:
mov dx, offset CommandErrorMessage
call dspmsg
; Print Error message and quit if program isn't
; called with command line argument
call dosxit
main endp
cseg ends
end main