My best piece of advice is to write the AI object with similar "inputs" like you would with the player object. When I first started writing AI my tendency was to take shortcuts and set values directly instead of using ai "inputs".
For example, if the AI character is standing in a fire and needs to run to the left to get out of the fire, instead of writing:
GML:
while(is_in_fire)
{
x += 2;
}
You should write:
GML:
if (is_in_fire)
{
x_go_to = //x position where there is no fire
}
if (x < x_go_to)
{
move_right();
}
if (x > x_go_to)
{
move_left();
}
And then move_left() and move_right() should have the same code you've written in the player's keyboard left/keyboard right events. This way you can handle collisions and the AI won't accidentally cheat by going through walls. And you can also do the same thing with attacks. Copy the attack code that you've written for when the player presses the "attack" button and use it in a script that the AI should call. This will make sure the AI is playing by the same rules and won't spam a fireball every step or something like that. The closer your AI object is to your player object the better things will be. Your AI won't accidentally cheat if it can only do actions based off of the same inputs that the player can do.
Now this doesn't tell you how to determine what the AI should do at each step. Like
@samspade said, Finite State machines will be your friend. You create a bunch of states that tell the AI what it's currently doing, and then switch between them when things happen. You can have an "Attack Close" state where the AI tries to move close to the player and use a punch/kick or a "Attack Far" state where the ai tries to get some distance from the player and use a fireball or throw something. Here's an example for the AI trying to not get hit by the player:
GML:
//If the AI is just sitting around
//If the player is kicking
//If I'm close enough to the player to get kicked
//See if I can get out of the way before getting hit
//If I can, move in the direction to get out of the way
//If not, see if I can block
//If I can block, then block and enter the "block" state
Another quick tip, add some randomness to keep the AI from being perfect. If the AI reacts instantly as soon as the player kicks, then it will be nearly impossible to win.
Hopefully this is helpful. AI is very tough, but it's also incredibly rewarding. Good luck!