/**
  * returns all models for the given area/user
  *
  * @param $id_game int
  * @param $id_zarea int
  * @param $id_user int
  * @return array - array(int id_unit => ModelInGameLandUnit)
  */
 public static function getUnitsByIdZAreaUser($id_game, $id_zarea, $id_user)
 {
     $output = array();
     $iter = ModelLandUnit::iterator();
     while ($iter->hasNext()) {
         $landUnit = $iter->next();
         $id_unit = (int) $landUnit->getId();
         $output[$id_unit] = self::getModelByIdZAreaUserUnit($id_game, $id_zarea, $id_user, $id_unit);
     }
     return $output;
 }
 private function validateNewProductionMove($round, $id_zarea, array $units)
 {
     // 1. check if zarea belongs to user
     $gameArea = ModelGameArea::getGameArea($this->id_game, $id_zarea);
     if ($this->id_user !== $gameArea->getIdUser()) {
         throw new ControllerException('Unable to create production move. Area doesn\'t belong to the current user.');
     }
     // 2. check if user has enough res left
     // 2.a check cost of previous productions
     $current_costs = 0;
     $moves = ModelProductionMove::iterator($this->id_user, $this->id_game, $round);
     while ($moves->hasNext()) {
         /* @var $move ModelProductionMove */
         $move = $moves->next();
         $current_costs += $move->getCost();
     }
     // 2.b get available res
     $current_production = UserViewHelper::getCurrentProductionForUserInGame($this->id_user, $this->id_game);
     // 2.c get cost of new move
     $new_cost = 0;
     $unit_iter = ModelLandUnit::iterator();
     while ($unit_iter->hasNext()) {
         /* @var $unit ModelLandUnit */
         $unit = $unit_iter->next();
         $id_unit = (int) $unit->getId();
         if (!isset($units[$id_unit]) || $units[$id_unit] <= 0) {
             continue;
         }
         $new_cost += (int) $unit->getPrice() * $units[$id_unit];
     }
     if ($current_production['sum'] - $current_costs < $new_cost) {
         throw new ControllerException('Insufficient funds!');
     }
 }
Ejemplo n.º 3
0
 private function handleInput(array &$data)
 {
     if (empty($_POST)) {
         return;
     }
     $controller = new LandMoveController(ModelUser::getCurrentUser()->getId(), ModelGame::getCurrentGame()->getId());
     // fixating land move
     if (isset($_POST['fixate_land_move'])) {
         $controller->finishMove();
         return;
     }
     // deleting land move
     if (isset($_POST['delete'])) {
         try {
             $controller->deleteLandMove(intval($_POST['delete']));
             $data['status'] = array('message' => 'Landzug gelöscht.');
         } catch (NullPointerException $ex) {
             $data['errors'] = array('message' => $ex->getMessage());
         } catch (ControllerException $ex) {
             $data['errors'] = array('message' => $ex->getMessage());
         } finally {
             return;
         }
     }
     // creating new land move
     if (isset($_POST['newmove'])) {
         try {
             if (!isset($_POST['start']) || !isset($_POST['destination'])) {
                 $data['errors'] = array('message' => 'Missing parameter!');
                 return;
             }
             $units = array();
             $iter = ModelLandUnit::iterator();
             while ($iter->hasNext()) {
                 /* @var $unit ModelLandUnit */
                 $unit = $iter->next();
                 $abbr = $unit->getAbbreviation();
                 $id_unit = $unit->getId();
                 $units[$id_unit] = isset($_POST[$abbr]) ? intval($_POST[$abbr]) : 0;
             }
             $controller->createLandMove(intval($_POST['start']), intval($_POST['destination']), $units);
             $data['status'] = array('message' => 'Landzug erstellt.');
         } catch (NullPointerException $ex) {
             $data['errors'] = array('message' => $ex->getMessage());
         } catch (ControllerException $ex) {
             $data['errors'] = array('message' => $ex->getMessage());
         }
     }
 }
 /**
  * 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;
 }
Ejemplo n.º 5
0
 private function showNewMove(array &$data)
 {
     $areasViewData = array();
     $areas = ModelArea::iterator(TYPE_LAND);
     while ($areas->hasNext()) {
         /* @var $area ModelArea */
         $area = $areas->next();
         $zArea = ModelGameArea::getGameAreaForArea(ModelGame::getCurrentGame()->getId(), $area->getId());
         $areaViewData = array();
         $areaViewData['id_zarea'] = $zArea->getId();
         $areaViewData['number'] = $area->getNumber();
         $areaViewData['name'] = $area->getName();
         if ($zArea->getIdUser() === ModelUser::getCurrentUser()->getId()) {
             $areasViewData[] = $areaViewData;
         }
     }
     $data['areas'] = $areasViewData;
     $unitsViewData = array();
     $unit_iter = ModelLandUnit::iterator();
     while ($unit_iter->hasNext()) {
         /* @var $unit ModelLandUnit */
         $unit = $unit_iter->next();
         $unitsViewData[] = array('id' => $unit->getId(), 'name' => $unit->getName());
     }
     $data['units'] = $unitsViewData;
 }
Ejemplo n.º 6
0
 private function executeAttack($id_target_area, array $moves)
 {
     // 0. init empty arrays for attacker/defender units
     $units_attacker = array();
     $units_defender = array();
     // 1. get units for defender
     $target_area = ModelGameArea::getGameArea($this->id_game, $id_target_area);
     $id_defender = $target_area->getIdUser();
     $iter = ModelLandUnit::iterator();
     while ($iter->hasNext()) {
         /* @var ModelLandUnit $unit */
         $unit = $iter->next();
         $units_attacker[$unit->getId()] = 0;
         $landUnit_defender = ModelInGameLandUnit::getModelByIdZAreaUserUnit($this->id_game, $id_target_area, $id_defender, $unit->getId());
         $units_defender[$unit->getId()] = $landUnit_defender->getCount();
     }
     // 2. add up all units for attacker (multiple moves possible, check already finished moves from NML-fights)
     // 2.a subtract units from originating country
     $id_attacker = 0;
     foreach ($moves as $id_move) {
         $move = ModelLandMove::getLandMove($this->id_game, $id_move);
         $id_user = $move->getIdUser();
         $id_attacker = $id_user;
         $steps = $move->getSteps();
         $from = reset($steps);
         $units = $move->getUnits();
         foreach ($units as $id_unit => $count) {
             $landUnit_from = ModelInGameLandUnit::getModelByIdZAreaUserUnit($this->id_game, $from, $id_user, $id_unit);
             $landUnit_from->addCount($count * -1);
             $units_attacker[$id_unit] += $count;
         }
     }
     // 3. calculate winner and remaining units
     $attacker_wins = $this->calculateFight($units_attacker, $units_defender);
     // 3.a update defender units
     $iter = ModelLandUnit::iterator();
     while ($iter->hasNext()) {
         /* @var ModelLandUnit $unit */
         $unit = $iter->next();
         $landUnit_defender = ModelInGameLandUnit::getModelByIdZAreaUserUnit($this->id_game, $id_target_area, $id_defender, $unit->getId());
         $landUnit_defender->setCount($units_defender[$unit->getId()]);
     }
     // 4. update target country units (and user if attacker won)
     if ($attacker_wins) {
         // 4.a update attacker units
         $iter = ModelLandUnit::iterator();
         while ($iter->hasNext()) {
             /* @var ModelLandUnit $unit */
             $unit = $iter->next();
             $landUnit_attacker = ModelInGameLandUnit::getModelByIdZAreaUserUnit($this->id_game, $id_target_area, $id_attacker, $unit->getId());
             $landUnit_attacker->setCount($units_attacker[$unit->getId()]);
         }
         // 4.b update country owner
         $area = ModelGameArea::getGameArea($this->id_game, $id_target_area);
         $area->setIdUser($id_attacker);
         // 4.c check ships
         // TODO : implement ship takeover or ship destruction
     }
     // 4. flag all moves as finished
     foreach ($moves as $id_move) {
         $this->finished_moves[] = $id_move;
     }
 }
 /**
  * @throws NullPointerException
  * @return int total cost of this production move (all units)
  */
 public function getCost()
 {
     $costsSum = 0;
     $unit_iter = ModelLandUnit::iterator();
     while ($unit_iter->hasNext()) {
         /* @var $unit ModelLandUnit */
         $unit = $unit_iter->next();
         $id_unit = (int) $unit->getId();
         if (!isset($this->units[$id_unit]) || $this->units[$id_unit] <= 0) {
             continue;
         }
         $costsSum += (int) $unit->getPrice() * $this->units[$id_unit];
     }
     return $costsSum;
 }
Ejemplo n.º 8
0
 /**
  * run the game logic
  *
  * @throws LogicException
  * @return void
  */
 public function run()
 {
     if (!$this->checkIfValid()) {
         throw new LogicException('Game ' . $this->id_game . ' not valid for processing.');
     }
     $this->startProcessing();
     try {
         // run through moves for each user
         $iter = ModelSelectStartMove::iterator($this->id_game);
         while ($iter->hasNext()) {
             // areas to select for user
             $selectStartMove = $iter->next();
             $regions_selected = $selectStartMove->getRegions();
             // array(int option_number => array(int id_zarea))
             $id_user = $selectStartMove->getIdUser();
             /* @var $iigi ModelIsInGameInfo */
             $iigi = ModelIsInGameInfo::getIsInGameInfo($id_user, $this->id_game);
             $id_set = $iigi->getIdStartingSet();
             foreach ($regions_selected as $option_number => $areas) {
                 $regions = ModelStartRegion::getRegionsForSetAndOption($id_set, $option_number);
                 // array(int id_area => ModelStartRegion)
                 foreach ($areas as $id_zarea) {
                     $gameArea = ModelGameArea::getGameArea($this->id_game, $id_zarea);
                     $id_area = $gameArea->getIdArea();
                     /* @var $region ModelStartRegion */
                     $region = $regions[$id_area];
                     $id_option = $region->getIdOptionType();
                     $unit_count = ModelOptionType::getOptionType($id_option)->getUnits();
                     // set user for game area
                     $gameArea->setIdUser($id_user);
                     // create units for user
                     $iterUnits = ModelLandUnit::iterator();
                     while ($iterUnits->hasNext()) {
                         $landUnit = $iterUnits->next();
                         $id_unit = $landUnit->getId();
                         $inGameLandUnit = ModelInGameLandUnit::getModelByIdZAreaUserUnit($this->id_game, $id_zarea, $id_user, $id_unit);
                         $inGameLandUnit->setCount($unit_count);
                     }
                 }
             }
         }
         // add units to all empty game-areas
         $iter = ModelGameArea::iterator(NEUTRAL_COUNTRY, $this->id_game);
         while ($iter->hasNext()) {
             /* @var $gameArea ModelGameArea */
             $gameArea = $iter->next();
             if ($gameArea->getIdType() !== TYPE_LAND) {
                 continue;
             }
             $count = $gameArea->getProductivity();
             if ($gameArea->getIdResource() === RESOURCE_OIL) {
                 ++$count;
             }
             $iterUnits = ModelLandUnit::iterator();
             while ($iterUnits->hasNext()) {
                 $landUnit = $iterUnits->next();
                 $id_unit = $landUnit->getId();
                 $inGameLandUnit = ModelInGameLandUnit::getModelByIdZAreaUserUnit($this->id_game, $gameArea->getId(), NEUTRAL_COUNTRY, $id_unit);
                 $inGameLandUnit->setCount($count);
             }
         }
         $this->finishProcessing();
     } catch (\Exception $ex) {
         $this->logger->fatal($ex);
         $this->rollback();
     }
 }
 /**
  * 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;
 }