~hangman8086-devs/hangman8086/competition-mode

« back to all changes in this revision

Viewing changes to game.asm

  • Committer: Fabien LOISON
  • Date: 2011-05-26 16:49:49 UTC
  • mfrom: (5.1.12 hangman8086)
  • Revision ID: flo@flogisoft.com-20110526164949-gjoge7vzw100ibc0
* Single player mode implemented (no scoring)
* Main game functions implemented

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
2
;;      __   __  _______  __    _  _______  __   __  _______  __    _       ;;
 
3
;;     |  | |  ||   _   ||  |  | ||       ||  |_|  ||   _   ||  |  | |      ;;
 
4
;;     |  |_|  ||  |_|  ||   |_| ||    ___||       ||  |_|  ||   |_| |      ;;
 
5
;;     |       ||       ||       ||   | __ |       ||       ||       |      ;;
 
6
;;     |       ||       ||  _    ||   ||  ||       ||       ||  _    |      ;;
 
7
;;     |   _   ||   _   || | |   ||   |_| || ||_|| ||   _   || | |   |      ;;
 
8
;;     |__| |__||__| |__||_|  |__||_______||_|   |_||__| |__||_|  |__|      ;;
 
9
;;                                                                          ;;
 
10
;;                                                                          ;;
 
11
;;  HANGMAN - An implementation of the Hang Man game in assembly (Emu8086)  ;;
 
12
;;                                                                          ;;
 
13
;;  Copyright (C) 2011  Fabien LOISON                                       ;;
 
14
;;  Copyright (C) 2011  Mathilde BOUTIGNY                                   ;;
 
15
;;  Copyright (C) 2011  Vincent PEYROUSE                                    ;;
 
16
;;  Copyright (C) 2011  Germain CARR�                                       ;;
 
17
;;  Copyright (C) 2011  Matthis FRENAY                                      ;;
 
18
;;                                                                          ;;
 
19
;;  HangMan is free software: you can redistribute it and/or modify         ;;
 
20
;;  it under the terms of the GNU General Public License as published by    ;;
 
21
;;  the Free Software Foundation, either version 3 of the License, or       ;;
 
22
;;  (at your option) any later version.                                     ;;
 
23
;;                                                                          ;;
 
24
;;  This program is distributed in the hope that it will be useful,         ;;
 
25
;;  but WITHOUT ANY WARRANTY; without even the implied warranty of          ;;
 
26
;;  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           ;;
 
27
;;  GNU General Public License for more details.                            ;;
 
28
;;                                                                          ;;
 
29
;;  You should have received a copy of the GNU General Public License       ;;
 
30
;;  along with this program.  If not, see <http://www.gnu.org/licenses/>.   ;;
 
31
;;                                                                          ;;
 
32
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
33
 
 
34
 
 
35
;;
 
36
;; Contains the game functions.
 
37
;;
 
38
;; Index:
 
39
;;     _play(WORD)          -- Play to hangman.
 
40
;;     _game_init()         -- Initializes the game.
 
41
;;     _print_gibbet()      -- Prints the gibbet with remaining lives.
 
42
;;     _print_gword()       -- Prints the guessed word (e.g. H _ _ _ _ _ N).
 
43
;;     _print_tried_letters -- Prints the letters that the player have already
 
44
;;                             tried (e.g. A U I O W).
 
45
;;     _game_anima()        -- Displays an animation when the player loose
 
46
;;                             or win.
 
47
;;
 
48
 
 
49
 
 
50
 
 
51
GAME_STATUS_LOOSE equ 0
 
52
GAME_STATUS_WIN   equ 1
 
53
GAME_STATUS_ABORT equ 2
 
54
 
 
55
 
 
56
 
 
57
;============================================================ _play(WORD) ====
 
58
;; Play to hangman.
 
59
 
 
60
;; Usage:
 
61
;; mov WORD, offset <word>
 
62
;; call _play
 
63
 
 
64
;; Function args:
 
65
WORD   dw 0 ;The adress of the word to guess.
 
66
 
 
67
;; Returns:
 
68
GAME_STATUS db 0 ;The game status (GAME_STATUS_LOOSE, GAME_STATUS_WIN,
 
69
                 ;GAME_STATUS_ABORT).
 
70
 
 
71
 
 
72
_play:
 
73
 
 
74
;Backup registers
 
75
push ax
 
76
push bx
 
77
push cx
 
78
push dx
 
79
 
 
80
call _draw_ui
 
81
mov HELP_STR, offset game_help
 
82
call _print_help
 
83
call _game_init
 
84
 
 
85
mov GAME_STATUS, GAME_STATUS_LOOSE
 
86
 
 
87
play_main_loop:
 
88
    call _clear_working
 
89
    call _print_gword
 
90
 
 
91
    call _print_tried_letters
 
92
    call _print_gibbet
 
93
 
 
94
    ;Check if the play win
 
95
    ;For checking we search underscores in play_gword... It is not very
 
96
    ;pretty but it works...
 
97
    play_check_win:
 
98
    mov cl, play_word_len
 
99
    mov bx, offset play_gword
 
100
    play_check_win_loop:
 
101
        cmp [bx], '_'
 
102
        je  play_check_win_end ;not won yet
 
103
        inc bx
 
104
        dec cl
 
105
        cmp cl, 0
 
106
        jne play_check_win_loop
 
107
        ;The player win !
 
108
        mov GAME_STATUS, GAME_STATUS_WIN
 
109
        jmp play_eog
 
110
    play_check_win_end:
 
111
 
 
112
    ;Get a letter
 
113
    call _input_letter
 
114
 
 
115
    ;Check fo special keys
 
116
    cmp LETTER, KB_ENTER ;skip Enter
 
117
    je  play_main_loop
 
118
    cmp LETTER, KB_BKSP  ;skip Backspace
 
119
    je  play_main_loop
 
120
    cmp LETTER, KB_ESC   ;stop with Escape
 
121
    je  play_abort
 
122
 
 
123
    ;Check if the player have already tried this letter
 
124
    mov cl, play_tried_len
 
125
    mov bx, offset play_tried_letters
 
126
    mov al, LETTER
 
127
    play_ckeck_tried:
 
128
        cmp [bx], al
 
129
        je play_main_loop ;Letter already in the list -> play_main_loop
 
130
        inc bx
 
131
        dec cl
 
132
        cmp cl, 0
 
133
        jne play_ckeck_tried
 
134
 
 
135
    ;The letter is not in the list (play_tried_letters), so we add it
 
136
    mov cl, play_tried_len
 
137
    mov bx, offset play_tried_letters
 
138
    mov al, LETTER
 
139
    play_add_letter:
 
140
        cmp [bx], ' ' ;Search a space
 
141
        je play_add_letter_add
 
142
        inc bx
 
143
        dec cl
 
144
        cmp cl, 0
 
145
        jne play_add_letter
 
146
        jmp play_add_letter_end ;Something is wrong... No more place !
 
147
        play_add_letter_add:
 
148
            mov [bx], al
 
149
        play_add_letter_end:
 
150
 
 
151
    ;Check if the letter is in the word
 
152
    mov cl, play_word_len
 
153
    sub cl, 2
 
154
    mov bx, offset play_word
 
155
    inc bx
 
156
    mov al, LETTER
 
157
    play_check_word:
 
158
        cmp [bx], al
 
159
        je play_check_word_ok
 
160
        inc bx
 
161
        dec cl
 
162
        cmp cl, 0
 
163
        jne play_check_word
 
164
        ;The letter is not in the word
 
165
        dec play_lives
 
166
        mov SOUND, offset SND_GAME_BAD_LTTR
 
167
        call _play_sound
 
168
        jmp play_check_word_end
 
169
        play_check_word_ok:
 
170
        mov SOUND, offset SND_GAME_GOOD_LTTR
 
171
        call _play_sound
 
172
        play_check_word_end:
 
173
 
 
174
    ;Check the lives
 
175
    cmp play_lives, 0
 
176
    je  play_eog ;Hanged x_x
 
177
 
 
178
    jmp play_main_loop
 
179
 
 
180
play_eog:
 
181
 
 
182
call _game_anima
 
183
jmp play_end
 
184
 
 
185
play_abort:
 
186
mov GAME_STATUS, GAME_STATUS_ABORT
 
187
 
 
188
play_end:
 
189
 
 
190
;Restore registers
 
191
pop dx
 
192
pop cx
 
193
pop bx
 
194
pop ax
 
195
 
 
196
ret
 
197
 
 
198
 
 
199
;_play vars
 
200
play_word          db  "------------------------------"
 
201
play_word_len      db  0
 
202
play_word_max_len  equ 30
 
203
 
 
204
play_gword         db  "------------------------------"
 
205
play_tried_letters db  "--------------------------"
 
206
play_tried_len     equ 26
 
207
 
 
208
play_lives         db  0
 
209
 
 
210
;Help
 
211
game_help  db 0xDA,"A-Z",0xBF," Try a letter                                 "
 
212
           db "         ",0xDA,"Esc",0xBF," End the game$"
 
213
 
 
214
 
 
215
 
 
216
;=========================================================== _game_init() ====
 
217
;; Initializes the game.
 
218
 
 
219
;; NOTE: Called by the _play() function.
 
220
 
 
221
;; Usage:
 
222
;; call _game_init
 
223
 
 
224
 
 
225
_game_init:
 
226
 
 
227
;Backup registers
 
228
push ax
 
229
push bx
 
230
push cx
 
231
push dx
 
232
 
 
233
;Put the length of WORD in play_word_len
 
234
mov ax, WORD
 
235
mov STRLEN_STR, ax
 
236
call _strlen
 
237
mov al, STRLEN_LEN
 
238
mov play_word_len, al
 
239
 
 
240
;Put the WORD in play_word
 
241
mov ax, WORD
 
242
mov MEMCPY_SRC, ax
 
243
mov MEMCPY_DEST, offset play_word
 
244
mov al, STRLEN_LEN
 
245
mov MEMCPY_LEN, al
 
246
call _memcpy
 
247
 
 
248
;Fill play_tried_letters with spaces
 
249
mov bx, offset play_tried_letters
 
250
mov cl, play_tried_len
 
251
 
 
252
game_init_sploop:
 
253
    mov [bx], ' '
 
254
    inc bx
 
255
    dec cl
 
256
    cmp cl, 0
 
257
    jne game_init_sploop
 
258
 
 
259
;Init the play_lives to 10 (with gibbet) or 6 (without gibbet)
 
260
mov play_lives, 10 ;FIXME
 
261
 
 
262
;Restore registers
 
263
pop dx
 
264
pop cx
 
265
pop bx
 
266
pop ax
 
267
 
 
268
ret
 
269
 
 
270
 
 
271
 
 
272
;======================================================== _print_gibbet() ====
 
273
;; Prints the gibbet with remaining lives.
 
274
 
 
275
;; Usage:
 
276
;; call _print_gibbet
 
277
 
 
278
 
 
279
_print_gibbet:
 
280
 
 
281
;Backup registers
 
282
push ax
 
283
push bx
 
284
push cx
 
285
push dx
 
286
 
 
287
;Calculate the address of the gibbet that fit with the remaining lives
 
288
mov ah, 0
 
289
mov al, GIBBET_WIDTH
 
290
mov bh, 0
 
291
mov bl, GIBBET_HEIGHT
 
292
mul bl
 
293
 
 
294
mov bx, 10
 
295
sub bl, play_lives
 
296
mul bl
 
297
 
 
298
mov bx, offset HANGMAN_LIVES_10
 
299
add bx, ax
 
300
 
 
301
;Print the gibbet
 
302
mov cl, GIBBET_HEIGHT
 
303
mov ah, 0x09
 
304
mov dx, bx
 
305
mov bx, GIBBET_WIDTH
 
306
mov POS_X, COLS - GIBBET_WIDTH - 2
 
307
mov POS_Y, (ROWS - GIBBET_HEIGHT) / 2 + (header_height - 1) / 2
 
308
print_gibbet_loop:
 
309
    call _move_cursor
 
310
    int 0x21 ;Print
 
311
    add dx, bx
 
312
    inc POS_Y
 
313
    dec cl
 
314
    cmp cl, 0
 
315
    jne print_gibbet_loop
 
316
 
 
317
;Restore registers
 
318
pop dx
 
319
pop cx
 
320
pop bx
 
321
pop ax
 
322
 
 
323
ret
 
324
 
 
325
 
 
326
 
 
327
;========================================================= _print_gword() ====
 
328
;; Prints the guessed word (e.g. H _ _ _ _ _ N).
 
329
 
 
330
;; Usage:
 
331
;; call _print_gword
 
332
 
 
333
 
 
334
_print_gword:
 
335
 
 
336
;Backup registers
 
337
push ax
 
338
push bx
 
339
push cx
 
340
push dx
 
341
 
 
342
;Copy the word in play_gword
 
343
mov ax, WORD
 
344
mov MEMCPY_SRC, ax
 
345
mov MEMCPY_DEST, offset play_gword
 
346
mov al, STRLEN_LEN
 
347
mov MEMCPY_LEN, al
 
348
call _memcpy
 
349
 
 
350
;Make the string
 
351
mov cl, play_word_len
 
352
sub cl, 2
 
353
mov bx, offset play_gword
 
354
inc bx
 
355
 
 
356
print_gword_mkloop:
 
357
    mov al, [bx]
 
358
    mov ch, play_tried_len
 
359
    push bx
 
360
    mov bx, offset play_tried_letters
 
361
    print_gword_mkloop1:
 
362
        mov ah, [bx]
 
363
        cmp ah, al
 
364
        je print_gword_lil
 
365
        dec ch
 
366
        inc bx
 
367
        cmp ch, 0
 
368
        jne print_gword_mkloop1
 
369
 
 
370
    print_gword_lnil: ;Letter Not In List
 
371
        pop bx
 
372
        mov [bx], '_'
 
373
        jmp print_gword_mkloopend
 
374
 
 
375
    print_gword_lil: ;Letter In List
 
376
        pop bx
 
377
 
 
378
    print_gword_mkloopend:
 
379
        dec cl
 
380
        inc bx
 
381
        cmp cl, 0
 
382
        jne print_gword_mkloop
 
383
 
 
384
;Print the word
 
385
mov POS_Y, ROWS / 2 + (header_height - 1) - 5
 
386
mov POS_X, COLS / 2 - GIBBET_WIDTH + 3
 
387
mov al, play_word_len
 
388
sub POS_X, al
 
389
mov bx, offset play_gword
 
390
mov cl, play_word_len
 
391
mov ah, 0x02
 
392
print_gword_prnloop:
 
393
    call _move_cursor
 
394
    mov dl, [bx]
 
395
    int 0x21 ;print
 
396
    inc bx
 
397
    add POS_X, 2
 
398
    dec cl
 
399
    cmp cl, 0
 
400
    jne print_gword_prnloop
 
401
 
 
402
;Restore registers
 
403
pop dx
 
404
pop cx
 
405
pop bx
 
406
pop ax
 
407
 
 
408
ret
 
409
 
 
410
 
 
411
 
 
412
;================================================= _print_tried_letters() ====
 
413
;; Print the letters that the player have already tried (e.g. A U I O W).
 
414
 
 
415
;; Usage:
 
416
;; call _print_tried_letters
 
417
 
 
418
 
 
419
_print_tried_letters:
 
420
 
 
421
;Backup registers
 
422
push ax
 
423
push bx
 
424
push cx
 
425
push dx
 
426
 
 
427
;Calculate the length of the string
 
428
mov cl, 0
 
429
mov bx, offset play_tried_letters
 
430
prn_tried_strlen:
 
431
    cmp [bx], ' '
 
432
    je  prn_tried_strlen_end
 
433
    inc bx
 
434
    inc cl
 
435
    jmp prn_tried_strlen
 
436
prn_tried_strlen_end:
 
437
 
 
438
;Calculate the cursor position
 
439
mov POS_Y, ROWS / 2 + (header_height - 1) - 2
 
440
mov POS_X, COLS / 2 - GIBBET_WIDTH + 3
 
441
sub POS_X, cl
 
442
 
 
443
;Print letters
 
444
cmp cl, 0
 
445
je  prn_tried_end
 
446
mov bx, offset play_tried_letters
 
447
mov ah, 0x02
 
448
 
 
449
prnletters_loop:
 
450
    call _move_cursor
 
451
    mov dl, [bx]
 
452
    int 0x21 ;print
 
453
    inc bx
 
454
    add POS_X, 2
 
455
    dec cl
 
456
    cmp cl, 0
 
457
    jne prnletters_loop
 
458
 
 
459
prn_tried_end:
 
460
 
 
461
;Restore registers
 
462
pop dx
 
463
pop cx
 
464
pop bx
 
465
pop ax
 
466
 
 
467
ret
 
468
 
 
469
 
 
470
 
 
471
;========================================================== _game_anima() ====
 
472
;; Displays an animation when the player loose or win.
 
473
 
 
474
;; Usage:
 
475
;; call _game_anima
 
476
 
 
477
 
 
478
_game_anima:
 
479
 
 
480
;Backup registers
 
481
push ax
 
482
push bx
 
483
push cx
 
484
push dx
 
485
 
 
486
;Play a sound
 
487
cmp GAME_STATUS, GAME_STATUS_WIN
 
488
je  game_anima_sndwin
 
489
mov SOUND, offset SND_GAME_DIE
 
490
jmp game_anima_sndend
 
491
game_anima_sndwin:
 
492
mov SOUND, offset SND_GAME_GG
 
493
game_anima_sndend:
 
494
call _play_sound
 
495
 
 
496
;Draw the ui
 
497
call _draw_ui
 
498
 
 
499
;Print the help message
 
500
mov HELP_STR, offset game_anima_help
 
501
call _print_help
 
502
 
 
503
;Flush the input buffer
 
504
mov ah, 0x0C
 
505
mov al, 0
 
506
int 0x21
 
507
 
 
508
;Print the word
 
509
mov cl, play_word_len
 
510
mov bx, offset play_word
 
511
mov POS_X, COLS/2
 
512
sub POS_X, cl
 
513
mov POS_Y, header_height + GIBBET_HEIGHT + 5
 
514
mov ah, 0x02
 
515
game_anima_pnrloop:
 
516
    call _move_cursor
 
517
    mov dl, [bx]
 
518
    int 0x21 ;print
 
519
    inc bx
 
520
    add POS_X, 2
 
521
    dec cl
 
522
    cmp cl, 0
 
523
    jne game_anima_pnrloop
 
524
 
 
525
;Loop until the player press any key
 
526
game_anima_loop0:
 
527
mov ch, 4
 
528
cmp GAME_STATUS, GAME_STATUS_WIN
 
529
je  game_anima_win
 
530
mov dx, offset HANGMAN_GAMEOVER_00
 
531
jmp game_anima_loop1
 
532
game_anima_win:
 
533
mov dx, offset HANGMAN_GOODGAME_00
 
534
game_anima_loop1:
 
535
    ;Check for keystroke
 
536
    mov ah, 0x01
 
537
    int 0x16
 
538
    jnz game_anima_end
 
539
 
 
540
    ;Print the animation (step 00)
 
541
    mov cl, GIBBET_HEIGHT
 
542
    mov ah, 0x09
 
543
    mov POS_X, (COLS - GIBBET_WIDTH) / 2
 
544
    mov POS_Y, header_height + 3
 
545
    game_anima_prnloop00:
 
546
        call _move_cursor
 
547
        int 0x21 ;Print
 
548
        inc POS_Y
 
549
        dec cl
 
550
        add dx, GIBBET_WIDTH
 
551
        cmp cl, 0
 
552
        jne game_anima_prnloop00
 
553
 
 
554
    ;Sleep
 
555
    push cx
 
556
    mov ah, 0x86
 
557
    mov cx, 3
 
558
    int 0x15
 
559
    pop cx
 
560
 
 
561
    dec ch
 
562
    cmp ch, 0
 
563
    je  game_anima_loop0
 
564
 
 
565
    jmp game_anima_loop1
 
566
 
 
567
game_anima_end:
 
568
 
 
569
;Check the char
 
570
mov ah, 0x00
 
571
int 0x16
 
572
cmp al, KB_ESC
 
573
jne game_anima_chrend
 
574
mov GAME_STATUS, GAME_STATUS_ABORT
 
575
 
 
576
game_anima_chrend:
 
577
 
 
578
;Restore registers
 
579
pop dx
 
580
pop cx
 
581
pop bx
 
582
pop ax
 
583
 
 
584
ret
 
585
 
 
586
 
 
587
;Help
 
588
game_anima_help  db "Press any key to continue                          "
 
589
                 db "         ",0xDA,"Esc",0xBF," End the game$"
 
590
 
 
591