YGOPRO Forum

Welcome Guest! To enable all features please try to register or login.
4 Pages<1234>
Options
Go to last post Go to first unread
stan_stan  
#21 Posted : Sunday, March 08, 2015 7:27:14 PM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
Thanks Snarky.

I'll keep trying. :thup
stan_stan  
#22 Posted : Sunday, March 08, 2015 10:48:57 PM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
Snarky. I finally did it :dance

Now Sishunder is only summoned if the AI has at least 1 Kagetokage on hand.

Made something similar for Pahunder and Mahunder.


Also, added Batteryman AAA and Masked Chameleon

Batteryman and Masked Ch are only summoned if there's already 1 or more BmanAAA in the Graveyard.


I still don't know how to limit Hunders' effect to one per turn. I mean, Pahunder and Mahunder can swarm the field, on top of that Kagetogake effect is always activated.

Edited by user Sunday, March 08, 2015 11:59:59 PM(UTC)  | Reason: Not specified

Bateriemann  
#23 Posted : Monday, March 09, 2015 1:46:40 AM(UTC)
Bateriemann

Rank: Advanced Member

Joined: 3/17/2013(UTC)
Posts: 131

Thanks: 10 times
Was thanked: 14 time(s) in 13 post(s)
Thank you Snarky!

i have a question: When i want to work with my own ai_tutorial.lua file and i want to work with a priority list then i have to make my own function PrioritySetup()?. When does the ai calls this function? Do i have to call this function at the start of the duel?

I think i found a small mistake in your tutorial: http://www.fotos-hochlad...iew/snarky2mcq85p9hg.jpg
the "end" should be a "else".

Bateriemann
Bat
Snarky  
#24 Posted : Monday, March 09, 2015 2:10:00 AM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
Originally Posted by: stan_stan Go to Quoted Post

I still don't know how to limit Hunders' effect to one per turn. I mean, Pahunder and Mahunder can swarm the field, on top of that Kagetogake effect is always activated.

You could add a limitation to their abilities by only activating them, if the AI controls x amount of cards. For example if you check for #AIMon()<2 and only use the effect then, they will only activate, if the AI controls less than 2 monsters. Or FieldCheck(4)<2, then they will only activate, if the AI controls 2 or less Level 4 monsters.

Do note, that the Hunders perform an additional normal summon, but they activate an effect to do so, so this normal summon is not handled by cards.summonable_cards, but rather by the activatable cards, and the normal summoned target is selected in OnSelectCard.

Originally Posted by: Bateriemann Go to Quoted Post

i have a question: When i want to work with my own ai_tutorial.lua file and i want to work with a priority list then i have to make my own function PrioritySetup()?. When does the ai calls this function? Do i have to call this function at the start of the duel?

You can include most of the priority stuff by adding require("ai.mod.AIOnDeckSelect"). And yes, once you have the requirement, you should be able to run AddPriority() in your start of duel function, as all it does is setting up variables.
PrioritySetup() might fail, if you call it without requiring all the other deck functions.

Also, you don't need to actually add your priorities to the same file. As seen in the Constellar and Dark World files, you can just as well put the priority list in other files, I'll probably relocate the priorities to their respective deck files at some point, since that seems to make more sense, and the deck selection became kinda cramped.
Quote:

I think i found a small mistake in your tutorial: http://www.fotos-hochlad...iew/snarky2mcq85p9hg.jpg
the "end" should be a "else".


That doesn't really matter in this case.

Code:
if a then
  return b
else
  return c
end

if a then
  return b
end
return c


In this context, these do pretty much the same thing.

Edited by user Monday, March 09, 2015 2:31:49 AM(UTC)  | Reason: Not specified

Snarky  
#25 Posted : Monday, March 09, 2015 2:54:52 PM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
Added another chunk of information. Also, for anyone wanting to use the custom functions provided by the AI in their own AI: Instead of adding the required files one by one, you can just use this line:

require("ai.ai")

This links your AI file to the standard AI file, and in succession to all files the standard AI uses. Also, any function you don't add to your AI will be taken from the standard AI then. Don't feel like creating a new attack target logic? Just don't include an OnSelectBattleCommand function, it should use the one from the standard AI instead (there might be issues, because its partly handled in OnSelectCard, but I'm sure that can be sorted out).

Edited by user Monday, March 09, 2015 5:31:52 PM(UTC)  | Reason: Not specified

francot514  
#26 Posted : Monday, March 09, 2015 10:06:34 PM(UTC)
francot514

Rank: Advanced Member

Joined: 12/14/2013(UTC)
Posts: 280

Thanks: 3 times
Was thanked: 62 time(s) in 49 post(s)
Good work youre doing here Snarky, this is a really complete information, and hope ai can be extended so far, to get story mode in ygopro.

Quote:
Mm!! If i remember correct on the past there is a program called Puzzle Editor by francot514 where you are able to make puzlzle duels but also this program have some tools about ai scripting and there is an option to allow you to change the ai name though i never test it and it seems at this moment this Puzzle Editor have not anymore any ai scripting tool!!:(


What are you talking about Tea82??, my program did not was intended to allow ai scirpting only, tried to do it once, but after that in latest updates removed it, because create an ai editor will be a huge task for programming tool.. But the editor is still avaliable and very functional...
stan_stan  
#27 Posted : Tuesday, March 10, 2015 1:48:02 AM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
Originally Posted by: Snarky Go to Quoted Post
Added another chunk of information. Also, for anyone wanting to use the custom functions provided by the AI in their own AI: Instead of adding the required files one by one, you can just use this line:

require("ai.ai")

This links your AI file to the standard AI file, and in succession to all files the standard AI uses. Also, any function you don't add to your AI will be taken from the standard AI then. Don't feel like creating a new attack target logic? Just don't include an OnSelectBattleCommand function, it should use the one from the standard AI instead (there might be issues, because its partly handled in OnSelectCard, but I'm sure that can be sorted out).


Snarky, it seems like the require("ai.ai") doesn't handle the summoning of monsters from the Extra Deck.

So, let's say that I want to add some Xyz monsters like Shark Knight and Ragnazero. Obviously, the AI needs info like if I have a a SS monster, if it's in attack position, etc.

So, instead of adding all that info, what should I do?

Snarky  
#28 Posted : Tuesday, March 10, 2015 2:02:54 AM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
Originally Posted by: stan_stan Go to Quoted Post

Snarky, it seems like the require("ai.ai") doesn't handle the summoning of monsters from the Extra Deck.

So, let's say that I want to add some Xyz monsters like Shark Knight and Ragnazero. Obviously, the AI needs info like if I have a a SS monster, if it's in attack position, etc.

So, instead of adding all that info, what should I do?



All extra deck summoning is handled in OnSelectInitCommand. So if you use a custom one here, you will override the default AI summoning logic for that.

You can try to call the generic extra deck summoning logic separately, within your own OnSelectInit function. Something like this:
Code:

OnSelectInit(...

  --handle all your own stuff

  local result = SummonExtraDeck(cards) -- function handling a lot of generic extra deck cards
  if result then 
    return result[1],result[2]
  end
  return COMMAND_TO_NEXT_PHASE,1
end


Unfortunately, the AI is not modular enough, that you can implement all the parts by themselves at will. Many extra deck monsters are spread throughout different files, lots of functions you might want to include instead of remaking are within the main functions you will automatically override, if you declare new ones. Honestly, I am not sure, how to handle this the best way.

Edited by user Tuesday, March 10, 2015 2:03:36 AM(UTC)  | Reason: Not specified

stan_stan  
#29 Posted : Tuesday, March 10, 2015 2:21:55 AM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
Originally Posted by: Snarky Go to Quoted Post
Originally Posted by: stan_stan Go to Quoted Post

Snarky, it seems like the require("ai.ai") doesn't handle the summoning of monsters from the Extra Deck.

So, let's say that I want to add some Xyz monsters like Shark Knight and Ragnazero. Obviously, the AI needs info like if I have a a SS monster, if it's in attack position, etc.

So, instead of adding all that info, what should I do?



All extra deck summoning is handled in OnSelectInitCommand. So if you use a custom one here, you will override the default AI summoning logic for that.

You can try to call the generic extra deck summoning logic separately, within your own OnSelectInit function. Something like this:
Code:

OnSelectInit(...

  --handle all your own stuff

  local result = SummonExtraDeck(cards) -- function handling a lot of generic extra deck cards
  if result then 
    return result[1],result[2]
  end
  return COMMAND_TO_NEXT_PHASE,1
end


Unfortunately, the AI is not modular enough, that you can implement all the parts by themselves at will. Many extra deck monsters are spread throughout different files, lots of functions you might want to include instead of remaking are within the main functions you will automatically override, if you declare new ones. Honestly, I am not sure, how to handle this the best way.



Sounds complicated lol. But I'll keep trying. Thanks.
stan_stan  
#30 Posted : Tuesday, March 10, 2015 8:32:44 PM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
Snarky, could you please tell me about this function? and if I understan correctly this language?

Code:
function SummonImpKing(c) -- how it decides if it's ok to summon Feral Imp
  return MP2Check()  -- I have no idea what this is suppossed to mean
  and (CardsMatchingFilter(AIDeck(),FilterRace,RACE_REPTILE)>0 -- the AI has 1 or more reptile cards in the deck
  and NotNegated(c) -- i read that is a negation check, but not sure how it works
  or Negated(c) and OppGetStrongestAttDef() < 2300 -- the Opp has a monster with less than 2300 in atk or def
  and OppHasStrongestMonster()) -- not sure about this
end



So, far I've managed to copy-paste the functions for Feral Imp and Shark Knight. But Shark K. randomly targets my monsters. I still need to figure out how it decides what monster will "absorb".

Edited by user Tuesday, March 10, 2015 8:41:22 PM(UTC)  | Reason: Not specified

Snarky  
#31 Posted : Tuesday, March 10, 2015 9:03:35 PM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
Originally Posted by: stan_stan Go to Quoted Post
Snarky, could you please tell me about this function? and if I understan correctly this language?

MP2Check -> Checks, if the AI can wait until MP2 to summon a monster, or if it needs to summon it right away. MP2Check checks for the current phase (obviously), if the BP is even allowed, and if the opponent controls stronger monsters. This is done, so the AI can attack with the materials before XYZing to maybe get more damage in.

Negated and NotNegated check, if a card is currently (not) negated, or is about to be negated when it hits the field. Simple as that. If the card is on the field, it checks for the EFFECT_DISABLED, if its in a different location, it will check for stuff like Skill Drain, Jinzo, Decree, Majesty's Fiend, stuff like that.

OppHasStrongestMonster -> checks, if the opponent currently controls the strongest monster on the field. Pretty straight forward.

The summoning condition in its entirety should summon Imp King, if it is not negated on the field and has valid targets in the deck, with the option to wait until MP2. Or it will summon him, if it will be negated on the field (Skill Drain maybe), and the opponent currently controls the strongest monster on the field but Imp King would be stronger. Not much sense to XYZ under Skill Drain, if not to get a monster with stronger ATK, right? If your monsters are stronger anyway, it would just waste an XYZ summon.

Quote:

So, far I've managed to copy-paste the functions for Feral Imp and Shark Knight. But Shark K. randomly targets my monsters. I still need to figure out how it decides what monster will "absorb".


Well, that is handled in OnSelectCard again. You can make this really easy for yourself:

Code:

function SharkKnightTarget(cards,min)              -- pass the minTargets count as well, just to be on the safe side. 
  return BestTargets(cards,min,TARGET_OTHER)  --Remember, the detach part targets 2 cards
end


Normally, you would use Add for the detach, but since it usually detaches all materials at once anyway, you don't need to bother. Just make sure, you return the correct count, otherwise, you'll get an error message. And, as usual, you need to call that function in OnSelectCard.

Edited by user Tuesday, March 10, 2015 9:07:11 PM(UTC)  | Reason: Not specified

stan_stan  
#32 Posted : Tuesday, March 10, 2015 9:24:16 PM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
^^^^
Got it! Thanks Snarky.

AccessDenied  
#33 Posted : Thursday, March 12, 2015 2:31:29 PM(UTC)
AccessDenied

Rank: Advanced Member

Joined: 12/3/2012(UTC)
Posts: 110

Thanks: 9 times
Was thanked: 20 time(s) in 12 post(s)
Thanks this helped explain alot of the YGOPro Network API to me. I can start coding again. After reading this I've started making Salvation a bot;

https://github.com/Salva...blob/master/server/ai.js

I wrote like 300 lines of code in one day based on what you wrote. This tutorial has been a huge help!

Edited by user Thursday, March 12, 2015 3:20:22 PM(UTC)  | Reason: Not specified

stan_stan  
#34 Posted : Friday, March 13, 2015 1:57:42 PM(UTC)
stan_stan

Rank: Advanced Member

Joined: 5/31/2014(UTC)
Posts: 43

Thanks: 4 times
Snarky

Shark Knight now it targets the strongest SS monster I control, but I still get a script error message when SK is summoned, when it activates its effect and when it has to detach one card to avoid destruction.

I managed to make Sishunder use its effect but how do I make a priority list for the targets?

Also, I've tried to use Batteryman AAA's effect only to summon another BAAA from the grave, but no luck yet, the game crashes, so, for now, it's using it's effect to summon another copy from the hand or grave.

Also, the attack logic usually stops working after a few turns :S (I added the require("ai.ai") line and deleted OnSelectBattleCommand)

I thought I was getting good at this lol, this is way harder than I expected.

Michael Lawrence Dee  
#35 Posted : Tuesday, May 12, 2015 1:38:49 AM(UTC)
Michael Lawrence Dee

Rank: Advanced Member

Joined: 1/28/2014(UTC)
Posts: 8,804

Thanks: 730 times
Was thanked: 1337 time(s) in 1077 post(s)
Snarky, can you please bump this post when there is an update to the Tutorial and what part(s) are updated?
Now this is how I play:
Snarky  
#36 Posted : Tuesday, May 12, 2015 4:42:38 AM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
I usually do, there were no further updates in quite a while, though.
thanks 1 user thanked Snarky for this useful post.
Michael Lawrence Dee  
#37 Posted : Monday, July 13, 2015 10:37:20 AM(UTC)
Michael Lawrence Dee

Rank: Advanced Member

Joined: 1/28/2014(UTC)
Posts: 8,804

Thanks: 730 times
Was thanked: 1337 time(s) in 1077 post(s)
Umm... I'm not sure if it's already here but how do I make an AI Deck. Specifically my problem is detecting the .lua file. I have added my something like ai.decks.name in ai.lua. But I'm trying to make an Empty Jar FTK for a start also I'm planning to detect situations so it's able to surrender.

I'm basing my scripts from Spellbook.lua and ExodiaLib.lua

I have found Exodia surrender check but I don't know how to trigger it.

EDIT: My current script:

Code:

--
-- Empty Jar FTK
-- produced by Michael Lawrence Dee
--
--
function EmptyJarStartup(cards)
    AI.Chat("Testing...")
    local mset = cards.monster_setable_cards
    local stset = cards.st_setable_cards
    local activate = cards.activatable_cards
    local e1=Effect.GlobalEffect()
    e1:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_CONTINUOUS)
    e1:SetCode(EVENT_ADJUST)
    e1:SetOperation(EJSurrenderCheck(e,tp,eg,ep,ev,re,r,rp))
    Duel.RegisterEffect(e1,0)
end
DECK_EMPTYJAR    = NewDeck("Empty Jar",38699854,EmptyJarStartup)

AntiSpellM={84636823,48229808}
AntiMon={24348804,83965310,82732705}
function EJSurrenderCheck(e,tp,eg,ep,ev,re,r,rp)
    
end


It's not yet complete since the surrender condition didn't apply in-game.

Edited by user Monday, July 13, 2015 10:43:46 AM(UTC)  | Reason: Not specified

Now this is how I play:
Snarky  
#38 Posted : Monday, July 13, 2015 5:28:06 PM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
I wouldn't start with the surrender, that should be more of a gimmick after the deck is already playing properly imo. To make the AI surrender, you can just call the "Surrender()" function at any point. For exodia, I run the SurrenderCheck() both in the OnSelectInit and OnSelectChain functions, as these are pretty much always called when the AI can actually do something.

I would not look at the Exodia deck for orientation (except for the surrender, as thats the only deck that uses it), I just took the base script of the Exodia AI and cramped it into a separate file. The script itself is quite outdated and doesn't interact all that well with the other decks.

If you want to use a deck as orientation, use the Spellbook or Boxer decks, those are a pretty good showcase on how I intended people to add their decks. The creator of the spellbook deck does have a little different coding style compared to me, but that is not necessarily a bad thing.
Quote:

I have added my something like ai.decks.name in ai.lua.

This line should look something like this:
Code:

    require("ai.decks.EmptyJar")
,
assuming your file is called EmptyJar.lua. You can also use requireoptional, it doesn't matter (require throws an error if the file is missing, requireoptional makes the script work regardless of the files existence). This is probably pretty obvious from the other lines that work just like that.

Note, that this takes the name of the script file, not the name of the deck file, those may differ. Also make sure, you use the "" and don't add the ".lua" at the end. If you use require instead of the optional, you can see, if you did it correctly, because it will only let you start the game, if you did it right.
Quote:

DECK_EMPTYJAR = NewDeck("Empty Jar",38699854,EmptyJarStartup)

This line adds your deck to the system. If you start the game in debug mode, the console should print a message, which deck the AI is playing. Make sure, it prints the correct name for your deck.

Edited by user Monday, July 13, 2015 5:30:21 PM(UTC)  | Reason: Not specified

Michael Lawrence Dee  
#39 Posted : Tuesday, July 14, 2015 11:19:22 AM(UTC)
Michael Lawrence Dee

Rank: Advanced Member

Joined: 1/28/2014(UTC)
Posts: 8,804

Thanks: 730 times
Was thanked: 1337 time(s) in 1077 post(s)
Sorry. I was able to make the surrender now my new problem is an error about length of activatable_cards.
I'm pretty sure I checked the tutorial several times, so what went wrong.

Code:

--
-- Empty Jar FTK
-- produced by Michael Lawrence Dee
--
--
--NOTE: 0 - player
--        1 - AI
function EmptyJarStartup(cards)
    --local mset = cards.monster_setable_cards
    --local stset = cards.st_setable_cards
    --local activate = cards.activatable_cards
    local boechk = false --Book of Eclipse
    AI.Chat("Testing...")
    --check for surrender
    local e1=Effect.GlobalEffect()
    e1:SetType(EFFECT_TYPE_FIELD+EFFECT_TYPE_CONTINUOUS)
    e1:SetCode(EVENT_ADJUST)
    e1:SetOperation(function(e,tp,eg,ep,ev,re,r,rp)
        if Duel.IsExistingMatchingCard(negchk,1,LOCATION_ONFIELD,LOCATION_ONFIELD,1,nil) then
            Surrender()
            return
        end
        if Duel.IsExistingMatchingCard(asst,1,LOCATION_SZONE,LOCATION_SZONE,1,nil) then
            Surrender()
            return
        end
        if Duel.IsExistingMatchingCard(asm,1,LOCATION_MZONE,LOCATION_MZONE,1,nil)
            and not Duel.IsExistingMatchingCard(jars,1,LOCATION_MZONE+LOCATION_HAND+LOCATION_DECK,0,1,nil) then
            Surrender()
            return
        end
    end)
    Duel.RegisterEffect(e1,0)
    
    --priority
    for i=1,#cards.activatable_cards do
        local c = cards.activatable_cards[i]
        if c.id == 72892473 and Duel.GetFieldGroupCount(0,LOCATION_HAND,0)>Duel.GetFieldGroupCount(0,LOCATION_DECK,0)
        and Duel.GetFieldGroupCount(1,LOCATION_HAND,0)<=Duel.GetFieldGroupCount(1,LOCATION_DECK,0) then -- Card Destruction
            return COMMAND_ACTIVATE,i
        end
    end
end
DECK_EMPTYJAR    = NewDeck("Empty Jar",38699854,EmptyJarStartup) --Check Book of Taiyou

function negchk(c) --check Anti-Effect Monsters
    if c:IsLocation(LOCATION_MZONE) then
        return c:IsCode(83965310) and c:IsControler(0) and c:IsFaceup() and not c:IsStatus(STATUS_DISABLED)
    elseif c:IsLocation(LOCATION_SZONE) then
        return (c:IsCode(24348804) or c:IsCode(82732705)) and c:IsFaceup() and not c:IsStatus(STATUS_DISABLED)
    end
    return false
end
function asst(c) --check Anti-Spell Traps
    return c:IsCode(61740673) and c:IsFaceup() and not c:IsStatus(STATUS_DISABLED)
end
function asm(c) --check Anti-Spell Monsters
    return (c:IsCode(84636823) or (c:IsCode(48229808) and c:IsControler(0))) and c:IsFaceup() and not c:IsStatus(STATUS_DISABLED)
end
function jars(c) --check Morphing Jar#2 / Cyber Jar / Level Jar / Night Assailant
    return (c:IsCode(34124316) or c:IsCode(79106360) or c:IsCode(16226786) or c:IsCode(511000585))
        and (c:IsFacedown() or not c:IsLocation(LOCATION_MZONE))
end


The one with "priority" comment.
Now this is how I play:
Snarky  
#40 Posted : Tuesday, July 14, 2015 1:05:35 PM(UTC)
Snarky

Rank: Advanced Member

Joined: 7/6/2013(UTC)
Posts: 2,197

Thanks: 11 times
Was thanked: 462 time(s) in 340 post(s)
Your Startup function is only called at the start of the duel once, and it does not have any cards to list. It receives the deck as a parameter, which allows you to setup various functions and blacklists affecting this deck only. What you most likely want to do is define an "Init" function, which is called whenever the AI can do something in its main phase, maybe like this:

Code:


function EmptyJarStartup(deck) 
  -- check Boxer.lua or the tutorial template for a list of things you can setup here
  deck.Init = EmptyJarInit -- this links your own Init function to the deck
end

DECK_EMPTYJAR    = NewDeck("Empty Jar",38699854,EmptyJarStartup) -- Check Book of Taiyou

function EmptyJarInit(cards,to_bp_allowed,to_ep_allowed) 
  -- same parameters as "OnSelectInitCommand", check the ai-template.lua
  -- feel free to leave out the latter, it works just fine with only "cards"
  print("The AI can activate "..#cards.activatable_cards.." different effects.")
end 



This sets up your deck and tells the script to call your Init function whenever OnSelectInit is called by the system

Edited by user Tuesday, July 14, 2015 1:06:49 PM(UTC)  | Reason: Not specified

thanks 1 user thanked Snarky for this useful post.
Users browsing this topic
4 Pages<1234>
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Notification

Icon
Error