Ansätze für KI



  • Ich meine nicht die Möglichkeiten. Ich meine den Ansatzt mit >Select Case< ob es da auch was anderes gibt.



  • ich glaub, es ist eine ziemlich sinnvolle methode, sowas zu lösen, ich mach das in der regel auch so...
    du kannst auch probieren, mit flags zu hantieren (Reim !!!),
    aber das wird glaub ich recht schnell unübersichtlich und wirr. außerdem isses bestimmt langsamer....aber ich bin da leider kein profi 🙂
    gruß
    konstantin



  • Such mal im Netz nach einer State Machine. Oder lese im Buch Gameprogramming Gems 1 den artikel von Steve Rabin



  • Also unter StateMachine verstehe ich. Ein Zustand bleibt solange erhalten bis dieser geändert wird.

    Und das kann man doch mit select case am besten realisieren.



  • Ich würde die State machine als Macro´s definieren. Damit kann man den Präprozi super mißbrauchen 🙂

    Hier ein Beispiel aus den GPG

    //This is the state machine language.
    //To see the keywords, look in the file "fsmmacros.h".
    //You can get MS Visual Studio to highlight these words by listing them in
    //a text file called "usertype.dat" put in the same directory where Msdev.exe
    //is stored (like C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin).
    //You'll find the "usertype.dat file in the same directory this file is in.
    //Just copy it to the correct directory.
    
    #define BeginStateMachine   if( STATE_Global == state ) { if(0) {
    #define State(a)            return( true ); } } else if( a == state ) { if(0) {
    #define OnEnter             return( true ); } else if( MSG_RESERVED_Enter == msg->name ) { 
    #define OnExit              return( true ); } else if( MSG_RESERVED_Exit == msg->name ) { 
    #define OnUpdate            return( true ); } else if( MSG_RESERVED_Update == msg->name ) { 
    #define OnMsg(a)            return( true ); } else if( a == msg->name ) {
    #define SetState(a)         go->next_state = a; go->force_state_change = true;
    #define EndStateMachine     return( true ); } } else { assert( !"Invalid State" ); \
                                return( false );}  return( false );
    

    Siehst du was ich meine?

    Verwenden tut man es dann so:

    bool DroneProcessStateMachine( GameObject* go, unsigned int state, MsgObject* msg )
    {
    
    //This is the state machine language.
    //To see the keywords, look in the file "fsmmacros.h".
    //You can get MS Visual Studio to highlight these words by listing them in
    //a text file called "usertype.dat" put in the same directory where Msdev.exe
    //is stored (like C:\Program Files\Microsoft Visual Studio\Common\MSDev98\Bin).
    //You'll find the "usertype.dat file in the same directory this file is in.
    //Just copy it to the correct directory.
    
    BeginStateMachine
    
        //----------------------------------------------------------------
        //This first section (before STATE declarations) is known as the
        //Global section. These responses apply over all states, regardless
        //of the current state. Importantly, these responses are only
        //active after the current state has been checked. When the state
        //machine first starts up, its not in any state. Therefore, the code
        //below is critical for setting the starting state.
    
        OnEnter
            //When the state machine becomes initialized, it will execute this code 
            SetState( STATE_Idle ); //This sets the initial state that it starts up in
    
        OnMsg( MSG_ChangeState )
            //If a ChangeState message doesn't get handled by the current state,
            //it would be handled right here. You can execute any code or even
            //change state right here. Therefore, you can have global triggers
            //that can change from any state to any other state.
    
        //----------------------------------------------------------------
        //This is a state definition
        State( STATE_Idle )
    
            OnEnter //When the state is entered, it executes the following code
                SendMsg( MSG_ChangeState, go->unique_id, go->unique_id );
    
            OnMsg( MSG_ChangeState ) //When a MSG_ChangeState is received, it executes the following code
                SetState( STATE_Wander );
    
            OnExit
                //You can execute code right here on exiting this state - but I didn't put any
    
        //----------------------------------------------------------------
        State( STATE_Wander )
    
            OnEnter
                //Sends a delayed message (a timer) between 1 and 10 seconds in the future to ourselves
                SendDelayedMsg( MSG_Timeout, RandomBetween( 1.0f, 10.0f ), go->unique_id, go->unique_id );
    
            OnUpdate
                //You can execute code right here every game tick - but I didn't put any
    
            OnMsg( MSG_Timeout )
                if( rand()%100 < 50 ) {
                    SetState( STATE_Pursue );
                }
                else {
                    SetState( STATE_Evade );
                }
    
        //----------------------------------------------------------------
        State( STATE_Pursue )
    
            OnEnter
                SendDelayedMsg( MSG_Timeout, RandomBetween( 1.0f, 10.0f ), go->unique_id, go->unique_id );
    
            OnMsg( MSG_Timeout )
                if( rand()%100 < 30 ) {
                    SetState( STATE_Wander );
                }
                else {
                    SetState( STATE_Evade );
                }
    
        //----------------------------------------------------------------
        State( STATE_Evade )
    
            OnEnter
                SendDelayedMsg( MSG_Timeout, RandomBetween( 1.0f, 10.0f ), go->unique_id, go->unique_id );
    
            OnMsg( MSG_Timeout )
                if( rand()%100 < 70 ) {
                    SetState( STATE_Wander );
                }
                else {
                    SetState( STATE_Cower );
                }
    
        //----------------------------------------------------------------
        State( STATE_Cower )
    
            OnEnter
                SendDelayedMsg( MSG_Timeout, RandomBetween( 1.0f, 10.0f ), go->unique_id, go->unique_id );
    
            OnMsg( MSG_Timeout )
                if( rand()%100 < 10 ) {
                    SetState( STATE_Dead );
                }
                else {
                    SetState( STATE_Hide );
                }
    
        //----------------------------------------------------------------
        State( STATE_Hide )
    
            OnEnter
                SendDelayedMsg( MSG_Timeout, RandomBetween( 1.0f, 10.0f ), go->unique_id, go->unique_id );
    
            OnMsg( MSG_Timeout )
                if( rand()%100 < 30 ) {
                    SetState( STATE_Evade );
                }
                else {
                    SetState( STATE_Wander );
                }
    
        //----------------------------------------------------------------
        State( STATE_Dead )
    
            //We're dead - don't do anything
            //A state can exist without responding to any messages or
            //without actually doing anything
    
    EndStateMachine
    
    }
    


  • Wenn´s dich interessiert kann ich dir ja das Komplette Projekt schicken 🙂


  • Mod

    ich mach das mit matrizen, man kann einen eingangsvector und einen ausganzsvector definieren (binär), daraus generiert man sich ne matrix.

    das macht man halt für mehrere eingangs und ausgangs vectoren und erstellt ebensoviele matrizen dafür.

    dann addiert man die matrizen zu einr einzigen auf.

    danach kann man je nach eingangsvector mittels multiplikation mit der matrix einen ausgangsvector bekommen.

    das tolle daran ist, dass man nicht alle eingangs- und ausgangsmöglichkeiten definieren muss, sondern dass quasi durch assoziation entscheidungen getroffen werden.

    das ist ne ganz primitive art von neuralen netzen.

    rapso->greets();



  • @rapso:
    Wie siehts bei dieser Möglichkeit mit der Performance aus? Neurale Netze sind ja leider etwas lahm...



  • @snorre
    auf so was muss man mal erst kommen. 😃 Ich brauche midestens das ganze Wochenende um zu verstehen was der Code macht :p


  • Mod

    schneller als die ganzen conditional jumps, wenn du einen sprung durchführst von dem die cpu nicht ausging, dann muss die ganze pipe neu gefüllt werden
    wenn du also noch ne verschachtelung hast, wird schlimmer.
    wenn du dazu noch irgendwo ne bedingung stecken möchtest, mußte den ganzen entscheidungsbaum durchgehen und prüfen, ob du das nicht irgendwo vergessen hast einzufügen oder nicht noch besondere fälle beachten mußt. (ist wohl eher programmier und debug performance ;D)

    und mit einer matrix*vector multiplikation kannst du das leicht lösen, da es nur ganze zahlen sind, kannst du das vielleicht optimieren und mit float und int gleichzeitig rechnen (zwei vectoren) kannst das noch auf ISSE und 3dknow optimieren oder mit mmx 8 werte bearbeiten...
    also performancetechnisch ist das wirklich nicht die rede in relation zu dem sonstigen (hatte deswegen noch nie optimierzwang)

    rapso->greets();


Anmelden zum Antworten