-- Tries to kill the Stooge with her glare. Will smile
-- when the Stooge is in sight or within one step of
-- being in sight. Succeeds in killing the Stooge if said Stooge
-- shares same row or column and nothing between the two 
-- blocks Medusa's glare.


deferred class MEDUSA

inherit

  GAME_PIECE
  redefine
    react, win, restart, build_record, customized_init
  end


feature{NONE}

  display_smile is
  deferred
  end

  display_frown is
  deferred
  end

  vanish is
  deferred
  end

  appear is
  deferred
  end

  display_rock is
  deferred
  end

  display_medusa is
  deferred
  end

  become_rock is
  -- Take on the aspects of a rock.
  do
    is_rock := True
    display_rock
  end

  become_medusa is
  -- Return to medusa state.
  do
     is_rock := False
     display_medusa
  end

  smile is
  -- I'm gonna get him!
  do
    is_smiling := True
    display_smile
  end

  frown is
  -- Where's the Stooge?
  do
    is_smiling := False
    display_frown
  end

feature -- save/restore

  build_record is
-- from MOBILE_MEDUSA:
-- 1 through ( 6 or 7 ) from AUTO_MOBILE
-- 8  vanished from MEDUSA
-- 9  is_rock from MEDUSA
-- 10 strategy direction MOBILE_MEDUSA
-- 11 initial_direction MOBILE_MEDUSA

-- from SESSILE_MEDUSA:
-- 1,2,3 from GAME_PIECE 
-- 4 vanished from MEDUSA
-- 5 is_rock from MEDUSA 

  do
-- Both SESSILE_MEDUSAE and MOBILE_MEDUSAE must get to build_record
-- of GAME_PIECE by another inheritance path
    if vanished then
      record.extend( 0 )
    else
      record.extend( 1 )
    end
    if is_rock then
      record.extend( 0 )
    else
      record.extend( 1 )
    end
-- Based on inheritance path from SESSILE_MEDUSA
  ensure then
    proper_num_rec: record.count > 4
  end

feature{NONE} -- save/restore

  customized_init( r : like room ; pr : like record ) is
  do
    pr.forth
    if pr.item = 0 then
      vanished := True
      display_vacate
    else 
      vanished := False
      occupy( northwest )
    end
    pr.forth
    if pr.item = 0 then
      become_rock
    end
  end

feature

  blocks_glare : BOOLEAN is True
  blocks_shots : BOOLEAN is True

  win is
  -- The Stooge wins! I disappear!
  do
    vanish
    vanished := True
  end

  vanished : BOOLEAN
  -- Have I been claimed by the Stooge.

  restart is
  do
    precursor
    become_medusa
    appear
    vanished := False
  ensure then
    not is_rock
  end

  react is
  -- If I can see the Stooge, smile and try to kill him, 
  -- else frown.
  do
    if not is_rock then
      if (stooge.northwest.row - northwest.row).abs <= 1 or else
         (stooge.northwest.column - northwest.column).abs <= 1 then
        smile
        try_to_kill
      else
        frown
      end
    end
  end

  receive_own_glare is
  -- Yikes! It...it...it's me!! Turn into a rock if my own glare is
  -- reflected back at me.
  do
     become_rock
  ensure
     is_rock
  end

  is_rock : BOOLEAN
  -- Have I been stoned?

  is_smiling : BOOLEAN
  -- Do I have a good look at the Stooge?


feature{NONE}

  try_to_kill is
  -- I'm gonna glare in the Stooge's direction!
  require
    stooge /= Void
  do
    if stooge.northwest.row = northwest.row then
      if stooge.northwest.column < northwest.column then
        glare_west
      else
        glare_east
      end
    elseif stooge.northwest.column = northwest.column then
      if stooge.northwest.row < northwest.row then
        glare_north
      else
        glare_south
      end
    end
  end

  glare_south is
  -- The Stooge is all lined up south of me. Kill him unless
  -- there's something in my way!.
  require
    stooge /= Void
  local
    c1, c2 : GAME_CELL
  do
    from
      c1 := southwest.south
      c2 := southeast.south
    until
      c1.blocks_glare or c2.blocks_glare
    loop
      c1 := c1.south
      c2 := c2.south
    end
    if c1.visited and then c1.visitor = stooge then
      stooge.receive_glare( Current )
    end
  end

  glare_north is
  -- The Stooge is all lined up north of me. Kill him unless
  -- there's something in my way!.
  require
    stooge /= Void
  local
    c1, c2 : GAME_CELL
  do
    from
      c1 := northwest.north
      c2 := northeast.north
    until
      c1.blocks_glare or c2.blocks_glare
    loop
      c1 := c1.north
      c2 := c2.north
    end
    if c1.visited and then c1.visitor = stooge then
      stooge.receive_glare( Current )
    end
  end

  glare_east is
  -- The Stooge is all lined up east of me. Kill him unless
  -- there's something in my way!.
  require
    stooge /= Void
  local
    c1, c2 : GAME_CELL
  do
    from
      c1 := northeast.east
      c2 := southeast.east
    until
      c1.blocks_glare or c2.blocks_glare
    loop
      c1 := c1.east
      c2 := c2.east
    end
    if c1.visited and then c1.visitor = stooge then
      stooge.receive_glare( Current )
    end
  end

  glare_west is
  -- The Stooge is all lined up west of me. Kill him unless
  -- there's something in my way!.
  require
    stooge /= Void
  local
    c1, c2 : GAME_CELL
  do
    from
      c1 := southwest.west
      c2 := northwest.west
    until
      c1.blocks_glare or c2.blocks_glare
    loop
      c1 := c1.west
      c2 := c2.west
    end
    if c1.visited and then c1.visitor = stooge then
      stooge.receive_glare( Current )
    end
  end

end 
