Exemple #1
0
        // Busca los 4 vecinos de una casilla, en horizontal y vertical
        public List <Casilla> Get4Neighbours(Casilla cell)
        {
            List <Casilla> neighbours = new List <Casilla>();

            for (int r = -1; r <= 1; r++)
            {
                for (int c = -1; c <= 1; c++)
                {
                    if (r == 0 && c == 0)
                    {
                        continue;
                    }
                    if (r == 0 || c == 0)  //Para no coger las diagonales
                    {
                        int checkCol = Mathf.RoundToInt(cell.pos.GetColumn() + r);
                        int checkRow = Mathf.RoundToInt(cell.pos.GetRow() + c);

                        if (checkCol >= 0 && checkCol < casillas_.GetLength(0) && checkRow >= 0 && checkRow < casillas_.GetLength(1))
                        {
                            neighbours.Add(casillas_[checkRow, checkCol]);
                        }
                    }
                }
            }
            return(neighbours);
        }
Exemple #2
0
        // Te enseña el camino hasta el candy
        public void showPath()
        {
            for (int i = 0; i < path_.Count - 1; i++)
            {
                Vector3 holi = path_[i].transform.position - path_[i + 1].transform.position;

                Casilla cel = Instantiate(flechaPrefab, new Vector3(path_[i].transform.position.x, (float)0.3, path_[i].transform.position.z),
                                          Quaternion.identity.normalized);

                if (holi.x == 0 && holi.z > 0)
                {
                    cel.transform.Rotate(new Vector3(0, 0, 0), Space.Self);
                }
                else if (holi.x < 0 && holi.z == 0)
                {
                    cel.transform.Rotate(new Vector3(0, -90, 0), Space.Self);
                }
                else if (holi.x == 0 && holi.z < 0)
                {
                    cel.transform.Rotate(new Vector3(0, 180, 0), Space.Self);
                }
                else if (holi.x > 0 && holi.z == 0)
                {
                    cel.transform.Rotate(new Vector3(0, 90, 0), Space.Self);
                }
                cel.Init(this, 7);
                flechas_.Add(cel);
            }
        }
Exemple #3
0
        //Calculo original del coste de movimiento
        private int GetDistance(Casilla a, Casilla b)
        {
            int dstX = Mathf.RoundToInt(Mathf.Abs(a.pos.GetRow() - b.pos.GetRow()));
            int dstY = Mathf.RoundToInt(Mathf.Abs(a.pos.GetColumn() - b.pos.GetColumn()));

            if (dstX > dstY)
            {
                return(14 * dstY + 10 * (dstX - dstY));
            }
            else
            {
                return(14 * dstX + 10 * (dstY - dstX));
            }
        }
Exemple #4
0
        // Te devuelve el camino que deves seguir dando la vuelta a la lista de casillas que se ha ido guardando
        private void RetracePath(Casilla startCasilla, Casilla endCasilla)
        {
            List <Casilla> path           = new List <Casilla>();
            Casilla        currentCasilla = endCasilla;

            while (currentCasilla != startCasilla)
            {
                cost += currentCasilla.penalty;
                path.Add(currentCasilla);
                currentCasilla = currentCasilla.parent;
            }
            path.Reverse();
            tablero_.setPath(path);
        }
Exemple #5
0
        private int PenaltyDistance(Casilla a, Casilla b)
        {
            int dstX    = Mathf.RoundToInt(Mathf.Abs(a.pos.GetRow() - b.pos.GetRow()));
            int dstY    = Mathf.RoundToInt(Mathf.Abs(a.pos.GetColumn() - b.pos.GetColumn()));
            int penalty = b.penalty;

            if (dstX > dstY)
            {
                return(10 * dstY + 10 * (dstX - dstY) + 10 * penalty);
            }
            else
            {
                return(10 * dstX + 10 * (dstY - dstX) + 10 * penalty);
            }
        }
Exemple #6
0
 // Realiza la busqueda
 private void search()
 {
     if (Input.GetButtonDown("Jump"))
     {
         this.setWorking(true);
         mode_  = tablero_.getTank().getMode();
         seeker = tablero_.getTank();
         target = tablero_.getCandy();
         if (seeker != null && target != null && working)
         {
             selectMode();
             tablero_.getTank().setSteps(0);
         }
     }
 }
Exemple #7
0
        private void Move()
        {
            towardsTarget = targetPosition - transform.position;

            if (towardsTarget.magnitude < 0.25f)   //Si llega al destino obtener la siguiente posicion
            {
                steps_++;
                Casilla nextObj = board_.MoveTank(steps_);
                if (nextObj != null)
                {
                    RecalculateTargetPosition(nextObj);
                }
            }

            transform.position += towardsTarget.normalized * movementSpeed * Time.deltaTime;
            pos = tPos;
        }
Exemple #8
0
        //Elimina el candy actual y lo sustituye por una casilla pisable cualquiera
        private void deleteLastCandy()
        {
            Casilla cel = null;

            switch (UnityEngine.Random.Range(0, 3))
            {
            case 0:     //Creamos un suelo
                cel = Instantiate(sueloPrefab,
                                  new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + candy_.pos.GetColumn() * POSITION_FACTOR_C,
                                              0,
                                              (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - candy_.pos.GetRow() * POSITION_FACTOR_R),
                                  Quaternion.identity);
                cel.pos = candy_.pos;
                cel.Init(this, 0);
                break;

            case 1:     //Creamos un agua
                cel = Instantiate(aguaPrefab,
                                  new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + candy_.pos.GetColumn() * POSITION_FACTOR_C,
                                              0,
                                              (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - candy_.pos.GetRow() * POSITION_FACTOR_R),
                                  Quaternion.identity);
                cel.pos = candy_.pos;
                cel.Init(this, 1);
                break;

            case 2:     //Creamos un barro
                cel = Instantiate(barroPrefab,
                                  new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + candy_.pos.GetColumn() * POSITION_FACTOR_C,
                                              0,
                                              (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - candy_.pos.GetRow() * POSITION_FACTOR_R),
                                  Quaternion.identity);
                cel.pos = candy_.pos;
                cel.Init(this, 2);
                break;

            default:
                break;
            }
            if (cel != null)
            {
                Destroy(casillas_[candy_.pos.GetRow(), candy_.pos.GetColumn()].gameObject);
                casillas_[cel.pos.GetRow(), cel.pos.GetColumn()] = cel;
            }
        }
Exemple #9
0
        //--------------------------------Privates--------------------

        //Crea un candy en la posicion de la casilla que le pasas
        private void createCandy(Casilla c)
        {
            if (candy_ != null)
            {
                deleteLastCandy();
            }

            Casilla cel = Instantiate(banderaPrefab,
                                      new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c.pos.GetColumn() * POSITION_FACTOR_C,
                                                  0,
                                                  (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - c.pos.GetRow() * POSITION_FACTOR_R),
                                      Quaternion.identity.normalized);

            cel.transform.Rotate(0, 180, 0, Space.Self);
            cel.pos = c.pos;
            cel.Init(this, 4);
            cel.candy_ = true;
            setCandy(cel);

            Destroy(casillas_[c.pos.GetRow(), c.pos.GetColumn()].gameObject); //Borramos la casilla a cambiar
            casillas_[cel.pos.GetRow(), cel.pos.GetColumn()] = cel;           //Asignamos la nueva casilla
        }
Exemple #10
0
        //Seleccionar una casilla con Candy (Solo se usa en el init de game manager para colocar la primera casilla)
        public void GiveCandy(uint r, uint c)
        {
            Casilla cell = casillas_[r, c];

            if (cell != null)
            {
                cell = null;
                Destroy(casillas_[r, c].gameObject);
            }
            cell = Instantiate(candyPrefab,
                               new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                           0,
                                           (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                               Quaternion.identity);
            cell.candy_ = true;

            Position pos = new Position(r, c);

            cell.pos = pos;

            cell.Init(this, 4);
            setCandy(cell);
            casillas_[r, c] = cell;
        }
Exemple #11
0
 //Calculo del coste de movimiento por ManhattanDistance
 private int ManhattanDistance(Casilla a, Casilla b)
 {
     return(10 * Mathf.RoundToInt(Mathf.Abs(a.pos.GetRow() - b.pos.GetRow()) + Mathf.Abs(a.pos.GetColumn() - b.pos.GetColumn())));
 }
Exemple #12
0
        // Implementa el mismo A* que el metodo de arriba, solo que en vez de usar Heap usa Listas, lo que incrementa el coste de ejecucion
        private void SlowerFindingPath(Position iPos, Position fPos)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            Casilla startCasilla  = tablero_.GetBlock(iPos);
            Casilla targetCasilla = tablero_.GetBlock(fPos);

            List <Casilla>    openSet   = new List <Casilla>();
            HashSet <Casilla> closedSet = new HashSet <Casilla>();

            openSet.Add(startCasilla);

            while (openSet.Count > 0)
            {
                Casilla currentCasilla = openSet[0];
                for (int i = 1; i < openSet.Count; i++)
                {
                    // Coomparamos los fCost de las casillas
                    if (openSet[i].fCost < currentCasilla.fCost || openSet[i].fCost == currentCasilla.fCost && openSet[i].hCost < currentCasilla.hCost)
                    {
                        currentCasilla = openSet[i];
                    }
                }

                openSet.Remove(currentCasilla);
                closedSet.Add(currentCasilla);

                //En caso de que lleguemos al caramelo
                if (currentCasilla == targetCasilla)
                {
                    sw.Stop();
                    UnityEngine.Debug.Log(ToString() + "Path found: " + sw.ElapsedMilliseconds + " ms");

                    TiempoText_.text = "Tiempo: " + sw.ElapsedMilliseconds + "ms";
                    RetracePath(startCasilla, targetCasilla);
                    return;
                }

                foreach (Casilla neighbour in tablero_.Get4Neighbours(currentCasilla))
                {
                    //Si es muro o default pasamos la iteracion
                    if (neighbour.type_ == 3 || neighbour.type_ == 6 || closedSet.Contains(neighbour) || neighbour == null)
                    {
                        continue;
                    }

                    // A partir de aqui se calcula el coste de movimiento (hCost, gCost y penalty)
                    int newMovementCostToNeighbour = currentCasilla.gCost + GetDistance(currentCasilla, neighbour) + neighbour.penalty;

                    if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                    {
                        neighbour.gCost  = newMovementCostToNeighbour;
                        neighbour.hCost  = GetDistance(neighbour, targetCasilla);
                        neighbour.parent = currentCasilla;

                        if (!openSet.Contains(neighbour))
                        { // Si ya lo tiene esque ha cambiado el valor de esa casilla
                            openSet.Add(neighbour);
                        }
                    }
                }
            }
        }
Exemple #13
0
 public void setCandy(Casilla c)
 {
     candy_ = c;
 }
Exemple #14
0
        // Generador de casillas
        private void GenerateCasillas(Map m)
        {
            if (m == null)
            {
                throw new ArgumentNullException(nameof(m));
            }

            var rows = casillas_.GetLength(0);
            var cols = casillas_.GetLength(1);

            for (var r = 0u; r < rows; r++)
            {
                for (var c = 0u; c < cols; c++)
                {
                    //Creamos la casilla en una row y col del vector de casillas
                    Casilla cel = casillas_[r, c];

                    // Le damos esa row y col como posicion
                    Position pos = new Position(r, c);

                    uint value = m.GetValue(pos);

                    if (cel == null)
                    {
                        switch (value)
                        {
                        //Suelo
                        case 0:
                            cel = Instantiate(sueloPrefab,
                                              new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                                          0,
                                                          (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                              Quaternion.identity);
                            break;

                        //Agua
                        case 1:
                            cel = Instantiate(aguaPrefab,
                                              new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                                          0,
                                                          (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                              Quaternion.identity);
                            break;

                        //Barro
                        case 2:
                            cel = Instantiate(barroPrefab,
                                              new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                                          0,
                                                          (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                              Quaternion.identity);
                            break;

                        //Muro
                        case 3:
                            cel = Instantiate(muroPrefab,
                                              new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                                          0,
                                                          (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                              Quaternion.identity);
                            break;

                        //Default
                        default:
                            cel = Instantiate(sueloPrefab,
                                              new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c * POSITION_FACTOR_C,
                                                          0,
                                                          (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - r * POSITION_FACTOR_R),
                                              Quaternion.identity);
                            break;
                        }

                        cel.pos = pos;

                        cel.Init(this, value);

                        casillas_[r, c] = cel;
                    }
                }
            }
        }
Exemple #15
0
        //-------------------------------------------------Interacciones con el tablero---------------------------------

        // Cambia un tipo de casilla por otra
        public void changeCasilla(Casilla c)
        {
            Casilla cel;

            if (!tank_.selected)
            {
                if (tank_.pos != c.pos)   // Si la posicion de la casilla y el tanque no es la misma
                {
                    switch (c.type_)
                    {
                    case 0:     // El suelo pasa a ser agua
                        cel = Instantiate(aguaPrefab,
                                          new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c.pos.GetColumn() * POSITION_FACTOR_C,
                                                      0,
                                                      (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - c.pos.GetRow() * POSITION_FACTOR_R),
                                          Quaternion.identity);

                        cel.pos = c.pos;
                        cel.Init(this, 1);
                        Destroy(casillas_[c.pos.GetRow(), c.pos.GetColumn()].gameObject); //Borramos la casilla a cambiar
                        casillas_[cel.pos.GetRow(), cel.pos.GetColumn()] = cel;           //Asignamos la nueva casilla
                        break;

                    case 1:     // El agua pasa a ser barro
                        cel = Instantiate(barroPrefab,
                                          new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c.pos.GetColumn() * POSITION_FACTOR_C,
                                                      0,
                                                      (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - c.pos.GetRow() * POSITION_FACTOR_R),
                                          Quaternion.identity);
                        cel.pos = c.pos;
                        cel.Init(this, 2);
                        Destroy(casillas_[c.pos.GetRow(), c.pos.GetColumn()].gameObject); //Borramos la casilla a cambiar
                        casillas_[cel.pos.GetRow(), cel.pos.GetColumn()] = cel;           //Asignamos la nueva casilla
                        break;

                    case 2:     // El barro pasa a ser muro
                        cel = Instantiate(muroPrefab,
                                          new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c.pos.GetColumn() * POSITION_FACTOR_C,
                                                      0,
                                                      (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - c.pos.GetRow() * POSITION_FACTOR_R),
                                          Quaternion.identity);
                        cel.pos = c.pos;
                        cel.Init(this, 3);
                        Destroy(casillas_[c.pos.GetRow(), c.pos.GetColumn()].gameObject); //Borramos la casilla a cambiar
                        casillas_[cel.pos.GetRow(), cel.pos.GetColumn()] = cel;           //Asignamos la nueva casilla
                        break;

                    case 3:     // El muro pasa a ser suelo
                        cel = Instantiate(sueloPrefab,
                                          new Vector3(-((casillas_.GetLength(1) / 2.0f) * POSITION_FACTOR_C - (POSITION_FACTOR_C / 2.0f)) + c.pos.GetColumn() * POSITION_FACTOR_C,
                                                      0,
                                                      (casillas_.GetLength(0) / 2.0f) * POSITION_FACTOR_R - (POSITION_FACTOR_R / 2.0f) - c.pos.GetRow() * POSITION_FACTOR_R),
                                          Quaternion.identity);
                        cel.pos = c.pos;
                        cel.Init(this, 0);
                        Destroy(casillas_[c.pos.GetRow(), c.pos.GetColumn()].gameObject); //Borramos la casilla a cambiar
                        casillas_[cel.pos.GetRow(), cel.pos.GetColumn()] = cel;           //Asignamos la nueva casilla
                        break;

                    default:
                        break;
                    }
                }
            }
            else
            {
                resetPath();
                switch (c.type_)
                {
                case 0:     // Nuevo candy!
                    createCandy(c);
                    break;

                case 1:     // Nuevo candy!
                    createCandy(c);
                    break;

                case 2:     // Nuevo candy!
                    createCandy(c);
                    break;

                default:
                    break;
                }
            }
        }
Exemple #16
0
        // Busqueda por el algoritmo de A* busca en las 4-8 posiciones adjuntas a la posicion de busqueda
        // "los 4-8 vecinos" y calcula por cual de ellos es mas rapido llegar a la meta, si es que se puede
        // pasar por ellos claro.
        // Dependiendo del modo activado tiene en cuenta el coste de avanzar por una casilla o no
        private void FindPath(Position initPos, Position targetPos)
        {
            Stopwatch sw = new Stopwatch();

            sw.Start();

            Casilla startCasilla  = tablero_.GetBlock(initPos);
            Casilla targetCasilla = tablero_.GetBlock(targetPos);

            //List<Casilla> openSet = new List<Casilla>();

            Heap <Casilla>    openSet   = new Heap <Casilla>(tablero_.MaxSize);
            HashSet <Casilla> closedSet = new HashSet <Casilla>();

            openSet.Add(startCasilla);

            while (openSet.Count > 0)
            {
                Casilla currentCasilla = openSet.RemoveFirst();

                closedSet.Add(currentCasilla);

                //En caso de que lleguemos al caramelo
                if (currentCasilla == targetCasilla)
                {
                    sw.Stop();
                    UnityEngine.Debug.Log(ToString() + "Path found: " + sw.ElapsedMilliseconds + " ms");

                    TiempoText_.text = "Tiempo: " + sw.ElapsedMilliseconds + "ms";
                    RetracePath(startCasilla, targetCasilla);
                    return;
                }

                //Mirar los vecinos de cada Casilla que exploramos
                //foreach(Casilla neighbour in tablero_.Get8Neighbours(currentCasilla)) {   // Para 8 vecinos
                foreach (Casilla neighbour in tablero_.Get4Neighbours(currentCasilla))   // Para 4 vecinos
                //Si es muro o default pasamos la iteracion
                {
                    if (neighbour.type_ == 3 || neighbour.type_ == 6 || closedSet.Contains(neighbour) || neighbour == null)
                    {
                        continue;
                    }

                    // A partir de aqui se calcula el coste de movimiento (hCost, gCost)
                    int newMovementCostToNeighbour;
                    //--------------------Modo 0-------------------
                    if (!mode2)
                    {
                        newMovementCostToNeighbour = currentCasilla.gCost + PenaltyDistance(currentCasilla, neighbour);

                        if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                        {
                            neighbour.gCost  = newMovementCostToNeighbour;
                            neighbour.hCost  = PenaltyDistance(neighbour, targetCasilla);
                            neighbour.parent = currentCasilla;

                            if (!openSet.Contains(neighbour))
                            { // Si ya lo tiene esque ha cambiado el valor de esa casilla
                                openSet.Add(neighbour);
                            }
                            else // Actualizamos la casilla
                            {
                                openSet.UpdateItem(neighbour);
                            }
                        }
                    }
                    //---------------------Modo 2------------------
                    else
                    {
                        newMovementCostToNeighbour = currentCasilla.gCost + GetDistance(currentCasilla, neighbour) + neighbour.penalty;

                        if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour))
                        {
                            //cost += newMovementCostToNeighbour;
                            neighbour.gCost  = newMovementCostToNeighbour;
                            neighbour.hCost  = GetDistance(neighbour, targetCasilla);
                            neighbour.parent = currentCasilla;

                            if (!openSet.Contains(neighbour))
                            { // Si ya lo tiene esque ha cambiado el valor de esa casilla
                                openSet.Add(neighbour);
                            }
                            else // Actualizamos la casilla
                            {
                                openSet.UpdateItem(neighbour);
                            }
                        }
                    }
                }
            }
        }
Exemple #17
0
 public void RecalculateTargetPosition(Casilla p)
 {
     targetPosition   = p.transform.position;
     targetPosition.y = 1;
     tPos             = p.pos;
 }