void Solve()
{
    for(int i=0;i<=15;i++)
    {
        for(int j=0;j<4;j++)
        {
            rect[j].width=r[j].width;
            rect[j].height=r[j].height;
        }
        for(int j=0;j<4;j++)
        {
            if(i&(1<<j))
            {
                swap(rect[j].width,rect[j].height);
            }
        }
        Solve1(), Solve2(), Solve3();
    }
}
Пример #2
0
int Solver::Search1(int twist, int flip, int choice, int depth)
{
	int cost, totalCost;
	int move;
	int power;
	int twist2, flip2, choice2;
	int result;

	// Compute cost estimate to phase 1 goal state
	cost = Phase1Cost(twist, flip, choice);	// h

	if (cost == 0)	// Phase 1 solution found...
	{
		solutionLength1 = depth;	// Save phase 1 solution length

		// We need an appropriately initialized cube in order
		//   to begin phase 2.  First, create a new cube that
		//   is a copy of the initial scrambled cube.  Then we
		//   apply the phase 1 move sequence to that cube.  The
		//   phase 2 search can then determine the initial
		//   phase 2 coordinates (corner, edge, and slice
		//   permutation) from this cube.
		//
		//   Note: No attempt is made to merge moves of the same
		//   face adjacent to the phase 1 & phase 2 boundary since
		//   the shorter sequence will quickly be found.

		KociembaCube phase2Cube = cube;
		for (int i = 0; i < solutionLength1; i++)
		{
			for (power = 0; power < solutionPowers1[i]; power++)
				phase2Cube.ApplyMove(solutionMoves1[i]);
		}
		// Invoke Phase 2
		(void)Solve2(phase2Cube);
	}

	// See if node should be expanded
	totalCost = depth + cost;	// g + h

	if (totalCost <= threshold1)	// Expand node
	{
		// If this happens, we should have found the
		//   optimal solution at this point, so we
		//   can exit indicating such.  Note: the first
		//   complete solution found in phase1 is optimal
		//   due to it being an addmissible IDA* search.
		if (depth >= minSolutionLength-1 || minSolutionLength < 24)
			return OPTIMUM_FOUND;

		for (move = Cube::Move::R; move <= Cube::Move::B; move++)
		{
			if (Disallowed(move, solutionMoves1, depth)) continue;

			twist2  = twist;
			flip2   = flip;
			choice2 = choice;

			solutionMoves1[depth] = move;
			for (power = 1; power < 4; power++)
			{
				solutionPowers1[depth] = power;
				twist2  = twistMoveTable[twist2][move];
				flip2   = flipMoveTable[flip2][move];
				choice2 = choiceMoveTable[choice2][move];
				nodes1++;
				// Apply the move
				if (result = Search1(twist2, flip2, choice2, depth+1))
						return result;
			}
		}
	}
	else	// Maintain minimum cost exceeding threshold
	{
		if (totalCost < newThreshold1)
			newThreshold1 = totalCost;
	}
	return NOT_FOUND;
}
Пример #3
0
int Solver::Search1(int twist, int flip, int choice, int depth)
{
	int cost, totalCost;
	int move;
	int power;
	int twist2, flip2, choice2;
	int result;

	cost = Phase1Cost(twist, flip, choice);

	if (cost == 0)
	{
		solutionLength1 = depth;
		
		KociembaCube phase2Cube = cube;
		for (int i = 0; i < solutionLength1; i++)
		{
			for (power = 0; power < solutionPowers1[i]; power++)
				phase2Cube.ApplyMove(solutionMoves1[i]);
		}

		(void)Solve2(phase2Cube);
		if(stopped) return ABORT;
	}

	totalCost = depth + cost;

	if (totalCost <= threshold1)
	{
		if (depth >= minSolutionLength-1)
			return OPTIMUM_FOUND;
		
		for (move = Cube::R; move <= Cube::B; move++)
		{
			if (Disallowed(move, solutionMoves1, depth)) continue;
				
			twist2  = twist;
			flip2   = flip;
			choice2 = choice;

			solutionMoves1[depth] = move;
			for (power = 1; power < 4; power++)
			{
				solutionPowers1[depth] = power;
				twist2  = twistMoveTable[twist2][move];
				flip2   = flipMoveTable[flip2][move];
				choice2 = choiceMoveTable[choice2][move];

				if ((result =
					Search1(twist2, flip2, choice2, depth+1)))
						return result;
			}
		}
	}
	else
	{
		if (totalCost < newThreshold1)
			newThreshold1 = totalCost;
	}
	return NOT_FOUND;
}