Beispiel #1
0
      void
      add (uint32_t id, char side, uint32_t price, uint32_t size)
      {
        if (orders.end () != orders.find (id, OrderIdHasher (), OrderIdEqual ()))
          {
            throw std::runtime_error ("duplicate add");
          }

        AggregateOrders::iterator found = aggregateOrders.find (std::make_pair (side, price), AggregateOrderLess ());

        if (found == aggregateOrders.end ())
          {
            AggregateOrder *a = aggregateOrderPool.construct (boost::in_place (side, price));
            found = aggregateOrders.insert (*a).first;
          }

        assert(aggregateOrders.end () != found);

        Order *order = orderPool.construct (boost::in_place (id, boost::ref (*found)));
        assert(order);

        bool orderInserted __attribute__((unused)) = orders.insert (*order).second;
        assert(orderInserted);

        order->size = size;
        order->aggregateOrder.size += size;

        assert(order->size);
        assert(order->aggregateOrder.size);
      }
Beispiel #2
0
 void
 visitOrders (V const& v) const
 {
   for (auto i = orders.begin (), e = orders.end (); i != e; ++i)
     {
       if (!v (*i))
         return;
     }
 }
Beispiel #3
0
 void clear()
 {
   while(!orders.empty()) {
       auto const& order = *orders.begin();
       reduce(order.id, order.size);
   }
   assert(orders.empty());
   assert(aggregateOrders.empty());
 }
Orders OrderBook::cross() {
    sort(orders_);
    size_t indicativeQuantity = 0;
    size_t currentBidQuantity = totalBid_;
    size_t currentAskQuantity = 0;
    double indicativePrice = 1e9;
    for (const auto& o : orders_) {
        if (o.isBid_) {
            currentBidQuantity -= o.quantity_;
        } else {
            currentAskQuantity += o.quantity_;
        }
        auto quantity = min(currentBidQuantity, currentAskQuantity);
        if (quantity > indicativeQuantity) {
            indicativePrice = o.price_;
            indicativeQuantity = o.quantity_;
        }
    }

    Orders result;

    for (auto toOrder = orders_.begin(); toOrder != orders_.end();) {
        bool include = false;
        if (toOrder->isBid_) {
            if (toOrder->price_ >= indicativePrice) {
                include = true;
            }
        } else {
            if (toOrder->price_ <= indicativePrice) {
                include = true;
            }
        }

        if (include) {
            if (toOrder->quantity_ <= indicativeQuantity) {
                indicativeQuantity -= toOrder->quantity_;
                result.emplace_back(*toOrder);
                orders_.erase(toOrder);
            } else {
                indicativeQuantity = 0;
                toOrder->quantity_ -= indicativeQuantity;
                ++toOrder;
            }
        } else {
            ++toOrder;
        }

        if (0 == indicativeQuantity) {
            break;
        }
    }

    return result;
}
Beispiel #5
0
      void
      reduce (uint32_t id, uint32_t size)
      {
        Orders::iterator found = orders.find (id, OrderIdHasher (), OrderIdEqual ());

        if (found == orders.end ())
          {
            throw std::runtime_error ("order not found");
          }

        assert(&*found);
        assert(&found->aggregateOrder);

        Order &o = *found;
        AggregateOrder &a = found->aggregateOrder;

        if (size > o.size)
          {
            throw std::runtime_error ("attempt to over reduce");
          }
        if (size == o.size)
          {
            a.size -= o.size;

            orders.erase (found);
            orderPool.destroy (&o);

            if (0 == a.size)
              {
                aggregateOrders.erase (AggregateOrders::s_iterator_to (a));
                aggregateOrderPool.destroy (&a);
              }
          }
        else
          {
            o.size -= size;
            a.size -= size;
            assert(o.size);
            assert(a.size);
          }
      }
//----------------------------------------------------------------------
void AIController::processAgentPathOrders( ArenaMap& currentMap, Orders& tentativeOrders )
{
	EnterCriticalSection( &m_agentsCS );
	
	for( auto agentIter = m_agents.begin(); agentIter != m_agents.end(); ++agentIter )
	{
		Agent* currAgent = agentIter->second;
		if( !currAgent->currentPath.empty() )
		{
			if( currAgent->entityType == ENTITY_TYPE_WORKER && currAgent->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
			{
				currentMap.getMapTile( currAgent->currentTargetLoc.x, currAgent->currentTargetLoc.y ).isClaimed = true;
			}
			tentativeOrders.AddOrder( currAgent->entityID, currAgent->currentPath.back(), true );
		}
	}

	LeaveCriticalSection( &m_agentsCS );
}
//----------------------------------------------------------------------
void AIController::handleQueenOrders( Agent* queen, ArenaMap& currentMap, const ObservedEntities& entities, Orders& tentativeOrders )
{
	if( ( m_turnNumber > 0 && m_turnNumber % TURN_INTERVAL_QUEEN_MOVES_ON == 0 ) || m_numWorkersThatCouldntFindFoodThisFrame >= NUM_WORKERS_IDLE_BEFORE_QUEEN_MOVES || m_currentNumWorkers <= 0 )
	{
		if( m_currentNumWorkers <= 0 && m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthWorker )
			tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_WORKER );
		else if( queen->currentPath.empty() && !queen->waitingForPath )
		{
			queen->currentTargetLoc = getLocationForQueenToGoTo( currentMap );
			m_agentsRequestingPaths.push( queen->entityID );
			queen->waitingForPath = true;
		}
	}
	else 
	{
		switch( m_currentQueenState )
		{
		case GATHER_RESOURCES:
			if( m_currentNutrients > m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthWorker )//&& !m_spawnedWorkerLastFrame )
			{
				tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_WORKER );
				m_spawnedWorkerLastFrame = true;
			}
			else if( m_currentNutrients > m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthScout )
			{
				if( m_currentNumScouts < MAX_NUM_SCOUTS )
					tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_SCOUT );
				m_spawnedWorkerLastFrame = false;	
			}
			break;
		case DEFEND:
			if( m_currentNutrients > m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthSoldier && m_currentNumWorkers >= MIN_NUM_WORKERS )
			{
				tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_SOLDIER, true );
				m_spawnedWorkerLastFrame = false;	
			}
			else if( m_currentNumScouts < MAX_NUM_SCOUTS )
				tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_SCOUT );
			else if( m_currentNutrients > m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthWorker && !m_spawnedWorkerLastFrame && !currentMap.hasNoMoreResources() )
			{
				tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_WORKER );
				m_spawnedWorkerLastFrame = true;
			}
			m_spawnedWorkerLastFrame = false;
			break;
		case ATTACK:
			if( m_currentNutrients > m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthSoldier && ( currentMap.hasNoMoreResources() || m_currentNumWorkers >= MIN_NUM_WORKERS ) )
			{
				tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_SOLDIER );
				m_spawnedWorkerLastFrame = false;	
			}
			else if( m_currentNutrients > m_currentUpkeep*TURN_UPKEEP_TOLERANCE + m_arenaInfo.nutrientCostToBirthWorker && !m_spawnedWorkerLastFrame && !currentMap.hasNoMoreResources() )
			{
				tentativeOrders.AddOrder( queen->entityID, ORDER_CREATE_WORKER );
				m_spawnedWorkerLastFrame = true;
			}
			else
				m_spawnedWorkerLastFrame = false;
			break;		
		}
	}
}
//----------------------------------------------------------------------
void AIController::handleWorkerOrders( Agent* worker, ArenaMap& currentMap, const ObservedEntities& entities, Orders& tentativeOrders )
{
	if( m_currentQueenState == ATTACK && currentMap.hasNoMoreResources() && worker->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
	{
		tentativeOrders.AddOrder( worker->entityID, ORDER_SUICIDE );
	}
	else
	{
		if( worker->currentPath.empty() && !worker->waitingForPath )
		{
			if( worker->pos == m_queen->pos && worker->specialStatus == ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
			{
				tentativeOrders.AddOrder( worker->entityID, ORDER_DROP_FOOD, true );
				--m_numWorkersWithFood;
				worker->currentTargetAgentID = -1;
			}
			else if( worker->pos == worker->currentTargetLoc && currentMap.getMapTileType( worker->pos.x, worker->pos.y ) == ARENA_SQUARE_TYPE_FOOD )
			{
				tentativeOrders.AddOrder( worker->entityID, ORDER_TAKE_FOOD, true );
				m_agentsRequestingPaths.push( worker->entityID );
				worker->currentTargetLoc = m_queen->pos;
				worker->currentTargetAgentID = m_queen->entityID;
				worker->waitingForPath = true;
				currentMap.getMapTile( worker->pos.x, worker->pos.y ).isClaimed = false;
			}	
			else if( worker->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
			{
				int x, y;
				if( currentMap.getClosestNutrient( m_arenaInfo.visibilityRangeQueen*QUEEN_RANGE_FACTOR, m_queen->pos, x, y ) )
				{
					m_agentsRequestingPaths.push( worker->entityID );
					worker->currentTargetLoc = TileCoords( x, y );
					worker->currentTargetAgentID = -1;
					worker->waitingForPath = true;
					currentMap.getMapTile( x, y ).isClaimed = true;
				}
				else
				{
					++m_numWorkersThatCouldntFindFoodThisFrame;
					if( m_numWorkersThatCouldntFindFoodThisFrame >= NUM_WORKERS_IDLE_BEFORE_QUEEN_MOVES )
					{
						worker->currentTargetAgentID = m_queen->entityID;
					}
					else
					{
						worker->currentTargetAgentID = -1;
						worker->currentTargetLoc = currentMap.getRandomLocationInArea( worker->pos, m_arenaInfo.visibilityRangeQueen*QUEEN_RANGE_FACTOR );
					}
					m_agentsRequestingPaths.push( worker->entityID );
					worker->waitingForPath = true;
				}
			}
			else
			{
				worker->currentTargetAgentID =  m_queen->entityID;
				m_agentsRequestingPaths.push( worker->entityID );
				worker->waitingForPath = true;
			}
		}
		else if( currentMap.getMapTileType( worker->currentTargetLoc.x, worker->currentTargetLoc.y ) != ARENA_SQUARE_TYPE_FOOD && worker->specialStatus != ENTITY_SPECIAL_STATUS_CARRYING_FOOD )
		{
			int x, y;
			if( currentMap.getClosestNutrient( m_arenaInfo.visibilityRangeQueen*QUEEN_RANGE_FACTOR, m_queen->pos, x, y ) )
			{
				m_agentsRequestingPaths.push( worker->entityID );
				worker->currentTargetLoc = TileCoords( x, y );
				worker->currentTargetAgentID = -1;
				worker->waitingForPath = true;
				currentMap.getMapTile( x, y ).isClaimed = true;
			}
		}
		else if( currentMap.hasNewMapInfo() && !worker->waitingForPath && !validPath( currentMap, worker->pos, worker->currentPath ) )
		{
			m_agentsRequestingPaths.push( worker->entityID );
			worker->waitingForPath = true;
		}
	}
}
//----------------------------------------------------------------------
void AIController::handleAgentReports( ArenaMap& currentMap, const AgentReports& agentReports, const ObservedEntities& entities, Orders& tentativeOrders )
{
	EnterCriticalSection( &m_agentsCS );
	for( int i = 0; i < agentReports.m_numberAgentReports; ++i )
	{
		Agent*& currentAgent = m_agents[ agentReports.m_agentReports[i].m_entityID ];
		//Indicates this is a new entity
		if( currentAgent == nullptr )
		{
			createNewAgent( currentAgent, agentReports.m_agentReports[i] );
		}
		else
		{
			if( agentReports.m_agentReports[i].m_reportCode == REPORT_WAS_KILLED_IN_COMBAT || 
				agentReports.m_agentReports[i].m_reportCode == REPORT_STARVED_TO_DEATH ||
				agentReports.m_agentReports[i].m_reportCode == REPORT_SUICIDE_SUCCESSFUL )
			{
				handleAgentDied( currentAgent, currentMap, agentReports.m_agentReports[i] );
				m_currentQueenState = DEFEND;
			}
			else
			{
				if( agentReports.m_agentReports[i].m_agentType == ENTITY_TYPE_WORKER && agentReports.m_agentReports[i].m_reportCode == REPORT_TAKE_SUCCESSFUL )
					++m_numWorkersWithFood;

				currentAgent->pos.x = agentReports.m_agentReports[i].m_newPositionX;
				currentAgent->pos.y = agentReports.m_agentReports[i].m_newPositionY;
				currentAgent->specialStatus = agentReports.m_agentReports[i].m_specialStatus;
				if( agentReports.m_agentReports[i].m_reportCode == REPORT_MOVE_SUCCESSFUL )
				{
					if( !currentAgent->currentPath.empty() )
						currentAgent->currentPath.pop_back();
					if( currentAgent->currentPath.empty() )
						currentAgent->waitingForPath = false;
				}
				else if( agentReports.m_agentReports[i].m_reportCode == REPORT_HOLD_SUCCESSFUL )
				{
					if( currentAgent == m_queen && !m_queen->currentPath.empty() && m_queen->currentPath.back() == ORDER_HOLD )
						currentAgent->currentPath.pop_back();
					if( currentAgent->currentPath.empty() )
						currentAgent->waitingForPath = false;
				}
				else if( agentReports.m_agentReports[i].m_reportCode == REPORT_ERROR_BLOCKED_BY_ROCK )
				{
					currentAgent->currentPath.clear();
					m_agentsRequestingPaths.push( currentAgent->entityID );
				}
				else if( currentAgent->entityType == ENTITY_TYPE_QUEEN )
				{
					if( agentReports.m_agentReports[i].m_reportCode == REPORT_QUEEN_WAS_FED )
						currentMap.getMapTile( m_queen->pos.x, m_queen->pos.y ).isClaimed = false;	
					else if( agentReports.m_agentReports[i].m_reportCode == REPORT_CREATE_SUCCESSFUL && m_currentQueenState == DEFEND )
					{
						m_currentQueenState = GATHER_RESOURCES;
					}
					else if( agentReports.m_agentReports[i].m_reportCode == REPORT_QUEEN_WAS_ASSAULTED && m_queen->currentPath.empty() )
					{
						tentativeOrders.AddOrder( m_queen->entityID, ORDER_CREATE_SOLDIER, true );
					}
				}
			}
		}
	}
	LeaveCriticalSection( &m_agentsCS );
}
Beispiel #10
0
int main(int argc, char *argv[])
{
    ssl_init();
    OrderBook order_book(3);
    Orders<1000> orders;
    auto poller = Poller::create();

    Url diff_url("wss://ws.pusherapp.com/app/de504dc5763aeef9ff52?protocol=5");
    auto diff_socket = create_tcp_socket(diff_url.host(), 80);
    diff_socket->set_callbacks<DiffLogic<1000>>(std::ref(diff_url), std::ref(orders));
    poller->update_socket(diff_socket, EPOLLIN | EPOLLOUT);

    Url order_book_url("https://www.bitstamp.net/api/order_book");
    auto order_book_socket = create_tcp_socket(order_book_url.host(), 443);
    order_book_socket->set_callbacks<ReceiveOrderBookLogic>(std::ref(order_book_url), std::ref(order_book));
    poller->update_socket(order_book_socket, EPOLLOUT | EPOLLIN);

    //----------------------

    std::shared_ptr<Order> order;
    Timer reconect_timer;
    Timer update_timer;
    Timer stop_timer;
    stop_timer.reset();
    uint64_t last_time = 0;
    const uint64_t RECONECT_INTERVAL = 20;

    bool order_book_ready = false;

    for (;;)
    {
        poller->poll();

        for (;;)
        {
            auto event = poller->get_next_event();
            if (!event.action)
                break;

            try
            {
                if (event.action & PollerEvent::READ)
                    event.socket->read();

                if (event.action & PollerEvent::WRITE)
                    event.socket->write();

                if (event.action & PollerEvent::CLOSE)
                    event.socket->close(event.close_reason);
            }
            catch (const std::exception & e)
            {
                std::cerr << "Exception in callback: " << e.what() << std::endl << "Closing socket." << std::endl;
                event.socket->close();
            }
        }

        if (!order_book)
        {
            if (!order_book_socket.get() && reconect_timer.elapsed_seconds() > RECONECT_INTERVAL)
            {
                std::cerr << "creating new order_book_socket" << std::endl;
                order_book_socket = create_tcp_socket(order_book_url.host(), 443);
                order_book_socket->set_callbacks<ReceiveOrderBookLogic>(std::ref(order_book_url), std::ref(order_book));
                poller->update_socket(order_book_socket, EPOLLOUT | EPOLLIN);
            }

            continue;
        }

        if (!order_book_ready)
        {
            uint64_t first_diff_timestamp = orders.get_first_timestamp();
            uint64_t last_book_timestamp  = order_book.get_last_timestamp();

            std::cerr << first_diff_timestamp << "/" << last_book_timestamp << std::endl;

            if (last_book_timestamp < first_diff_timestamp)
            {
                order_book.clear();
                reconect_timer.reset();
                order_book_socket.reset();
                continue;
            }

            order_book_ready = true;
        }

        while (order = orders.get_order())
            order_book.add(*order);

        if (update_timer.elapsed_seconds() != last_time)
        {
            last_time = update_timer.elapsed_seconds();
            order_book.print();
        }
    }

    ssl_destroy();
    return 0;
}
Beispiel #11
0
//-----------------------------------------------------------------------------------------------
void BeginWork()
{
//	DebuggerPrintf( "[%d] WORKER THREAD: BeginWork() called.\n", g_playerID );

	while( !g_isQuitting )
	{
		EnterCriticalSection( &cs_ordersAndResults );
		bool areTentativeOrdersEmpty = g_tentativeOrders.m_numberOfOrders == 0;
		bool areResultsEmpty = g_resultsForPreviousOrders.m_numberAgentReports == 0;
		LeaveCriticalSection( &cs_ordersAndResults );

		bool readyToStartGeneratingNewOrders = areTentativeOrdersEmpty && !areResultsEmpty;
		if( !readyToStartGeneratingNewOrders )
		{
			EnterCriticalSection( &cs_ordersAndResults );
			g_readyToDispatchOrders = true;
			LeaveCriticalSection( &cs_ordersAndResults );
			Sleep( 0 );
		}
		else
		{
            EnterCriticalSection( &cs_ordersAndResults );
			Orders tempOrdersWhileWeDoLotsOfWork;
			int numOrdersToGive = (int) g_resultsForPreviousOrders.m_numberAgentReports;

			for( int resultIndex = 0; resultIndex < numOrdersToGive; ++ resultIndex )
			{
                const AgentReport& result = g_resultsForPreviousOrders.m_agentReports[ resultIndex ];
                int antID = result.m_entityID;
                OrderCode orderCode = ORDER_HOLD;

                if( result.m_specialStatus == ENTITY_SPECIAL_STATUS_DEAD )
                {
                    if( result.m_reportCode == REPORT_WAS_KILLED_IN_COMBAT )
                        ++GameInfo::g_myQueen->numberOfAntsLostInCombat;

                    if( g_myAnts.find( antID ) != g_myAnts.end() )
                    {
                        g_myAnts[antID]->ProcessDeath();
                        --gameInfo.numOfAntsPerType[(int)result.m_agentType];
                        delete g_myAnts[antID];
                        g_myAnts.erase( antID );
                        continue;
                    }
                }

                else
                {
                    if( result.m_reportCode == REPORT_WAS_CREATED )
                    {
                        switch( result.m_agentType )
                        {
                        case ENTITY_TYPE_SCOUT: 
                            g_myAnts[antID] = new AntScout( result );
                            break;

                        case ENTITY_TYPE_SOLDIER:
                            g_myAnts[antID] = new AntSoldier( result );
                            break;

                        case ENTITY_TYPE_QUEEN: 
                            gameInfo.g_myQueen = new AntQueen( result );
                            g_myAnts[antID] = gameInfo.g_myQueen;
                            break;

                        case ENTITY_TYPE_WORKER: 
                            g_myAnts[antID] = new AntWorker( result );
                            break;
                        }
                        ++gameInfo.numOfAntsPerType[(int)result.m_agentType];
                    }

                    if( gameInfo.myAnts.find( antID ) != gameInfo.myAnts.end() )
                        orderCode = g_myAnts[antID]->update( result );

                    tempOrdersWhileWeDoLotsOfWork.AddOrder( antID, orderCode, true );
                }
			}
            
            //float timeSpent = GetAbsoluteTimeSeconds() - gameInfo.secondsSinceLastFetchOrders;
            //DebuggerPrintf( "Milliseconds Spent: %f\n", timeSpent * 1000 );

            /*if( GameInfo::totalAStarRequests )
            {
                DebuggerPrintf( "Average Milliseconds Spent: %f\n", ( GameInfo::totalTimeSpentRequestingAStarPaths / GameInfo::totalAStarRequests ) * 1000 );
            }*/
            GameInfo::bSoldierSacrificed = false;
            g_readyToDispatchOrders = true;
			g_tentativeOrders = tempOrdersWhileWeDoLotsOfWork;
            g_resultsForPreviousOrders.m_numberAgentReports = 0;
			LeaveCriticalSection( &cs_ordersAndResults );
		}
	}
}