0 Favourites

How do I make turn based tactics AI?

  • Hi,

    I only want to know how to go through all of the enemy units one by one without all of them moving/attacking at once. I have tried looping through them but that results in all of them moving at once. I put a Wait action with 1*loopindex into the loop and it kind of works but the results are unreliable (I can't really say why). I have also tried making a recursive "loop" but it also has its own problems. It does not seem to wait for other functions to finish or return a value.

    For each unit, a certain amount of functions must be ran. So far I have implemented functions for checking if the unit can attack and if not then it moves. The movement function checks if path blocked and tries to go around. These functions work.

    Thank you!

  • Construct 3

    Buy Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Buy Now Construct 3 users don't see these ads
  • Do the events have to be run in order one by one for any particular reason? You could just have them act independently by giving them their own states for what they're currently doing.

  • I want to pick enemy unit UIDs one by one and check if that particular unit can attack/move/etc and act accordingly.. then pick the next unit and perform the same checks. What do you mean by having them act independently with states?

  • Anyone? I'm stuck...

  • Give your units a variable that signifies whether they have moved or not (or use one that they already have like action points etc). For simplicity lets use a boolean, "Ready".

    When you go to pick a enemy unit to move you use these events :

    Pick all - Enemies (pick all is from the system menu)

    Enemy is Ready (get this from the enemy object itself, comparing boolean)

    Pick a random instance of Enemy (from the system menu again)

    The above picks all enemies for you to select from,

    Then only selects those that are ready,

    Then refines it a single random one that is ready.

    Now that you have 1 unit selected you can run your chain of functions.

  • Thank you for the reply! It seems to work.. But how do I do the random selection again for the remaining enemies? The selecting needs to be repeated and I would run into the original problem again I fear. In my game you can move all of your soldiers during your turn and not only one like in chess for example.

    I'm using arrays containing unit UIDs for each team. The arrays are populated on start of layout. When the player changes turn, the game checks if the next player is AI. If it is AI, then loops player2_team.Width many times and picks a unit based on the UIDs in the array: player2_team.At(loopindex). After picking the unit, a series of functions are ran. These functions check if the current unit can attack or move to a tile.

    This all works fine but it all happens so fast that the player will be confused. I want to find a way to delay the picking of the next unit.

  • You need to have an array that keeps track of all the units on a team 1 for players and 1 for monsters. for instance x 16 and y 8 z 1 16 slots 8 player vs 8 monster with each 8 variables UID,DoneTurn/TimeUnits,Health,HealthMax,Mana ect ect You should be looping through all of the active teams men to look for DoneTurn variable to see who has a turn still and giving them control at that point. It shouldn't be team changed be until your loop of Player.At(loopindex,2) (2 was DoneTurn in my example of the Y dimension) was COMPLETELY ran out without a single person showing a DoneTurn switch not thrown yet Then you throw all the Doneturn's back to 0 and switch teams.

  • You need to have an array that keeps track of all the units on a team 1 for players and 1 for monsters. for instance x 16 and y 8 z 1 16 slots 8 player vs 8 monster with each 8 variables UID,DoneTurn/TimeUnits,Health,HealthMax,Mana ect ect You should be looping through all of the active teams men to look for DoneTurn variable to see who has a turn still and giving them control at that point. It shouldn't be team changed be until your loop of Player.At(loopindex,2) (2 was DoneTurn in my example of the Y dimension) was COMPLETELY ran out without a single person showing a DoneTurn switch not thrown yet Then you throw all the Doneturn's back to 0 and switch teams.

    Thank you for the reply! What you are suggesting is basically what I'm doing. Looping through an array and checking if unit is active. Problem is that the loop goes through so fast... All of the AI unit movement and attacks become a simultaneous mess.

    I have been planning the following: Let the loop go through fast, without moving or attacking, but recording all of the AI's decisions into an array, and then "playing" the array like a record with a 1 sec delay between every array entry. I tested a simple version of this and it worked but I noticed there is a major hurdle with this approach... Each AI unit would have to base their decisions on the new "record" instead of the current state visible to the player. I believe I may have to go this route anyway because it would be a nice feature to record all turns for later playback.

  • I was taking a dump and realized how stupid I have been. The answer to my question seems to be the 'Every x seconds' event. I put it into a group and activate the group when its AI's turn. Everything seems to work for now... Thank you all for taking the time to help!

  • Glad you got it to work! Okay, I understand now what is going on. When you are acting on behalf of a AI unit you need to remember to use System - Wait constantly because you are putting on an automated show just do it in between decisions, attacks, movement all of them so you get an effect like your watching something happen. Also put the "Scroll-to" behavior on all your AI and when it is that unit's turn flip behavior enabled on so your camera will leap around to the current computer unit acting. Tell me if you have any more questions.

  • Glad you got it to work! Okay, I understand now what is going on. When you are acting on behalf of a AI unit you need to remember to use System - Wait constantly because you are putting on an automated show just do it in between decisions, attacks, movement all of them so you get an effect like your watching something happen. Also put the "Scroll-to" behavior on all your AI and when it is that unit's turn flip behavior enabled on so your camera will leap around to the current computer unit acting. Tell me if you have any more questions.

    Thank you for replying! You are correct I have to use the "System Wait" but using it in a loop results in unwanted behavior and recursive looping was not any better. There must be something I'm missing. Your suggestion with the camera is very good I need to implement it later.. right now the map is just one screen. I have not had the time to continue my game project in a while. The "Every X seconds" approach did not work fully but I have to work on it.

  • Sweet, I think I finally got it working. doAI function is called every X seconds and within the doAI function all the checking for attacking and moving is done for the currently picked AI unit. A variable value gets incremented by 1 after every doAI function completed. This allows the picking of the next AI unit, after the "Every X seconds" fires again, with the help of the array of unit UIDs. p2_units.At(increment)

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)
Similar Topics Posts Views Last Post
Unread hot topic
167 14,512
DMT2005's avatar
DMT2005
Unread hot topic
89 7,383
lolpaca's avatar
lolpaca
Unread sticky
1 Favourites
C2 Games made with CocoonIO
136 89,835
minhcuong's avatar
minhcuong