K_ENTER EQU 13               ; 'ENTER' ƽŰ ڵ
K_ESC   EQU 27               ; 'ESC' ƽŰ ڵ
K_BS    EQU 8                ; 'BS' ƽŰ ڵ

S_LEFT  EQU 75               ;    ȭǥŰ ĵڵ
S_RIGHT EQU 77               ;  ȭǥŰ ĵڵ
S_UP    EQU 72               ;    ȭǥŰ ĵڵ
S_DOWN  EQU 80               ; Ʒ ȭǥŰ ĵڵ

POINT_START	EQU ( (54) + ( 1)*80 )*2
POINT_GOAL	EQU ( (78) + (23)*80 )*2

STACK_EMPTY	EQU 0FFFFH

;  
C_WALL		EQU 2*16
C_WALL_SIDE_LOW	EQU 1
C_WALL_FRONT	EQU 9*16+9
C_WALL_FRONT_HI	EQU 9*16
C_WALL_FRONT_LOW	EQU 9
C_TOP			EQU 0*16+0
C_TOP_HI		EQU 0*16
C_TOP_LOW		EQU 0
C_ROAD		EQU 7*16
C_ROAD_1		EQU 15*16
C_ROAD_2		EQU 8*16
C_BLACK		EQU 0
C_GOAL		EQU 14*16

;////////////////////////////////////////////////////////////////////

CODE SEGMENT
	ASSUME CS:CODE, DS:CODE
	ORG 100H

START:
	mov ax, CS
	mov DS, ax

	;    (ý Ŭ)
	mov ax, 0
	mov es, ax
	mov ax, es:[046CH]
	mov RandomSeed, ax

	; hide cursor
	mov ah, 1
	mov ch, 20H
	int 10H

	; hide mouse cursor
	mov ax, 2
	int 33H

	;  Ӽ Ͽ    Ѵ.
	mov ax, 1003H
	mov bl, 0
	int 10H

	; ȭ 
	mov ax, 0B800H
	mov ES, ax

	call drawScreen

NewStart:
	call InitAdol

	FindGoal:
		mov	AH, 0  ;
		int	16h    ; AH:Ű ĵڵ AL:ƽŰڵ

		cmp	AH, S_LEFT                   ;
		jnz	IS1                          ;
		mov	AX, 3                        ;
		call 	Adol_Turn	             ;
		jmp	FindGoal	             ;
	IS1:	cmp	AH, S_RIGHT                  ;
		jnz	IS2                          ;
		mov	AX, 1                        ;
		call	Adol_Turn                    ;
		jmp	FindGoal	             ;
	IS2:	cmp	AH, S_UP                     ;
		jnz	IS3                          ;
		call	Adol_MoveForard              ;
		mov ax, point_Adol
		cmp ax, POINT_GOAL
		je NewStart
		jmp	FindGoal		     ;
	IS3:	cmp	AH, S_DOWN                   ;
		jnz	IS4                          ;
		call 	Adol_MoveBack                ;
		jmp	FindGoal	             ;
	IS4:	cmp	AL, K_ESC                    ;
		jnz	FindGoal                     ;


exit_program:

	; ȭ ...
	mov ax, 3
	int 10H

	; view mouse cursor
	mov ax, 1
	int 33H

	mov ah, 4Ch
	int 21h

;////////////////////////////////////////////////////////////////////


;*******************
;**     **
;*******************

POINT_START	EQU ( (54) + ( 1)*80 )*2
POINT_GOAL	EQU ( (78) + (23)*80 )*2

STACK_EMPTY	EQU 0FFFFH

;  
C_WALL		EQU 2*16
C_WALL_SIDE_LOW	EQU 1
C_WALL_FRONT	EQU 9*16+9
C_WALL_FRONT_HI	EQU 9*16
C_WALL_FRONT_LOW	EQU 9
C_TOP			EQU 0*16+0
C_TOP_HI		EQU 0*16
C_TOP_LOW		EQU 0
C_ROAD		EQU 7*16
C_ROAD_1		EQU 15*16
C_ROAD_2		EQU 8*16
C_BLACK		EQU 0

; ⿡  ġ. 0=left, 1=right, 2=up, 3=down
;directionAdd DW -2, 2, -160, 160;
;LeftdirectionAdd DW 160,-160, -2, 2;
;RightdirectionAdd DW -160, 160, 2, -2;

; ⿡  ġ. 0=up, 1=left, 2=down, 3=right
directionAdd	DW -160,    2,  160,   -2
LeftdirectionAdd	DW   -2, -160,    2,  160
RightdirectionAdd	DW    2,  160,   -2, -160

; ⿡  Ƶ 
AdolChar	DB '','','',''

; 3 ǥ 
Start_Left_Top		DW ((00)+(00)*80)*2+1,((05)+(02)*80)*2+1,((13)+(06)*80)*2+1,((19)+(09)*80)*2+1,((23)+(11)*80)*2+1
Start_Left_Center	DW ((00)+(02)*80)*2+1,((05)+(06)*80)*2+1,((13)+(09)*80)*2+1,((19)+(11)*80)*2+1,((23)+(12)*80)*2+1
Start_Left_Bottom	DW ((00)+(23)*80)*2+1,((05)+(19)*80)*2+1,((13)+(16)*80)*2+1,((19)+(14)*80)*2+1,((23)+(13)*80)*2+1
Start_Center_Top	DW ((05)+(00)*80)*2+1,((13)+(02)*80)*2+1,((19)+(06)*80)*2+1,((23)+(09)*80)*2+1,((25)+(11)*80)*2+1
Start_Center_Center	DW ((05)+(02)*80)*2+1,((13)+(06)*80)*2+1,((19)+(09)*80)*2+1,((23)+(11)*80)*2+1,((25)+(12)*80)*2+1
Start_Center_Bottom	DW ((05)+(23)*80)*2+1,((13)+(19)*80)*2+1,((19)+(16)*80)*2+1,((23)+(14)*80)*2+1,((25)+(13)*80)*2+1
Start_Right_Top		DW ((47)+(00)*80)*2+1,((39)+(02)*80)*2+1,((33)+(06)*80)*2+1,((29)+(09)*80)*2+1,((27)+(11)*80)*2+1
Start_Right_Center	DW ((47)+(02)*80)*2+1,((39)+(06)*80)*2+1,((33)+(09)*80)*2+1,((29)+(11)*80)*2+1,((27)+(12)*80)*2+1
Start_Right_Bottom	DW ((47)+(23)*80)*2+1,((39)+(19)*80)*2+1,((33)+(16)*80)*2+1,((29)+(14)*80)*2+1,((27)+(13)*80)*2+1
Width_Left		DB  5, 8, 6, 4, 2
Width_Center		DB 42,26,14, 6, 2 
Width_Right		DB  5, 8, 6, 4, 2
Height_Top		DB  2, 4, 3, 2, 1
Height_Center		DB 21,13, 7, 3, 1 
Height_Bottom		DB  2, 4, 3, 2, 1

;*******************
;**     **
;*******************

RandomSeed	DW ?

point_Adol	DW POINT_GOAL		; Ƶ ǥ
dir_Adol	DW 1				; Ƶ 

; 3 
C_Left_Top		DB 5 dup(?)
C_Left_Center	DB 5 dup(?)
C_Left_Bottom	DB 5 dup(?)
;C_Center_Top	DB 5 dup(?)
C_Center_Center	DB 5 dup(?)
C_Center_Bottom	DB 5 dup(?)
C_Right_Top		DB 5 dup(?)
C_Right_Center	DB 5 dup(?)
C_Right_Bottom	DB 5 dup(?)

;////////////////////////////////////////////////////////////////////

;******************
;**   ä **
;******************
;
; BX DH * DL  AL ä.
;
Rectangle PROC
	mov ch, DH
	mov cl, DL

	mov dh, DL
	shl dh, 1
	neg dh
	add dh, 160

rectangle_loop:
	    mov BYTE PTR ES:[BX], AL
	    add BX, 2
	    dec cl
	    jnz rectangle_loop
	add BL, dh
	adc BH, 0
	mov cl, DL
	dec ch
	jnz rectangle_loop

	ret
Rectangle ENDP


;************************
;**   ߻ Ű  **
;************************
;
Random PROC
	mov CX, RandomSeed
	add CX, 9248H
	ror CX, 1
	ror CX, 1
	ror CX, 1
	mov RandomSeed, CX
	ret
Random ENDP


;************************
;**   ̷   **
;************************
;
Random_Miro PROC
	; ϴ   ä.
	mov BX, 107
	mov DH, 25
	mov DL, 27
	mov AL, C_WALL
	call Rectangle

	; ʱȭ
	mov DI, POINT_START+1

	mov ax, STACK_EMPTY
	push ax

Set_Point:			;  ġ  ׸.
	mov BYTE PTR ES:[DI], C_ROAD

chk_NextPoint:		;  ġ ¿츦 üũ ÷ 
	xor BX, BX

check_up:			; ʿ  ׸  ִ°?
	mov si, DI
	add si, -320
	cmp si, POINT_START+1
	jna check_right

	mov al, ES:[si]
	cmp al,C_WALL
	jne check_right
	or BX,1

check_right:		;   ׸  ִ°?
	mov ax, DI
	mov dl, 160
	div dl
	cmp ah, 78*2+1
	jae check_down

	mov si, DI
	add si, 4
	mov al, ES:[si]
	cmp al, C_WALL
	jne check_down
	or BX, 2

check_down:		; Ʒʿ  ׸  ִ°?
	mov si, DI
	add si, 320
	cmp si, POINT_GOAL+1
	ja check_left

	mov al, ES:[si]
	cmp al, C_WALL
	jne check_left
	or BX,4

check_left: 		;   ׸  ִ°?
	mov ax, DI
	mov dl, 160
	div dl
	cmp ah, 54*2+1
	jbe moveTo_nextPoint

	mov si, DI
	add si, -4
	mov al, ES:[si]
	cmp al, C_WALL
	jne moveTo_nextPoint
	or BX, 8

moveTo_nextPoint:		;      ˻Ѵ.
	cmp BX,0
	je check_stack

Random_NextPoint:		;       .
	call Random
	and CX, 3
	mov ax, 1
	shl ax, cl
	and ax, BX
	jz Random_NextPoint

	shl cx, 1		;  鼭  ġ .
	mov bx, cx
	mov bx, [directionAdd+bx]
	mov BYTE PTR ES:[ DI+bx ], C_ROAD;

	push DI		;    ġ PUSH!
	shl bx, 1
	add DI, bx
	jmp Set_Point

check_stack:		;   ̷ΰ ϼǾ.
	pop DI
	cmp DI, STACK_EMPTY
	je finish_random_miro
	jmp chk_NextPoint

finish_random_miro:

	ret
Random_Miro ENDP


;*********************************
;**  ̷θ 3 Ÿ  **
;*********************************
;
View3D PROC
;/////// ̷θ ׸  غ۾ ////////////////

	; DX =  
	mov bx, dir_Adol
	shl bx, 1
	mov DX, [directionAdd+bx]

	; DI =  ġ
	mov DI, point_Adol
	inc DI

	; SI = 
	mov si, dir_Adol
	shl si, 1
	mov ax, [LeftdirectionAdd+si]
	mov SI, DI
	add SI, ax

	; BX = 
	mov bx, dir_Adol
	shl bx, 1
	mov ax, [RightdirectionAdd+bx]
	mov BX, DI
	add BX, ax

	mov BP, 0		; BP = ݺ ó, cl = ӽú
check_color:
	mov CH, ES:[DI]	; CH =  ٴڻ
	mov AH, ES:[SI]	; AH =  ٴڻ
	mov AL, ES:[BX]	; AL =  ٴڻ

check_color_left:			; ó
	cmp AH, C_WALL
	je is_left_wall
is_left_road:
	mov cl, AH
	shr cl, 1
	shr cl, 1
	shr cl, 1
	shr cl, 1
	or cl, CH
	mov [C_Left_Bottom+BP], cl
	mov cl, C_WALL_FRONT_LOW
	mov [C_Left_Center+BP], cl
	mov BYTE PTR [C_Left_Top+BP], C_TOP
	jmp check_color_right
is_left_wall:
	mov cl, CH
	or cl, C_WALL_SIDE_LOW
	mov [C_Left_Center+BP], cl
	mov [C_Left_Bottom+BP], cl
	mov cl, C_WALL_SIDE_LOW
	or cl, C_TOP_HI
	mov [C_Left_Top+BP], cl

check_color_right:		; ó
	cmp AL, C_WALL
	je is_right_wall
is_right_road:
	mov cl, AL
	shr cl, 1
	shr cl, 1
	shr cl, 1
	shr cl, 1
	or cl, CH
	mov [C_Right_Bottom+BP], cl
	mov cl, C_WALL_FRONT_LOW
	mov [C_Right_Center+BP], cl
	mov BYTE PTR [C_Right_Top+BP], C_TOP
	jmp check_color_center
is_right_wall:
	mov cl, ch
	or cl, C_WALL_SIDE_LOW
	mov [C_Right_Center+BP], cl
	mov [C_Right_Bottom+BP], cl
	mov cl, C_WALL_SIDE_LOW
	or cl, C_TOP_HI
	mov [C_Right_Top+BP], cl

check_color_center:
	mov [C_Center_Bottom+BP], CH	;  ߾ ٴ
	add DI, DX
	add SI, DX
	add BX, DX

	mov al, ES:[DI]
	cmp al, C_WALL
	je exit_check_color_wall

	cmp BP, 4
	je exit_check_color_black
	inc BP
	jmp check_color

exit_check_color_black:
	cmp al, C_WALL
	je exit_check_color_wall
	mov [C_Center_Center+BP], C_BLACK
	jmp Draw3D

exit_check_color_wall:
	mov [C_Center_Center+BP], C_WALL_FRONT

;//////// ̷θ ׸ ///////////////
Draw3D:
	mov SI, 0
	mov DI, 0
Left_Top:
	mov BX, [Start_Left_Top+SI]
	mov DH, [Height_Top+DI]
	mov DL, [Width_Left+DI]
	mov AL, [C_Left_Top+DI]
	call Rectangle
Left_Center:
	mov BX, [Start_Left_Center+SI]
	mov DH, [Height_Center+DI]
	mov DL, [Width_Left+DI]
	mov AL, [C_Left_Center+DI]
	call Rectangle
Left_Bottom:
	mov BX, [Start_Left_Bottom+SI]
	mov DH, [Height_Bottom+DI]
	mov DL, [Width_Left+DI]
	mov AL, [C_Left_Bottom+DI]
	call Rectangle
Right_Top:
	mov BX, [Start_Right_Top+SI]
	mov DH, [Height_Top+DI]
	mov DL, [Width_Right+DI]
	mov AL, [C_Right_Top+DI]
	call Rectangle
Right_Center:
	mov BX, [Start_Right_Center+SI]
	mov DH, [Height_Center+DI]
	mov DL, [Width_Right+DI]
	mov AL, [C_Right_Center+DI]
	call Rectangle
Right_Bottom:
	mov BX, [Start_Right_Bottom+SI]
	mov DH, [Height_Bottom+DI]
	mov DL, [Width_Right+DI]
	mov AL, [C_Right_Bottom+DI]
	call Rectangle
Center_Top:
	mov BX, [Start_Center_Top+SI]
	mov DH, [Height_Top+DI]
	mov DL, [Width_Center+DI]
	mov AL, C_TOP
	call Rectangle
Center_Bottom:
	mov BX, [Start_Center_Bottom+SI]
	mov DH, [Height_Bottom+DI]
	mov DL, [Width_Center+DI]
	mov AL, [C_Center_Bottom+DI]
	call Rectangle
Center_Center:
	cmp DI, BP
	jne Draw3D_continue

	mov BX, [Start_Center_Center+SI]
	mov DH, [Height_Center+DI]
	mov DL, [Width_Center+DI]
	mov AL, [C_Center_Center+DI]
	call Rectangle

Draw3D_continue:
	cmp DI, BP
	je ExitView3D
	add SI, 2
	inc DI
	jmp Left_Top

ExitView3D:
	ret
View3D ENDP


;*******************
;**  Ƶ ʱȭ  **
;*******************
;
InitAdol PROC

	call Random_Miro

	; Ƶ ,
	mov di, point_Adol
	mov al, ' '
	mov ES:[di], al

	; Ƶ ...
	mov ax, POINT_START
	mov point_Adol, ax

	;  ׸,
	mov al, C_GOAL
	mov ES:[POINT_GOAL+1], al

	; Ƶ 
	mov di, point_Adol
	mov bx, dir_Adol
	mov al, [bx+AdolChar]
	mov ES:[DI], al

	call SetFloorColor
	call View3D

	ret
InitAdol ENDP


;********************
;**  ٴڻ ٲٱ **
;********************
;
SetFloorColor PROC
	mov di, point_Adol
	inc di

check_move_first:

	xor BX, BX
	chk_up:
		mov al, ES:[di-160]
		cmp al, C_ROAD
		je chk_up_ok
		cmp al, C_GOAL
		jne chk_down
	  chk_up_ok:
		inc BX
	chk_down:
		mov al, ES:[di+160]
		cmp al, C_ROAD
		je chk_down_ok
		cmp al, C_GOAL
		jne chk_left
	  chk_down_ok:
		inc BX
	chk_left:
		mov al, ES:[di-2]
		cmp al, C_ROAD
		je chk_left_ok
		cmp al, C_GOAL
		jne chk_right
	  chk_left_ok:
		inc BX
	chk_right:
		mov al, ES:[di+2]
		cmp al, C_ROAD
		je chk_right_ok
		cmp al, C_GOAL
		jne chk_3wall
	  chk_right_ok:
		inc BX
	chk_3wall:
		cmp BX, 0
		je check_move_second

	mov BYTE PTR ES:[di], C_ROAD_1
	jmp exit_setFC

check_move_second:
	mov BYTE PTR ES:[di], C_ROAD_2

exit_setFC:
	ret

SetFloorColor ENDP


;***********************
;**  Ƶ  ٲٱ **
;***********************
;
Adol_Turn PROC
	mov bx, dir_Adol
	add bx, ax
	and bx, 3
	mov dir_Adol, bx

	; Ƶ 
	mov di, point_Adol
	mov al, [bx+AdolChar]
	mov ES:[di], al
	call View3D

	ret
Adol_Turn ENDP

;*****************
;**  ĭ   **
;*****************
;
Adol_MoveForard PROC
	; DI =  ġ, BX =  
	mov DI, point_Adol
	mov BX, dir_Adol

	;  Ѱ?
	mov si, BX
	shl si, 1
	mov SI, [directionAdd+si]
	add SI, DI
	mov al, ES:[SI+1]
	cmp al, C_WALL
	je exit_moveForward

	;  ġ ׸ 
	mov BYTE PTR ES:[DI], ' '

	mov DI, SI
	mov point_Adol, SI

	; Ƶ 
	mov al, [BX+AdolChar]
	mov ES:[DI], al

	call SetFloorColor
	call View3D

exit_moveForward:
	ret
Adol_MoveForard ENDP

;*****************
;**  ĭ   **
;*****************
;
Adol_MoveBack PROC
	; DI =  ġ, BX =  , CX =  
	mov DI, point_Adol
	mov BX, dir_Adol
	mov CX, BX
	add CX, 2
	and CX, 3

	;  Ѱ?
	mov si, CX
	shl si, 1
	mov SI, [directionAdd+si]
	add SI, DI
	mov al, ES:[SI+1]
	cmp al, C_WALL
	je exit_moveForward

	;  ġ ׸ 
	mov BYTE PTR ES:[DI], ' '

	mov DI, SI
	mov point_Adol, SI

	; Ƶ 
	mov al, [BX+AdolChar]
	mov ES:[DI], al

	call SetFloorColor
	call View3D

exit_moveBack:
	ret
Adol_MoveBack ENDP


;***************************
;**  ȭ ׸ ƾ **
;***************************
;
putch PROC
putch_loop:
	mov ES:[BX], AH
	add BX, 2
	dec AL
	jnz putch_loop
	ret
putch ENDP


;*******************
;**  ȭ ׸  **
;*******************
;
DrawScreen PROC

	mov BX, 0
	mov CL, 1

draw_screen1:
	  mov AH, 219
	  mov AL, CL
	  call putch
	  mov AH, 220
	  mov AL, 1
	  call putch
	  mov AH, ' '
	  mov AL, 25
	  sub AL, CL
	  shl AL, 1
	  call putch
	  mov AH, 220
	  mov AL, 1
	  call putch
	  mov AH, 219
	  mov AL, CL
	  call putch
	  mov AH, ' '
	  mov AL, 28
	  call putch
	add CL, 2
	cmp CL, 25
	jb draw_screen1

draw_screen2:
	mov AH, 219
	mov AL, 25
	call putch
	mov AH, ' '
	mov AL, 2
	call putch
	mov AH, 219
	mov AL, 25
	call putch
	mov AH, ' '
	mov AL, 28
	call putch

	mov CL, 23
draw_screen3:
	  mov AH, 219
	  mov AL, CL
	  call putch
	  mov AH, 223
	  mov AL, 1
	  call putch
	  mov AH, ' '
	  mov AL, 25
	  sub AL, CL
	  shl AL, 1
	  call putch
	  mov AH, 223
	  mov AL, 1
	  call putch
	  mov AH, 219
	  mov AL, CL
	  call putch
	  mov AH, ' '
	  mov AL, 28
	  call putch
	sub CL, 2
	cmp CL, 23
	jb draw_screen3

	ret
DrawScreen ENDP

CODE ENDS
END START
