Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rubik's Cube
#1
This Rubik's Cube program first appeared on QB64.net.  A Rubik's Cube is scrambled and the user has to solve it - a graphical representation of the real thing.
  • Rubik's Cube © and any graphical representation of it are copyrighted.  I was only allowed to put this program onto QB64 by agreeing that it will only be used for hobbyists.  Personal use is courtesy of  Rubik's Brand Ltd.  You may not distribute any files or any executable which you make.


.zip   Rubik's Cube.zip (Size: 100.16 KB / Downloads: 21)
Unzip the file and extract the folder into your PEQB64 directory.  In the IDE make sure that you have the Run Option “Save EXE in source folder” checked.

   

Using the Program (rather strange F-key usage)

The program displays a Rubik's Cube.  Two views are shown, one from the front and a second (smaller) one from the rear.  The rear view is as if you moved around the cube to view it from behind (and is not how you would view the rear-facing sides in a mirror).

All moves are made with F-keys.

When the program has started, press F4 to scramble the cube.

Then use the function keys F1-F3, F5-F7, CtlF1-CtlF3, CtlF5-CtlF7, AltF1-AltF3 and AltF5-AltF7 to rotate and manipulate the cube.  On-screen instructions are given as to how these function keys manipulate the cube.  How the manipulations take place may seem peculiar to begin with, but it is a question of getting used to which keys operate which manipulation.

If you are unable to solve the cube, press F4 and this will perform that task.


Program Details

In order to simulate a Rubik's Cube, there were two aspects to deal with.  Simulating a 3D cube graphically, and writing the logic to know where the colours are and when the cube is solved – when every face has only one colour.

The program was written before I had become acquainted with the amazing QB64 _MAPTRIANGLE(3D) - members will know that I am now a great fan of _MAPTRIANGLE(3D).  So, in this program I had to create my own perspective mathematics, and rules such that only forward-facing surfaces are displayed.  Also, at every screen update the displayable objects are ordered from furthest to nearest.  Again, all that would be perfectly handled by _MAPTRIANGLE(3D).

The logic part has to determine which colours are on which faces of all the 26 small cubes which make up the complete cube.  To deal simultaneously with the graphics and logic is exceedingly complicated and now years later I do not exactly understand what is going on!  The code is lengthy and mysterious.

Additionally, I have never actually had a Rubik's Cube in my hands and do not know the solution methods.  So, this programs “solves” the cube merely by undoing all the moves and is therefore a great cheat.

The video shows the program in action:




Code: (Select All)
' Rubik's Cube by Magdha 2025-12-14 ex Qwerkey
' Graphics Program - solve the cube.
' "Rubik's Cube (Reg. Trade Mark)" used by permission Rubik's Brand Ltd.  www.rubiks.com
' Slight graphics fault on bottom rotations

'Variables/constants
CONST False = 0, True = NOT False
CONST Uscreen% = 1000, Vscreen% = 800, Persp% = -800, Origin% = -2100
CONST NoCubes%% = 26, CubeSize% = 200, FaceImage% = 300, FaceDiam% = 50, ScrambleTurns% = 20
DIM SHARED RotateCount%, RotateStep%, CornerUnit%%(7, 4)
DIM FaceVector!(5, NoCubes%% - 1), CubePlace%%(NoCubes%% - 1, 2), LookUp%%(17), Corners%(7, 4, NoCubes%% - 1)
DIM Initial%(7, 1, NoCubes%% - 1), Depth%%(NoCubes%% - 1), XMid!(NoCubes%% - 1), FindCentre!(7, NoCubes%% - 1)
DIM Faces%%(5, 3), FaceColour%%(5, NoCubes%% - 1), RubikColour&(6)

_TITLE "Rubik's Cube - Esc to Quit"
$EXEICON:'.\Rubik.ico'
OPEN "rubik.mki" FOR RANDOM AS #1 LEN = 2
FIELD #1, 2 AS Entry$

'Load Descriptor Images
RearView& = _LOADIMAGE("RView.png", 32)
FrontView& = _LOADIMAGE("FView.png", 32)
Copyright& = _LOADIMAGE("Copyright.png", 32)
F4Start& = _LOADIMAGE("F4ToStart.png", 33)
F4Restart& = _LOADIMAGE("F4ToRestart.png", 33)
TitleImg& = _LOADIMAGE("Title.png", 33)
Scrambling& = _LOADIMAGE("Scrambling.png", 33)
Solving& = _LOADIMAGE("Solving.png", 33)
Solved& = _LOADIMAGE("Solved.png", 33)
Quit& = _LOADIMAGE("Quit.png", 33)
F4Solve& = _LOADIMAGE("F4ToSolve.png", 33)
Undo& = _LOADIMAGE("Undo.png", 33)
ToNotShow& = _LOADIMAGE("NotShowAll.png", 33)
ToShow& = _LOADIMAGE("ShowAll.png", 33)
RotationHelp& = _LOADIMAGE("Rotations.png", 33)
ManipulationHelp& = _LOADIMAGE("Manipulations.png", 33)

'Screen Background
TempImg& = _NEWIMAGE(Uscreen%, Vscreen%, 32)
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(150, 150, 150)
CLS
_PUTIMAGE (394, 782), Copyright&
_PUTIMAGE (700, 315), RearView&
_PUTIMAGE (200, 240), FrontView&
Background& = MakeHardware&(TempImg&)
_FREEIMAGE RearView&
_FREEIMAGE FrontView&
_FREEIMAGE Copyright&

'Cube Face Images
TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'Blank
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(90, 90, 90)
CLS
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 3), _RGB32(0, 0, 0), B
RubikColour&(0) = MakeHardware&(TempImg&)

FaceRadius% = FaceDiam% / 2
TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'Yellow
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(100, 100, 100)
CLS
LINE (FaceDiam%, FaceRadius%)-(FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceRadius%), _RGB32(255, 255, 0), BF
LINE (FaceRadius%, FaceDiam%)-(FaceImage% - 1 - FaceRadius%, FaceImage% - 1 - FaceDiam%), _RGB32(255, 255, 0), BF
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 255, 0)
PAINT (FaceImage% - FaceDiam%, FaceImage% - FaceDiam%), _RGB32(255, 255, 0), _RGB32(255, 255, 0)
CIRCLE (FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 255, 0)
PAINT (FaceDiam% - 1, FaceDiam% - 1), _RGB32(255, 255, 0), _RGB32(255, 255, 0)
CIRCLE (FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 255, 0)
PAINT (FaceDiam% - 1, FaceImage% - FaceDiam%), _RGB32(255, 255, 0), _RGB32(255, 255, 0)
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 255, 0)
PAINT (FaceImage% - FaceDiam%, FaceDiam% - 1), _RGB32(255, 255, 0), _RGB32(255, 255, 0)
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 2), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 2), _RGB32(0, 0, 0), B
RubikColour&(1) = MakeHardware&(TempImg&)

TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'White
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(100, 100, 100)
CLS
LINE (FaceDiam%, FaceRadius%)-(FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceRadius%), _RGB32(255, 255, 255), BF
LINE (FaceRadius%, FaceDiam%)-(FaceImage% - 1 - FaceRadius%, FaceImage% - 1 - FaceDiam%), _RGB32(255, 255, 255), BF
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 255, 255)
PAINT (FaceImage% - FaceDiam%, FaceImage% - FaceDiam%), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
CIRCLE (FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 255, 255)
PAINT (FaceDiam% - 1, FaceDiam% - 1), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
CIRCLE (FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 255, 255)
PAINT (FaceDiam% - 1, FaceImage% - FaceDiam%), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 255, 255)
PAINT (FaceImage% - FaceDiam%, FaceDiam% - 1), _RGB32(255, 255, 255), _RGB32(255, 255, 255)
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 2), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 2), _RGB32(0, 0, 0), B
RubikColour&(2) = MakeHardware&(TempImg&)

TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'Green
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(100, 100, 100)
CLS
LINE (FaceDiam%, FaceRadius%)-(FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceRadius%), _RGB32(0, 255, 0), BF
LINE (FaceRadius%, FaceDiam%)-(FaceImage% - 1 - FaceRadius%, FaceImage% - 1 - FaceDiam%), _RGB32(0, 255, 0), BF
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(0, 255, 0)
PAINT (FaceImage% - FaceDiam%, FaceImage% - FaceDiam%), _RGB32(0, 255, 0), _RGB32(0, 255, 0)
CIRCLE (FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(0, 255, 0)
PAINT (FaceDiam% - 1, FaceDiam% - 1), _RGB32(0, 255, 0), _RGB32(0, 255, 0)
CIRCLE (FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(0, 255, 0)
PAINT (FaceDiam% - 1, FaceImage% - FaceDiam%), _RGB32(0, 255, 0), _RGB32(0, 255, 0)
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(0, 255, 0)
PAINT (FaceImage% - FaceDiam%, FaceDiam% - 1), _RGB32(0, 255, 0), _RGB32(0, 255, 0)
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 2), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 2), _RGB32(0, 0, 0), B
RubikColour&(3) = MakeHardware&(TempImg&)

TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'Blue
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(100, 100, 100)
CLS
LINE (FaceDiam%, FaceRadius%)-(FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceRadius%), _RGB32(0, 0, 255), BF
LINE (FaceRadius%, FaceDiam%)-(FaceImage% - 1 - FaceRadius%, FaceImage% - 1 - FaceDiam%), _RGB32(0, 0, 255), BF
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(0, 0, 255)
PAINT (FaceImage% - FaceDiam%, FaceImage% - FaceDiam%), _RGB32(0, 0, 255), _RGB32(0, 0, 255)
CIRCLE (FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(0, 0, 255)
PAINT (FaceDiam% - 1, FaceDiam% - 1), _RGB32(0, 0, 255), _RGB32(0, 0, 255)
CIRCLE (FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(0, 0, 255)
PAINT (FaceDiam% - 1, FaceImage% - FaceDiam%), _RGB32(0, 0, 255), _RGB32(0, 0, 255)
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(0, 0, 255)
PAINT (FaceImage% - FaceDiam%, FaceDiam% - 1), _RGB32(0, 0, 255), _RGB32(0, 0, 255)
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 2), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 2), _RGB32(0, 0, 0), B
RubikColour&(4) = MakeHardware&(TempImg&)

TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'Orange
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(100, 100, 100)
CLS
LINE (FaceDiam%, FaceRadius%)-(FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceRadius%), _RGB32(255, 140, 0), BF
LINE (FaceRadius%, FaceDiam%)-(FaceImage% - 1 - FaceRadius%, FaceImage% - 1 - FaceDiam%), _RGB32(255, 140, 0), BF
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 140, 0)
PAINT (FaceImage% - FaceDiam%, FaceImage% - FaceDiam%), _RGB32(255, 140, 0), _RGB32(255, 140, 0)
CIRCLE (FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 140, 0)
PAINT (FaceDiam% - 1, FaceDiam% - 1), _RGB32(255, 140, 0), _RGB32(255, 140, 0)
CIRCLE (FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 140, 0)
PAINT (FaceDiam% - 1, FaceImage% - FaceDiam%), _RGB32(255, 140, 0), _RGB32(255, 140, 0)
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 140, 0)
PAINT (FaceImage% - FaceDiam%, FaceDiam% - 1), _RGB32(255, 140, 0), _RGB32(255, 140, 0)
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 2), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 2), _RGB32(0, 0, 0), B
RubikColour&(5) = MakeHardware&(TempImg&)

TempImg& = _NEWIMAGE(FaceImage%, FaceImage%, 32) 'Red
_DEST TempImg&
COLOR _RGB32(255, 255, 255), _RGB32(100, 100, 100)
CLS
LINE (FaceDiam%, FaceRadius%)-(FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceRadius%), _RGB32(255, 0, 0), BF
LINE (FaceRadius%, FaceDiam%)-(FaceImage% - 1 - FaceRadius%, FaceImage% - 1 - FaceDiam%), _RGB32(255, 0, 0), BF
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 0, 0)
PAINT (FaceImage% - FaceDiam%, FaceImage% - FaceDiam%), _RGB32(255, 0, 0), _RGB32(255, 0, 0)
CIRCLE (FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 0, 0)
PAINT (FaceDiam% - 1, FaceDiam% - 1), _RGB32(255, 0, 0), _RGB32(255, 0, 0)
CIRCLE (FaceDiam%, FaceImage% - 1 - FaceDiam%), FaceRadius%, _RGB32(255, 0, 0)
PAINT (FaceDiam% - 1, FaceImage% - FaceDiam%), _RGB32(255, 0, 0), _RGB32(255, 0, 0)
CIRCLE (FaceImage% - 1 - FaceDiam%, FaceDiam%), FaceRadius%, _RGB32(255, 0, 0)
PAINT (FaceImage% - FaceDiam%, FaceDiam% - 1), _RGB32(255, 0, 0), _RGB32(255, 0, 0)
LINE (0, 0)-(FaceImage% - 1, FaceImage% - 1), _RGB32(0, 0, 0), B
LINE (1, 1)-(FaceImage% - 2, FaceImage% - 2), _RGB32(0, 0, 0), B
LINE (2, 2)-(FaceImage% - 3, FaceImage% - 2), _RGB32(0, 0, 0), B
RubikColour&(6) = MakeHardware&(TempImg&)

'Define Cube Corners
DATA -1,-1,1
DATA 1,-1,1
DATA -1,1,1
DATA 1,1,1
DATA -1,-1,-1
DATA 1,-1,-1
DATA -1,1,-1
DATA 1,1,-1

FOR CornerNo%% = 0 TO 7
    FOR Cartesian%% = 0 TO 2
        READ CornerUnit%%(CornerNo%%, Cartesian%%)
    NEXT Cartesian%%
NEXT CornerNo%%

'Define Cube faces
DATA 2,0,4,6
DATA 1,3,7,5
DATA 3,1,0,2
DATA 6,4,5,7
DATA 0,1,5,4
DATA 3,2,6,7

FOR FaceNo%% = 0 TO 5
    FOR S%% = 0 TO 3
        READ Faces%%(FaceNo%%, S%%)
    NEXT S%%
NEXT FaceNo%%

'Define Cube Start Positions
DATA 0,-1,0
DATA -1,-1,0
DATA -1,0,0
DATA -1,1,0
DATA 0,1,0
DATA 1,1,0
DATA 1,0,0
DATA 1,-1,0

DATA 0,-1,-1
DATA -1,-1,-1
DATA -1,0,-1
DATA -1,1,-1
DATA 0,1,-1
DATA 1,1,-1
DATA 1,0,-1
DATA 1,-1,-1
DATA 0,0,-1

DATA 0,-1,1
DATA -1,-1,1
DATA -1,0,1
DATA -1,1,1
DATA 0,1,1
DATA 1,1,1
DATA 1,0,1
DATA 1,-1,1
DATA 0,0,1

FOR CubeNo%% = 0 TO NoCubes%% - 1
    FOR Cartesian%% = 0 TO 2
        READ CubePlace%%(CubeNo%%, Cartesian%%)
    NEXT Cartesian%%
NEXT CubeNo%%

'Set Start Positions of Corners of Cubes
FOR CubeNo%% = 0 TO NoCubes%% - 1
    FOR CornerNo%% = 0 TO 7
        FOR Cartesian%% = 0 TO 2
            Corners%(CornerNo%%, Cartesian%%, CubeNo%%) = CornerUnit%%(CornerNo%%, Cartesian%%) * CubeSize% / 2 + (CubeSize% * CubePlace%%(CubeNo%%, Cartesian%%))
        NEXT Cartesian%%
    NEXT CornerNo%%
NEXT CubeNo%%

'Define Cube Face Colours
DATA 0,0,0,0,1,0
DATA 1,0,0,0,1,0
DATA 1,0,0,0,0,0
DATA 1,0,0,0,0,1
DATA 0,0,0,0,0,1
DATA 0,1,0,0,0,1
DATA 0,1,0,0,0,0
DATA 0,1,0,0,1,0

DATA 0,0,0,1,1,0
DATA 1,0,0,1,1,0
DATA 1,0,0,1,0,0
DATA 1,0,0,1,0,1
DATA 0,0,0,1,0,1
DATA 0,1,0,1,0,1
DATA 0,1,0,1,0,0
DATA 0,1,0,1,1,0
DATA 0,0,0,1,0,0

DATA 0,0,1,0,1,0
DATA 1,0,1,0,1,0
DATA 1,0,1,0,0,0
DATA 1,0,1,0,0,1
DATA 0,0,1,0,0,1
DATA 0,1,1,0,0,1
DATA 0,1,1,0,0,0
DATA 0,1,1,0,1,0
DATA 0,0,1,0,0,0

FOR CubeNo%% = 0 TO NoCubes%% - 1
    FOR FaceNo%% = 0 TO 5
        READ S%%
        IF S%% = 1 THEN
            FaceColour%%(FaceNo%%, CubeNo%%) = FaceNo%% + 1
        ELSE
            FaceColour%%(FaceNo%%, CubeNo%%) = 0
        END IF
    NEXT FaceNo%%
NEXT CubeNo%%

'Forward/Reverse Look-up Table
DATA 3,4,5,0,1,2,9,10,11,6,7,8,15,16,17,12,13,14
FOR S%% = 0 TO 17
    READ LookUp%%(S%%)
NEXT S%%

'Set Array for Depth Order
JumpStart%% = 1
WHILE JumpStart%% <= NoCubes%%
    JumpStart%% = JumpStart%% * 2
WEND
FOR N%% = 0 TO NoCubes%% - 1
    Depth%%(N%%) = N%%
NEXT N%%

'Create Screen
SCREEN _NEWIMAGE(Uscreen%, Vscreen%, 32)
_SCREENMOVE 50, 13
_DEST 0
_DISPLAYORDER _HARDWARE 'Hardware Images Only

'Initial Values
ShowAll%% = True
NoTurns% = 0
DoManipulate%% = False
Revolver%% = False
SolutionFound%% = False
AtStart%% = True
DoUndo%% = False
DoScrambling%% = False
DoSolving%% = False
RotateCount% = 0
RotateStep% = 60
DoRubiks%% = True
RANDOMIZE (TIMER)

WHILE DoRubiks%%

    _LIMIT 120 'Game Frames/Second Rate

    'Display Background & Labels
    _PUTIMAGE (0, 0), Background&
    IF AtStart%% OR (DoManipulate%% AND NOT Revolver%%) OR SolutionFound%% THEN _PUTIMAGE (20, 750), Quit&
    IF DoUndo%% AND NOT Revolver%% AND DoManipulate%% THEN _PUTIMAGE (300, 750), Undo&
    IF AtStart%% THEN
        _PUTIMAGE (20, 20), F4Start&
        _PUTIMAGE (600, 500), TitleImg&
    ELSEIF DoScrambling%% THEN
        _PUTIMAGE (200, 100), Scrambling&
    ELSEIF DoSolving%% THEN
        _PUTIMAGE (200, 100), Solving&
    ELSEIF DoManipulate%% AND NOT Revolver%% THEN
        IF NoTurns% > ScrambleTurns% THEN _PUTIMAGE (20, 20), F4Solve&
        IF ShowAll%% THEN
            _PUTIMAGE (150, 80), RotationHelp&
            _PUTIMAGE (550, 450), ManipulationHelp&
            _PUTIMAGE (680, 15), ToNotShow&
        ELSE
            _PUTIMAGE (680, 15), ToShow&
        END IF
    ELSEIF SolutionFound%% THEN
        _PUTIMAGE (200, 100), Solved&
        _PUTIMAGE (20, 20), F4Restart&
    END IF

    'Find Corner Positions & Determine Face Vectors
    FOR CubeNo%% = 0 TO NoCubes%% - 1
        FOR CornerNo%% = 0 TO 7
            CALL ConvertAngles((True), (Corners%(CornerNo%%, 0, CubeNo%%)), (Corners%(CornerNo%%, 1, CubeNo%%)), (Corners%(CornerNo%%, 2, CubeNo%%)), Corners%(CornerNo%%, 3, CubeNo%%), Corners%(CornerNo%%, 4, CubeNo%%), FindCentre!(CornerNo%%, CubeNo%%))
        NEXT CornerNo%%
        XMid!(CubeNo%%) = (FindCentre!(0, CubeNo%%) + FindCentre!(7, CubeNo%%)) / 2
        FOR FaceNo%% = 0 TO 5
            VectorBAi! = Corners%(Faces%%(FaceNo%%, 0), 4, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 1), 4, CubeNo%%)
            VectorBAj! = Corners%(Faces%%(FaceNo%%, 0), 3, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 1), 3, CubeNo%%)
            VectorACi! = Corners%(Faces%%(FaceNo%%, 1), 4, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 3), 4, CubeNo%%)
            VectorACj! = Corners%(Faces%%(FaceNo%%, 1), 3, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 3), 3, CubeNo%%)
            FaceVector!(FaceNo%%, CubeNo%%) = VectorBAi! * VectorACj! - VectorBAj! * VectorACi!
        NEXT FaceNo%%
    NEXT CubeNo%%

    'Change Display Order: Furthest First
    Jump%% = JumpStart%%
    WHILE Jump%% > 1
        Jump%% = (Jump%% - 1) \ 2
        Finished%% = False
        WHILE NOT Finished%%
            Finished%% = True
            FOR Upper%% = 1 TO NoCubes%% - Jump%%
                Lower%% = Upper%% + Jump%%
                IF XMid!(Depth%%(Upper%% - 1)) > XMid!(Depth%%(Lower%% - 1)) THEN
                    SWAP Depth%%(Upper%% - 1), Depth%%(Lower%% - 1)
                    Finished%% = False
                END IF
            NEXT Upper%%
        WEND
    WEND

    'Display Faces In Front
    FOR Xorder%% = NoCubes%% - 1 TO 0 STEP -1
        FarToNear%% = Depth%%(Xorder%%)
        FOR FaceNo%% = 0 TO 5
            IF FaceVector!(FaceNo%%, FarToNear%%) >= 0 THEN
                _MAPTRIANGLE (0, 0)-(FaceImage% - 1, 0)-(0, FaceImage% - 1), RubikColour&(FaceColour%%(FaceNo%%, FarToNear%%)) TO(Corners%(Faces%%(FaceNo%%, 1), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 1), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 0), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 0), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 2), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 2), 4, FarToNear%%))
                _MAPTRIANGLE (FaceImage% - 1, FaceImage% - 1)-(0, FaceImage% - 1)-(FaceImage% - 1, 0), RubikColour&(FaceColour%%(FaceNo%%, FarToNear%%)) TO(Corners%(Faces%%(FaceNo%%, 3), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 3), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 2), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 2), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 0), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 0), 4, FarToNear%%))
            END IF
        NEXT FaceNo%%
    NEXT Xorder%%

    'Display Faces At Rear: Rear View is as view rotated through 180deg, NOT as in a mirror
    FOR CubeNo%% = 0 TO NoCubes%% - 1
        FOR CornerNo%% = 0 TO 7
            CALL ConvertAngles((False), (Corners%(CornerNo%%, 0, CubeNo%%)), (Corners%(CornerNo%%, 1, CubeNo%%)), (Corners%(CornerNo%%, 2, CubeNo%%)), Corners%(CornerNo%%, 3, CubeNo%%), Corners%(CornerNo%%, 4, CubeNo%%), FindCentre!(CornerNo%%, CubeNo%%))
        NEXT CornerNo%%
        FOR FaceNo%% = 0 TO 5
            VectorBAi! = Corners%(Faces%%(FaceNo%%, 0), 4, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 1), 4, CubeNo%%)
            VectorBAj! = Corners%(Faces%%(FaceNo%%, 0), 3, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 1), 3, CubeNo%%)
            VectorACi! = Corners%(Faces%%(FaceNo%%, 1), 4, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 3), 4, CubeNo%%)
            VectorACj! = Corners%(Faces%%(FaceNo%%, 1), 3, CubeNo%%) - Corners%(Faces%%(FaceNo%%, 3), 3, CubeNo%%)
            FaceVector!(FaceNo%%, CubeNo%%) = VectorBAi! * VectorACj! - VectorBAj! * VectorACi!
        NEXT FaceNo%%
    NEXT CubeNo%%
    FOR Xorder%% = 0 TO NoCubes%% - 1
        FarToNear%% = Depth%%(Xorder%%)
        FOR FaceNo%% = 0 TO 5
            IF FaceVector!(FaceNo%%, FarToNear%%) >= 0 THEN
                _MAPTRIANGLE (0, 0)-(FaceImage% - 1, 0)-(0, FaceImage% - 1), RubikColour&(FaceColour%%(FaceNo%%, FarToNear%%)) TO(Corners%(Faces%%(FaceNo%%, 1), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 1), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 0), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 0), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 2), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 2), 4, FarToNear%%))
                _MAPTRIANGLE (FaceImage% - 1, FaceImage% - 1)-(0, FaceImage% - 1)-(FaceImage% - 1, 0), RubikColour&(FaceColour%%(FaceNo%%, FarToNear%%)) TO(Corners%(Faces%%(FaceNo%%, 3), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 3), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 2), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 2), 4, FarToNear%%))-(Corners%(Faces%%(FaceNo%%, 0), 3, FarToNear%%), Corners%(Faces%%(FaceNo%%, 0), 4, FarToNear%%))
            END IF
        NEXT FaceNo%%
    NEXT Xorder%%

    'Check to See if Solution Found
    IF (DoManipulate%% OR DoSolving%%) AND NOT Revolver%% THEN
        SolutionFound%% = True: FaceNo%% = 0: CubeNo%% = 0: FirstonFace%% = True
        WHILE SolutionFound%% AND FaceNo%% <= 5 AND CubeNo%% <= NoCubes%% - 1
            FaceFirst%% = False
            SELECT CASE FaceNo%%
                CASE 0
                    IF CubePlace%%(CubeNo%%, 0) = -1 THEN FaceFirst%% = True
                CASE 1
                    IF CubePlace%%(CubeNo%%, 0) = 1 THEN FaceFirst%% = True
                CASE 2
                    IF CubePlace%%(CubeNo%%, 2) = 1 THEN FaceFirst%% = True
                CASE 3
                    IF CubePlace%%(CubeNo%%, 2) = -1 THEN FaceFirst%% = True
                CASE 4
                    IF CubePlace%%(CubeNo%%, 1) = -1 THEN FaceFirst%% = True
                CASE ELSE
                    IF CubePlace%%(CubeNo%%, 1) = 1 THEN FaceFirst%% = True
            END SELECT
            IF FaceFirst%% THEN
                IF NOT FirstonFace%% THEN
                    IF FaceColour%%(FaceNo%%, CubeNo%%) <> FirstCol%% THEN SolutionFound%% = False
                ELSE
                    FirstonFace%% = False
                    FirstCol%% = FaceColour%%(FaceNo%%, CubeNo%%)
                END IF
            END IF
            CubeNo%% = CubeNo%% + 1
            IF CubeNo%% > NoCubes%% - 1 THEN
                FaceNo%% = FaceNo%% + 1
                CubeNo%% = 0
                FirstonFace%% = True
            END IF
        WEND
    END IF
    IF SolutionFound%% THEN DoSolving%% = False

    'Key Input
    K$ = INKEY$
    IF K$ <> "" THEN
        KeyFunc%% = fkey%%(K$)
        IF ASC(K$) = 27 THEN
            DoRubiks%% = False 'Esc  to quit
        ELSEIF ASC(K$) = 26 AND NoTurns% > ScrambleTurns% AND DoManipulate%% AND DoUndo%% THEN 'Reverse Previous Move
            DoUndo%% = False
            Revolver%% = True
            GET #1, NoTurns% - 1
            Prev%% = CVI(Entry$)
            SetRev%% = LookUp%%(Prev%%) + 1
            NoTurns% = NoTurns% - 1
        ELSEIF KeyFunc%% = 4 THEN 'F4
            IF AtStart%% THEN 'Start Scramble Cube
                AtStart%% = False
                DoScrambling%% = True
            ELSEIF DoManipulate%% AND NOT Revolver%% AND NoTurns% > ScrambleTurns% THEN 'Start Solving
                DoManipulate%% = False
                DoSolving%% = True
                NoTurns% = NoTurns% - 1
                RotateStep% = 60
            ELSEIF SolutionFound%% THEN 'Reset to Start
                ShowAll%% = True: SolutionFound%% = False: NoTurns% = 0
                DoRubiks%% = True: DoManipulate%% = False: DoScrambling%% = False
                Revolver%% = False: AtStart%% = True: DoUndo%% = False: DoSolving%% = False
                RotateCount% = 0: RotateStep% = 60
            END IF
        ELSEIF DoManipulate%% AND NOT Revolver%% AND (KeyFunc%% = 49 OR KeyFunc%% = 39) THEN 'Alt/Ctl F4
            'Do Nothing
        ELSEIF DoManipulate%% AND NOT Revolver%% AND ((KeyFunc%% >= 1 AND KeyFunc%% <= 7) OR (KeyFunc%% >= 46 AND KeyFunc%% <= 52) OR (KeyFunc%% >= 36 AND KeyFunc%% <= 42)) THEN
            'Manipulation Key Presses
            Revolver%% = True
            GET #1, NoTurns% - 1
            Prev%% = CVI(Entry$)
            SELECT CASE KeyFunc%%
                CASE 1 '    F1  Rotate View z-
                    KeySet%% = 0
                CASE 5 '    F5 Rotate View z- reverse
                    KeySet%% = 3
                CASE 2 '    F2 Rotate View y-
                    KeySet%% = 1
                CASE 6 '    F6  Rotate View y- reverse
                    KeySet%% = 4
                CASE 3 '    F3  Rotate View x-
                    KeySet%% = 2
                CASE 7 '    F7 Rotate View x- reverse
                    KeySet%% = 5
                CASE 46 '  FKey Alt F1 - top rotate z
                    KeySet%% = 6
                CASE 50 '  FKey Alt F5 - top rotate z reverse
                    KeySet%% = 9
                CASE 36 '  FKey Ctl F1 - bottom rotate z
                    KeySet%% = 12
                CASE 40 '  FKey Ctl F5 - bottom rotate z  reverse
                    KeySet%% = 15
                CASE 47 '  FKey Alt F2 - front rotate y
                    KeySet%% = 7
                CASE 51 '  FKey Alt F6 - front rotate y  reverse
                    KeySet%% = 10
                CASE 37 '  FKey Ctl F2 - back rotate y
                    KeySet%% = 13
                CASE 41 '  FKey Ctl F6 - back rotate y  reverse
                    KeySet%% = 16
                CASE 48 '  FKey Alt F3 - front rotate x
                    KeySet%% = 8
                CASE 52 '  FKey Alt F7 - front rotate x  reverse
                    KeySet%% = 11
                CASE 38 '  FKey Ctl F3 - back rotate x
                    KeySet%% = 14
                CASE ELSE ' FKey Ctl F7 - back rotate x  reverse
                    KeySet%% = 17
            END SELECT
            IF Prev%% = LookUp%%(KeySet%%) THEN
                NoTurns% = NoTurns% - 1
                DoUndo%% = False
            ELSE
                LSET Entry$ = MKI$(KeySet%%)
                PUT #1, NoTurns%
                NoTurns% = NoTurns% + 1
                DoUndo%% = True
            END IF
            SetRev%% = KeySet%% + 1
        ELSEIF KeyFunc%% = 10 AND DoManipulate%% AND NOT Revolver%% THEN 'F10: Show or Blank Help
            IF ShowAll%% THEN
                ShowAll%% = False
            ELSE
                ShowAll%% = True
            END IF
        END IF
    END IF
    K$ = ""

    'Scramble or Solve Cube
    IF (DoScrambling%% OR DoSolving%%) AND NOT Revolver%% THEN
        Revolver%% = True
        IF DoScrambling%% THEN NoTurns% = NoTurns% + 1
        IF NoTurns% = ScrambleTurns% AND DoScrambling%% THEN
            DoManipulate%% = True
            DoScrambling%% = False
            Revolver%% = False
            RotateStep% = 110
        ELSE
            IF NoTurns% = 1 AND DoScrambling%% THEN
                Scramble%% = 6 + INT(RND * 12)
                LSET Entry$ = MKI$(Scramble%%)
                PUT #1, 1
            ELSEIF DoScrambling%% THEN
                IsNotSame%% = False
                GET #1, NoTurns% - 1
                Prev%% = CVI(Entry$)
                WHILE NOT IsNotSame%%
                    'Same as Previous and Reverse of Previous not allowed
                    Scramble%% = 6 + INT(RND * 12)
                    IF Scramble%% <> Prev%% AND LookUp%%(Scramble%%) <> Prev%% THEN
                        IsNotSame%% = True
                        LSET Entry$ = MKI$(Scramble%%)
                        PUT #1, NoTurns%
                    END IF
                WEND
            ELSE
                GET #1, NoTurns%
                Current%% = CVI(Entry$)
                NoTurns% = NoTurns% - 1
            END IF
            IF DoScrambling%% THEN
                SetRev%% = Scramble%% + 1
            ELSE
                SetRev%% = LookUp%%(Current%%) + 1
            END IF
        END IF
    END IF

    'Initiate Rotations
    IF SetRev%% <> 0 THEN
        SELECT CASE SetRev%%
            CASE 1, 4, 7, 10, 13, 16
                CALL SetCorners(Corners%(), Initial%(), 0, 1)
            CASE 2, 5, 8, 11, 14, 17
                CALL SetCorners(Corners%(), Initial%(), 2, 0)
            CASE ELSE '3, 6, 9, 12, 15, 18
                CALL SetCorners(Corners%(), Initial%(), 1, 2)
        END SELECT
        RotateMe%% = SetRev%%
        SetRev%% = 0
    END IF

    'Rotations
    IF Revolver%% THEN
        RotTrans%% = Revolver%%
        SELECT CASE RotateMe%%
            CASE 1 ' Rotate View in z-
                CALL Rotations((True), 3, RotTrans%%, 2, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 4 ' Rotate View in negative z-
                CALL Rotations((False), 3, RotTrans%%, 2, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 2 ' Rotate View in y-
                CALL Rotations((True), 3, RotTrans%%, 1, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 5 ' Rotate View in negative y-
                CALL Rotations((False), 3, RotTrans%%, 1, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 3 ' Rotate View in x-
                CALL Rotations((False), 3, RotTrans%%, 0, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 6 ' Rotate View in negative x-
                CALL Rotations((True), 3, RotTrans%%, 0, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 7 ' Rotate top row in z-
                CALL Rotations((True), 1, RotTrans%%, 2, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 10 'Rotate top row in z- reverse
                CALL Rotations((False), 1, RotTrans%%, 2, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 13 'Rotate bottom row in z-
                CALL Rotations((True), -1, RotTrans%%, 2, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 16 'Rotate bottom row in z- reverse
                CALL Rotations((False), -1, RotTrans%%, 2, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 8 'Rotate front row in y-
                CALL Rotations((True), 1, RotTrans%%, 1, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 11 'Rotate front row in y- reverse
                CALL Rotations((False), 1, RotTrans%%, 1, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 14 'Rotate back row in y-
                CALL Rotations((True), -1, RotTrans%%, 1, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 17 'Rotate back row in y- reverse
                CALL Rotations((False), -1, RotTrans%%, 1, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 9 'Rotate front row in x-
                CALL Rotations((False), -1, RotTrans%%, 0, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 12 'Rotate front row in x- in reverse
                CALL Rotations((True), -1, RotTrans%%, 0, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE 15 'Rotate back row in x-
                CALL Rotations((False), 1, RotTrans%%, 0, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
            CASE ELSE 'Rotate back row in x- in reverse
                CALL Rotations((True), 1, RotTrans%%, 0, Corners%(), CubePlace%%(), Initial%(), FaceColour%%())
        END SELECT
        Revolver%% = RotTrans%%
        IF NOT RotTrans%% THEN RotateMe%% = 0
    END IF

    _DISPLAY

WEND

'Free Images from Memory
_FREEIMAGE Background&
_FREEIMAGE F4Start&
_FREEIMAGE F4Restart&
_FREEIMAGE TitleImg&
_FREEIMAGE Scrambling&
_FREEIMAGE Solving&
_FREEIMAGE Solved&
_FREEIMAGE Quit&
_FREEIMAGE F4Solve&
_FREEIMAGE Undo&
_FREEIMAGE ToNotShow&
_FREEIMAGE ToShow&
_FREEIMAGE RotationHelp&
_FREEIMAGE ManipulationHelp&

FOR FaceNo%% = 0 TO 6
    _FREEIMAGE RubikColour&(FaceNo%%)
NEXT FaceNo%%

CLOSE #1

SYSTEM

FUNCTION MakeHardware& (ImageName&)
    MakeHardware& = _COPYIMAGE(ImageName&, 33)
    _FREEIMAGE ImageName&
END FUNCTION

FUNCTION fkey%% (Key$)
    IF ASC(Key$) <> 0 THEN
        fkey%% = 0
    ELSE
        fkey%% = ASC(RIGHT$(Key$, 1)) - 58
    END IF
END FUNCTION

SUB ConvertAngles (Viewer%%, X!, Y!, Z!, U%, V%, TiltX!)
    IF Viewer%% THEN
        Zoom! = 1
        Xaxis! = 0 'Could make view different for front/rear
        Yaxis! = -0.65
        Zaxis! = 0.8
    ELSE
        Zoom! = 1.8
        Xaxis! = 0
        Yaxis! = -0.65
        Zaxis! = 0.8
    END IF
    R1! = SQR(X! * X! + Y! * Y! + Z! * Z!)
    Theta2! = _ACOS(Z! / R1!)
    Phi2! = _ATAN2(Y!, X!) + Zaxis!
    X! = R1! * SIN(Theta2!) * COS(Phi2!)
    Y! = R1! * SIN(Theta2!) * SIN(Phi2!)
    R1! = SQR(X! * X! + Y! * Y! + Z! * Z!)
    Theta2! = _ACOS(X! / R1!)
    Phi2! = _ATAN2(Z!, Y!) + Xaxis!
    Y! = R1! * SIN(Theta2!) * COS(Phi2!)
    Z! = R1! * SIN(Theta2!) * SIN(Phi2!)
    R1! = SQR(X! * X! + Y! * Y! + Z! * Z!)
    Theta2! = _ACOS(Y! / R1!)
    Phi2! = _ATAN2(X!, Z!) + Yaxis!
    Z! = R1! * SIN(Theta2!) * COS(Phi2!)
    X! = R1! * SIN(Theta2!) * SIN(Phi2!)
    TiltX! = X!
    X2! = -X! / Zoom!
    Y2! = Y! / Zoom!
    Z2! = -Z! / Zoom!
    IF Viewer%% THEN
        X1! = X2! + Origin%
    ELSE
        X1! = Origin% - X2!
    END IF
    IF X1! < -1.0E-20 THEN
        IF Viewer%% THEN
            U1! = 300 + (Y2! * Persp% / X1!)
            V1! = 500 + (Z2! * Persp% / X1!)
        ELSE
            U1! = 800 - (Y2! * Persp% / X1!)
            V1! = 200 + (Z2! * Persp% / X1!)
        END IF
        U% = CINT(U1!): V% = CINT(V1!)
    END IF
END SUB

SUB Twist (I1%%, I2%%, I3%%, I4%%)
    I41%% = I1%%
    I1%% = I2%%
    I2%% = I3%%
    I3%% = I4%%
    I4%% = I41%%
END SUB

SUB Rotations (FwdRev%%, Tier%%, Rotor%%, Axis1%%, Cantos%(), CubePl%%(), Begin%(), Hues%%())
    RotateCount% = RotateCount% + 1
    IF FwdRev%% THEN
        Phi! = 2 * ATN(1) / RotateStep%
    ELSE
        Phi! = -2 * ATN(1) / RotateStep%
    END IF
    SELECT CASE Axis1%%
        CASE 2
            Axis2%% = 0
            Axis3%% = 1
            AFace1%% = 1
            AFace2%% = 4
            AFace3%% = 0
            AFace4%% = 5
        CASE 1
            Axis2%% = 2
            Axis3%% = 0
            AFace1%% = 1
            AFace2%% = 2
            AFace3%% = 0
            AFace4%% = 3
        CASE ELSE
            Axis2%% = 1
            Axis3%% = 2
            AFace1%% = 4
            AFace2%% = 2
            AFace3%% = 5
            AFace4%% = 3
    END SELECT
    'Rotate
    FOR S% = 0 TO NoCubes%% - 1
        IF CubePl%%(S%, Axis1%%) = Tier%% OR Tier%% = 3 THEN
            FOR R%% = 0 TO 7
                Cantos%(R%%, Axis2%%, S%) = Begin%(R%%, 0, S%) * COS(Phi! * RotateCount%) - Begin%(R%%, 1, S%) * SIN(Phi! * RotateCount%)
                Cantos%(R%%, Axis3%%, S%) = Begin%(R%%, 0, S%) * SIN(Phi! * RotateCount%) + Begin%(R%%, 1, S%) * COS(Phi! * RotateCount%)
            NEXT R%%
        END IF
    NEXT S%
    IF RotateCount% = RotateStep% THEN
        Rotor%% = False
        FOR S% = 0 TO NoCubes%% - 1
            IF CubePl%%(S%, Axis1%%) = Tier%% OR Tier%% = 3 THEN
                'Rotate Cube Positions
                I41%% = CubePl%%(S%, Axis2%%)
                IF FwdRev%% THEN
                    CubePl%%(S%, Axis2%%) = -CubePl%%(S%, Axis3%%)
                    CubePl%%(S%, Axis3%%) = I41%%
                ELSE
                    CubePl%%(S%, Axis2%%) = CubePl%%(S%, Axis3%%)
                    CubePl%%(S%, Axis3%%) = -I41%%
                END IF
                'Reset Corners
                FOR R%% = 0 TO 7
                    FOR Cartesian%% = 0 TO 2
                        Cantos%(R%%, Cartesian%%, S%) = CornerUnit%%(R%%, Cartesian%%) * CubeSize% / 2 + (CubeSize% * CubePl%%(S%, Cartesian%%))
                    NEXT Cartesian%%
                NEXT R%%
                'Rotate face colour on sides (not on tops/bottoms)
                IF FwdRev%% THEN
                    CALL Twist(Hues%%(AFace1%%, S%), Hues%%(AFace2%%, S%), Hues%%(AFace3%%, S%), Hues%%(AFace4%%, S%))
                ELSE
                    CALL Twist(Hues%%(AFace1%%, S%), Hues%%(AFace4%%, S%), Hues%%(AFace3%%, S%), Hues%%(AFace2%%, S%))
                END IF
            END IF
        NEXT S%
        WHILE INKEY$ <> "": WEND 'To use up stray key presses, but isn't required
    END IF
END SUB

SUB SetCorners (Cantos1%(), Comecar%(), I1%%, I2%%)
    RotateCount% = 0
    FOR S% = 0 TO NoCubes%% - 1
        FOR R% = 0 TO 7
            Comecar%(R%, 0, S%) = Cantos1%(R%, I1%%, S%)
            Comecar%(R%, 1, S%) = Cantos1%(R%, I2%%, S%)
        NEXT R%
    NEXT S%
END SUB
Reply
#2
The FaceFirst variable implies I could damage my nose.  "Revolver" suggests I could be shot.
Despite these dangers, I tried it.  Very impressive.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)