0 Members and 1 Guest are viewing this topic.
b_nodes: each bit represents the value assigned to the node when it was visited. This value is used for backtracking, and this is why the algorithm is interesting!
When the routine starts, the bit of the starting node in b_closed is set. Each iteration of the search passes over the entire buffer. Every bit in the b_closed buffer is "expanded" into each of the 4 adjacent bits that are not walls in b_tilemap.
Any newly expanded bits that were not already set in the b_closed buffer are assigned a value of either 1 or 0 in the b_nodes buffer. This value is the same for every new bit expanded during the iteration. After each pass, the bit of the goal node is tested in b_closed. If it is set, we know the goal node has been visited, so we can now backtrack from here to the start by following our b_nodes values!
The assigned b_nodes value follows the pattern 0, 1, 1, 0, 0, 1, 1, 0, etc, changing each iteration to the next value in the pattern. This is the key to this algorithm. At any given index in this pattern, the previous and next indices always have different values. With a reference of the current value and either the next value or the previous value in the pattern, the third value can always be determined
WIDTH = 15HEIGHT = 8SIZE = WIDTH*HEIGHTTILE = 0CLOSED = SIZENODES = 2*SIZEb_tilemap:.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1.db 1,0,0,0,0,0,0,1,0,0,0,0,1,0,1.db 1,0,0,0,1,0,0,1,0,0,0,0,0,0,1.db 1,0,0,0,0,0,0,0,0,0,1,0,0,0,1.db 1,0,1,1,0,0,1,1,0,0,1,0,1,1,1.db 1,0,0,1,1,0,0,1,0,0,1,0,1,3,1.db 1,2,0,0,0,0,0,1,1,0,1,0,0,0,1.db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1b_closed:.fill SIZE,0b_nodes:.fill SIZE,0end: bcall(_ClrLCDFull) di ld hl,b_tilemap;x + y ld de,1+(6*WIDTH) ld bc,13+(5*WIDTH) add hl,de ;starting position in mapstart: ld de,CLOSED add hl,de ;b_closed ld (hl),1 ;starting position marked as ready to check add hl,de ;b_nodes ld (hl),0 ;first node starts off at 0 ld hl,b_closed add hl,bc ld (hl),$FF ld bc,SIZE ex af,af' ld a,%00110011 ex af,af' ld hl,b_closedsearch_outer: push hl push bc ex af,af' push af call disp_frame pop af ex af,af' pop bc pop hl di ld de,0search_loop: ld a,(hl) dec a jr nz,$+4 push hl inc e inc hl dec bc ld a,c or b jr nz,search_loop ;check if bc = 0, repeat if noretrieve_tiles: ld a,e or a jr z,+_ pop hl push de call expand_tile pop de dec e jr nz,retrieve_tiles_ ld hl,b_closed ;reset search values ld bc,SIZE ex af,af' rrca ;rotate to next part of pattern ex af,af' jr search_outerexpand_tile:;search_right inc (hl) ;set to 2 = closed inc hl ld a,(hl) inc a cp 2 call c,check_tilesearch_left: dec hl dec hl ld a,(hl) inc a cp 2 call c,check_tilesearch_down: inc hl ld de,WIDTH add hl,de ld a,(hl) inc a cp 2 call c,check_tilesearch_up: ld de,-WIDTH*2 add hl,de ld a,(hl) inc a cp 2 ret nccheck_tile: ld de,CLOSED or a sbc hl,de ;hl points to -b_tilemap- ld a,(hl) or a ;check if current tile = 0 add hl,de ;doesn't affect z, -b_closed- jr nz,$+4 ld (hl),1 ;1 = expand during next iteration cp 3 jr nz,$+4 ld (hl),'X'-'0' add hl,de ;hl points to -b_node- ex af,af' ld b,a and %1 ld (hl),a ;load the current pattern ld a,b ex af,af' sbc hl,de ;restore hl retdisp_frame: bcall(_HomeUp)display_smc = $+1 ld hl,b_tilemap ld bc,WIDTH*256+HEIGHTd_loop: push hl ld de,-b_tilemap add hl,de ld de,-SIZE add hl,de jr c,$-1 or a sbc hl,de ld de,b_tilemap add hl,de ld a,(hl) cp 1 pop hl ld a,(hl) jr nz,$+4 ld a,$E0-'0' add a,'0' bcall(_PutC) inc hl djnz d_loop ld de,(curRow) inc e ld d,0 ld (curRow),de ld b,WIDTH dec c jr nz,d_loop_ call pause ld a,b dec a ld de,SIZE rra rra jr c,+_ ld hl,(display_smc) sbc hl,de ld (display_smc),hl jr disp_frame_ rra ret c ld hl,(display_smc) add hl,de ld (display_smc),hl jr disp_framepause: call release_keyspause_loop: xor a call read_keys inc a jr z,pause_loop ld b,arelease_keys: xor a call read_keys inc a jr nz,release_keys ret;direct inputread_keys: out (1),a ; push af ;short delay pop af in a,(1) ret