Condensing an if

I was hoping to get some help with this. The only real issue I'm having is that this code is not as efficient as it could be. Basically I have a set of tiles and need to decide what kind of tiles to instantiate based on the combination of tiles around them. In the code below, the position of the tile I'm checking is the key in my map (ex map[right] is the tile to the right, topLeft is the tile adjacent diagonally to the top left and top2 etc. is the tile two spaces in that direction).

The code in question:

if (map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.NOTHING && map[bottom].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeTopLeftInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.NOTHING && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeTopRightInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.WALL && map[top].Type == TileType.NOTHING && map[right].Type == TileType.NOTHING && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeBottomLeftInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.NOTHING && map[top].Type == TileType.NOTHING && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeBottomRightInternalCornerTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.WALL && map[top].Type == TileType.FLOOR && map[right].Type == TileType.FLOOR && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeCornerTopRightTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.FLOOR && map[top].Type == TileType.FLOOR && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeCornerTopLeftTile, t.Position, Quaternion.identity);
                    }

                    else if (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[topRight].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeCornerBottomLeftTile, t.Position, Quaternion.identity);
                    }
                    else if (map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.FLOOR && map[bottom].Type == TileType.WALL && map[topLeft].Type == TileType.NOTHING)
                    {
                        Instantiate(wallEdgeCornerBottomRightTile, t.Position, Quaternion.identity);
                    }

                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.NOTHING && map[left2].Type == TileType.NOTHING) || (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.WALL && map[left2].Type == TileType.FLOOR && map[bottom2].Type == TileType.WALL))
                    {
                        Instantiate(wallTopLeftTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.NOTHING && map[right2].Type == TileType.NOTHING) || (map[right].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[left].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.WALL && map[right2].Type == TileType.FLOOR && map[bottom2].Type == TileType.WALL))
                    {
                        Instantiate(wallTopRightTile, t.Position, Quaternion.identity);
                    }

                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[left2].Type == TileType.NOTHING) || (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[left2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallBottomLeftTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[right2].Type == TileType.NOTHING) || (map[right].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[left].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[right2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallBottomRightTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[left2].Type == TileType.NOTHING && map[bottom2].Type == TileType.FLOOR) || (map[left].Type == TileType.FLOOR && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[left2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallMidLeftTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[right2].Type == TileType.NOTHING && map[bottom2].Type == TileType.FLOOR) || (map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.FLOOR && map[bottom].Type == TileType.WALL && map[right2].Type == TileType.FLOOR && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallMidRightTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.NOTHING && map[bottom2].Type == TileType.WALL))
                    {
                        Instantiate(wallTopTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.FLOOR && map[top2].Type == TileType.WALL && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallBottomTile, t.Position, Quaternion.identity);
                    }
                    else if (map[top].Type == TileType.NOTHING && map[bottom].Type == TileType.WALL)
                    {
                        Instantiate(wallEdgeBottomTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.NOTHING && map[right].Type == TileType.FLOOR) || (map[left].Type == TileType.NOTHING && map[right].Type == TileType.WALL && map[top].Type != TileType.NOTHING))
                    {
                        Instantiate(wallEdgeRightTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.FLOOR && map[right].Type == TileType.NOTHING) || (map[left].Type == TileType.WALL && map[right].Type == TileType.NOTHING && map[top].Type != TileType.NOTHING))
                    {
                        Instantiate(wallEdgeLeftTile, t.Position, Quaternion.identity);
                    }
                    else if (map[bottom].Type == TileType.NOTHING && map[top].Type == TileType.FLOOR)
                    {
                        Instantiate(wallEdgeTopTile, t.Position, Quaternion.identity);
                    }
                    else if ((map[left].Type == TileType.WALL && map[top].Type == TileType.WALL && map[right].Type == TileType.WALL && map[bottom].Type == TileType.WALL && map[top2].Type == TileType.WALL && map[bottom2].Type == TileType.FLOOR))
                    {
                        Instantiate(wallMiddleTile, t.Position, Quaternion.identity);
                    }
                    else
                    {
                        // Should never get here, so if a white Tile is seen, something went wrong!
                        Instantiate(whiteTile, t.Position, Quaternion.identity);
                    }

I had made a table because I thought that I would instead check each position, assign it a number from 0-2, convert that number from base 3 to decimal, then use a switch statement on the outcome to determine which tile to instantiate. The number codes are on the very right. But there are so many combinations, I feel like there has to be a better or easier way. Any ideas at all are appreciated!

Table: Table of conditions


To simply reduce the number of caparison operations, I would suggest arrange your AND conditionals in a tree-type fashion. here is a simplified example.

note: I'm using single & for readability- I mean logical AND.

starting with:

if(a&b&c) {functionW(a);return;}  //1 comparison, 2 ANDops
else if(a&b&!c) {functionX(a);return;}//2 comparison, 4 ANDops
else if(a&!b&!c) {functionX(b);return;}//3 comparison, 6 ANDops
else if(a&!b&c) {functionX(c);return;}//4 comparison, 8 ANDops
else if(!&a&b&c) {functionY(b);return}//5 comparison, 10 ANDops
else if(!a&!b&c){functionZ(c);return}//6 comparison, 12 ANDops
else if(!b&!e){functionZ(c);return;}//7 comparison, 13 ANDops

Tree-format: take a branch for each element we are checking, so first check for a:

//out here,first, go all the statements, where it doesn't mater what value a has.  We haveonly one condition in our example, but if we had many, we could create a separate "tree" out here.
if(!b&!e){functionZ(c);return;}//1 comparison, 1 ANDops
//now we start a branch based on a
if(a)
{//in here go all the if statements where a is true
    //now we create onther tree branch based on b
    if(b)
    {   
        if(!c){ functionW(a); return;}// total 4 comparisons to get here. 1 ANDops
    }
    else 
    {//all option where b is false
        if(c) {functionX(c); return;}// total 4 comparisons to get here, 1 ANDops
        else {functionX(b); return;}// total 4 comparisons to get here, 1 ANDops
    }
}
else
{//in here go all the if statements where a is false (there are only two, so no need for a branch)
    if(b&c) {functionY(b);return}// total 3 comparisons to get here. 2 ANDops
    else if(!b&c){functionZ(c);return}// total 3 comparisons to get here, 3 ANDops
}

Obviously you don't get a huge advantage with only 7 different conditionals, but this improvement grows, with the amount of conditionals you start with.

链接地址: http://www.djcxy.com/p/63660.html

上一篇: WrapPanel滚动条

下一篇: 凝结如果