void FieldAddress::FillDirections4(AddressVector &directions)
{
	directions.clear();
	directions.push_back(*this + DOWN);
	directions.push_back(*this + UP);
	directions.push_back(*this + LEFT);
	directions.push_back(*this + RIGHT);
}
//---------------------------------------------------------------------
void SimulateClientMainFrame::updateServerList(const AddressVector& serverLister)
{
	m_serverList->Clear();
	AddressVector::const_iterator it=serverLister.begin();
	AddressVector::const_iterator endit=serverLister.end();
	for(;it!=endit;++it)
	{
		m_serverList->Insert(wxString(it->ToString()),0);
	}

}
//движение монстров рандомно
void MovingMonsters::MoveRandom()
{
	for (std::vector<Thief::HardPtr>::iterator it = _monstersPositions.begin(); it != _monstersPositions.end();)
	{
		Game::FieldAddress monsterFA((*it)->Cell());
		AddressVector directions; 
		monsterFA.FillDirections4(directions); //куда можем пойти
		std::random_shuffle(directions.begin(), directions.end()); //чтобы ходил случайно

		Game::FieldAddress foundFA;

		bool found = false;
		for (auto tryFa: directions)
		{
			Game::Square *sq = GameSettings::gamefield[tryFa];
			if (sq->IsGoodForMovingMonster() && Game::activeRect.Contains(tryFa.ToPoint()))	//идем в первую попавшуюся
			{
				foundFA = tryFa;
				found = true;
				break;
			}
		}

		if (found)  //если нашли ход, делаем
		{
			int leftMoves = MoveMonster(monsterFA, foundFA);
			if (leftMoves > 0) //если ходы еще остались
			{
				_someMonsterStillCanMove = true;
			}
			it = _monstersPositions.erase(it);
		} else {   //если не нашли значит в тупике, сбрасываем ходы
			int leftMoves = (*it)->GetMoves();
			(*it)->ChangeMoves(-leftMoves);
			++it;
		}
	}
}
ThreadPlanSP
DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
{
    LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
    ThreadPlanSP thread_plan_sp;

    StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
    const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
    Symbol *sym = context.symbol;

    if (sym == NULL || !sym->IsTrampoline())
        return thread_plan_sp;

    const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
    if (!sym_name)
        return thread_plan_sp;

    SymbolContextList target_symbols;
    Target &target = thread.GetProcess().GetTarget();
    ModuleList &images = target.GetImages();

    images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
    size_t num_targets = target_symbols.GetSize();
    if (!num_targets)
        return thread_plan_sp;

    typedef std::vector<lldb::addr_t> AddressVector;
    AddressVector addrs;
    for (size_t i = 0; i < num_targets; ++i)
    {
        SymbolContext context;
        AddressRange range;
        if (target_symbols.GetContextAtIndex(i, context))
        {
            context.GetAddressRange(eSymbolContextEverything, 0, false, range);
            lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
            if (addr != LLDB_INVALID_ADDRESS)
                addrs.push_back(addr);
        }
    }

    if (addrs.size() > 0) 
    {
        AddressVector::iterator start = addrs.begin();
        AddressVector::iterator end = addrs.end();

        std::sort(start, end);
        addrs.erase(std::unique(start, end), end);
        thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
    }

    return thread_plan_sp;
}
void MovingMonsters::MoveRound2() //поиск ходов чтобы придти как можно ближе к приемнику
{
	if (_monstersPositions.empty())
	{
		return;  //если все монстры двинулись - выходим
	}
	//теперь двигаем тех кто не может дойти до приемника
	//сперва меняем на блоки получателей и все рядом, чтобы не мешались
	for (int row = _fieldBottom; row <= _fieldTop; row++)
	{
		for (int col = _fieldLeft; col <= _fieldRight; col++)
		{
			Game::FieldAddress fa(col, row);
			if (_movesToRecievers[fa] >=0 )
			{
				_movesToRecievers[fa] = monsterFieldBlock;
			}
		}
	}

	//теперь остались только клетки изолированные от получателей
	//для каждого монстрика запустим поиск куда может дойти
	//и из этих клеток выберем ближайшую к потребителю
	_somethingMoved = true;
	while (_somethingMoved) //пока в теории могут двигаться
	{
		_somethingMoved = false;
		for (std::vector<Thief::HardPtr>::iterator it = _monstersPositions.begin(); it != _monstersPositions.end();)
		{
			//для каждого монстра	
			Game::FieldAddress monsterFa((*it)->Cell());

			//чистим массив от предыдущих попыток
			for (int row=_fieldBottom; row<=_fieldTop; row++)
				for (int col=_fieldLeft; col<=_fieldRight; col++)
				{
					Game::FieldAddress fa(col, row);
					if (_movesToRecievers[fa] >=0 )
					{
						_movesToRecievers[fa] = monsterFieldEmpty;
					}
				}


			_movesToRecievers[monsterFa] = 0;  //ставим исходную точку

			FillDistances(); //находим куда может пойти
			//находим на каком расстоянии сейчас, чтобы не ухудшить
			int bestDistance = 1000;
			for (std::list<Game::FieldAddress>::iterator it1 = _recieversPositions.begin(); it1 != _recieversPositions.end(); ++it1)
			{
				Game::FieldAddress recieverFa = *it1;
				int newDistance =  Distance(monsterFa, recieverFa);
				if (newDistance < bestDistance) 
				{
					bestDistance = newDistance;
				}
			}
			int bestMoves = 0;    //лучшее число ходов до ближней клетки (если 2 получателя в тупиках, пойдет к тому который ближе)
			std::vector<Game::FieldAddress> bestDestinations;
			bestDestinations.push_back(monsterFa);
			//Game::FieldAddress bestFa = monsterFa; //адрес ближайшей к получателю клетки, куда монстрик в итоге пойдет
			//перебираем найденные клетки и находим ближайшие к получателю
			for (int row = _fieldBottom; row <= _fieldTop; row++)
			{
				for (int col = _fieldLeft; col <= _fieldRight; col++)
				{
					Game::FieldAddress tryFa(col, row);
					Game::Square *sq = GameSettings::gamefield[tryFa];
					if(!Game::isVisible(sq) || !sq->GetChip().IsThief())
					{
						continue;
					}
					bool thereIsNoMonster = std::find(_monstersPositions.begin(), _monstersPositions.end(), sq->GetChip().GetThief()) == _monstersPositions.end();
					if (_movesToRecievers[tryFa] >0 && thereIsNoMonster) //может до сюда дойти  и там нет другого монстрика
					{
						//перебираем получателей
						for (std::list<Game::FieldAddress>::iterator it1 = _recieversPositions.begin(); it1 != _recieversPositions.end(); ++it1)
						{
							Game::FieldAddress recieverFa = *it1;
							int newDistance = Distance(tryFa, recieverFa);
							int newMoves = _movesToRecievers[tryFa];

							if ((newDistance < bestDistance) //если ближе до приемника
								|| (newDistance == bestDistance && newMoves <= bestMoves))  //или такое же расстояние но ближе идти
							{
								//это новая цель
								if (newDistance != bestDistance || newMoves != bestMoves)
								{
									bestDestinations.clear();
								}
								bestDistance = newDistance;
								bestMoves = newMoves;
								bestDestinations.push_back(tryFa);
							}
						}

					}
				}
			}
			
			if (bestMoves == 0) //если монстрику некуда ходить, значит он в тупике
			{
				//монстрик в тупике - пропускает ходы
				int leftMoves = (*it)->GetMoves();
				(*it)->ChangeMoves(-leftMoves);

				_movesToRecievers[monsterFa] = monsterFieldBlock; //ставим такм блок
				_monstersPositions.erase(it); //удаляем его
				_somethingMoved = true;  //и все по новой потому что надо пересчитать ходы
				break;
			}

			//теперь в bestDestinations список целей. выбираем случайную
			size_t count = bestDestinations.size();
			size_t n = math::random(0u, count-1);
			//с кем меняемся
			Game::FieldAddress bestFa = bestDestinations[n];

			if (bestFa != monsterFa) //если что то нашли то восстанавливаем путь и делаем 1-й шаг
			{
				Game::FieldAddress currentFa = bestFa;
				int currentDistance = _movesToRecievers[currentFa];
				while (currentDistance != 1)  
				{   //выбираем ячейку с числом на 1 меньше
					AddressVector directions; 
					currentFa.FillDirections4(directions); //куда можем пойти
					std::random_shuffle(directions.begin(), directions.end()); //чтобы ходил случайно

					bool found = false;
					for (auto tryFa: directions)
					{
						if (_movesToRecievers[tryFa] == currentDistance-1)	//идем в первую попавшуюся
						{
							currentFa = tryFa;
							found = true;
							break;
						}
					}

					if (!found) //если идти некуда, выходим, хотя не должно быть
					{
						break;
					}

					currentDistance = currentDistance -1;
				}
				//если нашли ячейку на расстоянии 1 хода и там нет монстрика
				if (currentDistance == 1 && !GameSettings::gamefield[currentFa]->GetChip().IsThief() )
				{
					int leftMoves = MoveMonster(monsterFa, currentFa);
					if (leftMoves > 0) //если ходы еще остались
					{
						_someMonsterStillCanMove = true;
					}
					it = _monstersPositions.erase(it);
					continue; //чтобы итератор не прибавился
				}
			}
			++it;
		}
	}
}
Beispiel #6
0
PersonVector BuildPersonVector(const ABPersonsVector & db_person,
				const ABMultiValueVector & db_contacts,
				const ABMultiValueEntryVector & db_addresses)
{
	size_t i;
	PersonVector db;

	/* Populate Persons vector - one element per contact */
	db.resize(db_person.size());
	for (i=1;i<db_person.size();++i) {
		Person &p = db.at(i);
		const ABPerson& abp = db_person.at(i);

		/* Populate person's values */
		p.rowid = abp.rowid;
		p.First = abp.First;
		p.Last = abp.Last;
		p.Middle = abp.Middle;
		p.Nickname = abp.Nickname;
		p.Prefix = abp.Prefix;
		p.Suffix = abp.Suffix;
		p.Organization = abp.Organization;
		p.Department = abp.Department;
		p.Note = abp.Note;
		p.Birthday = abp.Birthday;
		p.JobTitle = abp.JobTitle;
		p.DisplayName = abp.DisplayName;

		/* Sanity Check */
		if (abp.rowid != i)
			errx(1,"Internal error: BuildPersonVector: " \
				"ABPerson.rowid(%zu) doesn't match " \
				"index(i=%zu)", abp.rowid,i);
	}

	/* Add Contact Information for each person */
	for (i=1;i<db_contacts.size();++i) {
		const ABMultiValue &mv = db_contacts.at(i);

		/* We use a vector instead of a list,
		   with the UID as the index - so there are
		   possible gaps if a value was deleted - skip it.*/
		if (mv.empty())
			continue;

		ContactInfo ci;
		ci.rowid = mv.rowid;
		ci.uid   = mv.uid;
		ci.label_num = mv.label_num;
		ci.label = mv.label;
		ci.value = mv.value;

		/* Sanity Check */
		size_t person_index = mv.person_record_id;
		if (person_index>=db.size())
			errx(1,"Internal error: BuildPersonVector: "\
				"Found ABMultiValue(rowid=%zu, uid=%zu) "\
				"with invalid person_record_id(%zu) " \
				"[db.size()=%zu]",
				mv.rowid, mv.uid,person_index,db.size());

		/* This record has no direct value -
		   it is used as a ForigenKey with ABMultiValueEnty:
		   The ABMultiValueEntry points to this record,
		   and this record points to the Person's record. */
		if (ci.value.empty())
			continue;

		Person &p = db.at(person_index);
		
		/* Hard-coded options, based on ABMultiValueLabel table */
		if (ci.label == "Mobile"
		    ||
		    ci.label == "Home"
		    ||
		    ci.label == "Work"
		    ||
		    ci.label == "iPhone"
		    ||
		    ci.label == "WorkFAX"
		    ||
		    ci.label == "HomeFAX")
			p.phones.push_back(ci);
		else if (ci.label == "Email")
			p.emails.push_back(ci);
		else
			p.others.push_back(ci);
	}

	/* Collate Address Information into objects */
	AddressVector addrs;
	for (i=0;i<db_addresses.size();++i) {
		const ABMultiValueEntry &mve = db_addresses.at(i);
		size_t parent_id = mve.parent_id;

		if (parent_id >= db_contacts.size())
			errx(1,"Internal error: BuildPersonVector: "\
				"ABMultiValueEntry.parent_id(%zu) points "\
				"to non-existing ABMultiValue record",
				parent_id);
		const ABMultiValue &mv = db_contacts.at(parent_id);
		if (mv.empty())
			errx(1,"Internal error: BuildPersonVector: "\
				"ABMultiValueEntry.parent_id(%zu) points "\
				"to an empty ABMultiValue record",
				parent_id);

		if (addrs.size() <= parent_id)
			addrs.resize(parent_id+1);

		Address& ad = addrs.at(parent_id);
		ad.parent_id = parent_id;
		ad.person_record_id = mv.person_record_id;
		ad.type = mv.label;

		/* From ABMultiValueEntryKey Table */
		switch (mve.key_num)
		{
		case 1:
			ad.country = mve.value;
			break;
		case 2:
			ad.street = mve.value;
			break;
		case 3:
			ad.ZIP = mve.value;
			break;
		case 4:
			ad.city = mve.value;
			break;
		case 5:
			ad.country_code = mve.value;
			break;
		case 6:
			ad.state = mve.value;
			break;
		case 7:
			ad.sub_locality = mve.value;
			break;
		default:
			/* This should not happen */
			errx(1,"Internal Error: BuildPersonVector(): " \
				"Found unknown ABMultiValueEntryKey " \
				"(value = %zu , name = '%s')",
				mve.key_num,mve.key.c_str());
			break;

		}
	}

	/* Combine Addresses into persons */
	for (i=0;i<addrs.size();++i) {
		const Address &ad = addrs.at(i);
		if (ad.empty())
			continue;

		size_t person_id = ad.person_record_id;

		Person &p = db.at(person_id);
		p.addresses.push_back(ad);
	}

	sort(db.begin(),db.end(),PersonSorter());
	return db;
}