protected static void RemoveWallBetween(ref Wall4[,] cells, Tuple<int, int> current, Tuple<int, int> selected)
        {
            Contract.Requires(cells != null);
            Contract.Requires(current != null);
            Contract.Requires(selected != null);
            Contract.Ensures(cells != null);

            // X-Achse
            if (current.Item1 > selected.Item1)
            {
                cells[selected.Item1, selected.Item2] = cells[selected.Item1, selected.Item2] & ~Wall4.East;
                cells[current.Item1, current.Item2] = cells[current.Item1, current.Item2] & ~Wall4.West;
            }
            else if (current.Item1 < selected.Item1)
            {
                cells[selected.Item1, selected.Item2] = cells[selected.Item1, selected.Item2] & ~Wall4.West;
                cells[current.Item1, current.Item2] = cells[current.Item1, current.Item2] & ~Wall4.East;
            }

            // Y-Achse
            if (current.Item2 > selected.Item2)
            {
                cells[selected.Item1, selected.Item2] = cells[selected.Item1, selected.Item2] & ~Wall4.South;
                cells[current.Item1, current.Item2] = cells[current.Item1, current.Item2] & ~Wall4.North;
            }
            else if (current.Item2 < selected.Item2)
            {
                cells[selected.Item1, selected.Item2] = cells[selected.Item1, selected.Item2] & ~Wall4.North;
                cells[current.Item1, current.Item2] = cells[current.Item1, current.Item2] & ~Wall4.South;
            }
        }
    void Update()
    {
        if (Progress == 3)
        {
            store = Wall3.GetComponent <SpriteRenderer>().sprite;
            if (store == ThirdWall)
            {
                Progress = 4;
                Wall3.GetComponent <Animator>().enabled       = false;
                Wall3.GetComponent <SpriteRenderer>().enabled = false;
                Wall4.GetComponent <Animator>().enabled       = true;
                Wall4.GetComponent <SpriteRenderer>().enabled = true;
                Button3.GetComponent <Button>().interactable  = true;
            }
        }
        Cloud1.transform.Translate(Iteration, 0, 0);
        Cloud2.transform.Translate(-Iteration, 0, 0);
        Cloud3.transform.Translate(Iteration, 0, 0);

        if (T < 0)
        {
            PlayerPrefs.SetInt("Result", Win);
            Store.GetComponent <PresentResults>().enabled = true;
            Store.GetComponent <GameBuildWall>().enabled  = false;
        }
        else
        {
            T = T - Time.deltaTime;
        }
    }
 public void ThirdClick()
 {
     Win      = 1;
     Progress = 5;
     Wall4.GetComponent <Animator>().enabled       = false;
     Wall4.GetComponent <SpriteRenderer>().enabled = false;
     Wall5.GetComponent <SpriteRenderer>().enabled = true;
 }
        /// <summary>
        /// Fügt alle Wände einer Zelle zur Wandliste hinzu
        /// </summary>
        /// <param name="cells">Die Karte der Zellen</param>
        /// <param name="cell">Die aktuelle Zelle</param>
        /// <param name="wallList">Die Wandliste</param>
        private static void AddWallsToWallList(ref Wall4[,] cells, Tuple<int, int> cell, ref List<Tuple<int, int, Wall4>> wallList)
        {
            Contract.Requires(cells != null);
            Contract.Requires(cell != null);
            Contract.Requires(wallList != null);
            Contract.Requires(cell.Item1 >= 0);
            Contract.Requires(cell.Item2 >= 0);
            Contract.Ensures(cells != null);
            Contract.Ensures(wallList != null);

            // Nordwand
            if (cell.Item2 > 0 && cells[cell.Item1, cell.Item2].ContainsWall(Wall4.North))
            {
                wallList.Add(new Tuple<int, int, Wall4>(cell.Item1, cell.Item2, Wall4.North));
            }

            // Südwand
            if (cell.Item2 < cells.GetLength(1) - 1 && cells[cell.Item1, cell.Item2].ContainsWall(Wall4.South))
            {
                wallList.Add(new Tuple<int, int, Wall4>(cell.Item1, cell.Item2, Wall4.South));
            }

            // Ostwand
            if (cell.Item1 < cells.GetLength(0) - 1 && cells[cell.Item1, cell.Item2].ContainsWall(Wall4.East))
            {
                wallList.Add(new Tuple<int, int, Wall4>(cell.Item1, cell.Item2, Wall4.East));
            }

            // Westwand
            if (cell.Item1 > 0 && cells[cell.Item1, cell.Item2].ContainsWall(Wall4.West))
            {
                wallList.Add(new Tuple<int, int, Wall4>(cell.Item1, cell.Item2, Wall4.West));
            }
        }
        /// <summary>
        /// Ermittelt, ob die Zelle, die gegenüber der in <paramref name="wall"/> angegebenen Wand der Zelle an Position
        /// <paramref name="cell"/> liegt, bereits Teil des Labyrinths ist.
        /// </summary>
        /// <param name="mazeMap">Die Karte, die angibt, ob eine Zelle Teil des Labyrinthes ist</param>
        /// <param name="cell">Die aktuelle Position</param>
        /// <param name="wall">Die zu testende Wand</param>
        /// <param name="oppositeCell">Die Zelle auf der gegenüberliegenden Seite</param>
        /// <returns><c>true</c>, wenn die Zelle auf der anderen Seite Teil des Labyrinthes ist, ansonsten <c>false</c></returns>
        /// <exception cref="ArgumentException">Ein ungültiger Wert für <paramref name="wall"/> wurde übergeben.</exception>
        private static bool CellOnOppositeSideOfWallIsOnMaze(bool[,] mazeMap, Tuple<int, int> cell, Wall4 wall, out Tuple<int, int> oppositeCell)
        {
            Contract.Requires(mazeMap != null);
            Contract.Requires(cell != null);
            Contract.Requires(wall.ExactlyOneValueSet());
            Contract.Requires(cell.Item1 >= 0 && cell.Item2 >= 0);
            Contract.Ensures(Contract.ValueAtReturn(out oppositeCell) != null);

            switch (wall)
            {
                case Wall4.North:
                    Contract.Assume(cell.Item2 > 0);
                    oppositeCell = new Tuple<int, int>(cell.Item1, cell.Item2 - 1);
                    return mazeMap[oppositeCell.Item1, oppositeCell.Item2];
                case Wall4.South:
                    Contract.Assume(cell.Item2 < mazeMap.GetLength(1) - 1);
                    oppositeCell = new Tuple<int, int>(cell.Item1, cell.Item2 + 1);
                    return mazeMap[oppositeCell.Item1, oppositeCell.Item2];
                case Wall4.East:
                    Contract.Assume(cell.Item1 < mazeMap.GetLength(0) - 1);
                    oppositeCell = new Tuple<int, int>(cell.Item1 + 1, cell.Item2);
                    return mazeMap[oppositeCell.Item1, oppositeCell.Item2];
                case Wall4.West:
                    Contract.Assume(cell.Item1 > 0);
                    oppositeCell = new Tuple<int, int>(cell.Item1 - 1, cell.Item2);
                    return mazeMap[oppositeCell.Item1, oppositeCell.Item2];
                default:
                    throw new ArgumentException("Ungültige Wand-Werte:" + wall, "wall");
            }
        }
        protected Wall4[,] PrepareWalls(int width, int height)
        {
            Contract.Requires(width > 0 && height > 0);
            Contract.Ensures(Contract.Result<Wall4[,]>() != null);

            // Array vorbereiten und Affentest durchführen
            Wall4[,] cells = new Wall4[width,height];
            for (int y = 0; y < height; ++y) for (int x = 0; x < width; ++x) cells[x, y] = Wall4.All;
            return cells;
        }
        /// <summary>
        /// Bezieht die Zelle, die gegenüber der in <paramref name="wall"/> angegebenen Wand der Zelle an Position
        /// <paramref name="cell"/> liegt
        /// </summary>
        /// <param name="cell">Die aktuelle Position</param>
        /// <param name="wall">Die zu testende Wand</param>
        /// <returns>Die Zelle</returns>
        /// <exception cref="ArgumentException">Ein ungültiger Wert für <paramref name="wall"/> wurde übergeben.</exception>
        private static Tuple<int, int> SelectCellOnOppositeSideOfWall(Tuple<int, int> cell, Wall4 wall)
        {
            Contract.Requires(cell != null);
            Contract.Requires(wall.ExactlyOneValueSet());
            Contract.Requires(cell.Item1 >= 0 && cell.Item2 >= 0);

            switch (wall)
            {
                case Wall4.North:
                    Contract.Assume(cell.Item2 > 0);
                    return new Tuple<int, int>(cell.Item1, cell.Item2 - 1);
                case Wall4.South:
                    return new Tuple<int, int>(cell.Item1, cell.Item2 + 1);
                case Wall4.East:
                    return new Tuple<int, int>(cell.Item1 + 1, cell.Item2);
                case Wall4.West:
                    Contract.Assume(cell.Item1 > 0);
                    return new Tuple<int, int>(cell.Item1 - 1, cell.Item2);
                default:
                    throw new ArgumentException("Ungültige Wand-Werte:" + wall, "wall");
            }
        }
 public static bool ContainsWall(this Wall4 item, Wall4 wall)
 {
     return (item & wall) == wall;
 }
        /// <summary>
        /// Wandelt ein <see cref="Door4"/>-Array in ein <see cref="Wall4"/>-Array um
        /// </summary>
        /// <param name="doors">Die Türen.</param>
        /// <returns>Das <see cref="Door4"/>-Array</returns>
        /// <remarks></remarks>
        public static Wall4[,] ToWallArray(this Door4[,] doors)
        {
            Contract.Requires(doors != null);
            Contract.Ensures(Contract.Result<Wall4[,]>() != null);

            int width = doors.GetLength(0);
            int height = doors.GetLength(1);
            Wall4[,] walls = new Wall4[width, height];
            for (int y = 0; y < height; ++y)
            {
                for (int x = 0; x < height; ++x)
                {
                    walls[x, y] = doors[x, y].ToWall();
                }
            }
            return walls;
        }
        /// <summary>
        /// Der eigentliche Backtracking-Algorithmus
        /// </summary>
        /// <param name="cells">Die Liste der Zellen</param>
        /// <param name="visitMap">Die Besuchskarte</param>
        /// <param name="currentCell">Die aktuelle Position</param>
        /// <param name="backtrace">Der Stack für die Zurückverfolgung</param>
        private void Backtrack(ref Wall4[,] cells, ref bool[,] visitMap, Tuple<int, int> currentCell, Stack<Tuple<int, int>> backtrace)
        {
            Contract.Requires(cells != null);
            Contract.Requires(visitMap != null);
            Contract.Requires(currentCell != null);
            Contract.Requires(backtrace != null);
            Contract.Ensures(cells != null);
            Contract.Ensures(visitMap != null);

            do
            {
                int widthCoord = currentCell.Item1;
                int heightCoord = currentCell.Item2;

                // 1. Mark the current cell as 'Visited'
                visitMap[widthCoord, heightCoord] = true;

                // 2. If the current cell has any neighbours which have not been visited
                //	2.1 Choose randomly one of the unvisited neighbours
                Tuple<int, int> selectedCell;
                if ((selectedCell = SelectRandomUnvisitedNeighbor(ref visitMap, widthCoord, heightCoord)) != null)
                {
                    //	2.2 add the current cell to the stack
                    backtrace.Push(currentCell);

                    //  2.3 remove the wall between the current cell and the chosen cell
                    RemoveWallBetween(ref cells, currentCell, selectedCell);

                    //  2.4 Make the chosen cell the current cell
                    currentCell = selectedCell;

                    //  2.5 Recursively call this function
                    continue;
                }

                // 3. else
                //	3.1 remove the last current cell from the stack
                if (backtrace.Count == 0) break;
                currentCell = backtrace.Pop();

                //  3.2 Backtrack to the previous execution of this function
            } while (true);
        }