public bool IsMatch(Cube cube) { for (int f = 0; f < 4; f++) { CubeFace face = CubeSolver.MiddleLayerFaces[f]; CubeColor[] tiles = { cube.At(face, 6), cube.At(face, 7), cube.At(face, 8) }; int delta0 = SolvingUtility.NormalizeCount(middleLayerColors[tiles[0]] - middleLayerColors[tiles[1]]); int delta1 = SolvingUtility.NormalizeCount(middleLayerColors[tiles[0]] - middleLayerColors[tiles[2]]); int delta2 = SolvingUtility.NormalizeCount(middleLayerColors[tiles[1]] - middleLayerColors[tiles[2]]); if (delta0 != patternData[f][0] || delta1 != patternData[f][1] || delta2 != patternData[f][2]) { return(false); } } return(true); }
/// <summary> /// Gibt den Farbunterschied eines weißen Kantensteins zurück /// </summary> /// <param name="edge">Der Kantenstein, dessen Farbunterschied bestimmt werden soll</param> /// <returns></returns> protected int GetDelta(EdgeStone edge) { CubeColor edgeColor = edge.GetColors().First(c => c != WHITE); CubeFace face = edge.GetColorPosition(c => c != WHITE).Face; return(SolvingUtility.GetDelta(edgeColor, face, UP)); }
private static void FalsePairedDownLayer(FTLPair pair) { // move corner above right slot // 0-2 moves Position pos = pair.Corner.GetPositions().First(p => p.Face == DOWN); int delta = SolvingUtility.GetDelta(cube.At(pos), pair.CornerWhitePosition.Face, DOWN); DoMove(DOWN, delta); // do algorithm 7-10 moves var faceToRot = Cube.GetFace(pair.Corner.GetColor(p => p.Face != DOWN)); FTLPair secondPair = pairs.First(p => p.Edge.HasColor(Cube.GetFaceColor(faceToRot)) && p != pair); bool secondPairSolved = secondPair.Solved; int direction = pair.CornerWhitePosition.Tile == 6 ? 1 : -1; DoMove(faceToRot, direction); DoMove(DOWN, 2); DoMove(faceToRot, 2); DoMove(DOWN, -direction); DoMove(faceToRot, -direction); if (secondPairSolved) { DoMove(faceToRot, -direction); DoMove(DOWN, -direction); DoMove(faceToRot, direction); } }
private static void CornerDown_YellowSide_EdgeDown(FTLPair pair) { CubeColor color = pair.Edge.GetColor(p => p.Face != DOWN); CubeFace targetFace = Cube.GetFace(color); while (pair.Edge.GetPosition(p => p.Face != DOWN).Face != targetFace) { DoMove(DOWN); } CubeFace faceToRot = pair.Edge.GetPosition(p => p.Face != DOWN).Face; int direction = SolvingUtility.GetDelta(pair.Edge.GetColor(p => p.Face != DOWN), faceToRot, DOWN); // move edge in right position DoMove(faceToRot, direction); // pair the stones while (pair.Corner.GetColorPosition(color).Face != targetFace) { DoMove(DOWN); } DoMove(faceToRot, -direction); // handle as right paired RightPairedDownLayer(pair); }
/// <summary> /// Bring einen weißen falsch orientierten Kantenstein auf der mittleren Ebene in die richtige Position relativ zum Pivotstein. /// </summary> /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param> protected void HandleFalseOrientatedStone(EdgeStone edge) { if (Array.TrueForAll(MiddleLayerFaces, f => edge.GetColorPosition(WHITE).Face != f) || edge.GetColorPosition(WHITE).Tile == 3 || edge.GetColorPosition(WHITE).Tile == 5) { throw new ArgumentOutOfRangeException("Der weiße Kantenstein muss sich in der oberen oder unteren Ebene befinden und die weiße Fläche muss auf einer der seitlichen Seiten (Orange, Grün, Rot, Blau) sein", nameof(edge)); } #if DEBUG Log.LogStuff("Handle false orientated stone\r\n\t" + edge.ToString()); #endif // get edge information CubeColor secndColor = GetSecondColor(edge); Position whitePos = edge.GetColorPosition(WHITE); // get face of white pos int middleLayerFaceID = Array.IndexOf(MiddleLayerFaces, whitePos.Face); // face in anti clockwise rotation of white position face CubeFace leftFace = MiddleLayerFaces[(middleLayerFaceID + 3) % 4]; // face in clockwise roation of white position face CubeFace rightFace = MiddleLayerFaces[(middleLayerFaceID + 1) % 4]; int leftDelta = Math.Abs(SolvingUtility.NormalizeCount(SolvingUtility.GetDelta(secndColor, leftFace, UP), -1)); int rightDelta = Math.Abs(SolvingUtility.NormalizeCount(SolvingUtility.GetDelta(secndColor, rightFace, UP), -1)); // on up layer if (whitePos.Tile == 1) { // move edge to middle layer if (leftDelta < rightDelta) { DoMove(whitePos.Face, -1); } else { DoMove(whitePos.Face); } HandleStoneMiddleLayer(edge); } else { // check if the face must rotated back after stone handling int[] tiles = { 3, 7, 5, 1 }; bool rotBack = cube.At(UP, tiles[middleLayerFaceID]) == WHITE; // move edge to middle layer int direction = leftDelta > rightDelta ? 1 : -1; DoMove(whitePos.Face, direction); HandleStoneMiddleLayer(edge); if (rotBack) { DoMove(whitePos.Face, -direction); } } }
/// <summary> /// Bring einen weißen Kantenstein auf der gelben Seite in die richtige Position relativ zum Pivotstein. /// </summary> /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param> protected void HandleStoneYellowFace(EdgeStone edge) { if (edge.GetColorPosition(WHITE).Face != DOWN) { throw new ArgumentException("Die weiße Fläche des Kantensteins muss sich auf der gelben Seite befinden", nameof(edge)); } #if DEBUG Log.LogStuff("Handle stone yellow face\r\n\t" + edge.ToString()); #endif int delta = SolvingUtility.GetDelta(GetSecondColor(edge), edge.GetColorPosition(c => c != WHITE).Face, UP); // rotate the white face to insert the stone right to pivot DoMove(UP, delta - WhiteFaceOrientation); CubeFace faceToRot = edge.GetColorPosition(c => c != WHITE).Face; DoMove(faceToRot, 2); }
/// <summary> /// Bring einen weißen Kantenstein auf der mittleren Ebene in die richtige Position relativ zum Pivotstein. /// </summary> /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param> protected void HandleStoneMiddleLayer(EdgeStone edge) { if (Array.TrueForAll(MiddleLayerFaces, f => edge.GetColorPosition(WHITE).Face != f) || edge.GetColorPosition(WHITE).Tile == 1 || edge.GetColorPosition(WHITE).Tile == 7) { throw new ArgumentException("Der weiße Kantenstein muss sich auf der mittleren Ebene befinden", nameof(edge)); } #if DEBUG Log.LogStuff("Handle stone middle layer\r\n\t" + edge.ToString()); #endif int delta = SolvingUtility.GetDelta(GetSecondColor(edge), edge.GetColorPosition(c => c != WHITE).Face, UP); // rotate the white face to insert the stone right to pivot DoMove(UP, delta - WhiteFaceOrientation); Position secondPos = edge.GetColorPosition(c => c != WHITE); DoMove(secondPos.Face, secondPos.Tile == 3 ? 1 : -1); }
/// <summary> /// Gibt die Anzahl der Züge zurück, die benötigt wird, um den Kantenstein in die richtige Position zu bringen. /// </summary> /// <param name="edge">Der Kantenstein, der in die richtige Position gebracht werden soll</param> /// <returns></returns> protected int GetStoneRating(EdgeStone edge) { // on white face and same delta as pivot stone if (IsEdgeRight(edge)) { return(0); } Position whitePosition = edge.GetColorPosition(WHITE); int edgeDelta; // on white face and not same delta as pivot stone or on yellow face if (whitePosition.Face == UP || whitePosition.Face == DOWN) { // get delta of edge if (whitePosition.Face == DOWN) { edgeDelta = SolvingUtility.GetDelta( GetSecondColor(edge), // second color edge.GetColorPosition(c => c != WHITE).Face, // second color face color UP); // face to rotate } else { edgeDelta = GetDelta(edge); } // return 2 + moves white face count int sortingMoves = Math.Abs(SolvingUtility.NormalizeCount(edgeDelta - WhiteFaceOrientation, -1)); return(2 + sortingMoves); } // on middle layer else { switch (whitePosition.Tile) { // false orientated on white face case 1: edgeDelta = SolvingUtility.GetDelta( GetSecondColor(edge), //second color edge.GetColorPosition(WHITE).Face, // middle layer face with white side of edge UP); //face to rotate int edgePivotDelta = SolvingUtility.NormalizeCount(edgeDelta - WhiteFaceOrientation); // return number of moves return((edgePivotDelta % 2) * -1 + 3); // false orientated on yellow face case 7: // this position can always solved in 3 moves return(3); // on middle layer default: edgeDelta = SolvingUtility.GetDelta( edge.GetColors().First(c => c != WHITE), // second color edge.GetColorPosition(c => c != WHITE).Face, // second color face color UP); // face to rotate int sortingMoves = Math.Abs(SolvingUtility.NormalizeCount(edgeDelta - WhiteFaceOrientation, -1)); return(1 + sortingMoves); } } }