예제 #1
0
    // Use this for initialization
    void Start()
    {
        timer = 1 / step_per_second;

        maze_generator mg = this.GetComponentInParent <maze_generator>();

        dungeon = mg.Get_Dungeon;

        int mazeLength = dungeon.getMaze_length();

        tableLength = mazeLength * mazeLength;

        rewardTable = new int[tableLength, tableLength];
        qTable      = new float[tableLength, tableLength];
        usedTable   = new int[tableLength, tableLength];
        //creates reward table
        for (int i = 0; i < tableLength; i++)
        {
            for (int j = 0; j < tableLength; j++)
            {
                //first put every state to state as -1 so it is not reachable
                rewardTable[i, j] = -1;
                int curVerIndex_j    = i % mazeLength;
                int curVerIndex_i    = (i - curVerIndex_j) / mazeLength;
                int targetVerIndex_j = j % mazeLength;
                int targetVerIndex_i = (j - targetVerIndex_j) / mazeLength;
                //foreach state to state
                cell current = dungeon.getCells()[curVerIndex_i][curVerIndex_j];
                cell target  = dungeon.getCells()[targetVerIndex_i][targetVerIndex_j];
                //look for current states neighbours
                foreach (cell neighbour in current.getNeighbours())
                {
                    //if its reachable
                    if (neighbour == target)
                    {
                        //then mark it as 0 so it is reachable
                        rewardTable[i, j] = 0;
                        //if it is the end point then mark it with reward
                        if (dungeon.end_i == targetVerIndex_i && dungeon.end_j == targetVerIndex_j)
                        {
                            rewardTable[i, j] = reward;
                        }
                        break;
                    }
                }
            }
        }

        character  = Instantiate(character, new Vector3(dungeon.start_x, dungeon.start_y, 0), Quaternion.identity);
        curVertice = dungeon.start_i * dungeon.getMaze_length() + dungeon.start_j;
    }
    //prims maze generation algorithm
    public maze generate()
    {
        maze dungeon = new maze(mazeLength);
        //Prim's maze generator algorithm
        List <cell>  toBeVisited = new List <cell>();
        List <short> choices     = new List <short>();

        toBeVisited.Add(dungeon.getCells()[0][0]);
        while (toBeVisited.Count != 0)
        {
            //select randomly
            cell selected = toBeVisited[Random.Range(0, toBeVisited.Count)];
            selected.visited = true;
            //find choices
            if (selected.getC_x() != 0 && selected.getNeighbours()[directions.north].visited)
            {
                choices.Add(directions.north);
            }
            if (selected.getC_y() != dungeon.getMaze_length() - 1 && selected.getNeighbours()[directions.east].visited)
            {
                choices.Add(directions.east);
            }
            if (selected.getC_x() != dungeon.getMaze_length() - 1 && selected.getNeighbours()[directions.south].visited)
            {
                choices.Add(directions.south);
            }
            if (selected.getC_y() != 0 && selected.getNeighbours()[directions.west].visited)
            {
                choices.Add(directions.west);
            }
            //choose where selected will be connected
            if (choices.Count > 0)
            {
                cell toWhere = selected.getNeighbours()[choices[Random.Range(0, choices.Count)]];
                dungeon.createPassage(selected.getC_x(), selected.getC_y(), toWhere.getC_x(), toWhere.getC_y());
            }
            //add unvisited nodes
            if (selected.getC_x() != 0 && !selected.getNeighbours()[directions.north].visited)
            {
                toBeVisited.Add(selected.getNeighbours()[directions.north]);
            }
            if (selected.getC_y() != dungeon.getMaze_length() - 1 && !selected.getNeighbours()[directions.east].visited)
            {
                toBeVisited.Add(selected.getNeighbours()[directions.east]);
            }
            if (selected.getC_x() != dungeon.getMaze_length() - 1 && !selected.getNeighbours()[directions.south].visited)
            {
                toBeVisited.Add(selected.getNeighbours()[directions.south]);
            }
            ;
            if (selected.getC_y() != 0 && !selected.getNeighbours()[directions.west].visited)
            {
                toBeVisited.Add(selected.getNeighbours()[directions.west]);
            }
            choices.Clear();
            toBeVisited.Remove(selected);
        }
        //Remove unreachable neighbours
        for (int i = 0; i < mazeLength; i++)
        {
            for (int j = 0; j < mazeLength; j++)
            {
                dungeon.getCells()[i][j].fix_neighbours();
            }
        }

        return(dungeon);
    }