338 lines
7.7 KiB
Plaintext
338 lines
7.7 KiB
Plaintext
|
note
|
||
|
description: "[
|
||
|
Root class for all the locations (ports, sea-areas, bases) in VITP.
|
||
|
]"
|
||
|
author: "Jimmy J. Johnson"
|
||
|
|
||
|
deferred class
|
||
|
LOCATION
|
||
|
|
||
|
inherit
|
||
|
|
||
|
VITP_ITEM
|
||
|
redefine
|
||
|
make
|
||
|
end
|
||
|
|
||
|
feature {NONE} -- Initialization
|
||
|
|
||
|
make (a_game: like game)
|
||
|
-- Initialize Current
|
||
|
do
|
||
|
Precursor (a_game)
|
||
|
-- create defining_position
|
||
|
create units_imp.make
|
||
|
is_stable := True
|
||
|
-- defining_cell := game.
|
||
|
end
|
||
|
|
||
|
feature -- Access
|
||
|
|
||
|
defining_position: TUPLE [x, y: INTEGER_32]
|
||
|
-- The x- and y-coordinate (in millimeters) of Current's
|
||
|
-- position relative to the top-left corner of the board.
|
||
|
deferred
|
||
|
end
|
||
|
|
||
|
defining_cell: VITP_CELL
|
||
|
-- The "central" cell for Current, around which its
|
||
|
-- positioning `grid' is built.
|
||
|
local
|
||
|
x, y: INTEGER_32
|
||
|
once
|
||
|
x := ((defining_position.x + game.board_left) / game.cell_size).truncated_to_integer + 1
|
||
|
y := ((defining_position.y + game.board_top) / game.cell_size).truncated_to_integer + 1
|
||
|
Result := game.cell (x, y)
|
||
|
end
|
||
|
|
||
|
units: LINKED_SET [like unit_anchor]
|
||
|
-- Copy of the list of units in current.
|
||
|
-- Why do I have this feature?
|
||
|
do
|
||
|
print ("LOCATION.units: why have this feature? %N");
|
||
|
Result := units_imp.twin
|
||
|
end
|
||
|
|
||
|
japanese_units: LINKED_SET [like unit_anchor]
|
||
|
-- All the japanese units in Current
|
||
|
do
|
||
|
create Result.make
|
||
|
from units_imp.start
|
||
|
until units_imp.exhausted
|
||
|
loop
|
||
|
if units_imp.item.nationality = game.Japanese then
|
||
|
Result.extend (units_imp.item)
|
||
|
end
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
allied_units: LINKED_SET [like unit_anchor]
|
||
|
-- All the allied units in Current
|
||
|
do
|
||
|
create Result.make
|
||
|
from units_imp.start
|
||
|
until units_imp.exhausted
|
||
|
loop
|
||
|
if units_imp.item.nationality /= game.Japanese then
|
||
|
Result.extend (units_imp.item)
|
||
|
end
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
adjacent_sea_areas: LINEAR [SEA_AREA]
|
||
|
-- A list of all sea areas that touch this location
|
||
|
deferred
|
||
|
end
|
||
|
|
||
|
feature -- Status report
|
||
|
|
||
|
is_port: BOOLEAN
|
||
|
-- Is the location a {PORT}?
|
||
|
do
|
||
|
Result := Current.conforms_to ({PORT})
|
||
|
end
|
||
|
|
||
|
is_sea_area: BOOLEAN
|
||
|
-- Is the location a {SEA_AREA}?
|
||
|
do
|
||
|
Result := Current.conforms_to ({SEA_AREA})
|
||
|
end
|
||
|
|
||
|
feature -- Basic operations
|
||
|
|
||
|
put (a_unit: like unit_anchor)
|
||
|
-- Ensure `a_unit' is in Current
|
||
|
require
|
||
|
unit_exists: a_unit /= Void
|
||
|
-- valid_move: a_unit.is_valid_move (Current)
|
||
|
do
|
||
|
is_stable := False
|
||
|
units_imp.put (a_unit)
|
||
|
if a_unit.location /= Current then
|
||
|
a_unit.set_location (Current)
|
||
|
end
|
||
|
is_stable := True
|
||
|
ensure
|
||
|
has_unit: has (a_unit)
|
||
|
location_integrity: a_unit.location = Current
|
||
|
end
|
||
|
|
||
|
prune (a_unit: like unit_anchor)
|
||
|
-- Ensure `a_unit' is NOT in Current
|
||
|
require
|
||
|
unit_exists: a_unit /= Void
|
||
|
do
|
||
|
is_stable := False
|
||
|
if has (a_unit) then
|
||
|
units_imp.prune (a_unit)
|
||
|
end
|
||
|
is_stable := True
|
||
|
ensure
|
||
|
not_has_unit: not has (a_unit)
|
||
|
end
|
||
|
|
||
|
feature -- Query
|
||
|
|
||
|
-- friendly_ports (a_nationality: NATIONALITY): LINKED_SET [PORT]
|
||
|
-- -- Of the `adjoining_ports' the ones that are friendly to `a_nationality'
|
||
|
-- local
|
||
|
-- p: like adjoining_ports
|
||
|
-- do
|
||
|
-- create Result.make
|
||
|
-- from ports.start
|
||
|
-- until ports.exhausted
|
||
|
-- loop
|
||
|
-- if not ports.item.is_enemy_controlled (a_nationality) then
|
||
|
-- Result.extend (ports.item)
|
||
|
-- end
|
||
|
-- ports.forth
|
||
|
-- end
|
||
|
-- end
|
||
|
|
||
|
distance_to (other: LOCATION): INTEGER
|
||
|
-- The distance between Current and `other'
|
||
|
do
|
||
|
io.put_string ("LOCATION.distance_to: Fix me - move functionality to VITP_GAME? %N")
|
||
|
Result := {INTEGER_32}.max_value
|
||
|
end
|
||
|
|
||
|
is_enemy_controlled (a_nationality: like game.japanese): BOOLEAN
|
||
|
-- Is the location controlled by the other side?
|
||
|
do
|
||
|
Result := (game.is_allied_nationality (a_nationality) and not game.is_allied_nationality (nationality)) or
|
||
|
(not game.is_allied_nationality (a_nationality) and game.is_allied_nationality (nationality))
|
||
|
end
|
||
|
|
||
|
has (a_unit: like unit_anchor): BOOLEAN
|
||
|
-- Does Current contain `a_unit'?
|
||
|
require
|
||
|
unit_exists: a_unit /= Void
|
||
|
do
|
||
|
Result := units_imp.has (a_unit)
|
||
|
end
|
||
|
|
||
|
has_allied: BOOLEAN
|
||
|
-- Does this location have any allied game piece here?
|
||
|
local
|
||
|
u: like unit_anchor
|
||
|
do
|
||
|
from units_imp.start
|
||
|
until Result or else units_imp.after
|
||
|
loop
|
||
|
u := units_imp.item
|
||
|
Result := game.is_allied_nationality (u.nationality)
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_japanese: BOOLEAN
|
||
|
-- Does this location have any japanese game piece here?
|
||
|
local
|
||
|
u: like unit_anchor
|
||
|
do
|
||
|
from units_imp.start
|
||
|
until Result or else units_imp.after
|
||
|
loop
|
||
|
u := units_imp.item
|
||
|
Result := not game.is_allied_nationality (u.nationality)
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_japanese_patroller: BOOLEAN
|
||
|
-- Does this location contain at least one Japanese patroller?
|
||
|
local
|
||
|
u: like unit_anchor
|
||
|
do
|
||
|
from units_imp.start
|
||
|
until Result or else units_imp.after
|
||
|
loop
|
||
|
u := units_imp.item
|
||
|
Result := u.is_patrolling and then
|
||
|
not game.is_allied_nationality (u.nationality)
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_allied_patroller: BOOLEAN
|
||
|
-- Does this location contain at least one Japanese patroller?
|
||
|
local
|
||
|
u: like unit_anchor
|
||
|
do
|
||
|
from units_imp.start
|
||
|
until Result or else units_imp.after
|
||
|
loop
|
||
|
u := units_imp.item
|
||
|
Result := u.is_patrolling and then
|
||
|
game.is_allied_nationality (u.nationality)
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_japanese_air_raiders: BOOLEAN
|
||
|
-- Does Current contain any Japanese carriers?
|
||
|
-- (Carriers are the only units that can air raid.)
|
||
|
local
|
||
|
set: like japanese_units
|
||
|
do
|
||
|
set := japanese_units
|
||
|
from set.start
|
||
|
until set.exhausted or Result
|
||
|
loop
|
||
|
Result := attached {SHIP} set.item as s and then s.airstrike_factor > 0
|
||
|
set.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_allied_air_raiders: BOOLEAN
|
||
|
-- Does Current contain any Japanese carriers?
|
||
|
-- (Carriers are the only units that can air raid.)
|
||
|
local
|
||
|
set: like allied_units
|
||
|
do
|
||
|
set := allied_units
|
||
|
from set.start
|
||
|
until set.exhausted or Result
|
||
|
loop
|
||
|
Result := attached {SHIP} set.item as s and then s.airstrike_factor > 0
|
||
|
set.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_allied_amphibious: BOOLEAN
|
||
|
-- Does Current contain any Allied amphibious units?
|
||
|
local
|
||
|
set: like allied_units
|
||
|
do
|
||
|
set := allied_units
|
||
|
from set.start
|
||
|
until set.exhausted or Result
|
||
|
loop
|
||
|
Result := attached {AMPHIBIOUS_UNIT} set.item
|
||
|
set.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
has_japanese_amphibious: BOOLEAN
|
||
|
-- Does Current contain any Japanese amphibious units?
|
||
|
local
|
||
|
set: like japanese_units
|
||
|
do
|
||
|
set := japanese_units
|
||
|
from set.start
|
||
|
until set.exhausted or Result
|
||
|
loop
|
||
|
Result := attached {AMPHIBIOUS_UNIT} set.item
|
||
|
set.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
feature {NONE} -- Implementation
|
||
|
|
||
|
units_imp: LINKED_SET [like unit_anchor]
|
||
|
-- The units that are in this location
|
||
|
|
||
|
has_invalid_unit: BOOLEAN
|
||
|
-- Does Current contain a unit that does not refer back to Current?
|
||
|
-- For invariant checking
|
||
|
-- Should always be false
|
||
|
require
|
||
|
call_only_when_stable: is_stable
|
||
|
do
|
||
|
from units_imp.start
|
||
|
until Result or units_imp.exhausted
|
||
|
loop
|
||
|
Result := units_imp.item.location /= Current
|
||
|
units_imp.forth
|
||
|
end
|
||
|
end
|
||
|
|
||
|
is_stable: BOOLEAN
|
||
|
-- Set to false when pruning and adding units for invariant checking
|
||
|
-- of referential integrity between units and locations
|
||
|
|
||
|
feature {NONE} -- Anchors (for covariant redefinitions)
|
||
|
|
||
|
unit_anchor: ATTACK_UNIT
|
||
|
-- Anchor for features using units.
|
||
|
-- Not to be called; just used to anchor types.
|
||
|
-- Declared as a feature to avoid adding an attribute.
|
||
|
require
|
||
|
not_callable: False
|
||
|
do
|
||
|
check
|
||
|
do_not_call: False then
|
||
|
-- Because give no info; simply used as anchor.
|
||
|
end
|
||
|
end
|
||
|
|
||
|
invariant
|
||
|
|
||
|
valid_controller: nationality = game.japanese or nationality = game.us or nationality = game.nobody
|
||
|
|
||
|
all_units_imp_refer_to_current: is_stable implies not has_invalid_unit
|
||
|
|
||
|
end
|