Inheritance: MonoBehaviour
    private void GetBestTiles(BoardCreator board, List <Tile> movementTiles)
    {
        moveTarget = null;

        int leastMoveDist = 100;
        int bestValue     = 0;

        AttackPattern pattern = GetComponent <AttackPattern>();

        foreach (Tile t in movementTiles)
        {
            List <List <Tile> > inRange = pattern.GetTilesInRange(board, t.pos);

            foreach (List <Tile> targets in inRange)
            {
                int value = GetTileGroupValue(targets);
                if (value >= bestValue)
                {
                    if (value > bestValue ||
                        (GetMoveDist(t) < leastMoveDist))
                    {
                        attackTarget = targets;
                        bestValue    = value;

                        moveTarget    = t;
                        leastMoveDist = GetMoveDist(t);
                    }
                }
            }
        }
    }
    public virtual IEnumerator TakeTurn(BoardCreator board)
    {
        if (!CanMove())
        {
            ResetMove();
        }
        else
        {
            if (nonNullAttackTarget != null)
            {
                AttackPattern pattern = GetComponent <AttackPattern>();
                yield return(StartCoroutine(pattern.Attack(nonNullAttackTarget)));

                pattern.SetData(GetComponent <UnitStats>().unitInfo.WeaponMain);
                yield return(StartCoroutine(pattern.HitUnits(board, attackTarget, moveTarget)));

                attackTarget        = null;
                nonNullAttackTarget = null;
            }
            else
            {
                SetNextMove(board);

                Movement m = GetComponent <Movement>();
                yield return(StartCoroutine(m.Traverse(moveTarget)));
            }
        }
    }
    // Update is called once per frame
    void Update()
    {
        Debug.Log(backGround.IsCreated());

        if (backGround.IsCreated() && ehe)
        {
            Debug.Log(backGround.IsCreated());

            Texture2D texture = new Texture2D(backGround.width, backGround.height);

            RenderTexture.active = backGround;
            texture.ReadPixels(new Rect(0, 0, backGround.width, backGround.height), 0, 0);
            texture.Apply();

            GetComponent <RawImage>().texture = texture;

            ehe = false;
            this.GetComponent <CopyTexture>().enabled = false;
            this.GetComponent <RawImage>().enabled    = true;

            BoardCreator.turnOffSprites();

            enabled = false;
            gameObject.transform.parent.GetChild(0).gameObject.SetActive(false);
            GameObject.FindGameObjectWithTag("texCam").SetActive(false);
        }
    }
    void Start()
    {
        ResetGeneratedBools();

        BoardCreator             = GetComponentInChildren <BoardCreator>();
        mapFloor                 = BoardCreator.FloorNum;
        GlobalControl.FloorLevel = GlobalControl.Floors.G;
        Hamburger_menu.SetActive(false);
        createPath_menu.SetActive(false);
        Settings_menu.SetActive(false);

        spriteNoSign = Map_nosign.GetComponent <SpriteRenderer>();
        spriteSigned = Map_signed.GetComponent <SpriteRenderer>();

        mapUp.onClick.AddListener(TaskOnClickUp);
        mapDown.onClick.AddListener(TaskOnClickDown);


        hamburger.onClick.AddListener(TaskOnClickHamburger);
        hamburgerClose.onClick.AddListener(TaskOnClickHamburgerClose);


        generatePath.onClick.AddListener(TaskOnClickGenerate);
        settings.onClick.AddListener(TaskOnClickSettingsMenu);



        floorTxt.text = "Ground Floor";
    }
Exemple #5
0
        public void ShouldPlaceAShip_WhenCorrectPositionsProvided(
            int boardRows, int boardColumns,
            int placementRow, int placementColumn,
            ShipType shipType)
        {
            //arrange

            //first create a board
            var boardCreator = new BoardCreator();
            var board        = boardCreator.CreateBoard(boardRows, boardColumns);

            //then create a ship
            var shipCreator = new ShipCreator();
            var ship        = shipCreator.CreateShip(shipType);

            //act
            //now place the ship on the board
            var shipPlacer = new ShipPlacer();

            shipPlacer.AddShipToBoard(ship, board, placementRow, placementColumn);

            //assert

            /*check that the ship has been placed on the board and that the board's
             * status is occupied for the ship*/
            Assert.True(
                board.BoardCellStatuses[placementRow, placementColumn] == BoardCellStatus.Occupied &&
                board.BoardCellStatuses[placementRow, placementColumn + ship.Size - 1] == BoardCellStatus.Occupied
                );
        }
Exemple #6
0
        public void ShouldFailToPlaceAShip_WhenIncorrectCorrectPositionsProvided(
            int boardRows, int boardColumns,
            int placementRow, int placementColumn,
            ShipType shipType)
        {
            //arrange

            //first create a board
            var boardCreator = new BoardCreator();
            var board        = boardCreator.CreateBoard(boardRows, boardColumns);

            //then create a ship
            var shipCreator = new ShipCreator();
            var ship        = shipCreator.CreateShip(shipType);

            //act
            //now place the ship on the board
            var shipPlacer = new ShipPlacer();

            IndexOutOfRangeException ex = Assert.Throws <IndexOutOfRangeException>(() =>
                                                                                   shipPlacer.AddShipToBoard(ship, board, placementRow, placementColumn));

            //assert
            Assert.Equal("Ship's placement position is out of bounds", ex.Message);
        }
Exemple #7
0
    public void SpawnEnemies(BoardCreator _board_creator)
    {
        rooms           = new Room[_board_creator.GetRooms().Length];
        Position_Spawns = new Vector2[_board_creator.GetRooms().Length];
        rooms           = _board_creator.GetRooms();
        int number_room = 0;

        while (counter_enemy < GameObject.Find("Scoring").GetComponent <ScoringManger>().GetSlimes())
        {
            number_room = 0;
            foreach (Room room in rooms)
            {
                if (counter_enemy < GameObject.Find("Scoring").GetComponent <ScoringManger>().GetSlimes())
                {
                    Position_Spawns[number_room] = new Vector2(room.xPos + (float)room.roomWidth / 2, room.yPos + (float)room.roomHeight / 2);

                    Vector2   size_spawn = new Vector2(((int)(room.roomWidth / 2.0f) - 0.5f), ((room.roomHeight / 2)));
                    Vector3[] pos_patrol = new Vector3[4];
                    pos_patrol[0] = new Vector3(Position_Spawns[number_room].x - (size_spawn.x), Position_Spawns[number_room].y + (size_spawn.y / 2), 0);
                    pos_patrol[1] = new Vector3(Position_Spawns[number_room].x - (size_spawn.x), Position_Spawns[number_room].y - (size_spawn.y), 0);
                    pos_patrol[2] = new Vector3(Position_Spawns[number_room].x + (size_spawn.x) - 1, Position_Spawns[number_room].y - (size_spawn.y), 0);
                    pos_patrol[3] = new Vector3(Position_Spawns[number_room].x + (size_spawn.x) - 1, Position_Spawns[number_room].y + (size_spawn.y / 2), 0);
                    GameObject tmp = Instantiate(_enemy_prefab[Random.Range(0, _enemy_prefab.Length - 1)], new Vector2(room.xPos + (float)Random.Range(0, room.roomWidth - 1), room.yPos + (float)Random.Range(0, room.roomHeight - 1)) - new Vector2(0.5f, 0.5f), Quaternion.identity);
                    tmp.GetComponent <Slime>().SetPositionsPatroller(pos_patrol);
                    counter_enemy++;
                }
                number_room++;
            }
            number_room--;
        }
    }
Exemple #8
0
    /// <summary>
    ///  Setup the first Room of the Dungeon
    /// </summary>
    /// <param name="widthRange">The range between which the width of the room is determined</param>
    /// <param name="heightRange">The range between which the height of the room is determined</param>
    /// <param name="columns">The amount of Columns in this Dungeon board</param>
    /// <param name="rows">The amount of Rows in this Dungeon board</param>
    public void SetupRoom(IntRange widthRange, IntRange heightRange, int columns, int rows)
    {
        BoardCreator board = BoardCreator.instance;

        // Set a random width and height.
        int width  = widthRange.Random;
        int height = heightRange.Random;

        roomWidth  = 9;
        roomHeight = 9;

        // Set the x and y coordinates so the room is roughly in the middle of the board.
        xPos = 10;
        yPos = Mathf.RoundToInt((rows / 2f) - (roomHeight / 2f));

        Vector3 playerPos = new Vector3(xPos + (roomWidth / 2), yPos + (roomHeight / 2), 0);

        /// Place the Player inside the first room
        board.player.transform.position = playerPos;

        Vector3[] corners = new[] { new Vector3(xPos, yPos, 0f), new Vector3(xPos + roomWidth - 1, yPos, 0f), new Vector3(xPos, yPos + roomHeight - 1, 0f), new Vector3(xPos + roomWidth - 1, yPos + roomHeight - 1, 0f) };

        middleTile = new TileLocation((roomWidth / 2) + xPos, (roomHeight / 2) + yPos);

        foreach (var corner in corners)
        {
            board.SpawnElement(corner, board.entranceTorch);
        }

        middleTile = new TileLocation((roomWidth / 2) + xPos, (roomHeight / 2) + yPos);
    }
    public IEnumerator ApplyKnockback(BoardCreator board, Point dir)
    {
        Point newPoint = GetComponent <Unit>().tile.pos - dir;
        Tile  newTile  = board.GetTile(newPoint);

        yield return(StartCoroutine(Knockback(newTile)));

        if (newTile == null)
        {
        }
        else if (WillCollideWithObject(newTile))
        {
            TakeDamage(1);
            newTile.content.GetComponent <UnitStats>().TakeDamage(1);
        }
        else
        {
            Unit unit = GetComponent <Unit>();
            unit.Place(newTile);
            unit.Match();

            if (unit.type == UnitType.ENEMY)
            {
                GetComponent <EnemyUnit>().MoveAttackTarget(board, dir);
            }
        }
    }
Exemple #10
0
    void Start()
    {
        //p1skills = GameObject.Find("P1Skills");
        //p2skills = GameObject.Find("P2Skills");
        //p1tickets = GameObject.Find("TicketsP1");
        //p2tickets = GameObject.Find("TicketsP2");
        //BGp1 = GameObject.Find("img Background p1");
        //BGp2 = GameObject.Find("img Background p2");

        for (int i = 0; i < 8; i++)
        {
            skillTextsp1[i].text = 0.ToString();
            skillTextsp2[i].text = 0.ToString();
            player1Values[i]     = 0;
            player2Values[i]     = 0;
        }

        for (int i = 0; i < 4; i++)
        {
            ticketTextsp1[i].text = 0.ToString();
            ticketTextsp2[i].text = 0.ToString();
        }

        mainCameraController = mainCamera.GetComponent <CameraController>();

        collectablesQnty = (tileSizeX * tileSizeY) - 2;
        collectablesMax  = collectablesQnty;
        boardCreator     = gameObject.GetComponent <BoardCreator>();
        tileMap          = new int[tileSizeX, tileSizeY];
        PlayerAllocation();
        tileMap = boardCreator.CreateBoard(tileMap, player1.transform, player2.transform);
        Debug.Log(PrintMap(tileMap));
        CheckPlayerTurn();
    }
Exemple #11
0
        public void ShouldNotReturnLostGameStatusTrue_WhenShipsNotSunk()
        {
            //arrange

            //first create a board
            var boardCreator = new BoardCreator();
            var board        = boardCreator.CreateBoard(10, 10);

            //then create a ship
            var shipCreator = new ShipCreator();
            var ship        = shipCreator.CreateShip(ShipType.Destroyer);

            //place the ship on the board
            var shipPlacer = new ShipPlacer();

            shipPlacer.AddShipToBoard(ship, board, 0, 0);

            //act
            //now attack the ship at all given positions for the ship
            var attacker = new Attacker();

            attacker.Attack(board, 0, 1);

            //assert that the status is not lost
            Assert.False(board.HasLost);
        }
    public static PlayerUnit GetAdjacentPlayer(BoardCreator board, Point pos)
    {
        Tile t = board.GetTile(pos + Point.North);

        if (t != null && t.content != null && t.content.GetComponent <Unit>().type == UnitType.PLAYER)
        {
            return(t.content.GetComponent <PlayerUnit>());
        }
        t = board.GetTile(pos + Point.South);
        if (t != null && t.content != null && t.content.GetComponent <Unit>().type == UnitType.PLAYER)
        {
            return(t.content.GetComponent <PlayerUnit>());
        }
        t = board.GetTile(pos + Point.West);
        if (t != null && t.content != null && t.content.GetComponent <Unit>().type == UnitType.PLAYER)
        {
            return(t.content.GetComponent <PlayerUnit>());
        }
        t = board.GetTile(pos + Point.East);
        if (t != null && t.content != null && t.content.GetComponent <Unit>().type == UnitType.PLAYER)
        {
            return(t.content.GetComponent <PlayerUnit>());
        }

        return(null);
    }
Exemple #13
0
 void Start()
 {
     setter    = GetComponent <AIDestinationSetter>();
     rb2d      = GetComponent <Rigidbody2D>();
     colliders = GetComponents <Collider2D>();
     creator   = GameObject.Find("GameManager").GetComponent <BoardCreator>();
 }
Exemple #14
0
        public void ShouldReturnException_WhenIncorrectAttackCoordinatesProvided(
            int boardRows, int boardColumns,
            int placementRow, int placementColumn,
            int attackRow, int attackColumn,
            ShipType shipType)
        {
            //arrange

            //first create a board
            var boardCreator = new BoardCreator();
            var board        = boardCreator.CreateBoard(boardRows, boardColumns);

            //then create a ship
            var shipCreator = new ShipCreator();
            var ship        = shipCreator.CreateShip(shipType);

            //place the ship on the board
            var shipPlacer = new ShipPlacer();

            shipPlacer.AddShipToBoard(ship, board, placementRow, placementColumn);

            //act
            //now attack the ship at the given position
            var attacker = new Attacker();
            IndexOutOfRangeException ex = Assert.Throws <IndexOutOfRangeException>(() =>
                                                                                   attacker.Attack(board, attackRow, attackColumn));

            //assert
            Assert.Equal("Attack position is out of bounds", ex.Message);
        }
    public void MoveAttackTarget(BoardCreator board, Point dir)
    {
        if (attackTarget == null)
        {
            return;
        }

        board.DeselectForecast(attackTarget);
        board.DeselectForecastWithoutColor(attackTarget);

        List <Tile> newAttack = new List <Tile>();

        for (int i = 0; i < attackTarget.Count; i++)
        {
            Tile curr = attackTarget[i];
            curr = board.GetTile(curr.pos - dir);

            if (curr != null)
            {
                board.Forecast(curr);
                newAttack.Add(curr);
            }
        }

        attackTarget = newAttack;
    }
Exemple #16
0
        public void ShouldReturnCorrectAttackStatus_WhenAttackLaunched(
            int boardRows, int boardColumns,
            int placementRow, int placementColumn,
            int attackRow, int attackColumn,
            ShipType shipType, BoardCellStatus boardCellStatus)
        {
            //arrange

            //first create a board
            var boardCreator = new BoardCreator();
            var board        = boardCreator.CreateBoard(boardRows, boardColumns);

            //then create a ship
            var shipCreator = new ShipCreator();
            var ship        = shipCreator.CreateShip(shipType);

            //place the ship on the board
            var shipPlacer = new ShipPlacer();

            shipPlacer.AddShipToBoard(ship, board, placementRow, placementColumn);

            //act
            //now attack the ship at the given position
            var attacker = new Attacker();

            attacker.Attack(board, attackRow, attackColumn);

            //assert
            /*check that the status on the board is hit*/
            Assert.True(
                board.BoardCellStatuses[attackRow, attackColumn] == boardCellStatus
                );
        }
    private List <Tile> GetAllTilesInRange(BoardCreator board, Point pos)
    {
        List <Tile> tiles = board.Search(board.GetTile(pos), ExpandSearch);

        tiles.Add(board.GetTile(pos));
        return(tiles);
    }
Exemple #18
0
        public void CreateBoard_CreatesBoard_DimensionsAreCorrect()
        {
            var actual = BoardCreator.CreateNewBoard(8, 8, 8);

            Assert.Equal(8, actual.GetLength(0));
            Assert.Equal(8, actual.GetLength(1));
        }
Exemple #19
0
    protected List <UnitStats> GetHitUnits(BoardCreator board, Tile tile, Tile source)
    {
        List <List <Tile> > tiles         = GetTilesInRange(board);
        List <Tile>         selectedGroup = GetGroup(tiles, tile);

        List <UnitStats> hit = new List <UnitStats>();

        if (data.isElectric && data.type == WeaponType.RANGED)
        {
            Tile hitTile = selectedGroup[selectedGroup.Count - 1];
            ExpandHitUnits(board, hit, hitTile.pos);

            return(hit);
        }

        foreach (Tile t in selectedGroup)
        {
            if (t != null && t.content != null && !t.content.GetComponent <UnitStats>().IsDead())
            {
                hit.Add(t.content.GetComponent <UnitStats>());
            }
        }

        return(hit);
    }
Exemple #20
0
    // Use this for initialization
    void Start()
    {
        if (playerSelection == PlayerSelection.PLAYER_GIRL)
        {
            PlayerGirl = true;
        }

        rigid       = GetComponent <Rigidbody2D>();
        board       = FindObjectOfType <BoardCreator>();
        gameManager = FindObjectOfType <GameManager>();
        Grid        = board.Grid;
        if (PlayerGirl)
        {
            currentNode = Grid[gameManager.spawnNodeA.x, gameManager.spawnNodeA.y];
        }

        else
        {
            currentNode = Grid[gameManager.spawnNodeB.x, gameManager.spawnNodeB.y];
        }

        targetNode         = currentNode;
        transform.position = currentNode.Position;
        if (PlayerGirl)
        {
            Trackers = new List <Transform>();

            Trackers.Add(GameObject.FindWithTag("Tracker").transform);
        }
    }
Exemple #21
0
    protected IEnumerator Hit(BoardCreator board, UnitStats target, Tile source)
    {
        if (data.Damage > 0)
        {
            target.TakeDamage(unit.GetComponent <UnitStats>().GetAttack(board, data));
        }
        if (data.Heal > 0)
        {
            target.Heal(data.Heal);
        }

        if (!target.IsDead())
        {
            if (data.hasKnockback && target.GetComponent <Unit>().KnockbackAble())
            {
                Point direction = source.pos - target.GetComponent <Unit>().tile.pos;
                yield return(StartCoroutine(target.ApplyKnockback(board, direction)));
            }

            if (data.status != StatusEffects.NONE)
            {
                target.AddStatus(data.status);
            }
        }
    }
Exemple #22
0
    private List <Tile> GetTilesInDirection(BoardCreator board, Point start, Point dir)
    {
        List <Tile> tiles = new List <Tile>();

        Tile mid = board.GetTile(start);

        if (mid != null)
        {
            tiles.Add(mid);
        }
        Tile pos = board.GetTile(start + dir);

        if (pos != null)
        {
            tiles.Add(pos);
        }
        Tile neg = board.GetTile(start - dir);

        if (neg != null)
        {
            tiles.Add(neg);
        }

        return(tiles);
    }
Exemple #23
0
 private void Start()
 {
     playerLife        = FindObjectOfType <PlayerLife>();
     playerController  = FindObjectOfType <PlayerController>();
     transitionManager = FindObjectOfType <TransitionManager>();
     boardCreator      = FindObjectOfType <BoardCreator>();
 }
    public override List <List <Tile> > GetTilesInRange(BoardCreator board, Point pos)
    {
        int range = data.range;
        List <List <Tile> > tiles = new List <List <Tile> >();

        List <List <List <Tile> > > temp = new List <List <List <Tile> > >();

        temp.Add(GetTilesInDirection(board, pos + new Point(0, range), Point.North));
        temp.Add(GetTilesInDirection(board, pos + new Point(0, -range), Point.South));
        temp.Add(GetTilesInDirection(board, pos + new Point(range, 0), Point.East));
        temp.Add(GetTilesInDirection(board, pos + new Point(-range, 0), Point.West));

        foreach (List <List <Tile> > l in temp)
        {
            foreach (List <Tile> t in l)
            {
                if (t.Count > 0)
                {
                    tiles.Add(t);
                }
            }
        }

        return(tiles);
    }
    private List <Tile> GetTilesInDirection(BoardCreator board, Point start, Point dir)
    {
        List <Tile> tiles = new List <Tile>();

        Point next     = start + dir;
        Tile  nextTile = board.GetTile(next);

        while (nextTile != null)
        {
            Unit u = nextTile.content.GetComponent <Unit>();
            if (u.type != UnitType.TERRAIN)
            {
                break;
            }
            TerrainUnitInfo info = u.GetComponent <UnitStats>().terrainUnitInfo;
            if (info.BlocksProjectiles() &&
                !(u.GetComponent <UnitStats>().IsDead() && !info.BlocksProjectileWhenDead()))
            {
                break;
            }

            tiles.Add(nextTile);

            next    += dir;
            nextTile = board.GetTile(next);
        }
        if (nextTile != null)
        {
            tiles.Add(nextTile);
        }

        return(tiles);
    }
    public virtual List <Tile> GetTilesInRange(BoardCreator board)
    {
        List <Tile> retValue = board.Search(unit.tile, ExpandSearch);

        Filter(retValue);
        retValue.Add(unit.tile);
        return(retValue);
    }
        public void BackwardDiagonalFourTest()
        {
            IBoard board = BoardCreator.GetBlankBoard();

            Point lastMove = BoardCreator.AddBackwardDiagonalLineToBoard(ConnectFourLineLength, board);

            Assert.IsTrue(board.HasConnectFour(lastMove));
        }
Exemple #28
0
        public void BoardCloneTest()
        {
            IBoard board       = BoardCreator.GetBoardWithVerticalLine(4);
            IBoard clonedBoard = board.Clone();

            clonedBoard.AddPiece(new GameMove(BoardCreator.PlayerTwoGamePiece, 0));
            Assert.AreNotEqual(board.GetBoard(), clonedBoard.GetBoard());
        }
Exemple #29
0
 private void DrawButtonTableCreator()
 {
     if (GUILayout.Button("Table Creator"))
     {
         BoardCreator.OpenWindow(newWindowAmount);
         newWindowAmount++;
     }
 }
Exemple #30
0
    public override IEnumerator HitUnits(BoardCreator board, Tile tile, Tile source)
    {
        data.status = GameInformation.instance.GetPlayerInfo(UnitID.PHYNNE).WeaponMain.status;

        yield return(base.HitUnits(board, tile, source));

        relationship.IncreaseSupport();
    }
    public void SpawnBoard()
    {
        if (!isServer)
            return;
        _boardCreator = new BoardCreator();
        _boardCreator.InitializeDestructible();

        //Initialize spawn for all connected players
        LobbyManager.instance.lobbySlots.Where(p => p != null).ToList()
            .ForEach(p => _boardCreator.InitializeSpawn(_playerSpawnVectors[p.slot]));

        //Initialize all upgrades
        _boardCreator.InitializeUpgrades();

        //Get the generated tiles in the board
        var board = _boardCreator.GetBoard();

        //Spawn all objects in the board
        foreach (var tile in board.tiles)
        {
            if (tile.isIndestructible)
            {
                NetworkServer.Spawn(Instantiate(indestructible, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);
                continue;
            }

            NetworkServer.Spawn(Instantiate(floor, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);

            if (tile.isDestructible)
                NetworkServer.Spawn(Instantiate(destructible, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);

            if (tile.isUpgrade)
                switch (tile.upgradeType)
                {
                    case (UpgradeType.Bomb):
                        NetworkServer.Spawn(Instantiate(bombUpgrade, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);
                        break;
                    case (UpgradeType.Kick):
                        NetworkServer.Spawn(Instantiate(kickUpgrade, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);
                        break;
                    case (UpgradeType.Laser):
                        NetworkServer.Spawn(Instantiate(laserUpgrade, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);
                        break;
                    case (UpgradeType.Line):
                        NetworkServer.Spawn(Instantiate(lineUpgrade, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);
                        break;
                    case (UpgradeType.Radioactive):
                        NetworkServer.Spawn(Instantiate(radioactiveUpgrade, new Vector3(tile.x, tile.y, 0.0f), Quaternion.identity) as GameObject);
                        break;
                    default:
                        // Do nothing
                        break;
                }
        }
    }