| Category: | Fun |
| Author/Contact Info | Ido Trivizki |
| Description: | Solves rubik's cube. It does it in about 100 moves. (103 is the average.) Which is quiet a lot, I might get it lower someday.. Notice my little ugly japh commented there;) |
#!perl -w
use strict;
use Tk;
use Tk::ROText;
use Data::Dumper;
$Data::Dumper::Terse=1;
my $rmw=new MainWindow(-title=>q/Rubik's Cube Solver/);
my $mw=$rmw->Frame->pack(-side=>'left');
my $out=$rmw->Frame->pack;
my $colors=$mw->Frame->pack;
my $cubes=$mw->Frame->pack;
my $control=$mw->Frame->pack;
my($button,@colors,@radios,@sides,@steps)=0;
my $resetcolor=$mw->cget('bg');
my @cvalues=('red','white','orange','yellow','blue','green');
my @ccounts=(1)x6;
my @names=('Front','Top','Left','Right','Bottom','Back');
$colors->Label(-text=>'Select your cube colors: ',-font=>'-*-*-bold-*-
+*-*-*-260-*-*-*-*-*-*-')->grid(-row=>1,-col=>1,-columnspan=>12);
$colors->Label(-text=>'(Slice\'s color is determined by the color of i
+ts center.)')->grid(-row=>2,-col=>1,-columnspan=>12);
for my $num(0..5){
$colors->Label(-text=>"$names[$num]:")->grid(-row=>3,-col=>$num*2+1,-c
+olumnspan=>2);
push @radios,$colors->Radiobutton(-variable=>\$button,-value=>$num)->g
+rid(-row=>4,-col=>$num*2+1);
push @colors,$colors->Button(-bg=>$cvalues[$num],-activebackground=>$c
+values[$num],-width=>5,-border=>3,-command=>sub{
if(my $new=$mw->chooseColor()){
$cvalues[$num]=$new;
$colors[$num]->configure(-bg=>$new,-activebackground=>$new);
$sides[$num][1][1][0]->configure(-bg=>$new,-activebackground=>
+$new);
for(0..5){
for my $in (0..8){
$sides[$_][$in/3][$in%3][0]->configure(-bg=>$new,-acti
+vebackground=>$new) if defined($sides[$_][$in/3][$in%3][1]) and $side
+s[$_][$in/3][$in%3][1]==$num;
}
}
}
})->grid(-row=>4,-col=>$num*2+2);
$colors->Label(-textvar=>\$ccounts[$num])->grid(-row=>5,-col=>$num*2+2
+);
}
sub createcube{
my($frame,$side)=(shift,shift);
for my $m (0..8){
$sides[$side][$m/3][$m%3][1]=$side if $m==4;
$sides[$side][$m/3][$m%3][0]=$$frame->Button(-width=>3,$m==4?
+(-bg=>$cvalues[$side],-activebackground=>$cvalues[$side]):(-command=>
+sub{
$sides[$side][$m/3][$m%3][0]->configure(-bg=>$cvalues[$but
+ton],-activebackground=>$cvalues[$button]);
defined($sides[$side][$m/3][$m%3][1]) and $ccounts[$sides[
+$side][$m/3][$m%3][1]]--;
$sides[$side][$m/3][$m%3][1]=$button;
$ccounts[$button]++
}))->grid(-row=>$m/3+1,-column=>$m%3+1);
}
}
$cubes->Label(-text=>'Draw your cube: ',-font=>'-*-*-bold-*-*-*-*-260-
+*-*-*-*-*-*-')->grid(-row=>1,-col=>1,-columnspan=>4);
my $top=$cubes->Frame()->grid(-row=>2,-col=>2);
$top->Label(-text=>"Top:",-font=>'-*-*-bold-*-*-*-*-200-*-*-*-*-*-*-')
+->grid(-row=>1,-col=>2,-columnspan=>3);
$top->Label(-text=>'Back',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')-
+>grid(-row=>2,-col=>2,-columnspan=>3);
$top->Label(-text=>'Left',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')-
+>grid(-row=>3,-col=>1);
$top->Label(-text=>'Right',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')
+->grid(-row=>3,-col=>3);
$top->Label(-text=>'Front',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')
+->grid(-row=>4,-col=>2,-columnspan=>3);
createcube(\($top->Frame->grid(-row=>3,-col=>2)),1);
my $left=$cubes->Frame()->grid(-row=>3,-col=>1);
$left->Label(-text=>"Left:",-font=>'-*-*-bold-*-*-*-*-200-*-*-*-*-*-*-
+',-justify=>'left')->grid(-row=>1,-col=>2,-columnspan=>3);
$left->Label(-text=>'Top',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')-
+>grid(-row=>2,-col=>2,-columnspan=>3);
$left->Label(-text=>'Back',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')
+->grid(-row=>3,-col=>1);
$left->Label(-text=>'Front',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-'
+)->grid(-row=>3,-col=>3);
$left->Label(-text=>'Bottom',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-
+')->grid(-row=>4,-col=>2,-columnspan=>3);
createcube(\($left->Frame->grid(-row=>3,-col=>2)),2);
my $front=$cubes->Frame()->grid(-row=>3,-col=>2);
$front->Label(-text=>"Front:",-font=>'-*-*-bold-*-*-*-*-200-*-*-*-*-*-
+*-')->grid(-row=>1,-col=>2,-columnspan=>3);
$front->Label(-text=>'Top',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')
+->grid(-row=>2,-col=>2,-columnspan=>3);
$front->Label(-text=>'Left',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-'
+)->grid(-row=>3,-col=>1);
$front->Label(-text=>'Right',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-
+')->grid(-row=>3,-col=>3);
$front->Label(-text=>'Bottom',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*
+-')->grid(-row=>4,-col=>2,-columnspan=>3);
createcube(\($front->Frame->grid(-row=>3,-col=>2)),0);
my $right=$cubes->Frame()->grid(-row=>3,-col=>3);
$right->Label(-text=>"Right:",-font=>'-*-*-bold-*-*-*-*-200-*-*-*-*-*-
+*-',-justify=>'left')->grid(-row=>1,-col=>2,-columnspan=>3);
$right->Label(-text=>'Top',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')
+->grid(-row=>2,-col=>2,-columnspan=>3);
$right->Label(-text=>'Front',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-
+')->grid(-row=>3,-col=>1);
$right->Label(-text=>'Back',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-'
+)->grid(-row=>3,-col=>3);
$right->Label(-text=>'Bottom',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*
+-')->grid(-row=>4,-col=>2,-columnspan=>3);
createcube(\($right->Frame->grid(-row=>3,-col=>2)),3);
my $back=$cubes->Frame()->grid(-row=>3,-col=>4);
$back->Label(-text=>"Back:",-font=>'-*-*-bold-*-*-*-*-200-*-*-*-*-*-*-
+')->grid(-row=>1,-col=>2,-columnspan=>3);
$back->Label(-text=>'Top',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')-
+>grid(-row=>2,-col=>2,-columnspan=>3);
$back->Label(-text=>'Right',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-'
+)->grid(-row=>3,-col=>1);
$back->Label(-text=>'Left',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-')
+->grid(-row=>3,-col=>3);
$back->Label(-text=>'Bottom',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-
+')->grid(-row=>4,-col=>2,-columnspan=>3);
createcube(\($back->Frame->grid(-row=>3,-col=>2)),5);
my $bottom=$cubes->Frame()->grid(-row=>4,-col=>2);
$bottom->Label(-text=>"Bottom:",-font=>'-*-*-bold-*-*-*-*-200-*-*-*-*-
+*-*-',-justify=>'left')->grid(-row=>1,-col=>2,-columnspan=>3);
$bottom->Label(-text=>'Front',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*
+-')->grid(-row=>2,-col=>2,-columnspan=>3);
$bottom->Label(-text=>'Left',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-
+')->grid(-row=>3,-col=>1);
$bottom->Label(-text=>'Right',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*
+-')->grid(-row=>3,-col=>3);
$bottom->Label(-text=>'Back',-font=>'-*-*-*-*-*-*-*-140-*-*-*-*-*-*-*-
+')->grid(-row=>4,-col=>2,-columnspan=>3);
createcube(\($bottom->Frame->grid(-row=>3,-col=>2)),4);
my $twin=$out->Scrolled('ROText',-height=>40,-width=>50,-scrollbars=>'
+oe')->pack;
$control->Button(-text=>'Solve',-command=>\&sendcube)->grid(-row=>1,-c
+ol=>1);
$control->Checkbutton(-text=>'Show Status',-variable=>\(my $showstatus
+))->grid(-row=>2,-col=>2);
my $statuscube;
$control->Button(-text=>'Show next step',-command=>sub{my $step=shift
+@steps or return;$twin->insert('end',$$step[1]);$twin->see('end');mak
+emove($statuscube,$$step[0]);updateview($statuscube) if $showstatus})
+->grid(-row=>1,-col=>2);
$control->Button(-text=>'Show all steps',-command=>sub{$twin->insert('
+end',$$_[1]) while($_=shift @steps)})->grid(-row=>1,-col=>3);
$control->Button(-text=>'Reset',-command=>sub{for my $side(@sides){@cc
+ounts[0..5]=(1)x6;for(0..3,5..8){$$side[$_/3][$_%3][0]->configure(-bg
+=>$resetcolor,-activebackground=>$resetcolor);undef $$side[$_/3][$_%3
+][1];}}})->grid(-row=>1,-col=>4);
$control->Button(-text=>'Random Cube',-command=>sub{updateview(getrand
+cube());sendcube()})->grid(-row=>1,-col=>5);
my $deg=pack 'B*','10110000';
my %conv=(F=>'front',D=>'bottom',B=>'back',R=>'right',L=>'left',U=>'to
+p',r=>"90$deg clockwise",a=>"90$deg anticlockwise",d=>"180$deg");
sub sendcube{
my($side,$cube)=0;
for(['F','U'],['U','B'],['L','U'],['R','U'],['D','F'],['B','U']){
settrans(@$_);
my $lcube=0;
for my $mc('FLU','FU','FRU','FL','F','FR','DFL','DF','DFR'){
defined($sides[$side][$lcube/3][$lcube%3][1]) and $cube->{
+jss($mc)}{$$_[0]}=$sides[$side][$lcube/3][$lcube%3][1]+1;
$lcube++;
}
$side++;
}
$statuscube=eval Dumper $cube;
$twin->delete('1.0','end');
(my $rc,@steps)=solve($cube);
if($rc==0){
$twin->insert('end',">>The input cube isn't valid. (Might be a
+ color used more or less than 9 times, or a sub-cube containing the s
+ame color twice or two opposite colors.)\n");
}elsif($rc==-1){
$twin->insert('end',">>The input cube isn't valid. (Probably w
+as taken apart and put together incorrectly.)\n");
}
$rc and $twin->insert('end','>>'.@steps." moves.\n");
my $i;
for(@steps){
my($slice,$type)=split //;
$_=[$_,++$i.". Turn the *$conv{$slice}* slice $conv{$type||'r'
+}.\n"];
}
}
sub updateview{
my $cube=shift;
my $side=0;
@ccounts[0..5]=(9)x6;
for(['F','U'],['U','B'],['L','U'],['R','U'],['D','F'],['B','U']){
settrans(@$_);
my $lcube=0;
for my $mc('FLU','FU','FRU','FL','F','FR','DFL','DF','DFR'){
$sides[$side][$lcube/3][$lcube%3][1]=$cube->{jss($mc)}{$$_
+[0]}-1;
$lcube++;
}
$side++;
}
for(0..5){
for my $in (0..8){
$sides[$_][$in/3][$in%3][0]->configure(-bg=>$cvalues[$side
+s[$_][$in/3][$in%3][1]],-activebackground=>$cvalues[$sides[$_][$in/3]
+[$in%3][1]]);
}
}
}
sub getrandcube{
my $cube={
FLU=>{F=>1,L=>3,U=>2},
FU=>{F=>1,U=>2},
FRU=>{F=>1,R=>4,U=>2},
FL=>{F=>1,L=>3},
F=>{F=>1},
FR=>{F=>1,R=>4},
DFL=>{D=>5,F=>1,L=>3},
DF=>{D=>5,F=>1},
DFR=>{D=>5,F=>1,R=>4},
LU=>{L=>3,U=>2},
U=>{U=>2},
RU=>{R=>4,U=>2},
L=>{L=>3},
R=>{R=>4},
DL=>{D=>5,L=>3},
D=>{D=>5},
DR=>{D=>5,R=>4},
BLU=>{B=>6,L=>3,U=>2},
BU=>{B=>6,U=>2},
BRU=>{B=>6,R=>4,U=>2},
BL=>{B=>6,L=>3},
B=>{B=>6},
BR=>{B=>6,R=>4},
BDL=>{B=>6,D=>5,L=>3},
BD=>{B=>6,D=>5},
BDR=>{B=>6,D=>5,R=>4},
};
makemove($cube,$_) for map +('F','Fa','Fd','R','Ra','Rd','L','La',
+'Ld','B','Ba','Bd','U','Ua','Ud','D','Da','Dd')[rand 18],0..60;
return $cube;
}
#JAPH
#my @jpah=([[0,7]],[[0,0,1,2,3,5,6,8]],[[2,0,1,3,6],[3,7,8]],[[3,0,1,2
+,3,5,6],[5,1,7]],[[2,2,5,7,8]],[[5,0,2,3,5,6,8]]);
#for(1..6){$button=$_;for(@{shift @jpah}){my $s=shift @$_;for(@$_){$si
+des[$s][$_/3][$_%3][0]->invoke()}}}
{
my %sides=(
F=>['U','R','D','L',{U=>0,R=>1,D=>2,L=>3},'B'],
R=>['U','B','D','F',{U=>0,B=>1,D=>2,F=>3},'L'],
B=>['U','L','D','R',{U=>0,L=>1,D=>2,R=>3},'F'],
L=>['U','F','D','B',{U=>0,F=>1,D=>2,B=>3},'R'],
U=>['B','R','F','L',{B=>0,R=>1,F=>2,L=>3},'D'],
D=>['B','L','F','R',{B=>0,L=>1,F=>2,R=>3},'U'],
);
my $types={r=>1,a=>-1,d=>2};
my($cube,%trans,@moves);
sub makemove{
my($cube,$side,$type)=(shift,split //,shift);
$type=$types->{$type||'r'};
my $copy=eval Dumper $cube;
for my $key(grep index($_,$side)+1,keys %$cube){
%{$cube->{join '',sort map +($side eq $_)?$_:$sides{$side}
+[($sides{$side}[4]{$_}+$type)%4],split //,$key}}=map +(/\d/ or $side
+eq $_)?$_:$sides{$side}[($sides{$side}[4]{$_}+$type)%4],%{$copy->{$ke
+y}};
}
}
sub checkvalid{
my @colors;
for(map values %{$cube->{$_}},keys %$cube){
defined($_)?$colors[$_-1]++:return 0;
}
return 0 unless @colors==6;
for(@colors){
return 0 unless $_==9;
}
return 1;
}
sub settrans{
@trans{'F','U'}=(shift||'F',shift||'U');
$trans{R}=$sides{$trans{F}}[($sides{$trans{F}}[4]{$trans{U}}+1
+)%4];
@trans{'B','D','L'}=map $sides{$_}[5],@trans{'F','U','R'};
return 1;
}
sub trans{
my @totr=@_;
s/(.)/$trans{$1}/ for @totr;
return @totr;
}
sub makemoves{
my @new=trans(@_);
push @moves,@new;
makemove($cube,$_) for @new;
}
sub findloc{
my $wanted=join '',sort map $cube->{$_}{$_},split //,shift;
for(keys %$cube){
return $_ if join('',sort values %{$cube->{$_}}) == $wante
+d;
}
}
sub correct{
my $check=shift;
for(split //,$check){
return 0 unless $cube->{$_}{$_}==$cube->{$check}{$_};
}
return 1;
}
sub jss{
my @ret;
push @ret,join '',sort +trans(split//,shift) for @_;
wantarray?@ret:$ret[0];
}
sub checkall{
for(keys %$cube){
return 0 unless correct($_);
}
return 1;
}
sub optimize{
my $done;
do{$done=0;
for(my $i=1;$i<=$#moves;$i++){
next unless substr($moves[$i],0,1) eq substr($moves[$i-1],0,1)
+;
my($type1,$type0)=(substr($moves[$i],1,1),substr($moves[$i-1],
+1,1));
for($type1,$type0){
$_=$types->{$_||'r'};
}
if($type1+$type0==0 or $type1+$type0==4){
splice @moves,$i-1,2;
$done++;
}elsif($type1==$type0){
splice @moves,$i-1,2,substr($moves[$i],0,1).'d';
$done++;
}else{
if(abs($type1)==1 and $type0==2){
splice @moves,$i-1,2,substr($moves[$i],0,1).(undef,'a'
+,'')[$type1];
$done++;
}elsif($type1==2 and abs($type0)==1){
splice @moves,$i-1,2,substr($moves[$i],0,1).(undef,'a'
+,'')[$type0];
$done++;
}
}
}}until not $done;
}
sub solve{
$cube=shift;
@moves=();
checkvalid() or return 0;
my %locs;
my @topedges=(['FU','F','U'],['LU','L','U'],['RU','R','U'],['B
+U','B','U']);
while(@topedges){
my $loc=findloc(my $cur=$topedges[0][0]);
$locs{join '',map "$_$cube->{$loc}{$_}",sort keys %{$cube-
+>{$loc}}}++ and return 0;
settrans(@{$topedges[0]}[1,2]);
if($loc eq $cur){
unless(correct($cur)){
makemoves('F');
}else{shift @topedges;%locs=();}
}elsif($loc eq jss('DF')){
makemoves($cube->{$loc}{$trans{D}}==$cube->{U}{U}?'Fd'
+:'Fa')
}elsif($loc eq jss('DR')){
makemoves('Da')
}elsif($loc eq jss('DL')){
makemoves('D')
}elsif($loc eq jss('BD')){
makemoves('Dd')
}elsif($loc eq jss('FR')){
makemoves($cube->{$loc}{$trans{R}}==$cube->{U}{U}?'Fa'
+:('Ua','R','U'))
}elsif($loc eq jss('FL')){
makemoves($cube->{$loc}{$trans{L}}==$cube->{U}{U}?'F':
+('U','La','Ua'))
}elsif($loc eq jss('BR')){
makemoves($cube->{$loc}{$trans{R}}==$cube->{U}{U}?('Ud
+','B','Ud'):('Ua','Ra','U'))
}elsif($loc eq jss('BL')){
makemoves($cube->{$loc}{$trans{L}}==$cube->{U}{U}?('Ud
+','Ba','Ud'):('U','L','Ua'))
}elsif($loc eq jss('BU')){
makemoves('B')
}elsif($loc eq jss('LU')){
makemoves('L')
}elsif($loc eq jss('RU')){
makemoves('R')
}else{return 0}
}
%locs=();
my @topcorners=(['FRU','F','U'],['BRU','R','U'],['BLU','B','U'
+],['FLU','L','U']);
while(@topcorners){
{my $t;
@topcorners=map $_->[0],sort {$a->[1] <=> $b->[1]} map [$_
+,(($t=findloc($_->[0])) eq $_->[0])?0:($t=~/D/ and $cube->{$t}{D}!=$c
+ube->{U}{U})?1:($t=~/U/)?2:3],@topcorners;
}
my $loc=findloc(my $cur=$topcorners[0][0]);
$locs{join '',map "$_$cube->{$loc}{$_}",sort keys %{$cube-
+>{$loc}}}++ and return 0;
settrans(@{$topcorners[0]}[1,2]);
if($loc eq $cur){
unless(correct($cur)){
makemoves($cube->{$cur}{$trans{R}}==$cube->{U}{U}?
+('Ra','Da','R'):('F','D','Fa'))
}else{shift @topcorners;%locs=()}
}elsif($loc eq jss('DFR')){
makemoves($cube->{$loc}{$trans{F}}==$cube->{U}{U}?('F'
+,'D','Fa'):$cube->{$loc}{$trans{R}}==$cube->{U}{U}?('Ra','Da','R'):('
+Ra','Dd','R'));
}elsif($loc eq jss('DFL')){
makemoves($cube->{$loc}{$trans{F}}==$cube->{U}{U}?'D':
+$cube->{$loc}{$trans{L}}==$cube->{U}{U}?('Ra','D','R'):correct(jss('F
+LU'))?'D':('Fa','D','F'))
}elsif($loc eq jss('BDR')){
makemoves($cube->{$loc}{$trans{R}}==$cube->{U}{U}?'Da'
+:$cube->{$loc}{$trans{B}}==$cube->{U}{U}?('F','Da','Fa'):correct(jss(
+'BRU'))?'Da':('R','Da','Ra'))
}elsif($loc eq jss('BDL')){
makemoves($cube->{$loc}{$trans{L}}==$cube->{U}{U}?'Da'
+:$cube->{$loc}{$trans{B}}==$cube->{U}{U}?'D':correct(jss('BLU'))?'Dd'
+:('La','D','L'))
}elsif($loc eq jss('FLU')){
makemoves($cube->{$loc}{$trans{L}}==$cube->{U}{U}?('L'
+,'Ra','D','R','La'):('L','D','La'))
}elsif($loc eq jss('BRU')){
makemoves($cube->{$loc}{$trans{B}}==$cube->{U}{U}?('Ba
+','F','Da','Fa','B'):$cube->{$loc}{$trans{R}}==$cube->{U}{U}?('R','Dd
+','Ra'):('Ba','Da','B'))
}elsif($loc eq jss('BLU')){
makemoves($cube->{$loc}{$trans{L}}==$cube->{U}{U}?('La
+','Da','L'):$cube->{$loc}{$trans{B}}==$cube->{U}{U}?('B','D','Ba'):('
+La','Dd','L'))
}else{return 0}
}
%locs=();
my @middleedges=(['FR','F','U'],['BR','R','U'],['BL','B','U'],
+['FL','L','U']);
while(@middleedges){
{my $t;
@middleedges=map $_->[0],sort {$a->[1] <=> $b->[1]} map [$
+_,(($t=findloc($_->[0])) eq $_->[0])?0:($t=~/D/)?1:2],@middleedges;
}
my $loc=findloc(my $cur=$middleedges[0][0]);
$locs{join '',map "$_$cube->{$loc}{$_}",sort keys %{$cube-
+>{$loc}}}++ and return 0;
settrans(@{$middleedges[0]}[1,2]);
if($loc eq $cur){
unless(correct($cur)){
makemoves('Ra','D','R','D','F','Da','Fa');
}else{shift @middleedges;%locs=();}
}elsif($loc eq jss('DR')){
makemoves($cube->{$loc}{$trans{R}}==$cube->{$trans{F}}
+{$trans{F}}?'Dd':'D')
}elsif($loc eq jss('DF')){
makemoves($cube->{$loc}{$trans{F}}==$cube->{$trans{F}}
+{$trans{F}}?'Da':'Dd')
}elsif($loc eq jss('DL')){
makemoves($cube->{$loc}{$trans{L}}==$cube->{$trans{F}}
+{$trans{F}}?('Ra','D','R','D','F','Da','Fa'):'Da')
}elsif($loc eq jss('BD')){
makemoves($cube->{$loc}{$trans{B}}==$cube->{$trans{R}}
+{$trans{R}}?('F','Da','Fa','Da','Ra','D','R'):'D')
}elsif($loc eq jss('FL')){
makemoves('Fa','D','F','D','L','Da','La')
}elsif($loc eq jss('BR')){
makemoves('Ba','D','B','D','R','Da','Ra')
}elsif($loc eq jss('BL')){
makemoves('La','D','L','D','B','Da','Ba')
}else{return 0}
}
my @down=map +(/([^D])/)[0],grep $cube->{$_}{D}==$cube->{D}{D}
+,'BD','DL','DF','DR';
unless(@down){
settrans('F','D');
makemoves('B','U','L','Ua','La','Ba','U','B','L','U','La',
+'Ua','Ba');
}elsif(@down==2){
if($down[0] eq $sides{$down[1]}[5]){
settrans($sides{$down[0]}[1],'D');
makemoves('B','L','U','La','Ua','Ba');
}else{
my $bigger=$sides{D}[4]{$down[1]}>$sides{D}[4]{$down[0
+]};
$bigger^=1 if $down[$bigger] eq 'R' and $down[$bigger^
+1] eq 'B';
settrans($down[$bigger],'D');
makemoves('B','U','L','Ua','La','Ba');
}
}
my(@corr,$do,$f)=map +(/([^D])/)[0],grep correct($_),'BD','DL'
+,'DF','DR';
if(not @corr){
if($cube->{BD}{B}+$cube->{DF}{F}==7){
unless(findloc('DR')=~/$sides{(findloc('BD')=~m!([
+^D])!)[0]}[3]/){
settrans($cube->{BD}{B}==$cube->{R}{R}?'B':'R'
+,'D');
makemoves('Rd','Dd','Bd','D','Ld','Fd','Ld','F
+d','Ld','Fd','Da','Bd','Dd','Rd');
}else{settrans('F','D');makemoves('U') until corre
+ct('BD')}
}else{
my($anycorrect,$wh)=sub{for('BD','DL','DF','DR'){r
+eturn $_ if correct($_)}};
settrans('F','D');
do{makemoves('U')} until $wh=$anycorrect->();
settrans($sides{($wh=~/([^D])/)[0]}[3],'D');
$do=1;
}
}elsif(@corr==2){
if($corr[0] eq $sides{$corr[1]}[5]){
settrans($corr[0],'D');
makemoves('Ua','Rd','Dd','Bd','D','Ld','Fd','Ld','Fd',
+'Ld','Fd','Da','Bd','Dd','Rd');
}else{
my $bigger=$sides{D}[4]{$corr[1]}>$sides{D}[4]{$corr[0
+]};
$bigger^=1 if $corr[$bigger] eq 'R' and $corr[$bigger^
+1] eq 'B';
settrans($corr[$bigger],'D');
makemoves('Ua');
$do=1;
}
}elsif(@corr==1){
settrans($sides{$corr[0]}[3],'D');
$do=1;
}
makemoves('Rd','Da',$cube->{jss('FU')}{$trans{F}}==$cube->{$tr
+ans{B}}{$trans{B}}?('Ud','Ra','L','Fd','R','La'):('Ra','L','Fd','R','
+La','Ud'),'D','Rd') if $do;
my @orie=grep findloc($$_[0]) eq $$_[0],['DFR'=>'R'],['DFL'=>'
+F'],['BDR'=>'B'],['BDL'=>'L'];
if(@orie==1){
settrans($orie[0][1],'D');
makemoves(findloc(jss('BLU')) eq jss('FLU')?('La','U',
+'R','Ua','L','U','Ra','Ua'):('U','R','Ua','La','U','Ra','Ua','L'));
}elsif(not @orie){
if(findloc('DFR') eq 'BDL'){
settrans('F','D');
makemoves('Ra','Bd','F','R','Fa','Ra','F','R','Fa','Ra
+','F','R','Fa','Ra','Bd','R');
}else{
settrans(findloc('DFR') eq 'DFL'?'F':'R','D');
makemoves('B','L','U','La','Ua','L','U','La','Ua','L',
+'U','La','Ua','Ba');
}
}
settrans('F','D');
for(0..3){
next if $cube->{jss('FRU')}{$trans{U}}==$cube->{$trans{U}}
+{$trans{U}};
makemoves($cube->{jss('FRU')}{$trans{F}}==$cube->{D}{D}?('
+F','D','Fa','Da','F','D','Fa','Da'):('D','F','Da','Fa','D','F','Da','
+Fa'));
}continue{makemoves('U')}
optimize();
checkall() or my $rc=-1;
return ($rc||1,@moves);
}
}
MainLoop;
|
|
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Rubik's Cube Solver
by Ido (Hermit) on Aug 02, 2002 at 01:38 UTC | |
|
Re: Rubik's Cube Solver
by hossman (Prior) on Aug 01, 2002 at 21:46 UTC | |
by BorgCopyeditor (Friar) on Aug 02, 2002 at 01:41 UTC | |
|
Re: Rubik's Cube Solver
by PodMaster (Abbot) on Aug 01, 2002 at 15:51 UTC | |
by jsprat (Curate) on Aug 01, 2002 at 17:29 UTC | |
by Ovid (Cardinal) on Aug 01, 2002 at 17:01 UTC |