Exemple #1
0
        public double Calculate()
        {
            // every open end should reference to blocked direction tile
            blockOpenEnds();
            Console.WriteLine("blocked open ends");
            //addOneWireToAdjacentTWires();
            Console.WriteLine("added wires to any adjacent Ts");
            var paths = FindAllPaths();

            Console.WriteLine("Found all paths");
            // one path, return sum of all.
            if (paths.Count == 0)
            {
                Console.WriteLine("No Paths Found... Something went wrong.");
                return(-2);
            }
            if (paths.Count == 1)
            {
                return(paths[0].Sum(gameTile => gameTile.resistance));
            }
            else
            {
                //first, put current index in each tile in paths.
                int currentIndex = 0;
                var allTWires    = new List <GameTile>();
                foreach (var path in paths)
                {
                    GameTile previousTile = path[0]; //should be endTile at the beginning.
                    for (var i = 1; i < path.Count; i++)
                    {
                        GameTile tile = path[i];
                        if (tile.firstAccessor == null)
                        {
                            tile.firstAccessor = previousTile;
                            tile.currentIndex  = currentIndex;
                        }
                        if (tile.type == GameTileTypes.Wire.typeT)
                        {
                            currentIndex++;
                            if (!allTWires.Contains(tile) && tile != startTile)
                            {
                                allTWires.Add(tile);
                            }
                        }

                        previousTile = tile;
                    }
                }
                Console.WriteLine("All indexes are written");
                double voltage = 12;
                double[,] solutionMatrix = new double[currentIndex + 1, currentIndex + 1];
                double[,] rightSide      = new double[currentIndex + 1, 1];
                //then find first nonblockdir T mach, get current index,
                //special case start tile
                int row = 0;
                if (
                    startTile.neighbors.Values.Where(neighbor => neighbor != GameTile.blockedDirectionTile)
                    .ToList()
                    .Count == 2)
                {
                    var neighbor1 =
                        startTile.neighbors.Values.First(neighbor => neighbor != GameTile.blockedDirectionTile);
                    var neighbor2 =
                        startTile.neighbors.Values.First(
                            neighbor => neighbor != GameTile.blockedDirectionTile && neighbor != neighbor1);
                    solutionMatrix[row, 0] = 1;
                    solutionMatrix[row, neighbor1.currentIndex] = -1;
                    solutionMatrix[row, neighbor2.currentIndex] = -1;
                    rightSide[row, 0] = 0;
                }
                else
                {
                    var neighbor1 =
                        startTile.neighbors.Values.First(neighbor => neighbor != GameTile.blockedDirectionTile);
                    solutionMatrix[row, 0] = 1;
                    solutionMatrix[row, neighbor1.currentIndex] = -1;
                    rightSide[row, 0] = 0;
                }
                row++;
                foreach (var wire in allTWires)
                {
                    var neighborA = wire.neighbors.Values.First(neighbor => neighbor != GameTile.blockedDirectionTile);
                    var neighborB = wire.neighbors.Values.First(neighbor => neighbor != GameTile.blockedDirectionTile && neighbor != neighborA);
                    var neighborC = wire.neighbors.Values.First(neighbor => neighbor != GameTile.blockedDirectionTile && neighbor != neighborA && neighbor != neighborB);
                    solutionMatrix[row, neighborA.currentIndex] = neighborA.firstAccessor == wire ? 1 : -1;
                    solutionMatrix[row, neighborB.currentIndex] = neighborB.firstAccessor == wire ? 1 : -1;
                    solutionMatrix[row, neighborC.currentIndex] = neighborC.firstAccessor == wire ? 1 : -1;
                    rightSide[row, 0] = 0;
                    row++;
                }
                foreach (var path in paths)
                {
                    double   tempResistance = 0;
                    int      tempIndex      = 0;
                    GameTile prevTile       = path[0];
                    for (var i = 1; i < path.Count; i++)
                    {
                        GameTile tempTile = path[i];
                        if (tempTile.type != GameTileTypes.Wire.typeT)
                        {
                            if (tempTile.currentIndex == tempIndex)
                            {
                                tempResistance += tempTile.getResistanceWithDirection(prevTile);
                            }
                            else
                            {
                                solutionMatrix[row, tempIndex] = tempResistance;
                                tempResistance = tempTile.getResistanceWithDirection(prevTile);
                            }
                            tempIndex = tempTile.currentIndex;
                        }
                        prevTile = tempTile;
                    }
                    rightSide[row, 0] = voltage;
                    row++;
                }
                //specific equals case for start and end tiles.
                //     set that 1, get other neighbors, their current indexes, 0 into solution matrix
                //Ideally, matrix should be square, but can be approximated if less.

                var    amp             = solutionMatrix.Solve(rightSide, leastSquares: true)[0, 0];
                double totalResistance = voltage / amp;
                return(totalResistance);
            }
        }