示例#1
0
 public function run(array &$data)
 {
     $game = ModelGame::getCurrentGame();
     $id_game = $game->getId();
     SQLCommands::init($id_game);
     // running game (or newly started but countries are already picked)
     if ($game->getStatus() === GAME_STATUS_RUNNING || $game->getStatus() === GAME_STATUS_STARTED && $game->getIdPhase() === PHASE_SETSHIPS) {
         $query = 'get_map_for_running_game';
     } else {
         if ($game->getStatus() === GAME_STATUS_STARTED && $game->getIdPhase() === PHASE_SELECTSTART) {
             $query = 'get_map_for_new_game';
         } else {
             throw new MapException('invalid game selected: ' . $id_game);
         }
     }
     $result = DataSource::getInstance()->epp($query);
     $countryData = array();
     foreach ($result as $country) {
         // newly started game countries have to be picked -> no landunits/ships available
         if (array_key_exists('countrySelectOption', $country)) {
             $countryData[] = $country;
             continue;
         }
         // running game (or newly started but countries are already picked)
         // check landunits
         $unitCount = 0;
         $id_user = (int) $country['id_user'];
         if ($id_user <= 0) {
             $id_user = NEUTRAL_COUNTRY;
         }
         $units = ModelInGameLandUnit::getUnitsByIdZAreaUser($id_game, (int) $country['id'], $id_user);
         $unitsViewData = array();
         /* @var $unit ModelInGameLandUnit */
         foreach ($units as $unit) {
             $unitCount += $unit->getCount();
             $landUnit = ModelLandUnit::getModelById($unit->getIdUnit());
             $unitViewData = array('name' => $landUnit->getName(), 'count' => $unit->getCount());
             $unitsViewData[] = $unitViewData;
         }
         if ($unitCount > 0) {
             $country['units'] = $unitsViewData;
         }
         $country['unitCount'] = $unitCount;
         // check ships
         $shipCount = 0;
         $shipViewData = array();
         if ((int) $country['area_type'] === TYPE_LAND) {
             $ships = ModelInGameShip::getShipsInPort($id_game, (int) $country['id_zarea']);
         } else {
             $ships = ModelInGameShip::getShipsInAreaNotInPort($id_game, (int) $country['id_zarea']);
         }
         while ($ships->hasNext()) {
             /* @var $ship ModelInGameShip */
             $ship = $ships->next();
             $id_ship_owner = $ship->getIdUser();
             if (!isset($shipViewData[$id_ship_owner])) {
                 $shipViewData[$id_ship_owner] = array('username' => ModelUser::getUser($id_ship_owner)->getLogin(), 'ships' => array());
             }
             $shipType = ModelShip::getModelById($ship->getIdUnit());
             $currShipViewData = array('name' => $ship->getName(), 'type' => $shipType->getName(), 'diveStatus' => $ship->getDiveStatus(), 'experience' => $ship->getExperience());
             if ((int) $country['area_type'] === TYPE_LAND) {
                 $portToArea = ModelGameArea::getGameArea($id_game, $ship->getIdZArea());
                 $currShipViewData['port'] = $portToArea->getName();
                 $currShipViewData['portNumber'] = $portToArea->getNumber();
             }
             $shipViewData[$id_ship_owner]['ships'][] = $currShipViewData;
             ++$shipCount;
         }
         if ($shipCount > 0) {
             $country['ships'] = $shipViewData;
         }
         $country['shipCount'] = $shipCount;
         $countryData[] = $country;
     }
     $data['countryData'] = $countryData;
     return $data;
 }
 /**
  * checks if this move is valid, throws exception if not valid
  *
  * @param int $id_move
  * @param int $round
  * @param $steps array(int step_nr => int id_zarea) -> step_nr counting from 1 to x
  * @param $units array(int id_unit => count)
  * @throws NullPointerException
  * @throws ControllerException
  * @return boolean
  */
 private function validateLandMove($id_move, $round, $steps, $units)
 {
     $attacks = array();
     /*
      * check if user owns the start country
      */
     $id_start_area = $steps[1];
     $zArea = ModelGameArea::getGameArea($this->id_game, $id_start_area);
     if ($zArea->getIdUser() !== $this->id_user) {
         throw new ControllerException('Start country isn\'t owned by this user.');
     }
     /*
      * check if start area is land area
      */
     if ($zArea->getIdType() !== TYPE_LAND) {
         throw new ControllerException('Start area not a country.');
     }
     /*
      * check if enough units are left in the country -> iterate over all moves (except this), substract outgoing
      * check if there are any incoming units
      * count number of attacks
      */
     $ingameLandUnits = ModelInGameLandUnit::getUnitsByIdZAreaUser($this->id_game, $id_start_area, $this->id_user);
     //array(int id_unit => ModelInGameLandUnit)
     $area_units = array();
     $units_incoming = 0;
     $landUnitsIterator = ModelLandUnit::iterator();
     while ($landUnitsIterator->hasNext()) {
         /* @var $landUnit ModelLandMove */
         $landUnit = $landUnitsIterator->next();
         $id_unit = (int) $landUnit->getId();
         if (isset($ingameLandUnits[$id_unit])) {
             /* @var $ingameLandUnit ModelInGameLandUnit */
             $ingameLandUnit = $ingameLandUnits[$id_unit];
             $area_units[$id_unit] = $ingameLandUnit->getCount();
         } else {
             $area_units[$id_unit] = 0;
         }
     }
     $landMovesIterator = ModelLandMove::iterator($this->id_user, $this->id_game, $round);
     while ($landMovesIterator->hasNext()) {
         /* @var $landMove ModelLandMove */
         $landMove = $landMovesIterator->next();
         if ($landMove->getId() === $id_move) {
             continue;
             // only subtract units from other moves
         }
         $move_steps = $landMove->getSteps();
         $zTargetArea = ModelGameArea::getGameArea($this->id_game, end($move_steps));
         $zStartArea = ModelGameArea::getGameArea($this->id_game, reset($move_steps));
         // check if this is an attack
         if ($zTargetArea->getIdUser() !== $this->id_user && !in_array($zTargetArea->getId(), $attacks)) {
             $attacks[] = $zTargetArea->getId();
         }
         if ($zStartArea->getId() === $id_start_area) {
             $move_units = $landMove->getUnits();
             foreach ($move_units as $id_unit => $count) {
                 $area_units[$id_unit] -= $count;
             }
         } else {
             if ($zTargetArea->getId() === $id_start_area) {
                 $move_units = $landMove->getUnits();
                 foreach ($move_units as $id_unit => $count) {
                     $units_incoming += $count;
                 }
             }
         }
     }
     $total_units_left = $units_incoming;
     foreach ($area_units as $id_unit => $count) {
         if (isset($units[$id_unit]) && $units[$id_unit] > $count) {
             throw new ControllerException('Invalid move, not enough units in area.');
         }
         $count_leaving = isset($units[$id_unit]) ? $units[$id_unit] : 0;
         $total_units_left += $count - $count_leaving;
     }
     if ($total_units_left <= 0) {
         throw new ControllerException('Can\'t leave country empty.');
     }
     /*
      * check if target area is reachable -> 2 cases: type land or type aircraft movement
      */
     $id_target_area = (int) end($steps);
     $type = TYPE_AIR;
     $speed = 99999;
     foreach ($units as $id_unit => $count) {
         if ($count <= 0) {
             continue;
         }
         /* @var $landUnit ModelLandUnit */
         $landUnit = ModelLandUnit::getModelById((int) $id_unit);
         if ($landUnit->getIdType() < $type) {
             $type = $landUnit->getIdType();
         }
         if ($landUnit->getSpeed() < $speed) {
             $speed = $landUnit->getSpeed();
         }
     }
     if (!$this->checkPossibleRoute($id_start_area, $id_target_area, $type, $speed)) {
         throw new ControllerException('Unable to find route between the 2 countries.');
     }
     /*
      * check if target area is enemy area, only MAX_LAND_ATTACKS attacks per round
      */
     $zTargetArea = ModelGameArea::getGameArea($this->id_game, $id_target_area);
     if ($zTargetArea->getIdUser() !== $this->id_user) {
         // move is an attack
         if (!in_array($zTargetArea->getId(), $attacks)) {
             $attacks[] = $zTargetArea->getId();
         }
         if (count($attacks) > MAX_LAND_ATTACKS) {
             throw new ControllerException('Unable to start any more attacks! Only ' . MAX_LAND_ATTACKS . ' per round allowed.');
         }
     }
     /*
      * check if target area is land area
      */
     if ($zTargetArea->getIdType() != TYPE_LAND) {
         throw new ControllerException('Destination not a country.');
     }
     return true;
 }
 /**
  * checks if this move is valid, throws exception if not valid
  *
  * @param int $id_move
  * @param int $round
  * @param $steps array(int step_nr => int id_zarea) -> step_nr counting from 1 to x
  * @param $units array(int id_unit => count)
  * @throws NullPointerException
  * @throws ControllerException
  * @return boolean
  */
 private function validateMove($id_move, $round, $steps, $units)
 {
     /*
      * check if user owns the start country and if start area is land area
      */
     $id_start_area = $steps[1];
     $zArea = ModelGameArea::getGameArea($this->id_game, $id_start_area);
     if ($zArea->getIdUser() !== $this->id_user) {
         throw new ControllerException('Start country isn\'t owned by this user.');
     }
     /*
      * check if user owns destination area
      */
     if (ModelGameArea::getGameArea($this->id_game, end($steps))->getIdUser() !== $this->id_user) {
         throw new ControllerException('destination country isn\'t owned by this user.');
     }
     /*
      * check if enough units are left in the country -> iterate over all moves (except this), substract outgoing
      * check if there are any incoming units
      * count number of attacks
      */
     $ingameLandUnits = ModelInGameLandUnit::getUnitsByIdZAreaUser($this->id_game, $id_start_area, $this->id_user);
     //array(int id_unit => ModelInGameLandUnit)
     $area_units = array();
     $units_incoming = false;
     $units_left = false;
     $landUnitsIterator = ModelLandUnit::iterator();
     while ($landUnitsIterator->hasNext()) {
         /* @var $landUnit ModelTroopsMove */
         $landUnit = $landUnitsIterator->next();
         $id_unit = (int) $landUnit->getId();
         if (isset($ingameLandUnits[$id_unit])) {
             /* @var $ingameLandUnit ModelInGameLandUnit */
             $ingameLandUnit = $ingameLandUnits[$id_unit];
             $area_units[$id_unit] = $ingameLandUnit->getCount();
         } else {
             $area_units[$id_unit] = 0;
         }
     }
     $movesIterator = ModelTroopsMove::iterator($this->id_user, $this->id_game, $round);
     while ($movesIterator->hasNext()) {
         /* @var $troopsMove ModelTroopsMove */
         $troopsMove = $movesIterator->next();
         if ($troopsMove->getId() === $id_move) {
             continue;
             // only subtract units from other moves
         }
         $move_steps = $troopsMove->getSteps();
         $zTargetArea = ModelGameArea::getGameArea($this->id_game, end($move_steps));
         $zStartArea = ModelGameArea::getGameArea($this->id_game, reset($move_steps));
         if ($zStartArea->getId() === $id_start_area) {
             $move_units = $troopsMove->getUnits();
             foreach ($move_units as $id_unit => $count) {
                 $area_units[$id_unit] -= $count;
             }
         } else {
             if ($zTargetArea->getId() === $id_start_area) {
                 $move_units = $troopsMove->getUnits();
                 foreach ($move_units as $id_unit => $count) {
                     if ($count > 0) {
                         $units_incoming = true;
                     }
                 }
             }
         }
     }
     foreach ($area_units as $id_unit => $count) {
         if (isset($units[$id_unit]) && $units[$id_unit] > $count) {
             throw new ControllerException('Invalid move, not enough units in area.');
         }
         $count_leaving = isset($units[$id_unit]) ? $units[$id_unit] : 0;
         if ($count - $count_leaving > 0) {
             $units_left = true;
         }
     }
     if (!$units_incoming && !$units_left) {
         throw new ControllerException('Can\'t leave country empty.');
     }
     /*
      * check if target area is reachable -> 2 cases: type land or type aircraft movement
      */
     $id_target_area = (int) end($steps);
     $type = TYPE_AIR;
     foreach ($units as $id_unit => $count) {
         if ($count <= 0) {
             continue;
         }
         /* @var $landUnit ModelLandUnit */
         $landUnit = ModelLandUnit::getModelById((int) $id_unit);
         if ($landUnit->getIdType() < $type) {
             $type = $landUnit->getIdType();
         }
     }
     if (!$this->checkPossibleRoute($id_start_area, $id_target_area, $type)) {
         throw new ControllerException('Unable to find route between the 2 countries.');
     }
     return true;
 }