Reputation: 33
So I am making a typing game, where the word drops down the screen and the user has to type the word before it reaches the bottom of the screen. My code has where if the user types the correct character, it prints it in green and over the original word. Then if the user types the incorrect character, it prints it in red and also over original word but the user has to type the right character for them to continue. The issue I am having is that the incorrect character does display correctly.
include Irvine32.inc
BUFMAX EQU 128
.data
Words BYTE "house", 0
BYTE "water", 0
BYTE "foods", 0
BYTE "apple", 0
BYTE "cloud", 0 ; List of words to be typed
msElapsed BYTE 0
positionX BYTE 0
positionY BYTE 1
nextWord DWORD 0
score DWORD 0
scoreMsg BYTE "Game Over", 0
char BYTE ? ; Character input by user
correctBuffer BYTE BUFMAX DUP (0) ; Buffer to store correctly typed characters
incorrectBuffer BYTE BUFMAX DUP (0)
Index DWORD 0
.code
main PROC
call TypingGame
invoke ExitProcess, 0
main ENDP
TypingGame PROC
gameLoop:
mov dl, positionX ; Move positionX value to DL register
mov dh, positionY ; Move positionY value to DH register
call Gotoxy ; Move cursor to the specified (X, Y) position
; Print the original word in white
mov eax, white + (black * 16) ; Set text color to white on black background
call SetTextColor ; Apply the text color
mov edx, OFFSET Words ; Load address of Words array into ESI
add edx, [nextWord]
call WriteString ; Print the current word
; Draw the correctly typed characters in green over the original word
mov dl, positionX
mov dh, positionY
call Gotoxy
mov eax, green + (black * 16) ; Set text color to green on black background
call SetTextColor
mov edx, OFFSET correctBuffer ; Load address of correctBuffer into EDX
call WriteString ; Print the correctBuffer string
; Draw the incorrectly typed characters in red over the original word
mov dl, positionX
mov dh, positionY
call Gotoxy
mov eax, red + (black * 16) ; Set text color to red on black background
call SetTextColor
mov edx, OFFSET incorrectBuffer ; Load address of incorrectBuffer into EDX
call WriteString ; Print the incorrectBuffer string
; Set delay for inputs
mov eax, 50
add [msElapsed], 1
call Delay
call ReadKey ; Read a key from the keyboard
jz continueLoop
mov char, al ; Store the read character in char
mov esi, OFFSET Words ; Load address of Words array into ESI
add esi, [nextWord]
add esi, [Index] ; Add Index value to ESI to point to the current character
movzx ebx, char ; Move char to EBX and zero-extend it
cmp [esi], bl ; Compare current character in Words with char
jne incorrect ; If they are not equal, jump to incorrect
correct:
mov esi, OFFSET correctBuffer ; Load address of correctBuffer into ESI
add esi, [Index] ; Add Index value to ESI to point to the correct position
mov [esi], bl ; Store the correct character in correctBuffer
inc esi
mov BYTE PTR [esi], 0 ; Null-terminate the correct buffer
inc [Index] ; Increment the Index
; Compare Index with the end of the current word
mov esi, OFFSET Words
add esi, [nextWord]
add esi, [Index]
cmp BYTE PTR [esi], 0
jne continueLoop ; If not the end, continue the loop
; If a word is completed, reset index and move to the next word
mov [Index], 0
add [nextWord], TYPE BYTE ; Move to next word
mov [positionX], 0 ; Reset X
mov [positionY], 0 ; Reset Y
jl gameLoop ; If positionY is less than 24, jump to gameLoop
jmp endGame ; Otherwise, jump to endGame
incorrect:
; Store the incorrect character in incorrectBuffer
mov esi, OFFSET incorrectBuffer ; Load address of incorrectBuffer into ESI
add esi, [Index] ; Add index to incorrectBuffer position
mov [esi], bl ; Store the incorrect character
inc esi
mov BYTE PTR [esi], 0 ; Null-terminate the incorrect buffer
; Move cursor to the correct position for the incorrect character
mov dl, positionX
movzx eax, BYTE PTR [Index]
add dl, al
mov dh, positionY
call Gotoxy
mov eax, red + (black * 16) ; Set text color to red on black background
call SetTextColor ; Apply the text color
mov al, char ; Move the incorrect character to AL
call WriteChar ; Print the incorrect character
inc [Index] ; Increment the Index
jmp continueLoop ; Jump to continueLoop
continueLoop:
; Clear previous word
mov dl, positionX ; Move positionX value to DL register
mov dh, [positionY] ; Move positionY value to DH register
call Gotoxy ; Move cursor to the specified (X, Y) position
; Print the original word in black
mov eax, black + (black * 16) ; Set text color to black on black background
call SetTextColor ; Apply the text color
mov edx, OFFSET Words ; Load address of Words array into ESI
add edx, [nextWord] ; 1
call WriteString ; Print the current word
cmp [msElapsed], 20
jl skipIncrement ; Do not increase y if not 1000ms (1 sec)
add [positionY], 1 ; Increment the Y position
mov [msElapsed], 0 ; Reset ms counter
skipIncrement:
cmp [positionY], 24 ; Compare positionY with 24
jl gameLoop ; If positionY is less than 24, jump to gameLoop
jmp endGame ; Otherwise, jump to endGame
endGame:
call Clrscr ; Clear the screen
mov edx, OFFSET scoreMsg ; Load address of scoreMsg into EDX
call WriteString ; Print the score message
ret ; Return from procedure
TypingGame ENDP
END main
I tried adding a delay in the incorrect loop but the character disappears after the delay ends. Also even if the delay is added, when the user wants to enter the right character to continue, the wrong character stays when it should disappear. I would greatly appreciate it if you can help me out. Thank you so much!
Upvotes: 1
Views: 64
Reputation: 39166
the user has to type the right character for them to continue.
This is an important piece of information. It immediately entails that the incorrectBuffer will never have to store more than one character (plus a terminating zero).
Currently you are storing the incorrect character at an indexed location within the incorrectBuffer. Consider what happens for the word "house" when the user types h followed by the incorrect z.
words: h, o, u, s, e, 0, ...
correctBuffer: h, 0, 0, 0, ...
incorrectBuffer: 0, z, 0, 0, ...
^
\ you have stored "z" at an indexed location (index=1)
The screen refresh logic that you have at the top of your gameLoop will first draw the whole word in white, then overwrite the "h" in green, and finally overwrite nothing at all in red because the incorrectBuffer begins with a terminating zero!
The solution is to store the incorrect character at the start of your (small) incorrectBuffer, and to not use Gotoxy
in the screen refresh logic when switching from outputting in green to red.
Hint: every time a correct character arrives, you should write a zero at the start of the incorrectBuffer.
Future problems:
; If a word is completed, reset index and move to the next word mov [Index], 0 add [nextWord], TYPE BYTE ; Move to next word mov [positionX], 0 ; Reset X mov [positionY], 0 ; Reset Y jl gameLoop ; If positionY is less than 24, jump to gameLoop jmp endGame ; Otherwise, jump to endGame
TYPE BYTE
will not allow you to move to the next word! Since all your zero-terminated words have 5 characters, just write add nextword, 6
.jl gameLoop
instruction should read jmp gameLoop
.Upvotes: 1