Esempio n. 1
0
        public void ShouldStartTrafficLightCycle()
        {
            var configuration = new TrafficLightConfig();

            configuration.Add(TrafficLightState.Go, 4);
            configuration.Add(TrafficLightState.Stop, 4);
            SetTrafficLightConfiguration(configuration);

            var lights = new TrafficLights {
                _l1, _l2, _l3, _l4
            };
            var timer = new TrafficLightTimer();

            var tc1 = new TetheredTrafficLightCluster {
                _l1, _l2
            };

            tc1.Name = "TC-1";

            var pc1 = new PolarTrafficLightCluster(_l3)
            {
                { _l4 }
            };

            pc1.Name = "TC-2";

            Assert.IsTrue(lights.Add(tc1));
            Assert.IsTrue(lights.Add(pc1));

            var controller = new TrafficLightController(lights, timer);

            //Assert initial state is where expected
            Assert.AreEqual(TrafficLightState.StopThenGo, _l1.State);
            Assert.AreEqual(TrafficLightState.StopThenGo, _l2.State);
            Assert.AreEqual(TrafficLightState.StopThenGo, _l3.State);
            Assert.AreEqual(TrafficLightState.StopThenGo, _l4.State);

            controller.Start();  //Will trigger traffic light state changes

            Thread.Sleep(2000);
            Assert.AreEqual(TrafficLightState.Go, _l1.State);
            Assert.AreEqual(TrafficLightState.Go, _l2.State);
            Assert.AreEqual(TrafficLightState.Go, _l3.State);
            Assert.AreEqual(TrafficLightState.Stop, _l4.State);

            Thread.Sleep(5000);
            Assert.AreEqual(TrafficLightState.Stop, _l1.State);
            Assert.AreEqual(TrafficLightState.Stop, _l2.State);
            Assert.AreEqual(TrafficLightState.Stop, _l3.State);
            Assert.AreEqual(TrafficLightState.Go, _l4.State);

            controller.Stop();
        }
Esempio n. 2
0
        public void ShouldSynchronizedAllPolarLights()
        {
            var lights = new TrafficLights {
                _l1, _l2, _l3, _l4
            };
            var timer = new TrafficLightTimer();

            var tc1 = new PolarTrafficLightCluster(_l3)
            {
                { _l1, _l2 }
            };

            tc1.Name = "TC-1";

            var tc2 = new PolarTrafficLightCluster(_l5)
            {
                { _l4 }
            };

            tc2.Name = "TC-2";

            Assert.IsTrue(lights.Add(tc1, tc2));

            var controller = new TrafficLightController(lights, timer);

            //Assert initial state is where expected
            Assert.AreEqual(TrafficLightState.StopThenGo, _l1.State);
            Assert.AreEqual(TrafficLightState.StopThenGo, _l2.State);
            Assert.AreEqual(TrafficLightState.StopThenGo, _l3.State);
            Assert.AreEqual(TrafficLightState.StopThenGo, _l4.State);

            controller.Start();  //Will trigger traffic light state changes
            Thread.Sleep(2500);

            Assert.AreEqual(TrafficLightState.Go, _l3.State);
            Assert.AreEqual(TrafficLightState.Go, _l5.State);
            Assert.AreEqual(TrafficLightState.Stop, _l1.State);
            Assert.AreEqual(TrafficLightState.Stop, _l2.State);
            Assert.AreEqual(TrafficLightState.Stop, _l4.State);

            controller.Stop();
        }
Esempio n. 3
0
 public SidewalkNode_TrafficLight(Grid grid, Vector2 position, TrafficLightTimer trafficLightTimer) : base(grid, position)
 {
     this.trafficLightTimer = trafficLightTimer;
 }
Esempio n. 4
0
        /******************************/

        public void SetTrafficLight(TrafficLightTimer trafficLight)
        {
            this.trafficLight = trafficLight;
        }
Esempio n. 5
0
    public void Instantiate_DrivewayTrafficLight(Transform parent, Vector2 pos, Grid rot, TrafficLightTimer trafficLight)
    {
        GameObject obj = Instantiate(drivewayTrafficLight_Prefab, parent, pos, rot);

        DrivewayTrafficLight comp = obj.AddComponent <DrivewayTrafficLight>();

        comp.SetTrafficLight(trafficLight);
        comp.SetComponent();
        StartCoroutine(comp.SetSpriteRenderer());
    }
Esempio n. 6
0
    public void InitializeMapGraph()
    {
        sidewalkGraph = new GridGraph_Node();
        drivewayGraph = new GridGraph <DrivewayNode>();
        blockTable    = new Dictionary <Grid, Block>();

        //sidewalkGraph 노드를 전부 생성한다.
        //block별로 입구 노드를 만들어준뒤, block과 연결해준다.
        //block을 생성한 후 blockTable에 넣는다.
        for (int x = -MAX_X_GRID; x <= MAX_X_GRID; x++)
        {
            for (int y = -MAX_Y_GRID; y <= MAX_Y_GRID; y++)
            {
                Grid blockGrid = new Grid(x, y);
                blockTable.Add(blockGrid, new Block(blockGrid, Area.Default));

                for (int i = 0; i < 4; i++)
                {
                    float offset_x = (float)(i % 2);
                    float offset_y = (float)((i >> 1) % 2);

                    Grid    grid = new Grid(x, y, offset_x, offset_y);
                    Vector2 pos  = GetSidewalkNodePos(x, y, offset_x, offset_y);
                    sidewalkGraph.AddVertex(new SidewalkNode(grid, pos), grid);
                }


                //set enterenceGrid
                float randomOffsetX = Random.Range(0f, 1f);
                float randomOffsetY = Random.Range(0f, 1f);

                bool horizontalOffset = Random.Range(0, 2) == 0 ? true : false; //horizontal or vertical
                if (horizontalOffset)
                {
                    randomOffsetY = Mathf.Round(randomOffsetY);
                }
                else
                {
                    randomOffsetX = Mathf.Round(randomOffsetX);
                }

                Grid enterenceGrid = new Grid(x, y, randomOffsetX, randomOffsetY);
                sidewalkGraph.AddVertex(new SidewalkNode(enterenceGrid, GetSidewalkNodePos(enterenceGrid)), enterenceGrid);
            }
        }

        //blockGraph의 ConnectedBlock을 설정한다.
        for (int i = 0; i < CONNECTED_BLOCK_NUM; i++)
        {
            int x = Random.Range(-MAX_X_GRID, MAX_Y_GRID + 1);
            int y = Random.Range(-MAX_Y_GRID, MAX_Y_GRID + 1);

            int setx  = Random.Range(0, 2);
            int sety  = 1 - setx;
            int value = Random.Range(0, 2) * 2 - 1;
            int offx  = value * setx;
            int offy  = value * sety;


            Block pair1, pair2;

            //pair1과 pair2에 Block을 연결해준다.
            //불가능한 Grid가 설정되었을 때에는 재시도한다.
            if (!(blockTable.TryGetValue(new Grid(x, y), out pair1) &&
                  (blockTable.TryGetValue(new Grid(x + offx, y + offy), out pair2))))
            {
                i--;
                continue;
            }

            //이미 연결되어 있을 때에는 재시도한다.
            foreach (Grid grid in pair1.LocalConnectedBlockPos)
            {
                if (grid == pair2.BlockGrid)
                {
                    i--;
                    continue;
                }
            }

            pair1.AddConnectedBlock(pair2.BlockGrid);
            pair2.AddConnectedBlock(pair1.BlockGrid);
        }

        //sidewalkGraph 노드를 연결한다.
        for (int x = -MAX_X_GRID; x <= MAX_X_GRID; x++)
        {
            for (int y = -MAX_Y_GRID; y <= MAX_Y_GRID; y++)
            {
                for (int i = 0; i < 4; i++)
                {
                    float offset_x = (float)(i % 2);
                    float offset_y = (float)((i >> 1) % 2);

                    Grid homeGrid = new Grid(x, y, offset_x, offset_y);
                    Grid grid1    = new Grid(x, y, 1.0f - offset_x, offset_y);
                    Grid grid2    = new Grid(x, y, offset_x, 1 - offset_y);

                    sidewalkGraph.AddEdge(homeGrid, grid1, walking_weight_coefficient);
                    sidewalkGraph.AddEdge(homeGrid, grid2, walking_weight_coefficient);
                }

                //연결된 블록끼리 연결해준다.
                //연결된 블록 사이에 있는 노드는 삭제한다.
                Block block = blockTable_TryGetValue(new Grid(x, y));

                foreach (Grid grid in block.LocalConnectedBlockPos)
                {
                    Grid  connectedBlockGrid = new Grid(x + grid.block_x, y + grid.block_y);
                    Block connectedBlock     = blockTable_TryGetValue(connectedBlockGrid);

                    Grid nodeGrid1;
                    Grid nodeGrid2;
                    Grid cnodeGrid1;
                    Grid cnodeGrid2;

                    //grid에 따라 nodeGrid1과 nodeGrid2를 결정해준다.
                    //상
                    if (grid == Grid.up)
                    {
                        nodeGrid1  = new Grid(0, 1);
                        nodeGrid2  = new Grid(1, 1);
                        cnodeGrid1 = new Grid(0, 0);
                        cnodeGrid2 = new Grid(1, 0);
                    }
                    //하
                    else if (grid == Grid.down)
                    {
                        nodeGrid1  = new Grid(0, 0);
                        nodeGrid2  = new Grid(0, 1);
                        cnodeGrid1 = new Grid(1, 0);
                        cnodeGrid2 = new Grid(1, 1);
                    }
                    //좌
                    else if (grid == Grid.left)
                    {
                        nodeGrid1  = new Grid(0, 0);
                        nodeGrid2  = new Grid(1, 0);
                        cnodeGrid1 = new Grid(0, 1);
                        cnodeGrid2 = new Grid(1, 1);
                    }
                    //우
                    else if (grid == Grid.right)
                    {
                        nodeGrid1  = new Grid(1, 0);
                        nodeGrid2  = new Grid(1, 1);
                        cnodeGrid1 = new Grid(0, 0);
                        cnodeGrid2 = new Grid(0, 1);
                    }
                    else
                    {
                        throw new System.Exception();
                    }

                    sidewalkGraph.RemoveEdge(nodeGrid1, nodeGrid2);
                    sidewalkGraph.RemoveEdge(nodeGrid2, nodeGrid1);

                    sidewalkGraph.AddEdge(nodeGrid1, cnodeGrid1, walking_weight_coefficient);
                    sidewalkGraph.AddEdge(nodeGrid2, cnodeGrid2, walking_weight_coefficient);
                }
            }
        }

        //dirvewayGraph 노드를 전부 생성한다.
        for (int x = -MAX_X_GRID + 1; x <= MAX_X_GRID; x++)
        {
            for (int y = -MAX_Y_GRID + 1; y <= MAX_Y_GRID; y++)
            {
                Grid    grid = new Grid(x, y);
                Vector2 pos  = new Vector2((BLOCK_HEIGHT + SIDEWALK_WIDTH * 2 + DRIVEWAY_WIDTH) * x - DRIVEWAY_WIDTH * 0.5f,
                                           (BLOCK_WIDTH + SIDEWALK_WIDTH * 2 + DRIVEWAY_WIDTH) * y - DRIVEWAY_WIDTH * 0.5f);
                drivewayGraph.AddVertex(new DrivewayNode(DrivewayNodeType.Default, grid, pos), grid);
            }
        }

        //drivewayGraph 노드를 전부 연결한다.
        for (int x = -MAX_X_GRID + 1; x <= MAX_X_GRID; x++)
        {
            for (int y = -MAX_Y_GRID + 1; y <= MAX_Y_GRID; y++)
            {
                Grid grid = new Grid(x, y);
                foreach (Grid udlr in Grid.UDLR)
                {
                    //first나 end가 존재하지 않는다면 연결하지 않는다.
                    drivewayGraph.AddEdge(grid, grid + udlr, bus_weight_coefficient, true);
                }
            }
        }

        //연결된 Block 사이에 연결된 drivewaynode를 끊어준다.
        for (int x = -MAX_X_GRID + 1; x <= MAX_X_GRID; x++)
        {
            for (int y = -MAX_Y_GRID + 1; y <= MAX_Y_GRID; y++)
            {
                Grid        blockGrid         = new Grid(x, y);
                Block       block             = blockTable_TryGetValue(blockGrid);
                List <Grid> connectedBlockPos = block.LocalConnectedBlockPos;

                foreach (Grid grid in connectedBlockPos)
                {
                    if (grid == Grid.left)
                    {
                        drivewayGraph.RemoveEdge(blockGrid, blockGrid + Grid.up, true);
                        drivewayGraph.RemoveEdge(blockGrid + Grid.up, blockGrid, true);
                    }
                    if (grid == Grid.down)
                    {
                        drivewayGraph.RemoveEdge(blockGrid, blockGrid + Grid.right, true);
                        drivewayGraph.RemoveEdge(blockGrid + Grid.right, blockGrid, true);
                    }
                }
            }
        }
        drivewayGraph.DestoryIsolatedVertex();

        //TrafficLight 위치를 설정한다.
        {
            bool[,] isConnected = new bool[2 * MAX_X_GRID + 1, 2 * MAX_Y_GRID + 1];


            int  x    = Random.Range(-MAX_X_GRID, MAX_X_GRID + 1);
            int  y    = Random.Range(-MAX_Y_GRID, MAX_Y_GRID + 1);
            Grid udlr = Grid.GetRandomUDLR();

            Stack <Grid> gridStack = new Stack <Grid>();
            isConnected[x + MAX_X_GRID, y + MAX_Y_GRID] = true;
            gridStack.Push(new Grid(x, y));
            foreach (Grid connectedBlockPos in blockTable_TryGetValue(new Grid(x, y)).LocalConnectedBlockPos)
            {
                isConnected[x + connectedBlockPos.block_x + MAX_X_GRID, y + connectedBlockPos.block_y + MAX_Y_GRID] = true;
            }


            //DFS
            while (gridStack.Count != 0)
            {
                Grid nowGrid = gridStack.Pop();

                //blockGrid가 Connected일 경우
                if (isConnected[nowGrid.block_x + MAX_X_GRID, nowGrid.block_y + MAX_Y_GRID])
                {
                    for (int i = 0; i < 4; i++)
                    {
                        //90도 회전변환 한다.
                        udlr = new Grid(-udlr.block_y, udlr.block_x);
                        Grid grid = nowGrid + udlr;

                        if (Mathf.Abs(grid.block_x) > MAX_X_GRID || Mathf.Abs(grid.block_y) < MAX_Y_GRID)
                        {
                            continue;
                        }


                        //주변에 unconnected가 있을 경우 연결하고, 연결한 블록에 대해 재귀한다.
                        if (isConnected[grid.block_x + MAX_X_GRID, grid.block_y + MAX_Y_GRID] == false)
                        {
                            blockTable_TryGetValue(nowGrid).AddTrafficLight(grid);
                            blockTable_TryGetValue(grid).AddTrafficLight(nowGrid);
                            isConnected[grid.block_x + MAX_X_GRID, grid.block_y + MAX_Y_GRID] = true;
                            gridStack.Push(grid);
                            foreach (Grid connectedBlockPos in blockTable_TryGetValue(grid).LocalConnectedBlockPos)
                            {
                                isConnected[x + connectedBlockPos.block_x + MAX_X_GRID, y + connectedBlockPos.block_y + MAX_Y_GRID] = true;
                            }
                        }
                    }
                }
            }
        }

        //TrafficLight를 생성한다.
        for (int x = -MAX_X_GRID; x <= MAX_X_GRID; x++)
        {
            for (int y = -MAX_Y_GRID; y <= MAX_Y_GRID; y++)
            {
                Grid blockGrid = new Grid(x, y);
                foreach (Grid trafficPos in blockTable_TryGetValue(blockGrid).LocalTrafficLightPos)
                {
                    if (trafficPos == Grid.up)
                    {
                        float   ratio     = Random.Range((1 - RANGE_TRAFFICLIGHT_MAY_EXIST) * 0.5f, (1 + RANGE_TRAFFICLIGHT_MAY_EXIST) * 0.5f);
                        Vector2 sNodePos1 = GetSidewalkNodePos(x, y, ratio, 1);
                        Vector2 sNodePos2 = GetSidewalkNodePos(x, y + 1, ratio, 0);
                        Vector2 dNodePos  = (sNodePos1 + sNodePos2) * 0.5f;


                        TrafficLightTimer trafficLightTimer = new TrafficLightTimer();
                        SidewalkNode      sidewalkNode1     = new SidewalkNode(SidewalkNodeType.TrafficLight,
                                                                               new Grid(x, y, ratio, 1),
                                                                               sNodePos1);
                        SidewalkNode sidewalkNode2 = new SidewalkNode(SidewalkNodeType.TrafficLight,
                                                                      new Grid(x, y + 1, ratio, 0),
                                                                      sNodePos2);
                        DrivewayNode drivewayNode = new DrivewayNode(DrivewayNodeType.TrafficLight,
                                                                     new Grid(x, y + 1, ratio, 0),
                                                                     dNodePos);
                    }
                }
            }
        }
    }