-- XLIB_RUBIK_RUBIK.ADA -- -- Abstract: Solves a 3x3 Rubik Cube within a Window -- --*********************************************************************** -- * -- * -- This software was written by Bevin Brett, of Digital Equipment * -- Corporation. * -- * -- Digital assumes no responsibility AT ALL for the use or reliability* -- of this software. * -- * -- Redistribution and use in source and binary forms are permitted * -- provided that the above copyright notice and this paragraph are * -- duplicated in all such forms and that any documentation, * -- advertising materials, and other materials related to such * -- distribution and use acknowledge that the software was developed * -- by Digital Equipment Corporation. The name of Digital Equipment * -- Corporation may not be used to endorse or promote products derived * -- from this software without specific prior written permission. * -- * -- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * -- IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * -- WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.* -- * --*********************************************************************** -- modified for use with Adabindx 10.8.1997 -- Hans-Frieder Vogt (vogt@ilaws6.luftfahrt.uni-stuttgart.de) with TEXT_IO; use TEXT_IO; with Ada.Numerics.Discrete_Random, Ada.Calendar; with COLORS, UNITS, RUBIKS_CUBE, DRAW_RUBIKS_CUBE, GRAPHICS_WINDOW_MANAGER; use COLORS, UNITS, RUBIKS_CUBE; procedure XLIB_RUBIK is INIT_RC : RUBIKS_CUBE_TYPE; RC : RUBIKS_CUBE_TYPE; WHOLE_SPIN : RADIANS := 0.0; package AXIS_Random is new Ada.Numerics.Discrete_Random (AXIS_TYPE); package LEVEL_Random is new Ada.Numerics.Discrete_Random (LEVEL_TYPE); package TURN_Random is new Ada.Numerics.Discrete_Random (TURN_TYPE); AXIS_Gen : AXIS_Random.Generator; LEVEL_Gen : LEVEL_Random.Generator; TURN_Gen : TURN_Random.Generator; Secs : constant Ada.Calendar.Day_Duration := Ada.Calendar.Seconds (Ada.Calendar.Clock); End_No_Error : exception; procedure PUT(RC : RUBIKS_CUBE_TYPE; A : AXIS_TYPE := AXIS_TYPE'first; L : LEVEL_TYPE := LEVEL_TYPE'first; T : RADIANS := 0.0) is begin DRAW_RUBIKS_CUBE(RC,A,L,T,WHOLE_SPIN); WHOLE_SPIN := WHOLE_SPIN + 0.01; GRAPHICS_WINDOW_MANAGER.START_NEW_PICTURE; if Graphics_Window_Manager.End_Requested then raise End_No_Error; end if; end; procedure PUT_INTERVENING( RC : RUBIKS_CUBE_TYPE; A : AXIS_TYPE; L : LEVEL_TYPE; T : TURN_TYPE) is begin for PARTIAL in 1..9 loop PUT(RC,A,L, RADIANS( FLOAT(PARTIAL)/10.0 * FLOAT(BOOLEAN'pos(T=CLOCKWISE)*2-1) * 1.55) ); end loop; end; begin GRAPHICS_WINDOW_MANAGER.STARTUP("Colored Cubes Toy"); INIT_RC := (others=>(others=>Color_Interior)); for X in LEVEL_TYPE loop for Y in LEVEL_TYPE loop INIT_RC(TO_CUBE_POSITION(X,Y,-1))(TO_FACE(0,0,-1)) := Color_6; INIT_RC(TO_CUBE_POSITION(X,Y,+1))(TO_FACE(0,0,+1)) := Color_2; INIT_RC(TO_CUBE_POSITION(X,-1,Y))(TO_FACE(0,-1,0)) := Color_3; INIT_RC(TO_CUBE_POSITION(X,+1,Y))(TO_FACE(0,+1,0)) := Color_4; INIT_RC(TO_CUBE_POSITION(-1,X,Y))(TO_FACE(-1,0,0)) := Color_5; INIT_RC(TO_CUBE_POSITION(+1,X,Y))(TO_FACE(+1,0,0)) := Color_1; end loop; end loop; if FALSE then RC := INIT_RC; PUT(RC); for A in AXIS_TYPE loop for L in LEVEL_TYPE loop for T in TURN_TYPE loop PUT_INTERVENING(RC,A,L,T); RC := ROTATE(RC,A,L,T); PUT(RC); end loop; end loop; end loop; return; end if; AXIS_Random.Reset (AXIS_Gen, Integer (Secs)); LEVEL_Random.Reset (LEVEL_Gen, Integer (Float'(0.7)*Float (Secs))); TURN_Random.Reset (TURN_Gen, Integer (Float'(0.6)*Float (Secs))); declare procedure TWIST( RC : RUBIKS_CUBE_TYPE; DEPTH : NATURAL; OLD_A: AXIS_TYPE; OLD_L : LEVEL_TYPE; OLD_T : TURN_TYPE; CHANGE_AXIS : BOOLEAN := FALSE) is A : AXIS_TYPE; L : LEVEL_TYPE; T : TURN_TYPE; NRC : RUBIKS_CUBE_TYPE; OPPOSITE : constant array(TURN_TYPE) of TURN_TYPE := (CLOCKWISE => ANTICLOCKWISE, ANTICLOCKWISE => CLOCKWISE); begin loop A := AXIS_Random.Random (AXIS_Gen); L := LEVEL_Random.Random (LEVEL_Gen); T := TURN_Random.Random (TURN_Gen); exit when A /= OLD_A; if not CHANGE_AXIS then if L = OLD_L then exit when T = OLD_T; else exit when T /= OLD_T; end if; end if; end loop; NRC := ROTATE(RC, A, L, T); if DEPTH < 15 then TWIST(NRC, DEPTH+1, A, L, T, A=OLD_A); delay 0.2; PUT_INTERVENING(NRC, A, L, OPPOSITE(T)); end if; PUT(RC); end; begin loop TWIST(INIT_RC, 0, AXIS_TYPE'first, LEVEL_TYPE'first, TURN_TYPE'first); delay 1.0; end loop; end; exception when End_No_Error => null; end;