Example #1
0
 public void Start()
 {
     hexTileController  = GameObject.FindGameObjectWithTag("HexController").GetComponent <HexTileController>();
     hexTile            = hexTileController.FindHex(transform.position);
     transform.position = hexTile.Position;
     hexTile.SetObject(gameObject, true);
 }
Example #2
0
    public static float EvaluateState(GameState gameState, HexTileController htc)
    {
        //Data is going into a MinQ, smaller number is better
        float inAttackRange   = 0; //Bounis if you can attack characters
        float distanceToEnemy = 0; //Minimise this
        float enemyCanAttack  = 0; //Minimise this (large is bad)

        foreach (Character c in gameState.playerChars)
        {
            float distance = htc.FindHexDistance(gameState.selfTile.Position, c.gameCharacter.position);
            //If you can attack this player character
            if (distance <= gameState.selfChar.stats.range)
            {
                //Bigger number is better, (you are subtracting this later)
                // You want to be able to attack the player, but only just. (Incase you have a longer range then them).
                // The enemy has a range of 5, you are 5 tiles away (and can attack) = good (1)
                // The enemy has a range of 5, you are 1 tile away = worst (.2)
                // The enemy has a range of 2, you are 3 tiles away = great (1.5)
                inAttackRange += distance / c.stats.range;
            }
            else if (distance <= c.stats.range)
            {
                //If the enemy can attack you, but you can't attack them, this is bad
                //Only slight penality, don't want the AI to be scared
                enemyCanAttack += .25f;
            }
            distanceToEnemy += distance;
        }
        //This is a MinQ, smaller is better!!!!

        /* Minimise distance to enemys (get into attack range),
         * subtract inAttackRange(you get bounises for being able to attack a character)
         * */
        return(distanceToEnemy - inAttackRange + enemyCanAttack);
    }
Example #3
0
    public static float EvaluateAOEAttackState(GameState gameState, HexTileController htc)
    {
        //Data is going into a MinQ, smaller number is better
        float          aiHealthLost = 0;
        float          playerLost   = 0;
        List <HexTile> attackRange  = htc.FindRadius(gameState.selfTile, gameState.selfChar.stats.aoeRange);

        attackRange.Add(gameState.selfTile);
        foreach (HexTile hex in attackRange)
        {
            foreach (Character c in gameState.aiChars)
            {
                if (hex.Equals(htc.FindHex(c.gameCharacter.position)))
                {
                    aiHealthLost += gameState.selfChar.stats.attackdmg;
                }
            }
            foreach (Character c in gameState.playerChars)
            {
                if (hex.Equals(htc.FindHex(c.gameCharacter.position)))
                {
                    playerLost += gameState.selfChar.stats.attackdmg;
                }
            }
        }


        return(aiHealthLost - playerLost);
    }
Example #4
0
    public static List <int> GreedySearch(HexTile start, HexTile end, HexTileController htc)
    {
        List <HexTile> closeSet = new List <HexTile>();
        PriorityQueue  fringe   = new PriorityQueue();

        fringe.Push((start, new List <int>()), 0);

        int sentinel = 200;

        //Greedy search is limited to 200 iterations to find goal
        while (fringe.HasNext() && sentinel > 0)
        {
            (HexTile state, List <int> actions) = fringe.Pop();
            if (state.Position.Equals(end.Position))
            {
                return(actions);
            }
            if (!closeSet.Contains(state))
            {
                closeSet.Add(state);
            }

            int action = 0;
            foreach (HexTile nextState in state.nexts)
            {
                //Check if the next tile is the goal state,
                // if it is, allow the AI to step onto it
                bool validMove = false;
                if (nextState != null)
                {
                    if (nextState.HoldingObject == null && !nextState.IsObstacle)
                    {
                        validMove = true;
                    }
                    else if (nextState.Position.Equals(end.Position))
                    {
                        validMove = true;
                    }
                }
                if (validMove)
                {
                    List <int> newActions = new List <int>();
                    foreach (int i in actions)
                    {
                        newActions.Add(i);
                    }
                    newActions.Add(action);
                    float cost = htc.FindHexDistance(nextState.Position, end.Position);
                    fringe.Push((nextState, newActions), cost);
                }

                action++;
            }
            sentinel--;
        }
        return(new List <int>()
        {
        });
    }
Example #5
0
 public AttackAction(Character takenby, Vector3 space)//,AttackType type,int damage)
 {
     this.space   = space;
     this.takenby = takenby;
     this.range   = takenby.stats.range;     //determine by character class
     this.damage  = takenby.stats.attackdmg; //determined by class
     htc          = GameObject.Find("TileController").GetComponent <HexTileController>();
 }
Example #6
0
 public MoveAction(Character c, params Vector3[] tiles)
 {
     takenby             = c;
     moveto              = tiles;
     total_move_action   = tiles.Length;
     current_move_action = 0;
     htc = GameObject.Find("TileController").GetComponent <HexTileController>();
 }
Example #7
0
 public void AttackMinionAtTileAndAdjacent(HexTileController tile, int damage)
 {
     AttackMinionAtTile(tile, damage);
     EasyDelayManager.instance.ExecuteAfter(0.1f, () => {
         foreach (var t in tile.AdjacentTiles.Where(adjacentTile => adjacentTile.Creature != null))
         {
             AttackMinionAtTile(t, damage);
         }
     });
 }
Example #8
0
    // public void AddActionTo(Player p , Action a) {
    //     //put the action into the players list of actions
    //     // gameSystem.AddCharacterAction();
    // }

    //get rid of this
    public void RandomlyPlace()
    {
        HexTileController htc = GameObject.Find("TileController").GetComponent <HexTileController>();

        Debug.Log(htc.Head.Position);
        // hexTileController.FindHex(mousePos, hexTile);

        int totalcharactercount = GameSystem.CurrentGame().PlayerCount() * classes.Length;

        HashSet <HexTile> tiles = new HashSet <HexTile>();

        while (tiles.Count < totalcharactercount)
        {
            try{
                tiles.Add(
                    htc.FindHex(new Vector3(
                                    UnityEngine.Random.Range(-10f, 10f),
                                    UnityEngine.Random.Range(-10f, 10), 0f)
                                )
                    );
            } catch (Exception e) {}
        }

        HexTile[] tilearray = new HexTile[totalcharactercount];
        tiles.CopyTo(tilearray);

        int cc = 0;

        foreach (Player p in GameSystem.CurrentGame().Players())
        {
            foreach (Character c in p.characters.Values)
            {
                Agent a = c.gameCharacter.GetComponent <Agent>();
                // c.gameCharacter.position
                //update character ref
                a.currentlyOn        = tilearray[cc];
                a.transform.position = tilearray[cc].transform.position;
                //update tile ref
                tilearray[cc].SetObject(c.gameCharacter.gameObject, false);
                cc++;
            }
        }
    }
Example #9
0
        public bool AddCreatureToTile(HexTileController tile, Card c)
        {
            if (tile.Creature != null)
            {
                return(false);
            }

            var transform1     = c.cm.transform;
            var creatureObject = Instantiate(CreaturePrefab, tile.transform);

            creatureObject.transform.position = transform1 == null ? Vector3.zero : transform1.position;
            var creature = creatureObject.GetComponent <CreatureController>();

            creature.Initialize(c);
            tile.Creature = creature;

            Destroy(transform1.gameObject, 0.2f);

            return(true);
        }
Example #10
0
        public void AttackMinionAtTile(HexTileController tile, int damage)
        {
            var target = tile?.transform.position ?? PlayerController.Instance.transform.position;

            var AttackObject = Instantiate(AttackPrefab);

            AttackObject.transform.position = target;
            Destroy(AttackObject, 1f);

            EasyDelayManager.instance.ExecuteAfter(0.3f, () => {
                if (tile == null)
                {
                    PlayerController.Instance.TakeDamage(damage, this);
                }
                else
                {
                    tile.Creature.TakeDamage(damage, this);
                }
                if (LifeLeechActive)
                {
                    CurrentHealth += damage;
                }
            });
        }
Example #11
0
    public static List <(HexTile, List <int>)> ValidateRadius(HexTile startTile, List <HexTile> group, int steps, List <Character> allChars, HexTileController htc)
    {
        List <(HexTile, List <int>)> result = new List <(HexTile, List <int>)>();

        foreach (HexTile hex in group)
        {
            if (!IsOnCharatcer(hex.Position, allChars) && !hex.IsObstacle)
            {
                List <int> path = Search.GreedySearch(startTile, hex, htc);
                if (path.Count <= steps && path.Count > 0)
                {
                    result.Add((hex, path));
                }
            }
        }
        return(result);
    }
Example #12
0
    public static MiniAction DecideAction(GameState gameState, HexTileController htc)
    {
        MoveDebug md           = GameObject.FindGameObjectWithTag("MoveDebug").GetComponent <MoveDebug>();
        int       attackRadius = gameState.selfChar.stats.range;

        // **** Spencer Notes ******

        /*  If you can attack, do
         *  Else evaluate all the locations you could possible move to,
         *  then take the largest and move to it
         */
        //If this character is the hacker, find best possible place to put the attack
        if (gameState.selfChar.characterclass == CharacterClass.HACKER)
        {
            List <HexTile> attackRange  = htc.FindRadius(gameState.selfTile, attackRadius);
            PriorityQueue  attackFringe = new PriorityQueue();
            md.ClearAll();
            foreach (HexTile hex in attackRange)
            {
                GameState gs    = new GameState(gameState.aiChars, gameState.playerChars, hex, gameState.selfChar);
                float     value = EvaluateAOEAttackState(gs, htc);
                md.SetText(hex, value);
                //If this attack will do more damage to yourself, don't add it to the list
                if (value < -1)
                {
                    attackFringe.Push((hex, null), value);
                }
            }
            //If there is nothing in the list (No good attacks) Move intead
            if (attackFringe.HasNext())
            {
                ((HexTile attackHex, List <int> a), float value) = attackFringe.PopWithVal();
                //If this attack only did damage to 1 character (or 1 more than your own chars)

                /* *** Come back if you have more time ****
                 * if (value <= gameState.selfChar.stats.attackdmg)
                 * {
                 *  //Find see if there is a better place to attack and move to that spot
                 *
                 * }*/
                return(new MiniAttack()
                {
                    type = "AOEAttack", attackLocation = attackHex.Position
                });
            }
        }
        else if (gameState.selfChar.characterclass == CharacterClass.PSYONIC)
        {
            Character needestChar     = null;
            Character cantReachChar   = null;
            float     cantReachHealth = 1;
            float     leastHealth     = 1;
            foreach (Character character in gameState.aiChars)
            {
                if (character.CompareTo(gameState.selfChar) != 0)
                {
                    int   distance = htc.FindHexDistance(gameState.selfChar.gameCharacter.position, character.gameCharacter.position);
                    float health   = character.stats.health / character.stats.maxHealth;
                    //If you can heal the character, and the health is less than 1
                    if (health < leastHealth)
                    {
                        if (distance <= attackRadius)
                        {
                            leastHealth = health;
                            needestChar = character;
                        }
                        else
                        {
                            cantReachHealth = health;
                            cantReachChar   = character;
                        }
                    }
                }
            }
            if (leastHealth < 1)
            {
                return(new MiniAttack()
                {
                    type = "Attack", toAttack = needestChar
                });
            }
            else if (cantReachHealth < 1)
            {
                //If there is a character in need that you can't reach, move towards it
                Debug.Log("Healer Moving towards " + cantReachChar.name);
                HexTile toMovTo = MoveTowards(cantReachChar, gameState, htc, true);
                return(new MiniMove()
                {
                    type = "Move", Dest = toMovTo
                });
            }
            else
            {
                //Can't heal yourself*******
                //Move towards the Ranger
                Character target = GetCharacter(gameState.aiChars, CharacterClass.RANGED);
                if (target != null)
                {
                    HexTile toMovTo = MoveTowards(target, gameState, htc, true);
                    return(new MiniMove()
                    {
                        type = "Move", Dest = toMovTo
                    });
                }
                target = GetCharacter(gameState.aiChars, CharacterClass.HACKER);
                if (target != null)
                {
                    HexTile toMovTo = MoveTowards(target, gameState, htc, true);
                    return(new MiniMove()
                    {
                        type = "Move", Dest = toMovTo
                    });
                }
                target = GetCharacter(gameState.aiChars, CharacterClass.MELEE);
                if (target != null)
                {
                    HexTile toMovTo = MoveTowards(target, gameState, htc, true);
                    return(new MiniMove()
                    {
                        type = "Move", Dest = toMovTo
                    });
                }
                //No other characters but you exist, await the sweet release of death
                return(new MiniMove()
                {
                    type = "Move", Dest = gameState.selfTile
                });
            }
        }
        else
        {
            Character weakestChar = null;
            Character deadChar    = null;
            float     leastHealth = int.MaxValue;
            foreach (Character character in gameState.playerChars)
            {
                int distance = htc.FindHexDistance(gameState.selfChar.gameCharacter.position, character.gameCharacter.position);

                if (distance <= attackRadius)
                {
                    //If your attack would kill this character, target this one above all else
                    if ((Mathf.Max(0, character.stats.health - gameState.selfChar.stats.attackdmg) / character.stats.maxHealth) <= 0)
                    {
                        deadChar = character;
                    }
                    if ((character.stats.health / character.stats.maxHealth) < leastHealth)
                    {
                        leastHealth = (character.stats.health / character.stats.maxHealth);
                        weakestChar = character;
                    }
                }
            }
            //Attack the soon to be dead character if it can
            if (deadChar != null)
            {
                return(new MiniAttack()
                {
                    type = "Attack", toAttack = deadChar
                });
            }
            if (weakestChar != null)
            {
                return(new MiniAttack()
                {
                    type = "Attack", toAttack = weakestChar
                });
            }
        }

        // **** Spencer Notes ******

        /* Could not find anything to attack so move to the best possible location
         */

        List <HexTile>               possibleMoves  = htc.FindRadius(gameState.selfTile, gameState.selfChar.stats.speed);
        List <Character>             allChars       = gameState.aiChars.Concat(gameState.playerChars).ToList();
        List <(HexTile, List <int>)> possibleMoves2 = ValidateRadius(gameState.selfTile, possibleMoves, gameState.selfChar.stats.speed, allChars, htc);

        //possibleMoves = ValidateRadius(gameState.selfTile, possibleMoves, gameState.selfChar.stats.speed, allChars, htc);
        possibleMoves = new List <HexTile>();
        foreach ((HexTile hex, List <int> path) in possibleMoves2)
        {
            possibleMoves.Add(hex);
        }
        PriorityQueue fringe = new PriorityQueue();

        foreach (HexTile hex in possibleMoves)
        {
            GameState gs = new GameState(gameState.aiChars, gameState.playerChars, hex, gameState.selfChar);
            fringe.Push((hex, null), EvaluateState(gs, htc));
        }

        if (!fringe.HasNext())
        {
            //No avialable moves, move to self
            return(new MiniMove()
            {
                type = "Move", Dest = gameState.selfTile
            });
        }
        (HexTile state, List <int> actions) = fringe.Pop();
        return(new MiniMove()
        {
            type = "Move", Dest = state
        });
    }
Example #13
0
 public static float EvaluateHideState(GameState gameState, HexTileController htc)
 {
     return(0);
 }
Example #14
0
    public static HexTile MoveTowards(Character target, GameState gameState, HexTileController htc, bool runFromEnemy = false)
    {
        //choose the tile you want to move to, either the character directly, or a tile next to the character that is away from the enemy
        HexTile targetTile = htc.FindHex(target.gameCharacter.position);

        if (runFromEnemy)
        {
            List <HexTile> tilesAroundTarget = htc.FindRadius(targetTile, 1);
            int            farthest          = 0;
            foreach (HexTile hexTile in tilesAroundTarget)
            {
                if (!hexTile.IsObstacle && hexTile.HoldingObject == null)
                {
                    //Find distance to all player characters
                    int newDist = 0;
                    foreach (Character c in gameState.playerChars)
                    {
                        newDist += htc.FindHexDistance(hexTile.Position, c.gameCharacter.position);
                    }
                    //You want the distance to the player to be largest
                    if (newDist > farthest)
                    {
                        farthest   = newDist;
                        targetTile = hexTile;
                    }
                }
            }
        }
        List <int> moves = GreedySearch(gameState.selfTile, targetTile, htc);

        //If run from enemy is false, your target in ON a character, so remove that last step
        if (!runFromEnemy)
        {
            //Remove the last step (the one on the distination character)
            if (moves.Count > 0)
            {
                moves.RemoveAt(moves.Count - 1);
            }
        }

        Debug.Log("Psyonic wants to move ...");
        foreach (int i in moves)
        {
            Debug.Log(i);
        }
        Debug.Log("To get to " + target.name);

        //If you were already right next to the target, don't go anywhere
        if (moves.Count == 0)
        {
            return(gameState.selfTile);
        }
        //Only keep the number of steps that you are allowed to move
        //Starting hex is your own
        HexTile hex = gameState.selfTile;

        //Repet until you hit your step count, or you run out of moves
        for (int i = 0; i < Mathf.Min(gameState.selfChar.stats.speed, moves.Count); i++)
        {
            //Get the neighbor that the path tells you too
            hex = hex.nexts[moves[i]];
        }
        return(hex);
    }
Example #15
0
    //filler code for now
    public void PutCharactersOnBoard()
    {
        GameObject tc = GameObject.Find("TileController");

        foreach (Player p in gameSystem.Players())
        {
            foreach (Character c in p.characters.Values)
            {
                //Debug.Log(c.name);
                //game is ready, show characters
                SpriteRenderer r = c.gameCharacter.gameObject.GetComponent <SpriteRenderer>();
                r.enabled          = true;
                r.sortingLayerName = "Characters";
            }
        }
        //GameObject.Find("Start").SetActive(false);
        //RandomlyPlace();

        HexTileController htc = GameObject.Find("TileController").GetComponent <HexTileController>();

        Player player1 = GameSystem.CurrentGame().Players()[0];
        int    index   = 0;

        foreach (Character c in player1.characters.Values)
        {
            Agent a = c.gameCharacter.GetComponent <Agent>();
            // c.gameCharacter.position
            //update character ref
            HexTile hex = htc.FindHex(player1_chars[index]);
            a.currentlyOn        = hex;
            a.transform.position = player1_chars[index];
            //update tile ref
            hex.SetObject(c.gameCharacter.gameObject, false);
            index++;

            //Add highlight to players
            Instantiate(playerHighlight, c.gameCharacter);
            GameObject temp = Instantiate(selectHighlight, c.gameCharacter);
            c.selectedHighlight = temp;
            c.SetSelected(false);
        }
        Player player2 = GameSystem.CurrentGame().Players()[1];

        index = 0;
        foreach (Character c in player2.characters.Values)
        {
            Agent a = c.gameCharacter.GetComponent <Agent>();
            // c.gameCharacter.pte character ref
            HexTile hex = htc.FindHex(player2_chars[index]);
            a.currentlyOn        = hex;
            a.transform.position = player2_chars[index];
            //update tile ref
            hex.SetObject(c.gameCharacter.gameObject, false);
            index++;

            //Add highlight to enemies
            Instantiate(enemyHighlight, c.gameCharacter);
            GameObject temp = Instantiate(selectHighlight, c.gameCharacter);
            c.selectedHighlight = temp;
            c.SetSelected(false);
        }
    }
Example #16
0
    public void CreateMap()
    {
        map    = GetComponent <HexMapController>();
        player = FindObjectOfType <PlayerController>();

        if (transform.Find(TILE_HOLDER_NAME))
        {
            DestroyImmediate(transform.Find(TILE_HOLDER_NAME).gameObject);
        }

        var tiles = new Dictionary <HexPos, HexTileController>();

        Transform tileHolder      = new GameObject(TILE_HOLDER_NAME).transform;
        Transform movableHolder   = new GameObject("Movable").transform;
        Transform immovableHolder = new GameObject("Immovable").transform;

        tileHolder.parent      = this.transform;
        movableHolder.parent   = tileHolder;
        immovableHolder.parent = tileHolder;

        if (mapString != null)
        {
            String[] lines = mapString.Split(new String[] { "\n" }, StringSplitOptions.RemoveEmptyEntries);
            for (int y = 0; y < lines.Length; y++)
            {
                String[] tileChars = lines[lines.Length - 1 - y].Split(new String[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                for (int x = 0; x < tileChars.Length; x++)
                {
                    TileEnum   tileType = (TileEnum)int.Parse(tileChars[x]);
                    GameObject tile     = GetTilePrefab(tileType);

                    if (tile != null)
                    {
                        HexPos            hexPos     = new HexPos(x, y);
                        GameObject        tileObject = Instantiate(GetTilePrefab(tileType), map.GetPositionFor(hexPos), Quaternion.identity);
                        HexTileController hexTile    = tileObject.GetComponentInChildren <HexTileController>();
                        hexTile.pos = hexPos;
                        var hexOrigScale = hexTile.transform.localScale;
                        hexTile.transform.localScale = new Vector3(scale * hexOrigScale.x, scaleY * hexOrigScale.y, scale * hexOrigScale.z);

                        switch (tileType)
                        {
                        case TileEnum.GRASS:
                        case TileEnum.HILL:
                        case TileEnum.RIVER:
                            tileObject.transform.parent = movableHolder;
                            break;

                        case TileEnum.MOUNTAIN:
                        case TileEnum.WATER:
                            tileObject.transform.parent = immovableHolder;
                            break;
                        }

                        if (!showTiles)
                        {
                            hexTile.flipped = startPos.DistanceTo(hexPos) <= player.viewDistance;
                        }

                        tiles.Add(hexPos, hexTile);
                    }
                }
            }
        }

        map.SetTiles(tiles);
        map.SetPlayerStart(startPos);
    }