-- A mobile piece that chases the Stooge deferred class ANACONDA inherit AUTO_MOBILE rename time_remaining as am_time_remaining -- perhaps just temporary undefine receive_bullet, restart, build_record, customized_init redefine react_to_first_movement, react, win, try_north, try_south, try_west, try_east, init, clear, wake_up, try_to_move end CHANGELING rename vacate as depart, occupy as visit undefine depart, win, build_record, create_record, customized_init redefine restart, react, react_to_first_movement, init, wake_up, clear, receive_bullet, build_record, customized_init end feature{NONE} can_move : BOOLEAN is -- I can move if I'm present do Result := present end -- deferred in AUTO_MOBILE -- Not used since there are three strategies here, hound, tendency and random strategy : STRATEGY period : INTEGER is 500 init( r : like room ; c : like northwest ) is do {CHANGELING}precursor( r, c ) -- {AUTO_MOBILE} precursor( r, c ) present := True -- Does start_moving in AUTO_MOBILE do this? -- Mobile_Medusa has the same line commented out. !!move_event.make_periodic( Current, period ) initialize_strategies end vanish is -- I go bye-bye deferred end appear is -- I'm ba-ack deferred end display_east is -- Look eastward deferred end display_west is -- Look westward deferred end stooge_is_neighbor : BOOLEAN is -- Am I next to the Stooge? do Result := ( ( stooge.northwest.row - northwest.row ).abs <= 1 and ( stooge.northwest.column - northwest.column ).abs = 2 ) or ( ( stooge.northwest.column - northwest.column ).abs <= 1 and ( stooge.northwest.row - northwest.row ).abs = 2 ) end -- The steps I have taken while using a particular strategy steps : INTEGER no_more_steps : BOOLEAN is do Result := ( steps = 0 ) end -- Random number of steps to take before I try another strategy total_steps : RANDOM_INTEGERS is -- Random number generator for when I don't have a clue -- where to move. once !!Result.make end tendency : TENDENCY hound : BLOODHOUND random : RANDOM_MOVE initialize_strategies is do create hound.make( Current ) create tendency.make( Current ) create random.make( Current ) end face_stooge is do if stooge.northwest.column < northwest.column then display_west else display_east end end feature{NONE} -- Stuck anachonda -- Keep the anaconda from getting stuck at the end of a spoor -- trail which occurs if Stoge teleports. If other pieces are -- allowed to teleport, then this code may be removed. previous_spoor, same_spoor_count, skip_hound_steps : INTEGER same_spoor_threshold : INTEGER is 2 resume_spoor_search : BOOLEAN is do Result := ( skip_hound_steps = 5 ) end lost_trail : BOOLEAN is -- the anaconda is stuck at the end of a spoor trail do Result := ( same_spoor_count > same_spoor_threshold ) end check_new_spoor is -- Has the anaconda encountered the same spoor while on the spoor trail? -- if so increment the same spoor count. do if( northwest.spoor = previous_spoor and previous_spoor /= 0 ) then same_spoor_count := same_spoor_count + 1 end -- record the previous spoor for the next time the anaconda moves previous_spoor := northwest.spoor end restart_unstick_values is do previous_spoor := 0 same_spoor_count := 0 skip_hound_steps := 0 end feature blocks_glare : BOOLEAN is True receive_bullet is -- Change to egg and stop moving. do -- precursor {CHANGELING}precursor stop_moving end try_to_move is -- Try to move, gotta get that Stooge! do -- Anaconda's strategy should really be a composite strategy. -- That composite should know about 'hound' and the others, -- thus keeping this code simple. success := False if lost_trail then -- the trail has been lost so skip the bloodhound strategy for a while skip_hound_steps := skip_hound_steps + 1 if resume_spoor_search then same_spoor_count := 0 skip_hound_steps := 0 end else -- first try bloodhound strategy if the trail has not been lost hound.try_move end if not success then -- bloodhound strategy failed to move the Anaconda if no_more_steps then -- the anaconda was not previously taking steps under a random strategy -- so try a tendency strategy next tendency.try_move if not success then -- tendency strategy failed to move the Anaconda -- set up a random number of steps to for the Anaconda to take total_steps.randomize( 10 ) steps := total_steps.random_integer + 1 -- then try a random strategy last random.try_move end else -- the anaconda was previously taking steps under a random strategy -- so lets continue to do so steps := steps - 1 random.try_move end else -- bloodhound strategy moved the Anaconda and may have preempted -- a random strategy so reset the steps to 0 -- check if the current spoor is the same as the last one -- which means the Anaconda may be stuck at the end of a trail check_new_spoor steps := 0 end if success then room.react end end react_to_first_movement is do if present then {AUTO_MOBILE} precursor steps := 0 end end win is -- The Stooge wins! I disappear! do {AUTO_MOBILE}precursor clear_timer vanish end restart is do stop_moving hound.init_spoor restart_unstick_values appear {CHANGELING}precursor end react is -- Kill stooge if she's in reach. do face_stooge if present and then stooge_is_neighbor then -- begin Rob add if not stooge.invincible then -- end rob add stooge.die -- begin rob add end -- end rob add end end -- Should be able to get away without redefining these. An -- Auto_mobile's try code should only be called as a result -- of try_to_move, so put the check for success there, and -- restrict export of these. try_west is do precursor if success then react end end try_east is do precursor if success then react end end try_north is do precursor if success then react end end try_south is do precursor if success then react end end wake_up( e : TM_EVENT ) is -- Move or reappear, depending on `e'. do if e = move_event then try_to_move else reappear if present then start_moving end end end clear is do {AUTO_MOBILE} precursor {CHANGELING}precursor end feature -- save/restore build_record is -- from CHANGELING -- 1 id -- 2 if egg exists egg col -- 3 if egg exists egg row -- 2 else piece col -- 3 else piece row -- 4 starting cell col -- 5 starting cell row -- 6 state -- 7 if state = egg or state = waiting to return, then time remaining -- from build_time_remaining in AUTOMOBILE -- 8 is_moving -- 9 if is_moving is true, then time_remaining -- 10 steps -- 11 previous_spoor -- 12 same_spoor_count -- 13 skip_hound_steps do {CHANGELING}precursor build_time_remaining record.extend( steps ) record.extend( previous_spoor ) record.extend( same_spoor_count ) record.extend( skip_hound_steps ) ensure then proper_num_rec: record.count > 10 end -- build_record feature{NONE} -- save/restore customized_init( r : like room ; pr : like record ) is do {CHANGELING}precursor( r, pr ) customized_init_time_remaining( pr ) pr.forth steps := pr.item pr.forth previous_spoor := pr.item pr.forth same_spoor_count := pr.item pr.forth skip_hound_steps := pr.item initialize_strategies end -- customized_init end