Найти тему
vcLive

Игра для vcOS

; ------------------------------------------------------------------

; hangman.asm vcOS NASM

;https://www.youtube.com/channel/UCEZI4ZzVDWTg_ytg0iKYFGA

BITS 16

%INCLUDE "vcdev.inc"

ORG 32768

start:

call os_hide_cursor

; First, reset values in case user is playing multiple games

mov di, real_string ; Full city name

mov al, 0

mov cx, 50

rep stosb

mov di, work_string ; String that starts as '_' characters

mov al, 0

mov cx, 50

rep stosb

mov di, tried_chars ; Chars the user has tried, but aren't in the real string

mov al, 0

mov cx, 255

rep stosb

mov byte [tried_chars_pos], 0

mov byte [misses], 1 ; First miss is to show the platform

mov ax, title_msg ; Set up the screen

mov bx, footer_msg

mov cx, 01100000b

call os_draw_background

mov ax, 0

mov bx, 255

call os_get_random ; Get a random number

mov bl, cl ; Store in BL

mov si, cities ; Skip number of lines stored in BL

skip_loop:

cmp bl, 0

je skip_finished

dec bl

.inner:

lodsb ; Find a zero to denote end of line

cmp al, 0

jne .inner

jmp skip_loop

skip_finished:

mov di, real_string ; Store the string from the city list

call os_string_copy

mov ax, si

call os_string_length

mov dx, ax ; DX = number of '_' characters to show

call add_underscores

cmp dx, 5 ; Give first char if it's a short string

ja no_hint

mov ax, hint_msg_1 ; Tell player about the hint

mov bx, hint_msg_2

mov cx, 0

mov dx, 0

call os_dialog_box

call os_hide_cursor

mov ax, title_msg ; Redraw screen

mov bx, footer_msg

mov cx, 01100000b

call os_draw_background

mov byte al, [real_string] ; Copy first letter over

mov byte [work_string], al

no_hint:

call fix_spaces ; Add spaces to working string if necessary

main_loop:

call show_tried_chars ; Update screen areas

call show_hangman

call show_main_box

cmp byte [misses], 11 ; See if the player has lost

je lost_game

call os_wait_for_key ; Get input

cmp al, KEY_ESC

je finish

cmp al, 122 ; Work with just "a" to "z" keys

ja main_loop

cmp al, 97

jb main_loop

mov bl, al ; Store character temporarily

mov cx, 0 ; Counter into string

mov dl, 0 ; Flag whether char was found

mov si, real_string

find_loop:

lodsb

cmp al, 0 ; End of string?

je done_find

cmp al, bl ; Find char entered in string

je found_char

inc cx ; Move on to next character

jmp find_loop

found_char:

inc dl ; Note that at least one char match was found

mov di, work_string

add di, cx ; Update our underscore string with char found

mov byte [di], bl

inc cx

jmp find_loop

done_find:

mov si, real_string ; If the strings match, the player has won!

mov di, work_string

call os_string_compare

jc won_game

cmp dl, 0 ; If char was found, skip next bit

jne main_loop

call update_tried_chars ; Otherwise add char to list of misses

jmp main_loop

won_game:

call show_win_msg

.loop:

call os_wait_for_key ; Wait for keypress

cmp al, KEY_ESC

je finish

cmp al, KEY_ENTER

jne .loop

jmp start

lost_game: ; After too many misses...

call show_lose_msg

.loop: ; Wait for keypress

call os_wait_for_key

cmp al, KEY_ESC

je finish

cmp al, KEY_ENTER

jne .loop

jmp start

finish:

call os_show_cursor

call os_clear_screen

ret

add_underscores: ; Create string of underscores

mov di, work_string

mov al, '_'

mov cx, dx ; Size of string

rep stosb

ret

; Copy any spaces from the real string into the work string

fix_spaces:

mov si, real_string

mov di, work_string

.loop:

lodsb

cmp al, 0

je .done

cmp al, ' '

jne .no_space

mov byte [di], ' '

.no_space:

inc di

jmp .loop

.done:

ret

; Here we check the list of wrong chars that the player entered previously,

; and see if the latest addition is already in there...

update_tried_chars:

mov si, tried_chars

mov al, bl

call os_find_char_in_string

cmp ax, 0

jne .nothing_to_add ; Skip next bit if char was already in list

mov si, tried_chars

mov ax, 0

mov byte al, [tried_chars_pos] ; Move into the list

add si, ax

mov byte [si], bl

inc byte [tried_chars_pos]

inc byte [misses] ; Knock up the score

.nothing_to_add:

ret

show_main_box:

pusha

mov bl, BLACK_ON_WHITE

mov dh, 5

mov dl, 2

mov si, 36

mov di, 21

call os_draw_block

mov dh, 7

mov dl, 4

call os_move_cursor

mov si, help_msg_1

call os_print_string

mov dh, 8

mov dl, 4

call os_move_cursor

mov si, help_msg_2

call os_print_string

mov dh, 17

mov dl, 4

call os_move_cursor

mov si, help_msg_3

call os_print_string

mov dh, 18

mov dl, 4

call os_move_cursor

mov si, help_msg_4

call os_print_string

mov dh, 12

mov dl, 6

call os_move_cursor

mov si, work_string

call os_print_string

popa

ret

show_tried_chars:

pusha

mov bl, BLACK_ON_WHITE

mov dh, 18

mov dl, 40

mov si, 39

mov di, 23

call os_draw_block

mov dh, 19

mov dl, 41

call os_move_cursor

mov si, tried_chars_msg

call os_print_string

mov dh, 21

mov dl, 41

call os_move_cursor

mov si, tried_chars

call os_print_string

popa

ret

show_win_msg:

mov bl, WHITE_ON_GREEN

mov dh, 14

mov dl, 5

mov si, 30

mov di, 15

call os_draw_block

mov dh, 14

mov dl, 6

call os_move_cursor

mov si, .win_msg

call os_print_string

mov dh, 12

mov dl, 6

call os_move_cursor

mov si, real_string

call os_print_string

ret

.win_msg db 'Yay! Hit enter to play again', 0

show_lose_msg:

mov bl, WHITE_ON_LIGHT_RED

mov dh, 14

mov dl, 5

mov si, 30

mov di, 15

call os_draw_block

mov dh, 14

mov dl, 6

call os_move_cursor

mov si, .lose_msg

call os_print_string

mov dh, 12

mov dl, 6

call os_move_cursor

mov si, real_string

call os_print_string

ret

.lose_msg db 'Doh! Hit enter to play again', 0

; Draw the hangman box and appropriate bits depending on the number of misses

show_hangman:

pusha

mov bl, BLACK_ON_WHITE

mov dh, 2

mov dl, 42

mov si, 35

mov di, 17

call os_draw_block

cmp byte [misses], 0

je near .0

cmp byte [misses], 1

je near .1

cmp byte [misses], 2

je near .2

cmp byte [misses], 3

je near .3

cmp byte [misses], 4

je near .4

cmp byte [misses], 5

je near .5

cmp byte [misses], 6

je near .6

cmp byte [misses], 7

je near .7

cmp byte [misses], 8

je near .8

cmp byte [misses], 9

je near .9

cmp byte [misses], 10

je near .10

cmp byte [misses], 11

je near .11

.11: ; Right leg

mov dh, 10

mov dl, 64

call os_move_cursor

mov si, .11_t

call os_print_string

.10: ; Left leg

mov dh, 10

mov dl, 62

call os_move_cursor

mov si, .10_t

call os_print_string

.9: ; Torso

mov dh, 9

mov dl, 63

call os_move_cursor

mov si, .9_t

call os_print_string

.8: ; Arms

mov dh, 8

mov dl, 62

call os_move_cursor

mov si, .8_t

call os_print_string

.7: ; Head

mov dh, 7

mov dl, 63

call os_move_cursor

mov si, .7_t

call os_print_string

.6: ; Rope

mov dh, 6

mov dl, 63

call os_move_cursor

mov si, .6_t

call os_print_string

.5: ; Beam

mov dh, 5

mov dl, 56

call os_move_cursor

mov si, .5_t

call os_print_string

.4: ; Support for beam

mov dh, 6

mov dl, 57

call os_move_cursor

mov si, .4_t

call os_print_string

.3: ; Pole

mov dh, 12

mov dl, 56

call os_move_cursor

mov si, .3_t

call os_print_string

mov dh, 11

mov dl, 56

call os_move_cursor

call os_print_string

mov dh, 10

mov dl, 56

call os_move_cursor

call os_print_string

mov dh, 9

mov dl, 56

call os_move_cursor

call os_print_string

mov dh, 8

mov dl, 56

call os_move_cursor

call os_print_string

mov dh, 7

mov dl, 56

call os_move_cursor

call os_print_string

mov dh, 6

mov dl, 56

call os_move_cursor

call os_print_string

.2: ; Support for pole

mov dh, 13

mov dl, 55

call os_move_cursor

mov si, .2_t

call os_print_string

.1: ; Ground

mov dh, 14

mov dl, 53

call os_move_cursor

mov si, .1_t

call os_print_string

.0:

popa

ret

.1_t db '-------------', 0

.2_t db '/|\', 0

.3_t db '|', 0

.4_t db '/', 0

.5_t db '________', 0

.6_t db '|', 0

.7_t db 'O', 0

.8_t db '---', 0

.9_t db '|', 0

.10_t db '/', 0

.11_t db '\', 0

title_msg db 'vcOS Hangman', 0

footer_msg db 'Press Esc to exit', 0

hint_msg_1 db 'Short word this time, so you', 0

hint_msg_2 db 'get the first letter for free!', 0

help_msg_1 db 'Can you guess the city name', 0

help_msg_2 db 'that fits the spaces beneath?', 0

help_msg_3 db 'Press keys to guess letters,', 0

help_msg_4 db 'but you only have 10 chances!', 0

real_string times 50 db 0

work_string times 50 db 0

tried_chars_msg db 'Tried characters...', 0

tried_chars_pos db 0

tried_chars times 255 db 0

misses db 1

cities:

db 'kabul', 0

db 'tirane', 0

db 'algiers', 0

db 'andorra la vella', 0

db 'luanda', 0

db 'saint johns', 0

db 'buenos aires', 0

db 'yerevan', 0

db 'canberra', 0

db 'adelaide', 0

db 'melbourne', 0

db 'vienna', 0

db 'baku', 0

db 'nassau', 0

db 'manama', 0

db 'dhaka', 0

db 'bridgetown', 0

db 'minsk', 0

db 'brussels', 0

db 'belmopan', 0

db 'porto novo', 0

db 'thimpu', 0

db 'sucre', 0

db 'sarajevo', 0

db 'gaborone', 0

db 'brasilia', 0

db 'bandar seri begawan', 0

db 'sofia', 0

db 'ouagadougou', 0

db 'bujumbura', 0

db 'phnom penh', 0

db 'yaounde', 0

db 'ottawa', 0

db 'praia', 0

db 'bangui', 0

db 'ndjamema', 0

db 'santiago', 0

db 'beijing', 0

db 'bogota', 0

db 'moroni', 0

db 'brazzaville', 0

db 'kinshasa', 0

db 'san jose', 0

db 'yamoussoukro', 0

db 'zagreb', 0

db 'havana', 0

db 'nicosia', 0

db 'prague', 0

db 'copenhagen', 0

db 'djibouti', 0

db 'roseau', 0

db 'santo domingo', 0

db 'dili', 0

db 'quito', 0

db 'cairo', 0

db 'san salvador', 0

db 'malabo', 0

db 'asmara', 0

db 'tallinn', 0

db 'addis ababa', 0

db 'suva', 0

db 'helsinki', 0

db 'paris', 0

db 'libreville', 0

db 'banjul', 0

db 'tbilisi', 0

db 'berlin', 0

db 'accra', 0

db 'athens', 0

db 'saint georges', 0

db 'guatemala city', 0

db 'conakry', 0

db 'bissau', 0

db 'georgetown', 0

db 'port au prince', 0

db 'tegucigalpa', 0

db 'budapest', 0

db 'reykjavik', 0

db 'new delhi', 0

db 'jakarta', 0

db 'baghdad', 0

db 'dublin', 0

db 'jerusalem', 0

db 'rome', 0

db 'kingston', 0

db 'tokyo', 0

db 'amman', 0

db 'astana', 0

db 'nairobi', 0

db 'tarawa atoll', 0

db 'pyongyang', 0

db 'seoul', 0

db 'pristina', 0

db 'kuwait city', 0

db 'bishkek', 0

db 'vientiane', 0

db 'riga', 0

db 'beirut', 0

db 'maseru', 0

db 'monrovia', 0

db 'tripoli', 0

db 'vaduz', 0

db 'vilnius', 0

db 'luxembourg', 0

db 'skopje', 0

db 'antananarivo', 0

db 'lilongwe', 0

db 'kuala lumpur', 0

db 'male', 0

db 'bamako', 0

db 'valletta', 0

db 'majuro', 0

db 'nouakchott', 0

db 'port louis', 0

db 'mexico city', 0

db 'palikir', 0

db 'chisinau', 0

db 'monaco', 0

db 'ulaanbaatar', 0

db 'podgorica', 0

db 'rabat', 0

db 'maputo', 0

db 'rangoon', 0

db 'windhoek', 0

db 'yaren district', 0

db 'kathmandu', 0

db 'amsterdam', 0

db 'the hague', 0

db 'wellington', 0

db 'managua', 0

db 'niamey', 0

db 'abuja', 0

db 'lagos', 0

db 'oslo', 0

db 'bergen', 0

db 'stavanger', 0

db 'muscat', 0

db 'islamabad', 0

db 'karachi', 0

db 'melekeok', 0

db 'panama city', 0

db 'port moresby', 0

db 'asuncion', 0

db 'lima', 0

db 'manila', 0

db 'warsaw', 0

db 'lisbon', 0

db 'doha', 0

db 'bucharest', 0

db 'moscow', 0

db 'kigali', 0

db 'basseterre', 0

db 'castries', 0

db 'kingstown', 0

db 'apia', 0

db 'san marino', 0

db 'sao tome', 0

db 'riyadh', 0

db 'dakar', 0

db 'belgrade', 0

db 'victoria', 0

db 'freetown', 0

db 'singapore', 0

db 'bratislava', 0

db 'ljubljana', 0

db 'honiara', 0

db 'mogadishu', 0

db 'pretoria', 0

db 'bloemfontein', 0

db 'madrid', 0

db 'colombo', 0

db 'khartoum', 0

db 'paramaribo', 0

db 'mbabane', 0

db 'stockholm', 0

db 'bern', 0

db 'geneva', 0

db 'zurich', 0

db 'damascus', 0

db 'taipei', 0

db 'dushanbe', 0

db 'dar es salaam', 0

db 'bangkok', 0

db 'lome', 0

db 'nukualofa', 0

db 'port of spain', 0

db 'tunis', 0

db 'ankara', 0

db 'ashgabat', 0

db 'funafuti', 0

db 'kampala', 0

db 'kiev', 0

db 'abu dhabi', 0

db 'dubai', 0

db 'london', 0

db 'washington', 0

db 'montevideo', 0

db 'tashkent', 0

db 'port vila', 0

db 'vatican city', 0

db 'caracas', 0

db 'hanoi', 0

db 'sanaa', 0

db 'lusaka', 0

db 'harare', 0

db 'st petersburg', 0

db 'odessa', 0

db 'manchester', 0

db 'liverpool', 0

db 'birmingham', 0

db 'frankfurt', 0

db 'munich', 0

db 'dortmund', 0

db 'new york', 0

db 'chicago', 0

db 'san francisco', 0

db 'los angeles', 0

db 'las vegas', 0

db 'boston', 0

db 'new jersey', 0

db 'dallas', 0

db 'atlanta', 0

db 'miami', 0

db 'vancouver', 0

db 'toronto', 0

db 'saopaulo', 0

db 'rio de janeiro', 0

db 'vladivostok', 0

db 'glasgow', 0

db 'edinburgh', 0

db 'lyon', 0

db 'venice', 0

db 'torshavn', 0

db 'nuuk', 0

db 'bristol', 0

db 'york', 0

db 'tel aviv', 0

db 'seattle', 0

db 'stuttgart', 0

db 'osaka', 0

db 'kyoto', 0

db 'sapporo', 0

db 'kagoshima', 0

db 'shanghai', 0

db 'chongqing', 0

db 'hong kong', 0

db 'macao', 0

db 'xian', 0

db 'lhasa', 0

db 'warrington', 0

db 'leeds', 0

db 'luxor', 0

db 'timbuktu', 0

db 'honolulu', 0

db 'bordeaux', 0

db 'cupertino', 0

; ------------------------------------------------------------------