Example #1
0
bool Board::move(Move move) {
    auto x = move.x;
    auto y = move.y;
    auto player = move.player;
    if (x < 0 || y < 0 || x > BOARD_WIDTH || y > BOARD_HEIGHT || (*this->getBoardState())[x][y] != Player::NoPlayer) {
        return false;
    }
    std::vector<std::pair<short, short>> searchDirections;
    for(auto itr = DIRECTIONS.begin(); itr != DIRECTIONS.end(); ++itr) {
        auto direction = *itr;
        short searchX = x + std::get<0>(direction);
        short searchY = y + std::get<1>(direction);
        if (searchX >=0 && searchX <= BOARD_WIDTH - 1 && searchY >=0 && searchY <= BOARD_HEIGHT - 1 && (*this->getBoardState())[searchX][searchY] == -player) {
            searchDirections.push_back(*itr);
        }
    }
    if(searchDirections.size() == 0) {
        return false;
    }
    std::shared_ptr<Matrix<short>> boardState = this->_boardStateStack.top()->clone();
    std::vector<std::pair<unsigned short, unsigned short>> path;
    PlayerScoreInfo playerScore(this->getPlayerScoreInfo());
    bool moveValid = false;
    for (auto itr = std::begin(searchDirections); itr != std::end(searchDirections); ++itr) {
        auto direction = *itr;
        short searchX = x + std::get<0>(direction);
        short searchY = y + std::get<1>(direction);
        while (searchX >=0 && searchX <= BOARD_WIDTH - 1 && searchY >=0 && searchY <= BOARD_HEIGHT - 1){
            if ((*boardState)[searchX][searchY] == player) {
                playerScore[player] += path.size();
                playerScore[PlayerUtil::swapPlayer(player)] -= path.size();
                for (auto pathItr = std::begin(path); pathItr != std::end(path); ++pathItr) {
                    (*boardState)[std::get<0>(*pathItr)][std::get<1>(*pathItr)] = player;
                }
                moveValid = true;
                break;
            } else {
                path.push_back({searchX, searchY});
            }
            if ((*boardState)[searchX][searchY] == Player::NoPlayer) {
                break;
            }
            searchX += std::get<0>(direction);
            searchY += std::get<1>(direction);
        }
        path.clear();
    }
    if (moveValid) {
        (*boardState)[x][y] = player;
        playerScore[player] ++;
		this->_boardStateStack.push(boardState);
        this->_playerScoreInfoStack.push(playerScore);
        this->_moveStack.push(move);
        this->_cachedAvailPosMap.clear();
    }
    return moveValid;
}
Example #2
0
void runGame(PlayerSet& players, 
             ControlData& control, 
             const GameState& gameState, 
             const Map& map, 
             const SimulationParameters& params,
             GameStats& gameStats,
             zmq::socket_t& stateSocket, 
             const json& settings, 
             InfoLogger& logger)
{
  
  uint targetFPS = settings["simulation"]["targetFPS"];
  uint totalGameTimeSeconds = settings["gameTime"];
  uint integrationSteps = uint(1. / float(targetFPS) / params.timeStep);

  // Make sure the per-game stats are cleared
  gameStats.playerRanks.clear();
  gameStats.playerDists.clear();

  uint nShips = players.fromId.size();
  uint targetMicroseconds = 1000000 / targetFPS;
  StateMatrix state(nShips, STATE_LENGTH);
  initialiseState(state, map, params);
  ControlMatrix inputs = control.inputs;
  bool running = true;
  unsigned int fpscounter = 0;
  
  auto gameStart = hrclock::now();
  logger("game", "status",
        {{"state","running"},{"map",map.name}, {"game",gameState.name}}); 
  while (running && !interruptedBySignal)
  {
    auto frameStart = hrclock::now();

    // Threadsafe copy of control inputs (unlock managed by scope)
    {
      std::lock_guard<std::mutex> lock(control.mutex);
      inputs = control.inputs;
    }

    for (uint i=0; i<integrationSteps;i++)
      rk4TimeStep(state, inputs, params, map);

    // Calculate game stats every second
    fpscounter++;
    if (fpscounter >= targetFPS)
    {
        fpscounter = 0;
        playerScore(state, control, map, params, gameStats);
        logger("game", "status",
            {{"state","running"},{"map",map.name}, {"game",gameState.name},
             {"ranking", gameStats.playerRanks}}); 
    }
    
    //check we don't need to end the game
    bool timeout = hasRoughIntervalPassed(gameStart, totalGameTimeSeconds, targetFPS);
    bool raceWon = winner(players, state,control, map, params) != "";
    running = (!timeout) && (!raceWon);

    // get control inputs from control thread
    broadcastState(players, state, gameState, control, params, stateSocket);

    // make sure we target a particular frame rate
    waitPreciseInterval(frameStart, targetMicroseconds);
  }

  // Game over, so tell the clients
  playerScore(state, control, map, params, gameStats); // get final score
  updateRanks(players, control,map, gameStats);
  logger("game", "status",
         {{"state","finished"},{"map",map.name}, {"game",gameState.name},
          {"ranking", gameStats.playerRanks}, {"totalScore", gameStats.totalPlayerScore},
          {"teamScore", gameStats.totalTeamScore}}); 
  send(stateSocket, {gameState.name,"{\"state\":\"finished\"}"});

}