Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


trying to make searching through a list more efficent (c++)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
gogodr
I post too much
Reputation: 125

Joined: 19 Dec 2006
Posts: 2041

PostPosted: Sun Aug 07, 2011 1:35 pm    Post subject: trying to make searching through a list more efficent (c++) Reply with quote

Code:
void test(UCanvas* pCanvas){
   if ( PawnList.empty() == false){
   int closest = 100000 ;
for(PawnIterator=PawnList.begin() ; PawnIterator != PawnList.end(); PawnIterator++ ){
    APawn* Target = *PawnIterator;
   if( Target !=NULL){
   FVector STargetPos;
   FVector TargetPos = PawnPosition(Target);
   STargetPos = WorldToScreen(pCanvas, TargetPos);
   FVector Center;
   Center.X = pCanvas->ClipX/2;
   Center.Y = pCanvas->ClipY/2;
   int distance = Distance2D(STargetPos,Center);
   if (distance < closest){
   closest = distance;
      }
   else{
   continue;
   }
   }
   
   }
if (closest < 50)
         {
for(PawnIterator=PawnList.begin() ; PawnIterator != PawnList.end(); PawnIterator++ ){
   
   APawn* Target = *PawnIterator;
   if( Target !=NULL){
            AcAPBPawn* ATarget;
            FVector STargetPos;
            FVector TargetPos = PawnPosition(Target);
            STargetPos = WorldToScreen(pCanvas, TargetPos);
            FVector Center;
            Center.X = pCanvas->ClipX/2;
            Center.Y = pCanvas->ClipY/2;
            int distance = Distance2D(STargetPos,Center);
            if (distance = closest){
      //debug
               if(Target->IsA(AcAPBPawn::StaticClass()))
               {
               ATarget = (AcAPBPawn*)Target;
               
               if(APBGameEngine->m_HostingClient->m_namequery != NULL){
               FString PlayerName;
               APBGameEngine->m_HostingClient->m_namequery->GetCharacterNameNative(ATarget->m_nControllerCharacterUID, &PlayerName);
               DrawStringEx(pCanvas,20 ,20,Green,true, PlayerName.Data);
               break;
                     }
                  }
               }
            }
         }
      }
   }
}


any suggestion?
Back to top
View user's profile Send private message MSN Messenger
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Sun Aug 07, 2011 2:54 pm    Post subject: Reply with quote

You seem to be looping through the list twice for no real reason. You loop the first time to get the closest pawn to you, then you reloop the list just to repull the same pawn to draw. Why not just store the pawn after you find the closest?

Code:


void test( UCanvas* pCanvas )
{
    int nClosest = 100000;
    APawn* pClosest = NULL;
   
    for( std::list< APawn* >::iterator iter = PawnList.begin(),
         std::list< APawn* >::iterator iterend = PawnList.end();
         iter != iterend;
         ++iter )
    {
        APawn* pTarget = reinterpret_cast< APawn* >( *iter );
        if( pTarget != NULL )
        {
            FVector vTargetPos = PawnPosition( pTarget );
            FVector vTargetPosScreen = WorldToScreen( pCanvas, vTargetPos );
            FVector vCenter;
            vCenter.X = pCanvas->ClipX / 2;
            vCenter.Y = pCanvas->ClipY / 2;
           
            int nDistance = Distance2D( vTargetScreen, vCenter );
            if( nDistance < nClosest )
            {
                nClosest = nDistance;
                pClosest = pTarget; // Store closest here..
            }
        }
    }

    // Closest is set..
    if( nClosest < 50 && pClosest != NULL )
    {
        if( pClosest->IsA( AcAPBPawn::StaticClass() ) )
        {
            AcAPBPawn* ATarget = reinterpret_cast< AcAPBPawn* >( pClosest );
            if( APBGameEngine->m_HostingClient->m_namequery != NULL )
            {
                FString strPlayerName;
                APBGameEngine->m_HostingClient->m_namequery->GetCharacterNameNative( ATarget->m_nControllerCharacterUID, &strPlayerName );
                DrawStringEx( pCanvas, 20, 20, Green, true, strPlayerName.Data );
            }
        }
    }
}

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
gogodr
I post too much
Reputation: 125

Joined: 19 Dec 2006
Posts: 2041

PostPosted: Sun Aug 07, 2011 4:51 pm    Post subject: Reply with quote

:O, you are right
thanks again

I dont know why I didn't notice I could store the pawn in the loop too x.x ;;
Back to top
View user's profile Send private message MSN Messenger
Jani
Grandmaster Cheater
Reputation: 2

Joined: 29 Dec 2006
Posts: 804

PostPosted: Mon Aug 08, 2011 1:07 pm    Post subject: Reply with quote

There's not much you can do anymore. Maybe you could try getting rid of the whole searching loop and constantly manage a pointer to the closest pawn all the time? I mean when you update their coordinates, just store the closest one there instead of searching for it separately?

Of course there are some micro optimizations such as using bit shift instead of division, but the compiler is probably already doing those for you. And the performance gain is very minimal, so if I were you, I'd really start looking performance boost elsewhere (such as design?)..

Also, why are you casting APawn* to APawn*? There's really no need to cast iterators. There's no overhead, but just wondering..
http://codepad.org/smOYedsy
Code:
#include <list>
#include <iostream>

int main(int argc, char *argv[])
{
    std::list<int*> list;
    int a = 10;
    int b = 13;
    list.push_back(&a);
    list.push_back(&b);

    std::list<int*>::iterator itr = list.begin();
    std::list<int*>::iterator end = list.end();
    while(itr != end) {
        // No need for reinterpret_cast here.
        int* pTarget = *(itr++);
        std::cout << (*pTarget >> 1) << std::endl;
    }
}
Back to top
View user's profile Send private message
gogodr
I post too much
Reputation: 125

Joined: 19 Dec 2006
Posts: 2041

PostPosted: Mon Aug 08, 2011 2:21 pm    Post subject: Reply with quote

I ended up with this
Code:
void test2( UCanvas* pCanvas )
{
   if ( PawnList.empty() == false){
    int Closest;
    APawn* CPawn = NULL;
   FVector Nvec;
   Nvec.X = 0;
   Nvec.Y = 0;
   Nvec.Z = 0;

   Closest = 10000;
    for( std::list< APawn* >::iterator iter = PawnList.begin(),
         iterend = PawnList.end();
         iter != iterend;
         ++iter )
    {
        APawn* Target = (APawn*)*iter;
        if( Target != NULL )
        {
            FVector vTargetPos = PawnPosition( Target );
         if (vTargetPos != Nvec){
            FVector vTargetPosScreen = WorldToScreen( pCanvas, vTargetPos );
            FVector vCenter;
            vCenter.X = pCanvas->ClipX / 2;
            vCenter.Y = pCanvas->ClipY / 2;
           
            int Distance = Distance2D( vTargetPosScreen, vCenter );
            if( Distance < Closest )
            {
                Closest = Distance;
                CPawn = Target;
            }
        }else { continue;}
      }else { continue;}
    }

    if( Closest < 70 && CPawn != NULL )
    {
        if( CPawn->IsA( AcAPBPawn::StaticClass() ) )
        {
            AcAPBPawn* ATarget = (AcAPBPawn*)CPawn;
            if( APBGameEngine->m_HostingClient->m_namequery != NULL )
            {
                FString strPlayerName;
                APBGameEngine->m_HostingClient->m_namequery->GetCharacterNameNative( ATarget->m_nControllerCharacterUID, &strPlayerName );
                DrawStringEx( pCanvas, 20, 20, Green, false, strPlayerName.Data );
            DrawStringEx( pCanvas, 20, 40, Green, false, IntTowchar_t(ATarget->Health) );
            }
         }
      }
   }
}


thanks to Wiccaan.
also yeah my plan instead of making it loop forever is to give it a condition with a bool so it only finds the pawn and hooks to it until a keystroke or the pawn dies, but before doing that I have a bigger problem.

I think I'm missing an error check that is causing the program to crash if after finding a pawn, test 2 runs again without any pawn in the screen.

the only thing that could be missing an error check that comes to my mind could be after declaring vTargetPosScreen...

any idea on what could be causing it?
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites