/* Ċ Ġ* ĠThis Ġfile Ġis Ġpart Ġof Ġcolor - cube - solver , Ġlicensed Ġunder Ġthe ĠMIT ĠLicense Ġ( MIT ). Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) ĠOct av ia ĠT og ami Ġ< https :// oct yl . net > Ċ Ġ* ĠCopyright Ġ( c ) Ġcontributors Ċ Ġ* Ċ Ġ* ĠPermission Ġis Ġhereby Ġgranted , Ġfree Ġof Ġcharge , Ġto Ġany Ġperson Ġobtaining Ġa Ġcopy Ċ Ġ* Ġof Ġthis Ġsoftware Ġand Ġassociated Ġdocumentation Ġfiles Ġ( the Ġ" Software "), Ġto Ġdeal Ċ Ġ* Ġin Ġthe ĠSoftware Ġwithout Ġrestriction , Ġincluding Ġwithout Ġlimitation Ġthe Ġrights Ċ Ġ* Ġto Ġuse , Ġcopy , Ġmodify , Ġmerge , Ġpublish , Ġdistribute , Ġsublicense , Ġand / or Ġsell Ċ Ġ* Ġcopies Ġof Ġthe ĠSoftware , Ġand Ġto Ġpermit Ġpersons Ġto Ġwhom Ġthe ĠSoftware Ġis Ċ Ġ* Ġfurnished Ġto Ġdo Ġso , Ġsubject Ġto Ġthe Ġfollowing Ġconditions : Ċ Ġ* Ċ Ġ* ĠThe Ġabove Ġcopyright Ġnotice Ġand Ġthis Ġpermission Ġnotice Ġshall Ġbe Ġincluded Ġin Ċ Ġ* Ġall Ġcopies Ġor Ġsubstantial Ġportions Ġof Ġthe ĠSoftware . Ċ Ġ* Ċ Ġ* ĠTHE ĠSOFTWARE ĠIS ĠPROVIDED Ġ" AS ĠIS ", ĠWITHOUT ĠWARRANTY ĠOF ĠANY ĠKIND , ĠEXPRESS ĠOR Ċ Ġ* ĠIMPLIED , ĠINCLUDING ĠBUT ĠNOT ĠLIMITED ĠTO ĠTHE ĠWARRANTIES ĠOF ĠMERCHANTABILITY , Ċ Ġ* ĠFITNESS ĠFOR ĠA ĠPARTICULAR ĠPURPOSE ĠAND ĠNONINFRINGEMENT . ĠIN ĠNO ĠEVENT ĠSHALL ĠTHE Ċ Ġ* ĠAUTHORS ĠOR ĠCOPYRIGHT ĠHOLDERS ĠBE ĠLIABLE ĠFOR ĠANY ĠCLAIM , ĠDAMAGES ĠOR ĠOTHER Ċ Ġ* ĠLIABILITY , ĠWHETHER ĠIN ĠAN ĠACTION ĠOF ĠCONTRACT , ĠTORT ĠOR ĠOTHERWISE , ĠARISING ĠFROM , Ċ Ġ* ĠOUT ĠOF ĠOR ĠIN ĠCONNECTION ĠWITH ĠTHE ĠSOFTWARE ĠOR ĠTHE ĠUSE ĠOR ĠOTHER ĠDEALINGS ĠIN Ċ Ġ* ĠTHE ĠSOFTWARE . Ċ Ġ*/ Ċ Ċ package Ġnet . oct yl . color cube . solver Ċ Ċ import Ġcom . tech sh room . un pl anned . core . util . time . Timer Ċ import Ġj opts imple . Option Exception Ċ import Ġj opts imple . Option Parser Ċ import Ġj opts imple . Option Set Ċ import Ġkotlinx . coroutines . Coroutine Name Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . channels . Channel Ċ import Ġkotlinx . coroutines . channels . Channel . Factory . UN LIMIT ED Ċ import Ġkotlinx . coroutines . launch Ċ import Ġnet . oct yl . color cube .* Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . random . Random Ċ import Ġkotlin . system . exit Process Ċ Ċ object ĠColor Cube Solver Runner Ġ{ ĊĊĠĠĠ Ġprivate Ġval ĠPARSER Ġ= ĠOption Parser () ĊĊĠĠĠ Ġprivate Ġval ĠHEL P Ġ= ĠPARSER . accept s All ( listOf (" h ", Ġ" help "), Ġ" Show Ġthis Ġhelp ") ĊĠĠĠĠĠĠĠ Ġ. for Help () ĊĊĠĠĠ Ġprivate Ġval ĠWAIT _ FOR _ CLICK Ġ= ĠPARSER . accept s All ( listOf (" c ", Ġ" wait - for - click "), Ġ" Wait Ġfor Ġa Ġscreen Ġclick Ġbetween Ġstages ") ĊĊĠĠĠ Ġprivate Ġval ĠSIZE Ġ= ĠPARSER . accept s All ( listOf (" s ", Ġ" size "), Ġ" Size Ġof Ġthe Ġcube , Ġmust Ġbe Ġodd ") ĊĠĠĠĠĠĠĠ Ġ. with Required Arg () ĊĠĠĠĠĠĠĠ Ġ. of Type ( Int :: class . java ) ĊĠĠĠĠĠĠĠ Ġ. defaults To ( 3 ) ĊĊĠĠĠ Ġprivate Ġval ĠS CR AM BLE _ TIMES Ġ= ĠPARSER . accept s All ( listOf (" scr amble - times "), Ġ" Number Ġof Ġtimes Ġto Ġrotate Ġwhen Ġsc ram bling ") ĊĠĠĠĠĠĠĠ Ġ. with Required Arg () ĊĠĠĠĠĠĠĠ Ġ. of Type ( Int :: class . java ) ĊĠĠĠĠĠĠĠ Ġ. defaults To ( 5 0 0 ) ĊĊĠĠĠ Ġprivate Ġval ĠMOVE _ SPEED Ġ= ĠPARSER . accept s All ( listOf (" m ", Ġ" move - speed "), Ġ" How Ġmany Ġframes Ġit Ġshould Ġtake Ġto Ġperform Ġone Ġmove ") ĊĠĠĠĠĠĠĠ Ġ. with Required Arg () ĊĠĠĠĠĠĠĠ Ġ. of Type ( Int :: class . java ) ĊĠĠĠĠĠĠĠ Ġ. defaults To ( 2 ) ĊĊĠĠĠ Ġprivate Ġval Ġapp Scope Ġ= ĠCor outine Scope ( Dispatch ers . Default Ġ+ ĠCor outine Name (" Application ")) ĊĊĠĠĠ Ġ@ Jvm Static ĊĠĠĠ Ġfun Ġmain ( args : ĠArray < String >) Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġopts : ĠOption Set ĊĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġopts Ġ= ĠPARSER . parse (* args ) ĊĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠOption Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . err . println ( e . message ) ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPARSER . print Help On ( System . err ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit Process ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġif Ġ( opts . has ( HELP )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠPARSER . print Help On ( System . err ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval ĠwaitFor Click Ġ= Ġopts . has ( WAIT _ FOR _ CLICK ) ĊĠĠĠĠĠĠĠ Ġval Ġcube Ġ= ĠColor Cube ( CC Array ( opts . size (), ĠSix Color . COLOR _ 1 ). apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( face Ġin ĠFace . values ()) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcolor Ġ= ĠSix Color . values ()[ face . ordinal ] ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ(( i , Ġj ) Ġin Ġface Points ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthis [ face , Ġi , Ġj ] Ġ= Ġcolor ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠĠĠĠĠ Ġval Ġmsg Channel Ġ= ĠChannel < Solver Message >( 5 ) ĊĠĠĠĠĠĠĠ Ġval Ġmoves Channel Ġ= ĠChannel < Cube Move >( 1 0 0 ) ĊĠĠĠĠĠĠĠ Ġval Ġclicks Channel Ġ= ĠChannel < Unit >( UN LIMIT ED ) ĊĊĠĠĠĠĠĠĠ Ġapp Scope . launch Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( waitFor Click ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclicks Channel . receive () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġstarting Cube Ġ= Ġscr amble ( cube , Ġopts . scr amble Times (), Ġmoves Channel ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( waitFor Click ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclicks Channel . receive () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Click Dis car der ( click s Channel ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsolver Ġ= ĠColor Cube Solver ( starting Cube , Ġmsg Channel , Ġmoves Channel ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġsolver . start () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ(! waitFor Click ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlaunch Click Dis car der ( click s Channel ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġval Ġdisplay Ġ= ĠDisplay ( cube , Ġopts . move Speed (), Ġmoves Channel , Ġclicks Channel ) ĊĠĠĠĠĠĠĠ Ġdisplay . run () ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġinline Ġfun Ġcheck User ( condition : ĠBoolean , Ġmessage : Ġ() Ġ-> ĠString ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ(! condition ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠSystem . err . println ( message ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexit Process ( 1 ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠOption Set . size (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsize Ġ= Ġvalue Of ( SIZE ) ĊĠĠĠĠĠĠĠ Ġcheck User ( size Ġ>= Ġ 3 ) Ġ{ Ġ" Size Ġmust Ġbe Ġgreater Ġthan Ġor Ġequal Ġto Ġ 3 ." Ġ} ĊĠĠĠĠĠĠĠ Ġcheck User ( size Ġ% Ġ 2 Ġ== Ġ 1 ) Ġ{ Ġ" Size Ġmust Ġbe Ġodd ." Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġsize ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠOption Set . scr amble Times (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġscr amble Times Ġ= Ġvalue Of ( SCR AM BLE _ TIMES ) ĊĠĠĠĠĠĠĠ Ġcheck User ( scr amble Times Ġ>= Ġ 0 ) Ġ{ Ġ" Scr amble Ġtimes Ġmust Ġbe Ġgreater Ġthan Ġor Ġequal Ġto Ġ 0 ." Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġscr amble Times ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun ĠOption Set . move Speed (): ĠInt Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġmove Speed Ġ= Ġvalue Of ( MOVE _ SPEED ) ĊĠĠĠĠĠĠĠ Ġcheck User ( move Speed Ġ> Ġ 0 ) Ġ{ Ġ" Move Ġspeed Ġmust Ġbe Ġgreater Ġthan Ġ 0 ." Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġmove Speed ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġlaunch Click Dis car der ( click s Channel : ĠChannel < Unit >) Ġ{ ĊĠĠĠĠĠĠĠ Ġapp Scope . launch Ġ{ Ġwhile Ġ( true ) Ġclicks Channel . receive () Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġsuspend Ġfun Ġscr amble ( ĊĠĠĠĠĠĠĠ Ġinitial Cube : ĠSix Cube , ĊĠĠĠĠĠĠĠ Ġrot ations : ĠInt , ĊĠĠĠĠĠĠĠ Ġmoves Channel : ĠChannel < Cube Move >, ĊĠĠĠĠĠĠĠ Ġrng : ĠRandom Ġ= ĠRandom ( Timer . getInstance (). getValue ( TimeUnit . MILLISECONDS )) ĊĠĠĠ Ġ): ĠSix Cube Ġ{ ĊĠĠĠĠĠĠĠ Ġvar Ġcube Ġ= Ġinitial Cube ĊĠĠĠĠĠĠĠ Ġvar Ġlast Face : ĠFace ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġvar Ġlast Direction : ĠRotation Direction ? Ġ= Ġnull ĊĠĠĠĠĠĠĠ Ġfor Ġ( x Ġin Ġ( 0 Ġuntil Ġrot ations )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġface : ĠFace ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġdirection : ĠRotation Direction ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdo Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġface Ġ= ĠFace . values (). random ( rng ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdirection Ġ= ĠRotation Direction . values (). random ( rng ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġwhile Ġ( face Ġ== Ġlast Face Ġ&& Ġdirection Ġ== Ġlast Direction ?. op pos ite ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Face Ġ= Ġface ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlast Direction Ġ= Ġdirection ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġmoves Channel . send ( Rotate ( face , Ġdirection )) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcube Ġ= Ġcube . rotate ( face , Ġdirection ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġreturn Ġcube ĊĠĠĠ Ġ} Ċ Ċ } Ċ