Not finishing a turn...

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Not finishing a turn...

Post by TheScribe »

The included map is for a scenario in my campaign. Every farm hex has a peasant on it. The only problem is that the AI only moves 30 or so of them and then ends his turn. Is there any way to fix this?

Sorry I included it as a .MAP, the extension isn't allowed otherwise.

EDIT: I added the scenario file.
Attachments
7b_Incursion.cfg
(4.11 KiB) Downloaded 147 times
7_B_P.MAP
(26.97 KiB) Downloaded 147 times
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: Not finishing a turn...

Post by Elvish_Hunter »

Moved to WML Workshop.
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
User avatar
artisticdude
Moderator Emeritus
Posts: 2424
Joined: December 15th, 2009, 12:37 pm
Location: Somewhere in the middle of everything

Re: Not finishing a turn...

Post by artisticdude »

If you want the AI to be more offensive, perhaps you should try upping their aggression? Side 2 has 0 gold and an income of 0, so I think the AI is trying to be very cautious with its units. Try including this in the side definition of side 2:

Code: Select all

[ai]
    agression=1
[/ai]
"I'm never wrong. One time I thought I was wrong, but I was mistaken."
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Re: Not finishing a turn...

Post by TheScribe »

All that does is affects what weapon it's units use and who they attack. Not what units they move.

And yes, I tried it.
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: Not finishing a turn...

Post by mattsc »

What happens here is that the AI considers that it has moved enough units for the priority it assigns to its targets. Moving more units would not improve the "strategic value of the overall unit positions", or whatever you want to call it. If you want it to move more (all) units, up the priority it gives to Side 1 targets (this needs to go inside the Side 2 [side] tag):

Code: Select all

[ai]
    [goal]
        [criteria]
            side=1
        [/criteria]
        value=1000
    [/goal]
[/ai]
That works, however I noticed that even with 'Skip AI turns' it is painfully slow. That's because the move-to-targets phase in the AI considers all units before moving one. If all you want is to have these units move toward the enemies in the north, you could write a very simple AI with either Formula AI or Lua AI that moves them a row at a time and would be much faster. (Most likely, I have never seen a scenario with that many units, so that'd have to be tested).
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Re: Not finishing a turn...

Post by TheScribe »

That worked. Thanks!

Though I can't write the AI modifier like you said yet, as I don't know how. I'll be reading the tutorials soon though.
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: Not finishing a turn...

Post by mattsc »

TheScribe wrote:Though I can't write the AI modifier like you said yet, as I don't know how. I'll be reading the tutorials soon though.
When you get to that, let me know if you want help with it. Or, if you can describe exactly what behavior you want (for movement only, I'd leave the attacks phase untouched), I could probably write a first simple version for you that you can then expand on. Just moving north won't quite work because of the deep water in the way.
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Re: Not finishing a turn...

Post by TheScribe »

mattsc wrote:I could probably write a first simple version for you that you can then expand on.
That would be great. Basically, I want them to overrun the player's keep and try to stop the silver mage from teleporting. If you could do that it
d be wonderful. Thanks.

P.S. The planned action of the AI isn't set in stone. If you can't do that or it's hard to do so then I can change it.
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: Not finishing a turn...

Post by mattsc »

Actually, having them go for a fixed location (the keep), rather than having to try to figure out which of several potentially moving targets (units) to go for, is quite simple. So here's one possibility:

Include this code into your side definition:

Code: Select all

        {ai/aliases/stable_singleplayer.cfg}
        [ai]
            [engine]
                name="lua"
                code= <<
                    local ai = ...
                    return wesnoth.require("~add-ons/AI-demos/lua/peasants_engine.lua").init(ai)
                >>
            [/engine]
        [/ai]
        [ai]
            {MODIFY_AI_ADD_CANDIDATE_ACTION 2 main_loop (
                [candidate_action]
                    engine=lua
                    name=peasants
                    evaluation="return (...):move_peasants_eval()"
                    execution="(...):move_peasants_exec()"
                [/candidate_action]
            )}
        [/ai]
And the following into a file 'peasants_engine.lua'. Note that you need to adjust the path inside the [engine] tag above to point to wherever you put that file.

Code: Select all

return {
    init = function(ai)

        local peasants = {}

        function peasants:move_peasants_eval()
            -- Positive eval if any of the peasants can still move
            local units = wesnoth.get_units { side = wesnoth.current.side, canrecruit = 'no' } 

            -- Don't use 'formula=' to test for moves, way too slow for this many units.  Instead:
            for i,u in ipairs(units) do
                if (u.moves > 0) then return 90000 end  -- score just below combat CA
            end

            return 0
        end

        function peasants:move_peasants_exec()

            local w,h,b = wesnoth.get_map_size()
            -- Go through the peasants one map row at a time
            for y = 1,h do
                -- All peasants in that row:
                local units = wesnoth.get_units { side = wesnoth.current.side, canrecruit = 'no', y = y }

                for i,u in ipairs(units) do
                    -- If the peasant can move:
                    if u.moves > 0 then
                        -- Find hex closest to (23,1), with y-distance (r[2]) twice as important as x distance (r[1])
                        local reach = wesnoth.find_reach(u)
                        local max_rating, best_hex = -9e99, {}
                        for i,r in ipairs(reach) do
                            -- Only unoccupied hexes are considered
                            -- This also excludes the unit's own hex, which is fine here
                            local unit_in_way = wesnoth.get_unit(r[1], r[2])
                            if not unit_in_way then
                                local rating = - (r[1] - 23)^2. / 4. - (r[2] - 1)^2
                                if rating > max_rating then
                                    max_rating, best_hex = rating, { r[1], r[2] }
                                end
                            end
                        end

                        -- If a target hex was found, go there
                        if best_hex[1] then
                            if (u.x ~= best_hex[1]) or (u.y ~= best_hex[2]) then
                                ai.move_full(u, best_hex[1], best_hex[2])
                            end
                        end
                    end
                end
            end
        end

        return peasants	
    end
}
I don't have time for more explanations than what's include in the comments right now. You can read up on this at Practical_Guide_to_Modifying_AI_Behavior or let me know if you'd like me to explain anything and I can do that later.

A couple things I noticed:
- There are a couple "pockets" on the map where the peasants get stuck due to the simplicity of the algorithm. The easiest would be if you adjusted the map a little. If you don't want to do that, we could add a condition to the code that takes care of things when this happens.
- The attacks (left to the normal AI) are still quite slow because there are so many units. Since there are at most a few attacks of them per turn, that's probably ok. Or, we could add a similar super-simple (and therefore fast) candidate action for attacks.

Let me know if this works for you, if you want something changed, and whether it is faster than the default version.
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Re: Not finishing a turn...

Post by TheScribe »

Slight issue. I got this message. Any idea what it means?
Attachments
Error.PNG
Error.PNG (13.03 KiB) Viewed 2984 times
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: Not finishing a turn...

Post by mattsc »

It means (probably) that there's a Lua AI error of some sort (I'm not using Windows, so I am not 100% sure, but that would be my guess). It could come from a bunch of different things: something I did wrong in my code, you putting it into the scenario incorrectly, etc. The easiest would be if you send me a zip of your entire campaign folder (either post it here or PM me) and I'll try to trouble shoot it for you.

EDIT: I promise I won't steal any ideas from your campaign before it is published. :lol2:

EDIT 2: If you want me to hazard a random guess, are you sure that this line:
return wesnoth.require("~add-ons/AI-demos/lua/peasants_engine.lua").init(ai)
got changed correctly and points to the correct file?
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Re: Not finishing a turn...

Post by TheScribe »

Never mind. I forgot to save the peasants_engine file as a .lua. :oops:

What are the coordinates for the trouble pockets?
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
mattsc
Inactive Developer
Posts: 1217
Joined: October 13th, 2010, 6:14 pm

Re: Not finishing a turn...

Post by mattsc »

TheScribe wrote:Never mind. I forgot to save the peasants_engine file as a .lua. :oops:
Just for reference, it does not have to be a .lua extension, but the filename needs to match that in the wesnoth.require() call. :)
TheScribe wrote:What are the coordinates for the trouble pockets?
What I saw where the two peninsula kind of areas at the bottom of the map. If you look at the code (the 'rating' line), it is trying to minimize (y-1) and (x-23) simultaneously, that is, move each unit toward hex (23,1). Therefore, if the terrain is set up so that a peasant can only move south and away from x=23, it will not be able to get out of there. Just let the AI play through a few turns and you will see the areas from which the peasants cannot get away.
User avatar
TheScribe
Posts: 465
Joined: June 17th, 2012, 8:17 pm
Location: You won't know till it's too late

Re: Not finishing a turn...

Post by TheScribe »

Yeah, I saw it. I replaced the irrigation canals with walking paths. It actually looks better now...
Sorta on a break from the forums ATM, have been for a while. If I was doing something for/with you and I haven't recently, that's why, I will be back soon hopefully.
Post Reply