Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Mad Deep AI (still has a problem though)
#1
This AI's strategy focus on dash attacks. He will only do punches when the target is really in the range. Otherwise, he will move away (by walking diagonally). He really likes to use dash attacks :D . And that's why he is Deep! If the opponent is too far in the z-axis, he will stop running and walk away again (diagonally).

However there's a problem which I still can't solve :'( . Sometimes if the target is exactly at the same z-position, he will do NOTHING. Evil . Will be really glad if someone will actually go through my script to check it up. Well, I have checked it up a few times and am now content with that, ;p . But I wrote the ai's strategy (or logics..) in comments throughout the code to make it easier to understand what I wanted to make.

He's quite strong though if you only use bandit/template. He's the worst AI against ranged moves D: .


Code:
void id(){

    A(0,0); //reset keys
    D(0,0);
    J(0,0);
    up(0,0);
    down(0,0);
    left(0,0);
    right(0,0);
    
    for (int i = 0; i < 400; i++){ //target
        if (loadTarget(i) == 0 && target.num != self.num && target.hp > 0 && target.id < 100 && target.team != self.team){
            break;
        }
    }
    
    int xdst = self.x-target.x; //useful variables
    int ydst = self.y-target.y;
    int zdst = self.z-target.z;
    int zbgu = self.z-bg_zwidth1;
    int zbgb = bg_zwidth2-self.z;
    int ztbgu = target.z-bg_zwidth1;
    int ztbgb = bg_zwidth2-target.z;
    int xbgr = bg_width-self.x;
    int xabs = abs(xdst);
    int yabs = abs(ydst);
    int zabs = abs(zdst);
    int sf;
    float xzdashratio;
    
    int zrangem = 120;
    
    if(zabs == 0){
        xzdashratio = 9999;
    }else{
        xzdashratio = (xabs+120)/zabs;
    }
    
    int xzratiomin = 5;
    
    int punchrange = 50; //settings, important constantd
    int punchzrange = 15;
    int escapezrange = 100;
    int dashattackrange = 120;
    int dashrangerundiff = 150;
    int dashrangebackrundiff = 40;
    int dashattackrangerundiff = 80;
    int dashattackrangebackrundiff = 0;
    int dashattackrunrange = 200;
    int dashingrange = 200;
    int switchrange = 180;
    int zswitchrange = 50;
    
    int dashlimit;
    int dashattacklimit;
    
    if(self.facing == true){ //using the variable sf to read facing
        sf = -1;
    }else{
        sf = 1;
    }
    
    if(target.blink == 0 && target.state != 14 && target.id < 100){ //the opponennt vulnerable?
        if(xabs < punchrange){ //if he's very close
            if(self.state == 2){ //I am running? well, time to do a dash attack..
                J(1,0);
                A(1,0);
            }else if(zabs < punchzrange){ //no? is the opponent close enough in z-axis to punch?
                if(sf == 1){ //yeah so check whether I need to switch facing or not, and do the punch
                    if(xdst < 20){
                        A(1,0);
                    }else{
                        left(1,0);
                    }
                }else{
                    if(xdst > -20){
                        A(1,0);
                    }else{
                        right(1,0);
                    }
                }
            }else{ //not close enough to punch? then I'll move diagonally
                if(zdst < 0){ //approach the target in z-axis
                    down(1,1);
                }else{
                    up(1,1);
                }
                
                if(xdst > 0){ //but away from it in x-axis
                    right(1,1);
                }else{
                    left(1,1);
                }
            }
        }else{ // hmm.. so he's not very close (in x-axis)
            if(self.state == 2){ //if I am running
                if(target.state == 2 || target.state == 5){ //if the target is running/dashing, adjust range limits accordingly
                    if(target.facing == self.facing){
                        dashlimit = dashingrange - dashrangebackrundiff;
                        dashattacklimit = dashattackrange - dashattackrangebackrundiff;
                    }
                    else{
                        dashlimit = dashingrange + dashrangerundiff;
                        dashattacklimit = dashattackrange + dashattackrangerundiff;
                    }
                }
                else{
                    dashlimit = dashingrange;
                    dashattacklimit = dashattackrange;
                }
                
                if(xabs < dashlimit){ //if the target is close enough, I will do a dash.
                    J(1,0);
                    if(zdst < 0){
                        down(1,1);
                    }else{
                        up(1,1);
                    }                        

                }else{ //the target isn't close enough. I stick to my zrangem
                    if(zdst < -zrangem - 1){
                        down(1,1);
                    }else if(zdst > -zrangem + 1 && zdst < 0){
                        up(1,1);
                    }else if(zdst > 0 && zdst < zrangem - 1){
                        down(1,1);
                    }else if(zdst > zrangem + 1){
                        up(1,1);
                    }
                }
            }
            if(self.state == 2 || self.state == 5){ //if I can do dash attack
                if(xabs < dashattacklimit){ //if he's even closer, I will do a dash attack as well.
                    A(1,0);
                }
            }
            
            if(xzdashratio > xzratiomin){ //if I am in position to run
                if(xdst > 0){ //I will chase my opponent
                    left(1,0);
                }else{
                    right(1,0);
                }
            }else{ //however if we are apart in z-axis too far away,
                if(xdst > 0){ //I will run away ;)
                    right(1,1);
                }else{
                    left(1,1);
                }
                if(zdst < 0){
                    down(1,1);
                }else{
                    up(1,1);
                }
            }
        }
    }else{ //nooo, the target is invulnerable!! Let's run away!
        if(target.x < switchrange){ // I don't want to get cornered at the side, so I will switch sides if I need to.
            right(1,1);
        }else if(bg_width - target.x < switchrange){
            left(1,1);
        }else{
            if(xdst > 0){
                right(1,1);
            }else{
                left(1,1);
            }
        }
        
        if(ztbgu < zswitchrange){
            down(1,1);
        }else if(ztbgb < zswitchrange){
            up(1,1);
        }else{
            if(zdst < 0){
                up(1,1);
            }else if(zdst >= 0){
                down(1,1);
            }
        }
    }
}
TEMPE
Reply
Thanks given by:
#2
Oh, I see. That is because all ur if statements got things to do with the zdist. And it never compares z to 0. So add some "|| zdist == 0" in your attack conditions. This will make the AI fights even if the distance in the z-axis is 0 (nothing). Hope this helps.
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by: Kevin
#3
it was my first guess, but I use the 'else' function so I think it already covers all possibility in z-axis position D:
so e.g. if(zdst > 0){do 'this';}else{do 'that';} which means if zdst is exactly 0, it is supposed to still do 'that'

TEMPE
Reply
Thanks given by:
#4
Code:
if(zdst < -1){
                up(1,1);
            }else if(zdst > 1){
                down(1,1);
            }
You don't cover the values (-1,0,1). That makes 3 units where you char doesn't know what to do.
Silverthorn / Blue Phoenix
~ Breaking LFE since 2008 ~

"Freeze, you're under vrest!" - Mark, probably.

» Gallery | » Sprites | » DeviantArt
Reply
Thanks given by: Kevin
#5
Code:
if(zdst < 0){ //approach the target in z-axis
                    down(1,1);
                }else{
                    up(1,1);
                }
                
                if(xdst > 0){ //but away from it in x-axis
                    right(1,1);
                }else{
                    left(1,1);
                }

but exactly after that, the char will definitely go either right or left (coz I use else, which covers everything).
TEMPE
Reply
Thanks given by:
#6
Well the reason that this happens is that there is an if statement, then an else statement, then an else statement AGAIN!. The computer will sure ignore everything in the conditioning after the 1st else statement it finds. And ur zdist conditioning is in the second else statement. In other words its ignored.The second else statement should be changed to an else if statement. I hope u understood wat i meant, cuz I am too busy now that I don't even have time to check wat I wrote. Hope it helps though.
Also put in mind that the z walking speed is usually 3. This means that ur character will walk in a zigzag route if that stayed zdist < 1.
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by:
#7
Hmm I can't find two elses in the same if-block D=
else if is written with space right? (like "else if(you_laugh){punch;}" , . . . . . instead of "elseif(you_laugh){punch;}")
TEMPE
Reply
Thanks given by:
#8
I don't know wat was wrong with me yesterday cuz i thought i saw that. My bad, I can't find it... And yeah, with space like "else if".
[Image: signature.png]
A-Engine: A new beat em up game engine inspired by LF2. Coming soon

A-Engine Dev Blog - Update #8: Timeout

Reply
Thanks given by:
#9
Had an idea for an AI like this as well.

Anyway, your problem is, that you are dividing by zero.
Use this instead:
    CPP-Code:
float xzdashratio;
if(zabs == 0){
    xzdashratio = 1337;//just some high number
}else{
    xzdashratio = (xabs+120)/zabs;
}
Age ratings for movies and games (and similar) have never been a good idea.
One can learn a lot from reinventing wheels.
An unsound argument is not the same as an invalid one.
volatile in C++ does not mean thread-safe.
Do not make APIs unnecessarily asynchronous.
Make C++ operator > again
Trump is an idiot.
Reply
Thanks given by: A-Man , Kevin
#10
Awesome!! I didn't think of that XD
It's now working, thanks! :D


EDIT:
I updated the AI, now it can also kill the original AI in 1v1 with almost no HP lost.
TEMPE
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)