public SingleFaceCrossSolver(FaceColour faceColour, int? layer = null) { if (layer.HasValue) { m_layer = layer.Value; } m_faceColour = faceColour; }
private static void Solve(FaceColour crossColour) { var configuration = ConfigurationGenerator.GenerateRandomConfiguration(5, 100); var solver = new SingleFaceCrossSolver(crossColour); solver.Solve(configuration).Wait(TestRunner.Timeout); CubeConfigurationAssert.FaceHasCrossOfColour(configuration, FaceType.Front, crossColour); }
public static void FaceHasCrossOfColour(CubeConfiguration<FaceColour> configuration, FaceType faceType, FaceColour faceColour) { int layer = Math.Max(configuration.Size - 4, 0); var face = configuration.Faces[faceType]; Assert.AreEqual(faceColour, face.Centre); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Right).Centre()); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Top).Centre()); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Bottom).Centre()); Assert.AreEqual(faceColour, face.GetEdge(layer, Edge.Bottom).Centre()); }
public static async Task<CubeRotation> PositionOnFront(CubeConfiguration<FaceColour> config, FaceColour faceColour) { var face = FindFaceWithCentreColour(config, faceColour); CubeRotation cubeRotation; switch (face) { case FaceType.Front: return null; case FaceType.Upper: cubeRotation = CubeRotations.XAntiClockwise; break; case FaceType.Right: cubeRotation = CubeRotations.YClockwise; break; case FaceType.Left: cubeRotation = CubeRotations.YAntiClockwise; break; case FaceType.Down: cubeRotation = CubeRotations.XClockwise; break; case FaceType.Back: cubeRotation = CubeRotations.Y2; break; default: throw new Exception("Unknown face"); } await config.RotateCube(cubeRotation).ConfigureAwait(false); return cubeRotation; }
public static void FaceIsColour(CubeConfiguration<FaceColour> configuration, FaceType face, FaceColour colour) { Assert.IsTrue(configuration.Faces[face].Items.AsEnumerable().All(c => c == colour)); }
public void Solve_GivenARandomConfiguration_ProducesASolvedCross(FaceColour crossColour) { TestRunner.RunTestMultipleTimes(TestRunner.MultipleTimesToRun, () => Solve(crossColour)); }
private static TredgeMatch MatchColoursOnDownFaceEdge(CubeConfiguration<FaceColour> configuration, FaceColour frontColour, FaceColour leftColour, FaceType face) { var bottomEdge = configuration.Faces[face].GetEdge(Edge.Bottom); var frontBottomLeft = bottomEdge[configuration.MinInnerLayerIndex()]; var frontBottomRight = bottomEdge[configuration.MaxInnerLayerIndex()]; Edge edge; switch (face) { case FaceType.Front: edge = Edge.Top; break; case FaceType.Back: edge = Edge.Bottom; break; case FaceType.Left: edge = Edge.Left; break; case FaceType.Right: edge = Edge.Right; break; default: throw new InvalidOperationException("Cannot get connecting edge as down layer does not connect to " + face); } var downLayerEdge = configuration.Faces[FaceType.Down].GetEdge(edge); if (face == FaceType.Back || face == FaceType.Left) { downLayerEdge = downLayerEdge.Reverse().ToArray(); } var downTopLeft = downLayerEdge[configuration.MinInnerLayerIndex()]; var downTopRight = downLayerEdge[configuration.MaxInnerLayerIndex()]; if (frontBottomLeft == frontColour && downTopLeft == leftColour) { return TredgeMatch.FrontLeftMatchesCenter; } if (frontBottomRight == frontColour && downTopRight == leftColour) { return TredgeMatch.FrontRightMatchesCenter; } if (frontBottomLeft == leftColour && downTopLeft == frontColour) { return TredgeMatch.DownLeftMatchesCenter; } if (frontBottomRight == leftColour && downTopRight == frontColour) { return TredgeMatch.DownRightMatchesCenter; } return TredgeMatch.None; }
private static async Task CheckFrontUpper(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, FaceColour frontFaceColour, FaceColour leftFaceColour) { var match = MatchColoursOnUpperFaceEdge(configuration, frontFaceColour, leftFaceColour, FaceType.Front); if (match != TredgeMatch.None) { await MatchingTredgeIsOnUpperFront(configuration, solution, match).ConfigureAwait(false); } }
private static async Task MoveTopCentreToMiddleLayer(CubeConfiguration<FaceColour> configuration, ICollection<IRotation> solution, FaceColour upperColour) { var faceOfUpperColour = FaceRules.GetFaceOfColour(upperColour, configuration); var upperRelation = FaceRules.RelativePositionBetweenFaces(FaceType.Front, faceOfUpperColour); switch (upperRelation) { case RelativePosition.Left: await MoveTopCentreToMiddleLeft(configuration, solution).ConfigureAwait(false); break; case RelativePosition.Right: await MoveTopCentreToMiddleRight(configuration, solution).ConfigureAwait(false); break; } }
private static FaceType FindFaceWithCentreColour(CubeConfiguration<FaceColour> config, FaceColour faceColour) { return config.Faces.First(f => f.Value.Centre == faceColour).Key; }
public static async Task<CubeRotation> PositionOnBottom(CubeConfiguration<FaceColour> config, FaceColour faceColour) { var face = FindFaceWithCentreColour(config, faceColour); return await PositionOnBottom(config, face).ConfigureAwait(false); }
public static FaceType GetFaceOfColour(FaceColour colour, CubeConfiguration<FaceColour> configuration) { return configuration.Faces.First(kvp => kvp.Value.Centre == colour).Key; }
private static async Task CheckUpperBottomLeft(CubeConfiguration<FaceColour> configuration, List<IRotation> solution, FaceColour frontFaceColour) { var bottomLeft = configuration.Faces[FaceType.Upper].GetEdge(configuration.MinInnerLayerIndex(), Edge.Bottom)[configuration.MinInnerLayerIndex()]; if (bottomLeft == frontFaceColour) { for (int i = 0; i <= 3; i++) { if (configuration.Faces[FaceType.Front].GetEdge(configuration.MinInnerLayerIndex(), Edge.Top)[configuration.MinInnerLayerIndex()] != frontFaceColour) { await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.UpperAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftAntiClockwise, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.Upper2, solution, configuration).ConfigureAwait(false); await CommonActions.ApplyAndAddRotation(Rotations.SecondLayerLeftClockwise, solution, configuration).ConfigureAwait(false); break; } await CommonActions.ApplyAndAddRotation(Rotations.FrontClockwise, solution, configuration).ConfigureAwait(false); } } }