gusucode.com > 三维模仿源码程序 > 三维模仿源码程序/MathRubik2/solverbbf.m

    function [moves,n,nNOK]=solverbbf(cube,moves,N)
% SOLVERBBF - Solve Rubik's cube using bruteforce recursive algorithm
%    [moves,OK]=solverbbf([Cube[,N])
%  or
%    [moves,OK]=solverbbf(N[,Cube])
%   with Cube : the definition of the Cube (from Rubik).  If not given,
%            this is searched in a window.
%        N    : the maximum number of recursive calls (default 3)
%
% This function is also used recursively, with other input and output
% arguments.
% remark : in later Matlab versions, this can be done nicer (using subfunctions)
%   but this is made with Matlab 5.2, so it was choosen to work this way.
%   ("this way" means:
%        using persistent data
%        made in the main function (not available in subfunctions)
%   )

%!!!kan uitgebreid worden naar beperkt zoeken (enkel bepaalde delen, zoals 1 of 2 lagen)
%  ook eenvoudig uit te breiden naar fullcube (maar werd niet gedaan)!

persistent M CUBE0

if nargin<=2
	Cube=[];
	N=3;
	if nargin
		if isstruct(cube)
			Cube=cube;
		elseif isnumeric(cube)
			if numel(cube)==1
				N=cube;
			else
				error('Wrong input')
			end
		end
	end
	if nargin>1
		if isstruct(moves)
			Cube=moves;
		elseif isnumeric(moves)
			if numel(moves)==1
				N=moves;
			else
				error('Wrong input')
			end
		end
	end
	if isempty(Cube)
		Cube=FindRubikCube;
	end
	% Use of Rubik-moves to initialise move-arrays
	C0=InitCube(Cube);
	% set the right colors for the current cube
	for i=1:6
		C0.Color(i,C0.RotLayerCube(i,:)) = Cube.Color(i,C0.RotLayerCube(i,5));
	end
	C1=C0;
	C1.Color(:)=0;
	for i=1:6
		C1.Color(i,C0.RotLayerCube(i,[1:4 6:9]))=1;
	end
	if Cube.bFullCube
		for i=1:6
			iCube=Cube.iMid(i);
			z=Cube.iExtraFaces(i,:);
			C0.Color(z,C0.iMid(i))=C0.Color(C0.iMidInd(z));
			%C0.Color(Cube.iExtraFaces(i,:),iCube)=C0.Color(Cube.iExtraFaces(i,:),iCube);
			C1.Color(Cube.iExtraFaces(i,:),iCube)=1;
		end
	end
	iP=find(C1.Color);
	Nfield=length(iP);
	C1.Color(iP)=(1:Nfield)';
	M=zeros(Nfield,18);
	i=0;
	for Axe=1:3
		for Side=[-1 1]
			for Direction=[-1 1 2]
				i=i+1;
				if Direction<2
					C=RotateLayer([],C1,Axe,Side,Direction,0);
				else
					C=RotateLayer([],C,Axe,Side,1,0);
				end
				M(:,i)=C.Color(iP);
			end
		end
	end
	CUBE0=C0.Color(iP);
	moves=zeros(N,3);	% determines the maximum depth
	[moves,n,nNOK]=solverbbf(Cube.Color(iP),moves,0);
	if nNOK
		moves=zeros(0,3);
		n=false;
	else
		moves=moves(1:n,:);
		n=true;
	end
	return
end

nNOK=sum(cube~=CUBE0);
if nNOK==0
	n=N;
	return
end
nMoves=size(moves,1);
if N>=nMoves
	n=0;
	return
end
cube0=cube;
N=N+1;
if N<nMoves
	nD=3;
else
	nD=2;
end
for Axe=0:2
	moves(N,1)=Axe+1;
	iA=Axe*6;
	for Side=0:1
		moves(N,2)=Side*2-1;
		if N==1|moves(N-1)~=moves(N)|moves(N,2)>moves(N-1,2)
			iS=iA+Side*3;
			N1=N;
			for Direction=1:nD
				if Direction<3
					moves(N,3)=Direction*2-3;
				else
					N1=N+1;
					moves(N1,:)=moves(N,:);
				end
				%disp([N N1 Axe Side Direction moves(N,:)])
				cube(:)=cube0(M(:,iS+Direction));
				[moves,n,nNOK]=solverbbf(cube,moves,N1);
				if nNOK==0
					return
				end
			end
		end
	end
end