Compare commits

...

2 Commits

Author SHA1 Message Date
Juhani Krekelä a90e026623 Implement hard mode 2022-02-25 01:26:18 +02:00
Juhani Krekelä 7af168618c Add command line parsing 2022-02-25 01:05:50 +02:00
1 changed files with 181 additions and 10 deletions

191
dosdl.asm
View File

@ -9,9 +9,60 @@ args_area equ 0x81
section .code
parse_arguments:
; TODO: Implement argument parsing
xor ch, ch
mov cl, [args_length]
mov si, args_area
; Skip leading spaces
.skip_leading_space:
test cx, cx
jz .leading_spaces_skipped
cmp byte [si], ' '
jne .leading_spaces_skipped
dec cx
inc si
jmp .skip_leading_space
.leading_spaces_skipped:
; See whether we have /h or /u
cmp cx, 2
jb .not_mode_option
cmp byte [si], '/'
jne .not_mode_option
cmp byte [si + 1], 'h'
jne .not_hard_mode
.hard_mode:
mov byte [hard_mode], 1
add si, 2
sub cx, 2
jmp .after_option_space
.not_hard_mode:
cmp byte [si + 1], 'u'
jne .not_ultra_hard_mode
.ultra_hard_mode:
mov byte [hard_mode], 1
mov byte [ultra_hard_mode], 1
add si, 2
sub cx, 2
.after_option_space:
test cx, cx
jz .option_done
cmp byte [si], ' '
jne .option_done
dec cx
inc si
jmp .after_option_space
.option_done:
.not_ultra_hard_mode:
.not_mode_option:
test cx, cx
jz seed_rng_date
@ -29,6 +80,11 @@ seed_rng_date:
int 0x21
mov [year], cx
mov [month], dh
%ifdef DEBUG
mov cx, 2022
mov dh, 2
mov dl, 24
%endif
mov [day], dl
; addl32 = year * 10000
@ -160,6 +216,98 @@ read_guess:
.done:
check_hard_mode:
cmp byte [hard_mode], 1
jne .done
; See whether exact hits are reused
xor bp, bp
mov cx, 5
.exact_hits:
mov al, [exact_hits + bp]
test al, al
jz .not_exact_hit
cmp al, [guess + bp]
je .exact_hit_match
mov dx, bp
add dl, '1'
mov [exact_hit_error_str.position], dl
mov [exact_hit_error_str.letter], al
mov si, exact_hit_error_str
jmp print_error
.exact_hit_match:
.not_exact_hit:
inc bp
loop .exact_hits
; See whether wrongly placed letters are reused
xor bp, bp
.wrong_places:
cmp bp, 5
je .done
mov dl, [wrong_places + bp]
test dl, dl
jz .not_wrong_place
; Count how many times letter is used in exact_hits + wrong_places
xor bx, bx
mov cx, 5
mov si, exact_hits
.count_exact_hits:
lodsb
cmp al, dl
jne .not_count_exact_hit
inc bh
.not_count_exact_hit:
loop .count_exact_hits
mov cx, 5
mov si, wrong_places
.count_wrong_places:
lodsb
cmp al, dl
jne .not_count_wrong_places
inc bh
.not_count_wrong_places:
loop .count_wrong_places
; Count how many times letter is used in guess
mov cx, 5
mov si, guess
.count_guess:
lodsb
cmp al, dl
jne .not_count_guess
inc bl
.not_count_guess:
loop .count_guess
cmp bl, bh
jae .used_enough
mov [wrong_place_error_str.letter], dl
mov ax, bp
add ax, '1'
mov [wrong_place_error_str.position], al
mov si, wrong_place_error_str
jmp print_error
.used_enough:
.not_wrong_place:
inc bp
jmp .wrong_places
.done:
check_ultra_hard_mode:
cmp byte [ultra_hard_mode], 1
jne .done
.done:
check_dictionary:
; Dictionary is split by initial letter
xor bx, bx
@ -243,10 +391,11 @@ check_targets:
loop .targets_loop
word_not_found:
mov si, not_found_str
print_error:
mov ah, 9
mov dx, space_dash_space_str
int 0x21
mov dx, not_found_str
mov dx, si
int 0x21
; Wait for a keypress
@ -262,7 +411,6 @@ word_not_found:
mov dx, erase_word_str
int 0x21
mov si, not_found_str
.clear_loop:
lodsb
cmp al, '$'
@ -274,7 +422,7 @@ word_not_found:
jmp .clear_loop
.done:
.done:
mov ah, 2
mov dl, 13
@ -780,6 +928,9 @@ guesses db 0
dictionary_entry times 5 db 0
hard_mode db 0
ultra_hard_mode db 0
rng_seed dd 0
rng_t dd 0
@ -794,14 +945,27 @@ addr32 dd 0
year dw 0
month dw 0
day db 0
day dw 0
exact_hit_error_str:
db ' - letter at position '
.position db '#'
db " must be '"
.letter db '#'
db "'$"
wrong_place_error_str:
db " - letter '"
.letter db '#'
db "' from position "
.position db '#'
db ' must be reused$'
section .rodata
greeting_str db 'Welcome to hello DOSdl. Run `dosdl /?` for help.', 13, 10, '$'
space_dash_space_str db ' - $'
not_found_str db 'word not found$'
not_found_str db ' - word not found$'
erase_word_str db ' $'
word_was_str db 'The word was: $'
correct_in_str db 'Correct in $'
@ -809,7 +973,9 @@ guesses_str db ' guesses.$'
guess_str db ' guess.$'
help_str:
db 'Usage: dosdl', 13, 10
db 'Usage: dosdl [/h | /u]', 13, 10
db '/h Enable hard mode.', 13, 10
db '/u Enable ultra hard mode.', 13, 10
db 13, 10
db 'Hello DOSdl is a word guessing game. You have six tries to guess the correct', 13, 10
db 'English word. After a guess the game displays feedback under each letter:', 13, 10
@ -820,7 +986,12 @@ help_str:
db ' above cases.', 13, 10
db 13, 10
db 'After the feedback, the game shows a list of letters that have not yet been', 13, 10
db 'ruled out.$'
db 'ruled out.', 13, 10
db 13, 10
db 'In hard mode all letters marked as being in the correct place must stay fixed', 13, 10
db 'and those marked as being in the wrong place must be reused. In ultra hard mode', 13, 10
db 'letters marked as being in the wrong place must also be moved and letters not', 13, 10
db 'in the word must not be played again.$'
%include "dictionary.inc"
%include "targets.inc"