YesNoOk
avatar

"Learning" AI (Read 27886 times)

Started by Himeragi Yukina, October 06, 2020, 03:55:30 am
Share this topic:
"Learning" AI
#1  October 06, 2020, 03:55:30 am
  • **
  • God Slayer
  • The path of resistance.
    • Philippines
    • nobodyhere@jabber.org
    • youtube.com/Thentavius
The following is the result of constant tweaking and a brief, but significant study of Misobon_ism's AI code, coupled with extensive work on the recently released Hitoshura 2.41 AI patch. While fairly rudimentary compared to the highly developed one seen in the studied AI, the reverse-engineered result was effective enough that I felt it could be shared here; not all of the variables are used, either, so assuming you use them all, that's around 30 moves the AI can memorize.

The code is below:

Code:
[Statedef 161616]
Type = U
Physics = U
Movetype = U
ctrl = 0

[State -1, AssertSpecial]
Type = AssertSpecial
flag = invisible
flag2 = noshadow
trigger1 = 1
supermovetime = 9999**2
pausemovetime = 9999**2

[state -1, nothitby]
type = nothitby
value = SCA
trigger1 = 1
supermovetime = 9999**2
pausemovetime = 9999**2
[state -1, dead]
type = destroyself
trigger1 = root,var(59) <= 0
supermovetime = 9999**2
pausemovetime = 9999**2
[state -1, nothitby]
type = bindtoroot
trigger1 = 1
supermovetime = 9999**2
pausemovetime = 9999**2

;
[State -1, Not Hit]
Type = VarSet
ignorehitpause = 1;
var(0) = 0
triggerall = root,var(59) >= 1
trigger1 = Root,movetype != H

[State -1, Got Hit]
Type = VarSet
ignorehitpause = 1;
var(0) = 1
triggerall = root,var(59) >= 1
triggerall = root,movetype = H
triggerall = root,time = 1
trigger1 = root,stateno = [5000,5030)
trigger2 = root,stateno = [120,160)

[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1) || enemynear,time < var(8)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(1)
trigger1 = var(8) := enemynear,time
var(1) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2) || enemynear,time < var(9)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(2)
trigger1 = var(9) := enemynear,time
var(2) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3) || enemynear,time < var(10)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(3)
trigger1 = var(10) := enemynear,time
var(3) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4) || enemynear,time < var(11)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(4)
trigger1 = var(11) := enemynear,time
var(4) = enemynear,stateno

[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5) || enemynear,time < var(12)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(5)
trigger1 = var(12) := enemynear,time
var(5) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6) || enemynear,time < var(13)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(6)
trigger1 = var(13) := enemynear,time
var(6) = enemynear,stateno

[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7) || enemynear,time < var(14)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(7)
trigger1 = var(14) := enemynear,time
var(7) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15) || enemynear,time < var(22)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(15)
trigger1 = var(22) := enemynear,time
var(15) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16) || enemynear,time < var(23)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(16)
trigger1 = var(23) := enemynear,time
var(16) = enemynear,stateno

[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17) || enemynear,time < var(24)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(17)
trigger1 = var(24) := enemynear,time
var(17) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18) || enemynear,time < var(25)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(18)
trigger1 = var(25) := enemynear,time
var(18) = enemynear,stateno

[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19) || enemynear,time < var(26)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(19)
trigger1 = var(26) := enemynear,time
var(19) = enemynear,stateno

[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20) || enemynear,time < var(27)
trigger1 = enemynear,stateno != var(21)
trigger1 = enemynear,movecontact = 1 ||var(0) ||enemynear,movereversed = 1
trigger1 = !var(20)
trigger1 = var(27) := enemynear,time
var(20) = enemynear,stateno
[State -1, Memory]
Type = VarSet
ignorehitpause = 1
trigger1 = root,var(59) >= 1
trigger1 = enemy,teammode=Single ||enemy,teammode=Turns
trigger1 = p2movetype = A
trigger1 = enemynear,stateno != var(1)
trigger1 = enemynear,stateno != var(2)
trigger1 = enemynear,stateno != var(3)
trigger1 = enemynear,stateno != var(4)
trigger1 = enemynear,stateno != var(5)
trigger1 = enemynear,stateno != var(6)
trigger1 = enemynear,stateno != var(7)
trigger1 = enemynear,stateno != var(15)
trigger1 = enemynear,stateno != var(16)
trigger1 = enemynear,stateno != var(17)
trigger1 = enemynear,stateno != var(18)
trigger1 = enemynear,stateno != var(19)
trigger1 = enemynear,stateno != var(20)
trigger1 = enemynear,stateno != var(21) || enemynear,time < var(28)
trigger1 = enemynear,movecontact = 1 ||var(0)  ||enemynear,movereversed = 1
trigger1 = !var(21)
trigger1 = var(28) := enemynear,time
var(21) = enemynear,stateno

The way this helper works is that it takes into account the exact time an attack hit, and simultaneously sets the stateno in question. It's not usable by itself, however; you have to make the AI account for this new data as it comes, which generally happens immediately.

This comes in the general form of the following triggers:

Code:
helper(Learning Helper ID),var(x) = enemynear,stateno
enemynear,time < helper(Learning Helper ID),var(y)

Where x is the state variable and y is the time variable. This will allow for more precise punishes on the AI's part that are more organic in nature due to a more nuanced understanding of what hit it. While not entirely infallible due to the variable limits in MUGEN (and the fact some things are just easy to bait if done frequently), it's workable enough that I've seen a difference almost immediately after applying the relevant triggers in the main AI blocks.

For emphasis: the helper seen in Misobon_ism's AI code is the exact reason why his AI for Geese, in particular, can counter so efficiently. So if you're wondering why it can get obnoxiously hard to break through his counters, this is the major reason I'd point to.
Last Edit: October 06, 2020, 04:02:58 am by Himeragi Yukina
Re: "Learning" AI
#2  June 23, 2024, 09:06:37 pm
  • **
  • Sr. Símio Enfermo
    • Brazil
    • www.mediafire.com/folder/utha9mw5dg7tn/My_Chars
Sorry for the bump, but I would like to post my version of this code real quick.  :lugoi:
Code:
[Statedef 30003350]
type = U
anim = 9741 ;Blank anim
ctrl = 0&&(fvar(0):= 0)&&(fvar(1):= 0)

[State 30003350, DestroySelf]
type = DestroySelf
trigger1 = !(Root, AILevel)

[State 30003350, BindToRoot]
type = BindToRoot
trigger1 = 1
 
[State 30003350, ChangeState]
type = ChangeState
trigger1 = fvar(2) < 30
trigger1 = Root, MoveType = H && Root, Time = 1
trigger1 = (Root, StateNo = [5000, 5029]) || (Root, StateNo = [120, 159])
trigger1 = Enemy, MoveContact = 1 && Enemy, HitDefAttr = SCA, AA
value = StateNo+1

;---------------------------------------------------------------------------
[Statedef 30003351]
type = U
ctrl = 0&&(fvar(0):= (fvar(0) + (PrevStateNo = StateNo)))

[State 30003351, ChangeState]
type = ChangeState
trigger1 = 1 || fvar(1):= (fvar(1) + (var(Floor(fvar(0)))!= P2StateNo))
value = StateNo + (fvar(0)>= 29)

;---------------------------------------------------------------------------
[Statedef 30003352]
type = U
ctrl = 0&Cond(fvar(1) = 30, (var(Floor(fvar(2))):= P2StateNo)&&(var(Floor(fvar(2)+30)):= Enemy, Time)&&(fvar(2):= (fvar(2)+1)), 0)

[State 30003352, ChangeState]
type = ChangeState
trigger1 = Time
value = StateNo - 2

It has basically the same result as the original code, but it can already capture the 30 moves.
Vars from 0 to 29 saves the StateNos, Vars from 30 to 59 save the timmings, Fvar from 0 to 1 serves as iterators and Fvar 2 is the slot counter.
Any suggestions will be greatly appreciated.