'===========================================================================
' Subject: Color Crazy - Rubiks Cub2 in 2D    Date: 18-18-02 (  :  )       
'  Author: Richard D. Clark                   Code: WXBASIC                
'  Origin: rickclark58@yahoo.com            Packet: GAMES.ABC
'===========================================================================
' Crazy Color
' Richard D. Clark
' rickclark58@yahoo.com
' Portions of code by:
' (c) 2002 David Cuny
' reminder grahpic by TronDoc
Option Explicit

Const RedColor = 1,
	  YellowColor = 2,
	  GreenColor = 3,
	  BlueColor = 4

//Pen
Const BlackPen = wxPenFromColorName( "Black", 3, wxSOLID )
//Brush
Const RedBrush = wxBrushFromColorName( "Red", wxSOLID ),
	  YellowBrush = wxBrushFromColorName( "Yellow", wxSOLID ),
	  GreenBrush = wxBrushFromColorName( "Green", wxSOLID ),
	  BlueBrush = wxBrushFromColorName( "Blue", wxSOLID ),
	  WhiteBrush = wxBrushFromColorName( "White", wxSOLID )
	  
//Menu ids
Const wxID_NewGame = wxID_HIGHEST + 1,
      wxID_Solve = wxID_HIGHEST + 2,
      wxID_Replay = wxID_HIGHEST + 3

//Working vars
Common NumberofMoves = 0
Common MovesToSolve = 0
Common Solution = ""
Common board[4,4]
Common shuffleboard[4,4]


//Define a frame
Common frame = new wxFrame(Null, -1, "Color Crazy",wxPoint(156,119),wxSize(390,430),wxSIMPLE_BORDER | wxCAPTION | wxSYSTEM_MENU | wxMINIMIZE_BOX)
frame.CreateStatusBar( 1 )
frame.SetStatusText("Ready")
//Button definition.
Common cmdRow1 = new wxButton(frame, -1, "Row 0", wxPoint(296,16), wxSize(69,65))
//Button definition.
Common cmdRow2 = new wxButton(frame, -1, "Row 1", wxPoint(296,84), wxSize(69,65))
//Button definition.
Common cmdRow3 = new wxButton(frame, -1, "Row 2", wxPoint(296,152), wxSize(69,65))
//Button definition.
Common cmdRow4 = new wxButton(frame, -1, "Row 3", wxPoint(296,220), wxSize(69,65))
//Button definition.
Common cmdCol1 = new wxButton(frame, -1, "Col 0", wxPoint(14,296), wxSize(65,65))
//Button definition.
Common cmdCol2 = new wxButton(frame, -1, "Col 1", wxPoint(82,296), wxSize(65,65))
//Button definition.
Common cmdCol3 = new wxButton(frame, -1, "Col 2", wxPoint(150,296), wxSize(65,65))
//Button definition.
Common cmdCol4 = new wxButton(frame, -1, "Col 3", wxPoint(218,296), wxSize(65,65))

//Menu
Common mBar = New wxMenuBar()
frame.SetMenuBar(mBar)
Common mMenu1 = New wxMenu()
mBar.Append(mMenu1, "&Game")
mMenu1.Append(wxID_NewGame, "&New Game", "Start a New Game")
mMenu1.Append(wxID_Solve, "&Solve", "Solve the Puzzle")
mMenu1.Append(wxID_Replay, "&Replay", "Replay Last Puzzle")
mMenu1.AppendSeparator()
mMenu1.Append(wxID_EXIT, "E&xit", "Exit the Game")

Common bmpX = 280,
	   bmpY = 280
' create a bitmap for double buffering
Common bmp = wxEmptyBitmap( bmpX, bmpY )
' create a store for the graphic
Common bmpDC = wxMemoryDC()
bmpDC.SelectObject( bmp )
bmpDC.SetBackground( WhiteBrush )
bmpDC.SetPen( BlackPen )
bmpDC.Clear()
Common reDC = wxMemoryDC()

'load the bitmap, return device context
Sub LoadReminder()
    Dim myBMP = New wxEmptyBitmap( 50, 50 )
    Dim dc
    
    If myBMP.LoadFile( "ccremind.bmp", wxBITMAP_TYPE_BMP ) Then
		reDC.SelectObject( myBMP )
    	dc = wxClientDC( frame )
    	dc.BeginDrawing()
    	dc.Blit( 306, 299, 50, 50, reDC, 0, 0 )
    	dc.EndDrawing()
    End If
End Sub


'Split routine for delimited lists
Sub Split(alist[], expression, delimiter)
	Dim tempstr  'Working string
	Dim stritem 'Delimited string
	Dim i       'Instr position
	Dim count = 0  'Array counter
	
	'Clear the passed array.
	Erase alist[]
	expression = RTrim$(expression)
	delimiter = RTrim$(delimiter)
	'See if we have an expression
	If Len(expression) > 0 And Len(delimiter) > 0 Then
		'See if we have a delimiter
		i = Instr(expression, delimiter)
		If i > 0 Then
			'Get a working copy of expression.
			tempstr = expression
		Else
			'Force this var to a string
			tempstr = ""
		End If
		'Get all the items.
		While i > 0
			'Get the array item.
			stritem = Left$(tempstr, i - 1)
			'Add it to the array w/o delimiter
			alist[count] = stritem
			'Clip off item and delimiter
			tempstr = Mid$(tempstr, i + Len(delimiter), Len(tempstr) - Len(delimiter))
			'Look for the next delimiter
			i = Instr(tempstr, delimiter)
			'Inc the array counter
			count += 1
		End While
		'Check to see if we have any items left.
		If Len(tempstr) > 0 Then
			'Add them to array
			alist[count] = tempstr
		End If
	End If
End Sub

'Returns the brush of the selected color
Function GetBrush(Color)
	Select Case Color
		Case RedColor
			Return RedBrush
		Case YellowColor
			Return YellowBrush
		Case GreenColor
			Return GreenBrush
		Case BlueColor
			Return BlueBrush
	End Select
End Function

Sub DrawBoard()
	Dim myBrush
	
	bmpDC.SetBackground( WhiteBrush )
	bmpDC.Clear()
	'Draw the red squares
	myBrush=GetBrush(board[0,0])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(4, 4, 64, 64, 5)
	myBrush=GetBrush(board[0,1])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(72, 4, 64, 64, 5)
	myBrush=GetBrush(board[1,0])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(4, 72, 64, 64, 5)
	myBrush=GetBrush(board[1,1])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(72, 72, 64, 64, 5)
	
	'Draw the yellow squares
	myBrush=GetBrush(board[0,2])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(140, 4, 64, 64, 5)
	myBrush=GetBrush(board[0,3])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(208, 4, 64, 64, 5)
	myBrush=GetBrush(board[1,2])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(140, 72, 64, 64, 5)
	myBrush=GetBrush(board[1,3])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(208, 72, 64, 64, 5)

	'Draw the Green squares
	myBrush=GetBrush(board[2,0])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(4, 140, 64, 64, 5)
	myBrush=GetBrush(board[2,1])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(72, 140, 64, 64, 5)
	myBrush=GetBrush(board[3,0])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(4, 208, 64, 64, 5)
	myBrush=GetBrush(board[3,1])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(72, 208, 64, 64, 5)

	'Draw the Blue squares
	myBrush=GetBrush(board[2,2])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(140, 140, 64, 64, 5)
	myBrush=GetBrush(board[2,3])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(208, 140, 64, 64, 5)
	myBrush=GetBrush(board[3,2])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(140, 208, 64, 64, 5)
	myBrush=GetBrush(board[3,3])
	bmpDC.SetBrush( myBrush )
	bmpDC.DrawRoundedRectangle(208, 208, 64, 64, 5)
End Sub

Sub InitBoard()
		
	'Draw the red squares
	board[0,0] = RedColor
	board[0,1] = RedColor
	board[1,0] = RedColor
	board[1,1] = RedColor
	
	'Draw the yellow squares
	board[0,2] = YellowColor
	board[0,3] = YellowColor
	board[1,2] = YellowColor
	board[1,3] = YellowColor

	'Draw the Green squares
	board[2,0] = GreenColor
	board[2,1] = GreenColor
	board[3,0] = GreenColor
	board[3,1] = GreenColor

	'Draw the Blue squares
	board[2,2] = BlueColor
	board[2,3] = BlueColor
	board[3,2] = BlueColor
	board[3,3] = BlueColor
	
	DrawBoard()
	NumberofMoves = 0
	MovesToSolve = 0
	Shuffle()
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
	
End Sub

'Updates the board
Sub ShowBoard()
	Dim dc

    dc = wxClientDC( frame )
    dc.BeginDrawing()
    dc.Blit( 10, 12, bmpX, bmpY, bmpDC, 0, 0 )
    dc.EndDrawing()
End Sub

'Rows are number 0 to 3
'Dir = 1, move right, Dir = -1, move left
Sub MoveRow(Row, Dir)
	Dim SaveColor
	Dim i
	
	'Moving column down
	If Dir = 1 Then
		'Save the color in last cell
		SaveColor = board[Row, 3]
		'Move cells down one
		For i = 3 to 1 Step -1
			board[Row, i] = board[Row, i-1]
		Next
		'Add in saved color to top cell.
		board[Row, 0] = SaveColor
	'Moving column up.
	Else
		'Save the color in last cell
		SaveColor = board[Row, 0]
		'Move cells down one
		For i = 0 to 2 
			board[Row, i] = board[Row, i+1]
		Next
		'Add in saved color to top cell.
		board[Row, 3] = SaveColor
	End If
	DrawBoard()
	ShowBoard()
End Sub

'Columns are number 0 to 3
'Dir = 1, move down, Dir = -1, move up
Sub MoveColumn(Col, Dir)
	Dim SaveColor
	Dim i
	
	'Moving column down
	If Dir = 1 Then
		'Save the color in last cell
		SaveColor = board[3, Col]
		'Move cells down one
		For i = 3 to 1 Step -1
			board[i, Col] = board[i-1, Col]
		Next
		'Add in saved color to top cell.
		board[0, Col] = SaveColor
	'Moving column up.
	Else
		'Save the color in last cell
		SaveColor = board[0, Col]
		'Move cells down one
		For i = 0 to 2 
			board[i, Col] = board[i+1, Col]
		Next
		'Add in saved color to top cell.
		board[3, Col] = SaveColor
	End If
	DrawBoard()
	ShowBoard()
End Sub

'Shuffles the board
'This is treated as playing the game backward.
Sub Shuffle()
	Dim Row = 0
	Dim Col = 0
	Dim i = 0
	Dim j = 0
	
	Randomize
	
	'Reset the solution
	Solution = ""
	'Get the number of shuffle moves.
	MovesToSolve = Rnd(10) + 8
	For i = 1 to MovesToSolve
		Row = Rnd(5) - 1
		While Row < 0
			Row = Rnd(5) - 1
		Wend
		Col = Rnd(5) - 1
		While Col < 0
			Col = Rnd(5) - 1
		Wend
		Solution = Solution & "C" & LTrim(Str(Col)) & ","
		MoveColumn(Col, 1)
		Solution = Solution & "R" & LTrim(Str(Row)) & ","
		MoveRow(Row, 1)
	Next
	MovesToSolve = (MovesToSolve * 2)
	'Get rid of last comma
	If Mid(Solution,Len(Solution),1) = "," Then
		Solution = Mid(Solution, 1, Len(Solution) - 1)
	End If
	'Save the shuffled board
	For i = 0 to 3
		For j = 0 to 3
			shuffleboard[i,j] = board[i, j]
		Next
	Next
End Sub

Sub Delay()
	Dim myTicks
	
    myTicks = Ticks()
    While Ticks() < myTicks + 1000
    Wend

End Sub

Sub Solve()
	Dim i = 0
	Dim j = 0
	Dim ch = ""
	Dim RowCol = 0
	Dim sol[]
	Dim NewSolution = ""
	
	'Reset the board to suffled board.
	'Save the shuffled board
	For i = 0 to 3
		For j = 0 to 3
			board[i,j] = shuffleboard[i, j]
		Next
	Next
	'Get the soluton parameters.
	Split(sol[], Solution, ",")
	For i = UBound(sol[], 1) to 0 Step -1
		ch = sol[i]
		frame.SetStatusText("Move: " & ch)
		NewSolution = NewSolution & ch & " "
		RowCol = Val(Mid(ch, 2, 1))
		If Mid(ch, 1, 1) = "C" Then
			MoveColumn(RowCol, -1)
		ElseIf Mid(ch, 1, 1) = "R" Then
			MoveRow(RowCol, -1)
		End If
		Delay	
	Next
	'Show the solution.
	wxMessageBox("Solution:\n" & NewSolution)	
End Sub

Sub onPaint( event )
	Dim dc
	
    ' get the DC of the frame
    dc = wxPaintDC( frame )
    dc.BeginDrawing()

    ' blit the bitmap
    dc.Blit( 10, 12, bmpX, bmpY, bmpDC, 0, 0 )
	'blit the reminder graphic
	dc.Blit( 306, 299, 50, 50, reDC, 0, 0 )
	
    dc.EndDrawing()
    
    
End Sub
Connect( frame, -1, wxEVT_PAINT, "onPaint" )

//Event Sub for the wxID_NewGame menu option
Sub OnMenuEvent3 ( event )
	InitBoard()
	ShowBoard()
End Sub
//***Change 'frame' to form name used***
Connect( frame, wxID_NewGame, wxEVT_COMMAND_MENU_SELECTED, "OnMenuEvent3" )

//Event Sub for the wxID_Solve menu option
Sub OnMenuEvent4 ( event )
	Solve()
End Sub
//***Change 'frame' to form name used***
Connect( frame, wxID_Solve, wxEVT_COMMAND_MENU_SELECTED, "OnMenuEvent4" )

//Event Sub for the wxID_Replay menu option
Sub OnMenuEvent5 ( event )
	Dim i = 0
	Dim j = 0
	
	'Reset the board to suffled board.
	'Save the shuffled board
	For i = 0 to 3
		For j = 0 to 3
			board[i,j] = shuffleboard[i, j]
		Next
	Next
	DrawBoard()
	ShowBoard()
	NumberofMoves = 0
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
		
End Sub
//***Change 'frame' to form name used***
Connect( frame, wxID_Replay, wxEVT_COMMAND_MENU_SELECTED, "OnMenuEvent5" )


//cmdRow1 event code.
Sub cmdRow1_Click ( event )
	MoveRow(0, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdRow1 connector.
Connect( cmdRow1, wxEVT_COMMAND_BUTTON_CLICKED, "cmdRow1_Click" )


//cmdRow2 event code.
Sub cmdRow2_Click ( event )
	MoveRow(1, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdRow2 connector.
Connect( cmdRow2, wxEVT_COMMAND_BUTTON_CLICKED, "cmdRow2_Click" )


//cmdRow3 event code.
Sub cmdRow3_Click ( event )
	MoveRow(2, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdRow3 connector.
Connect( cmdRow3, wxEVT_COMMAND_BUTTON_CLICKED, "cmdRow3_Click" )


//cmdRow4 event code.
Sub cmdRow4_Click ( event )
	MoveRow(3, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdRow4 connector.
Connect( cmdRow4, wxEVT_COMMAND_BUTTON_CLICKED, "cmdRow4_Click" )


//cmdCol1 event code.
Sub cmdCol1_Click ( event )
	MoveColumn(0, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdCol1 connector.
Connect( cmdCol1, wxEVT_COMMAND_BUTTON_CLICKED, "cmdCol1_Click" )


//cmdCol2 event code.
Sub cmdCol2_Click ( event )
	MoveColumn(1, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdCol2 connector.
Connect( cmdCol2, wxEVT_COMMAND_BUTTON_CLICKED, "cmdCol2_Click" )


//cmdCol3 event code.
Sub cmdCol3_Click ( event )
	MoveColumn(2, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdCol3 connector.
Connect( cmdCol3, wxEVT_COMMAND_BUTTON_CLICKED, "cmdCol3_Click" )


//cmdCol4 event code.
Sub cmdCol4_Click ( event )
	MoveColumn(3, -1)
	NumberofMoves += 1
	frame.SetStatusText("Move: " & NumberofMoves & " To Solve: " & MovesToSolve)
End Sub
//cmdCol4 connector.
Connect( cmdCol4, wxEVT_COMMAND_BUTTON_CLICKED, "cmdCol4_Click" )



'Add in the form exit event sub
Sub onFileExit( event )
	Dim dialog = new wxMessageDialog( frame, "Are you sure?", "Exiting Program", wxYES_NO + wxCENTRE + wxICON_QUESTION )
	Dim result = dialog.ShowModal()
	Delete dialog

	If result = wxID_YES Then
		End
	End If
End Sub
Connect( frame, wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED, "onFileExit" )
Connect( frame, wxEVT_CLOSE_WINDOW, "onFileExit" )


'Set the reminder graphic
LoadReminder()
'DrawBoard
InitBoard()

'Show the frame
frame.Show (True)

