Artifact [624189b0ee]

Artifact 624189b0eeff81a72c62b9f9e7d7e4608b595562:


using Tk

using SQLite

######
#DECLARATIONS - DICTIONARIES
######

global pieceValTenjiku = Dict{String, Int64}("_" => 0, "bishop" => 10, "bishop general" => 21, "blind tiger" => 3, "copper general" => 2, "chariot soldier" => 18, "dog" => 1, "drunk elephant" => 3, "dragon horse" => 12, "dragon king" => 14, "ferocious leopard" => 3, "flying ox" => 16, "flying stag" => 9, "fire demon" => 83, "free boar" => 16, "free eagle" => 22, "gold general" => 3, "great general" => 45, "heavenly tetrarch" => 12, "horned falcon" => 19, "iron general" => 2, "king" => 500, "kirin" => 3, "lance" => 6, "lion hawk" => 25, "lion" => 18, "multi general" => 6, "knight" => 1, "pawn" => 1, "phoenix" => 3, "queen" => 22, "rook" => 12, "reverse chariot" => 6, "rook general" => 23, "silver general" => 2, "soaring eagle" => 18, "side mover" => 7, "side soldier" => 7, "vice general" => 39, "vertical mover" => 7, "vertical soldier" => 8, "water buffalo" => 17, "whale" => 10, "white horse" => 14)

global rangeJumpPriority = Dict{String, Int64}("_" => 0, "bishop" => 0, "bishop general" => 1, "blind tiger" => 0, "copper general" => 0, "chariot soldier" => 0, "dog" => 0, "drunk elephant" => 0, "dragon horse" => 0, "dragon king" => 0, "ferocious leopard" => 0, "flying ox" => 0, "flying stag" => 0, "fire demon" => 0, "free boar" => 0, "free eagle" => 0, "gold general" => 0, "great general" => 3, "heavenly tetrarch" => 0, "horned falcon" => 0, "iron general" => 0, "king" => 4, "kirin" => 0, "lance" => 0, "lion hawk" => 0, "lion" => 0, "multi general" => 0, "knight" => 0, "pawn" => 0, "phoenix" => 0, "queen" => 0, "rook" => 0, "reverse chariot" => 0, "rook general" => 1, "silver general" => 0, "soaring eagle" => 0, "side mover" => 0, "side soldier" => 0, "vice general" => 2, "vertical mover" => 0, "vertical soldier" => 0, "water buffalo" => 0, "whale" => 0, "white horse" => 0)

global pieceValChu = Dict{String, Int64}("_" => 0, "lion" => 20, "queen" => 12, "dragon king" => 8, "soaring eagle" => 11, "dragon horse" => 7, "horned falcon" => 10, "rook" => 6, "bishop" => 5, "vertical mover" => 4, "flying ox" => 8, "side mover" => 4, "free boar" => 8, "king" => 50, "phoenix" => 3, "kirin" => 3, "reverse chariot" => 3, "whale" => 5 , "lance" => 3, "white horse" => 7, "drunk elephant" => 3, "gold general" => 3, "ferocious leopard" => 3, "blind tiger" => 3, "flying stag" => 6, "silver general" => 2, "copper general" => 2, "go between" => 1, "pawn" => 1)

global pieceVal = Dict{String,Int64}("_" => 0, "pawn"=>1, "pawn promoted" =>2, "lance" =>4, "lance promomted" =>5, "knight" =>6,
"knight promoted" =>7, "silver general" =>7,"silver general promoted" =>8, "gold general" =>8, "bishop" =>11, "rook" =>13, "bishop promoted" =>15, "rook promoted" =>17, "king"=>50)

global prStandard = Dict{String, String}("rook promoted" => "dragon king","bishop promoted" => "dragon horse","silver general promoted" => "gold general",
 	"knight promoted" => "gold general", "lance promoted" => "gold general", "pawn promoted" => "gold general")
global prTenjiku = Dict{String,String}("bishop promoted" => "dragon horse", "bishop general promoted" => "vice general",
 	"blind tiger promoted" => "flying stag", "chariot soldier promoted" => "heavenly tetrarch", "copper general promoted" => "side mover", "dog promoted" => "multi general",
  "dragon horse promoted" => "horned falcon", "dragon king promoted" => "soaring eagle", "drunk elephant promoted" => "king", "ferocious leopard promoted" => "bishop",
  "go between promomted" => "drunk elephant", "gold general promoted" => "rook", "horned falcon promoted" => "bishop general", "iron general promoted" => "vertical soldier", "kirin promoted" => "lion",
  "knight promoted" => "side soldier", "lance promoted" => "white horse", "lion promoted" => "lion hawk", "pawn promoted" => "gold general", "phoenix promoted" => "queen", "queen promoted" => "free eagle",
  "reverse chariot promoted" => "whale", "rook promoted" => "dragon king", "rook general promoted" => "great general", "side mover promoted" => "free boar",
  "side soldier promoted" => "water buffalo", "silver general promoted" => "vertical mover", "soaring eagle promoted" => "rook general", "vertical mover promoted" => "flying ox",
  "vertical soldier promoted" => "chariot soldier", "water buffalo promoted" => "fire demon"  )

######
#DECLARATIONS - GLOBAL VARIABLES
######
global fileName

global defEmpty = "_"
global defBishop = "bishop"
global defBishopGeneral = "bishop general"
global defBlindTiger = "blind tiger"
global defCopperGeneral = "copper general"
global defChariotSoldier = "chariot soldier"
global defDog = "dog"
global defDrunkElephant = "drunk elephant"
global defDragonHorse = "dragon horse"
global defDragonKing = "dragon king"
global defFerociousLeopard = "ferocious leopard"
global defFlyingOx = "flying ox"
global defFlyingStag = "flying stag"
global defFireDemon = "fire demon"
global defFreeBoar = "free boar"
global defFreeEagle = "free eagle"
global defGoBetween = "go between"
global defGoldGeneral = "gold general"
global defGreatGeneral = "great general"
global defHeavenlyTetrarch = "heavenly tetrarch"
global defHornedFalcon = "horned falcon"
global defIronGeneral = "iron general"
global defKing = "king"
global defPrince = "prince"
global defKirin = "kirin"
global defLance = "lance"
global defLionHawk = "lion hawk"
global defLion = "lion"
global defMultiGeneral = "multi general"
global defKnight = "knight"
global defPawn = "pawn"
global defPhoenix = "phoenix"
global defQueen = "queen"
global defRook = "rook"
global defReverseChariot = "reverse chariot"
global defRookGeneral = "rook general"
global defSilverGeneral = "silver general"
global defSoaringEagle = "soaring eagle"
global defSideMover = "side mover"
global defSideSoldier = "side soldier"
global defViceGeneral = "vice general"
global defVerticalMover = "vertical mover"
global defVerticalSoldier = "vertical soldier"
global defWaterBuffalo = "water buffalo"
global defWhale = "whale"
global defWhiteHorse = "white horse"


global defDummy = "D"
global defWhite = "Wh"
global defBlack = "Bl"

global dim
global tDim = 16
global cDim = 12
global sDim = 9
global mDim = 5

global tPrZoneB = 12
global cPrZoneB = 9
global sPrZoneB = 7
global mPrZoneB = 5

global tPrZoneW = 5
global cPrZoneW = 4
global sPrZoneW = 3
global mPrZoneW = 1



global moveChoice = Array{Int64}(9)
global validateMoveChoice = Array{Int64}(8)
global strength = -1
global whitePrison = String[]
global blackPrison = String[]
global chessboard
global tempChessboard
global demonPressure = 0

global currTurn = defBlack
global pieceImgWhite = Image("EmptyTile.gif")
global pieceImgBlack = Image("EmptyTileBlack.gif")
global royaltyTaken = false
global remainingRoyaltyBlack = 1
global remainingRoyaltyWhite = 1

#Global variable used for Board GUI

global indicateMoveArray = []
global pieceGUImoved
global pieGUImovedX = 0
global pieGUImovedY = 0
global multipleMoveCounter = 0
global previousMoveGUI = [0,0,0,0]

######
#DECLARATIONS - MOVE CHOICES
######

type moveOffset
	row::Int64
	col::Int64
end

moveOption = Array{moveOffset}(17)

moveOption[1] = moveOffset(-1, -1)
moveOption[2] = moveOffset(-1, 0)
moveOption[3] = moveOffset(-1, 1)
moveOption[4] = moveOffset(0, -1)
moveOption[5] = moveOffset(0, 0)
moveOption[6] = moveOffset(0, 1)
moveOption[7] = moveOffset(1, -1)
moveOption[8] = moveOffset(1, 0)
moveOption[9] = moveOffset(1, 1)
moveOption[10] = moveOffset(-2, -1)
moveOption[11] = moveOffset(-2, 1)
moveOption[12] = moveOffset(2, -1)
moveOption[13] = moveOffset(2, 1)
moveOption[14] = moveOffset(-1, -2)
moveOption[15] = moveOffset(-1, 2)
moveOption[16] = moveOffset(1, -2)
moveOption[17] = moveOffset(1, 2)

type piece
	#display::String # FOR TESTING
	name::String
	side::AbstractString
	BAttack::Int
	WAttack::Int
	promote::Bool
end

######
# MAIN FUNCTION
######
function transMoveNumber(num::Int64)
  if mod(num,2) == 1
    return defBlack
  else
    return defWhite
  end
end


function coordinates(index::Int64)
	x = index % dim
	if x == 0
		x = dim
	end
	y = (index - x)/dim + 1
	x = convert(Int64, x)
	y = convert(Int64, y)
  	return x, y
end


function moveFunctionsAll(option::String)
	global chessboard
	global strength
	global demonPressure
	local saveChessboard = deepcopy(chessboard)
	saveOption = option
	if saveOption == "pressure" || saveOption == "update"
		for i in 1:dim
			for j in 1:dim
				chessboard[i, j].WAttack = 0
				chessboard[i, j].BAttack = 0
			end
		end
	end
	blankChessboard = deepcopy(chessboard)
	if saveOption == "pressure"
		option = "update"
		strength = -1
		demonPressure = 1
	end
	for i in 1:dim
		for j in 1:dim
			if chessboard[i, j].side == currTurn && (saveOption == "capture" || saveOption == "pressure")
				pieceFunctions(option, i, j)
				demonPressure = 0
				if saveOption == "pressure"
					for a in 1:dim
						for b in 1:dim
							saveChessboard2 = deepcopy(chessboard)
							if currTurn == defBlack
								if chessboard[a, b].BAttack == 1 && saveChessboard[a, b].WAttack == 0 && chessboard[a, b].side == defDummy
									testMoveSingle(i, j, a, b)
									getTotalSum(i, j, a, b)
								end
							elseif currTurn == defWhite
								if chessboard[a, b].WAttack == 1 && saveChessboard[a, b].BAttack == 0 && chessboard[a, b].side == defDummy
									testMoveSingle(i, j, a, b)
									getTotalSum(i, j, a, b)
								end
							end
							chessboard = saveChessboard2
						end
					end
					chessboard = deepcopy(blankChessboard)
				end
			elseif saveOption == "update"
				pieceFunctions(option, i, j)
			end
		end
	end
	if saveOption == "capture" || saveOption == "pressure"
		chessboard = saveChessboard
	end
end

function moveFunctionsPick(option::String, srcRow::Int64, srcCol::Int64)
	global chessboard
	#println(validateMoveChoice)
	saveOption = option
	if option == "check" || option == "single update"
		option = "update"
	end
	saveChessboard = deepcopy(chessboard)
	pieceFunctions(option, srcRow, srcCol)
	chessboard = saveChessboard
	if saveOption == "check"
		checkMove(saveChessboard)
	end
end

function pieceFunctions(option::String, srcRow::Int64, srcCol::Int64)
	storePiece = chessboard[srcRow, srcCol]
	if contains(storePiece.name,"promoted")
		if dim == mDim || dim == sDim
			storePiece.name = prStandard[storePiece.name]
		elseif dim == cDim || dim == tDim
			storePiece.name = prTenjiku[storePiece.name]
		end
	end
	if storePiece.name == defBishop
		defBishopMove(srcRow, srcCol, option)
	elseif storePiece.name == defBishopGeneral
		defBishopGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defBlindTiger
		defBlindTigerMove(srcRow, srcCol, option)
	elseif storePiece.name == defCopperGeneral
		defCopperGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defChariotSoldier
		defChariotSoldierMove(srcRow, srcCol, option)
	elseif storePiece.name == defDog
		defDogMove(srcRow, srcCol, option)
	elseif storePiece.name == defDrunkElephant
		defDrunkElephantMove(srcRow, srcCol, option)
	elseif storePiece.name == defDragonHorse
		defDragonHorseMove(srcRow, srcCol, option)
	elseif storePiece.name == defDragonKing
		defDragonKingMove(srcRow, srcCol, option)
	elseif storePiece.name == defFerociousLeopard
		defFerociousLeopardMove(srcRow, srcCol, option)
	elseif storePiece.name == defFireDemon
		defFireDemonMove(srcRow, srcCol, option)
	elseif storePiece.name == defFlyingOx
		defFlyingOxMove(srcRow, srcCol, option)
	elseif storePiece.name == defFlyingStag
		defFlyingStagMove(srcRow, srcCol, option)
	elseif storePiece.name == defFreeBoar
		defFreeBoarMove(srcRow, srcCol, option)
	elseif storePiece.name == defFreeEagle
		defFreeEagleMove(srcRow, srcCol, option)
	elseif storePiece.name == defGoldGeneral
		defGoldGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defGreatGeneral
		defGreatGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defHeavenlyTetrarch
		defHeavenlyTetrarchMove(srcRow, srcCol, option)
	elseif storePiece.name == defHornedFalcon
		defHornedFalconMove(srcRow, srcCol, option)
	elseif storePiece.name == defIronGeneral
		defIronGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defKing
		defKingMove(srcRow, srcCol, option)
	elseif storePiece.name == defKirin
		defKirinMove(srcRow, srcCol, option)
	elseif storePiece.name == defLance
		defLanceMove(srcRow, srcCol, option)
	elseif storePiece.name == defLionHawk
		defLionHawkMove(srcRow, srcCol, option)
	elseif storePiece.name == defLion
		defLionMove(srcRow, srcCol, option)
	elseif storePiece.name == defMultiGeneral
		defMultiGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defKnight
		defKnightMove(srcRow, srcCol, option)
	elseif storePiece.name == defPawn
		defPawnMove(srcRow, srcCol, option)
	elseif storePiece.name == defPhoenix
		defPhoenixMove(srcRow, srcCol, option)
	elseif storePiece.name == defQueen
		defQueenMove(srcRow, srcCol, option)
	elseif storePiece.name == defRook
		defRookMove(srcRow, srcCol, option)
	elseif storePiece.name == defReverseChariot
		defReverseChariotMove(srcRow, srcCol, option)
	elseif storePiece.name == defRookGeneral
		defRookGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defSilverGeneral
		defSilverGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defSoaringEagle
		defSoaringEagleMove(srcRow, srcCol, option)
	elseif storePiece.name == defSideMover
		defSideMoverMove(srcRow, srcCol, option)
	elseif storePiece.name == defSideSoldier
		defSideSoldierMove(srcRow, srcCol, option)
	elseif storePiece.name == defViceGeneral
		defViceGeneralMove(srcRow, srcCol, option)
	elseif storePiece.name == defVerticalMover
		defVerticalMoverMove(srcRow, srcCol, option)
	elseif storePiece.name == defVerticalSoldier
		defVerticalSoldierMove(srcRow, srcCol, option)
	elseif storePiece.name == defWaterBuffalo
		defWaterBuffaloMove(srcRow, srcCol, option)
	elseif storePiece.name == defWhale
		defWhaleMove(srcRow, srcCol, option)
	elseif storePiece.name == defWhiteHorse
		defWhiteHorseMove(srcRow, srcCol, option)
	end
end

function checkMove(saveChessboard)
	i = 3
	storePiece = chessboard[validateMoveChoice[1], validateMoveChoice[2]]
	if contains(storePiece.name,"promoted")
		if dim == mDim || dim == sDim
			storePiece.name = prStandard[storePiece.name]
		elseif dim == cDim || dim == tDim
			storePiece.name = prTenjiku[storePiece.name]
		end
	end
	while (validateMoveChoice[i] != 0 && validateMoveChoice[i + 1] != 0) && i <=7
		if validateMoveChoice[5] != 0 && validateMoveChoice[6] != 0 && validateMoveChoice[7] == 0 && validateMoveChoice[8] == 0# double capture exceptions
			tempRow = validateMoveChoice[3] - validateMoveChoice[1]
			tempCol = validateMoveChoice[4] - validateMoveChoice[2]
			tempRow2 = validateMoveChoice[5] - validateMoveChoice[3]
			tempCol2 = validateMoveChoice[6] - validateMoveChoice[4]
			if (storePiece.name == defHornedFalcon)||
          (storePiece.name == defSoaringEagle)||
          (storePiece.name == defHeavenlyTetrarch)||
          (storePiece.name == defFreeEagle)||
          (storePiece.name == defLionHawk)||
          (storePiece.name == defLion)

				if (validateMoveChoice[5] == validateMoveChoice[1]) && (validateMoveChoice[6] == validateMoveChoice[2]) # Check igui. Returns to same spot
					if (storePiece.side != chessboard[validateMoveChoice[3], validateMoveChoice[4]].side)
						if (storePiece.name == defLionHawk)||
                (storePiece.name == defLion)||
                (storePiece.name == defHeavenlyTetrarch)
							if (tempRow <= 1 && tempRow >= -1) && (tempCol <= 1 && tempCol >= -1)
								if storePiece.name == defHeavenlyTetrarch
									if chessboard[validateMoveChoice[3], validateMoveChoice[4]].side == defDummy
										chessboard = saveChessboard
										return false
									end
								end
								chessboard = saveChessboard
								return true
							end
						elseif ((storePiece.name == defHornedFalcon) && tempCol == 0)||
              ((storePiece.name == defSoaringEagle) && (tempCol == 1 || tempCol == -1))
							if storePiece.side == defWhite && tempRow == -1||
                  storePiece.side == defBlack && tempRow == 1
								chessboard = saveChessboard
								return true
							end
						elseif storePiece.name == defFreeEagle
							if (tempRow == 1 || tempRow == -1) && (tempCol == 1 || tempCol == -1)
								chessboard = saveChessboard
								return true
							end
						end
					end
				elseif (storePiece.side != chessboard[validateMoveChoice[3], validateMoveChoice[4]].side)&&  # Check if both squares valid
          (chessboard[validateMoveChoice[3], validateMoveChoice[4]].side != chessboard[validateMoveChoice[5], validateMoveChoice[6]].side)
					if ((storePiece.name == defHornedFalcon) && tempCol == 0)||
              ((storePiece.name == defSoaringEagle) && (tempCol == 1 || tempCol == -1))
						if tempRow == tempRow2 && tempCol == tempCol2
							if (storePiece.side == defWhite && tempRow == -1)||
                  (storePiece.side == defBlack && tempRow == 1)
								chessboard = saveChessboard
								return true
							end
						end
					elseif storePiece.name == defFreeEagle
						if (tempRow == 1 || tempRow == -1) && (tempCol == 1 || tempCol == -1) && (tempRow2 == 1 || tempRow2 == -1) &&(tempCol2 == 1 || tempCol2 == -1)
							chessboard = saveChessboard
							return true
						end
					elseif (storePiece.name == defLionHawk)||
              (storePiece.name == defLion)
						if (tempRow <= 1 && tempRow >= -1) && (tempCol <= 1 && tempCol >= -1) && (tempRow2 <= 1 && tempRow2 >= -1) &&(tempCol2 <= 1 && tempCol2 >= -1)
							chessboard = saveChessboard
							return true
						end
					end
				end
			end
		elseif storePiece.side == defBlack
			if chessboard[validateMoveChoice[i], validateMoveChoice[i + 1]].BAttack == 0
				chessboard = saveChessboard
				return false
			end
			if chessboard[validateMoveChoice[i], validateMoveChoice[i + 1]].side == storePiece.side
				chessboard = saveChessboard
				return false
			end
		elseif storePiece.side == defWhite
			if chessboard[validateMoveChoice[i], validateMoveChoice[i + 1]].WAttack == 0
				chessboard = saveChessboard
				return false
			end
			if chessboard[validateMoveChoice[i], validateMoveChoice[i + 1]].side == storePiece.side
				chessboard = saveChessboard
				return false
			end
		end
		i += 2
	end
	chessboard = saveChessboard
	return true
end

function moveFunctions(option::String)
	global chessboard
	if option == "update" || option == "capture" || option == "pressure"
		if option == "capture"
			printBoardBAttack()
		end
		moveFunctionsAll(option)
	elseif option == "check" || option == "random" || option == "single update"
		moveFunctionsPick(option, validateMoveChoice[1], validateMoveChoice[2])
	end
end

function match(destRow::Int64, destCol::Int64)
	moveFunctionsPick("match", destRow, destCol)
end

######
# FUNCTIONS TO MODIFY BOARD
######

function move()
	global rangeBlock
	global moveChoice
	global strength
	global chessboard
	moveFunctions("update")
	saveChessboard = deepcopy(chessboard)
	moveChoice = [0, 0, 0, 0, 0, 0, 0, 0, 0]
	strength = -1
	checkKing()
	chessboard = deepcopy(saveChessboard)
	moveFunctions("capture")
	chessboard = deepcopy(saveChessboard)
	if moveChoice[1] == 0
		moveFunctions("pressure")
		if moveChoice[1] != 0 && moveChoice[2] != 0 && moveChoice[3] != 0 && moveChoice[4] != 0
			if chessboard[moveChoice[1], moveChoice[2]].name == defViceGeneral || chessboard[moveChoice[1], moveChoice[2]].name == defFireDemon
				match(moveChoice[3], moveChoice[4])
			end
		end
		chessboard = deepcopy(saveChessboard)
	end
  if dim == sDim || dim == mDim
	   dropChoice()
  end
	if moveChoice[1] == 0
		random()
		chessboard = deepcopy(saveChessboard)
	end
	aiPromote()
end

function checkKing()
	global validateMoveChoice
	for srcRow in 1:dim
		for srcCol in 1:dim
			if chessboard[srcRow, srcCol].side == currTurn
				storePiece = chessboard[srcRow, srcCol]
				if contains(storePiece.name,"promoted")
					if dim == mDim || dim == sDim
						storePiece.name = prStandard[storePiece.name]
					elseif dim == cDim || dim == tDim
						storePiece.name = prTenjiku[storePiece.name]
					end
				end
				if storePiece.name == defKing
					if (currTurn == defWhite && storePiece.BAttack != 0) || (currTurn == defBlack && storePiece.WAttack != 0) # Being attacked
						moveFunctionsPick("king", srcRow, srcCol)
					end
				end
			end
		end
	end
end

function aiPromote()
	global moveChoice
	i = 7
	while moveChoice[i] == 0 && moveChoice[i + 1] == 0
		i -= 2
		if i <= 0
			return
		end
	end
	if canPromote(moveChoice[i], moveChoice[i + 1])
		moveChoice[9] = 1
	end
end

function random()
	global moveChoice
	totalSquares = dim * dim
	while true
		i = rand(1:totalSquares)
		xyVal = coordinates(i)
		if chessboard[xyVal[1], xyVal[2]].side == currTurn
			moveChoice = [0, 0, 0, 0, 0, 0, 0, 0, 0]
      validateMoveChoice[1] = xyVal[1]
      validateMoveChoice[2] = xyVal[2]
			moveFunctions("random")
			if moveChoice[1] != 0
				return
			end
		end
	end
end

function getTotalSum(srcRow::Int64, srcCol::Int64, destRow::Int64, destCol::Int64)
	global strength
	global moveChoice
	temp = 0
	for i in 1:dim
		for j in 1:dim
			storePiece = chessboard[i, j]
			if contains(storePiece.name,"promoted")
				if dim == mDim || dim == sDim
					storePiece.name = prStandard[storePiece.name]
				elseif dim == cDim || dim == tDim
					storePiece.name = prTenjiku[storePiece.name]
				end
			end
			if currTurn == defBlack
				if storePiece.side != currTurn && storePiece.side != defDummy && storePiece.BAttack == 1
					if dim == tDim
						temp += pieceValTenjiku[storePiece.name]
					elseif dim == cDim
						temp += pieceValChu[storePiece.name]
					else
						temp += pieceVal[storePiece.name]
					end
				end
			elseif currTurn == defWhite
				if storePiece.side != currTurn && storePiece.side != defDummy && storePiece.WAttack == 1
					if dim == tDim
						temp += pieceValTenjiku[storePiece.name]
					elseif dim == cDim
						temp += pieceValChu[storePiece.name]
					else
						temp += pieceVal[storePiece.name]
					end
				end
			end
		end
	end
	if temp > strength && temp != 0
		storeMoveChoice = [srcRow, srcCol, destRow, destCol, 0, 0, 0, 0, 0]
		strength = temp
		moveChoice = deepcopy(storeMoveChoice)
		#println(strength)
		#println(moveChoice)
	end
end

function updatePiece(srcRow::Int64, srcCol::Int64, destRow::Int64, destCol::Int64, option::String)
	global tempChessboard
	global chessboard
	if option == "special update"
		if chessboard[srcRow, srcCol].side == defWhite
			tempChessboard[destRow, destCol].WAttack += 1
		elseif chessboard[srcRow, srcCol].side == defBlack
			tempChessboard[destRow, destCol].BAttack += 1
		end
	elseif option == "update"
		if chessboard[srcRow, srcCol].side == defWhite
			chessboard[destRow, destCol].WAttack += 1
		elseif chessboard[srcRow, srcCol].side == defBlack
			chessboard[destRow, destCol].BAttack += 1
		end
	end
end

function movePiece(srcRow, srcCol, destRow, destCol)
	#println("PATQA:: movePiece args: $srcRow $srcCol $destRow $destCol")
	pieceToMove = chessboard[srcRow, srcCol]
	pieceAttacked = chessboard[destRow, destCol]
	gamewin = false
	# Check if the pieceAttacked is opposing team
	if pieceToMove.side != pieceAttacked.side && pieceAttacked.side != defDummy && pieceAttacked.name != defEmpty
		gamewin = capturePiece(destRow, destCol)
	end
	setTile(destRow, destCol, pieceToMove.name, pieceToMove.side, pieceToMove.promote)
	clearTile(srcRow, srcCol)
	return gamewin
end

function capturePiece(destRow::Int64, destCol::Int64)
	captured = chessboard[destRow, destCol]
	if captured.side == defBlack
		capturedArray = whitePrison # Record which side the piece is on being captured, prison is the colour of where drop can check from
	elseif captured.side == defWhite # Use splice!(array, object) splice returns the object that is removed
		capturedArray = blackPrison
	end
	if captured.name == defKing # gamewin
		push!(capturedArray, captured.name)
		return true
	elseif captured.name == defGoldGeneral # Does not promote
		push!(capturedArray, captured.name)
		return false
	else
    if contains(captured.name,"promoted")
      splitName = rsplit(captured.name," ";limit = 2)
      captured.name = splitName[1]
    end
    push!(capturedArray, captured.name)
    return false
	end
	return false
end

# tempMoveChoice[1] is going to store the type of attack, 1 = single capture, 2 = double capture, 3 = vice general/fire demon
# Have not coded changing capturing chessboard
function capture(tempMoveChoice, demonBurnVal::Int64)
	printBoardBAttack()
	a = 0
	b = 0
	global strength
	global moveChoice
	global chessboard
	local saveChessboard
	temp = -1
	if demonBurnVal != 0
		temp = demonBurnVal
	end
	#println(demonBurnVal)
	if tempMoveChoice[1] == 1 || tempMoveChoice[1] == 4
		a = 4
		b = 5
	elseif tempMoveChoice[1] == 3 || tempMoveChoice[1] == 5
		a = 8
		b = 9
		while tempMoveChoice[a] == 0 && tempMoveChoice[b] == 0
			a -= 2
			b -= 2
		end
	end
	saveChessboard = deepcopy(chessboard)
	if tempMoveChoice[1] == 1 || tempMoveChoice[1] == 3
		if dim == tDim
			temp = pieceValTenjiku[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name] - pieceValTenjiku[chessboard[tempMoveChoice[2], tempMoveChoice[3]].name]
		elseif dim == cDim
			temp = pieceValChu[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name] - pieceValTenjiku[chessboard[tempMoveChoice[2], tempMoveChoice[3]].name]
		else
			temp = pieceVal[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name] - pieceValTenjiku[chessboard[tempMoveChoice[2], tempMoveChoice[3]].name]
		end
		if chessboard[tempMoveChoice[2], tempMoveChoice[3]].side == defWhite # check if attack is safe
			if chessboard[tempMoveChoice[a], tempMoveChoice[b]].BAttack == 0
				if chessboard[tempMoveChoice[2], tempMoveChoice[3]].name == defKing && dim == tDim
					temp += 600
				elseif chessboard[tempMoveChoice[2], tempMoveChoice[3]].name == defKing && dim == cDim
					temp += 91
				elseif chessboard[tempMoveChoice[2], tempMoveChoice[3]].name == defKing
					temp += 68
				elseif dim == tDim
					temp += 500
				else
					temp += 50
				end
			end
		elseif chessboard[tempMoveChoice[2], tempMoveChoice[3]].side == defBlack
			if chessboard[tempMoveChoice[a], tempMoveChoice[b]].WAttack == 0
				if chessboard[tempMoveChoice[2], tempMoveChoice[3]].name == defKing && dim == tDim
					temp += 600
				elseif chessboard[tempMoveChoice[2], tempMoveChoice[3]].name == defKing && dim == cDim
					temp += 91
				elseif chessboard[tempMoveChoice[2], tempMoveChoice[3]].name == defKing
					temp += 68
				elseif dim == tDim
					temp += 500
				else
					temp += 50
				end
			end
		end
	elseif tempMoveChoice[1] == 2
		a = 4
		b = 5
		saveChessboard = deepcopy(chessboard)
		while tempMoveChoice[a] != 0 && tempMoveChoice[b] != 0
			if chessboard[tempMoveChoice[a], tempMoveChoice[b]].side != defDummy && chessboard[tempMoveChoice[2], tempMoveChoice[3]].side != chessboard[tempMoveChoice[a], tempMoveChoice[b]].side
				if dim == tDim
					if temp == -1
						temp = pieceValTenjiku[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name] - pieceValTenjiku[chessboard[tempMoveChoice[2], tempMoveChoice[3]].name]
					else
						temp += pieceValTenjiku[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name]
					end
				elseif dim == cDim
					if temp == -1
						temp = pieceValChu[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name] - pieceValTenjiku[chessboard[tempMoveChoice[2], tempMoveChoice[3]].name]
					else
						temp += pieceValChu[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name]
					end
				end
			end
			testMove(tempMoveChoice[a-2], tempMoveChoice[b-2], tempMoveChoice[a], tempMoveChoice[b])
			if tempMoveChoice[a + 2] == 0 && tempMoveChoice[b + 2] == 0
				if chessboard[tempMoveChoice[a], tempMoveChoice[b]].side == defWhite # check if attack is safe
					if chessboard[tempMoveChoice[a], tempMoveChoice[b]].BAttack == 0
						if dim == tDim
							temp += 500
						else
							temp += 50
						end
					end
				elseif chessboard[tempMoveChoice[a], tempMoveChoice[b]].side == defBlack
					if chessboard[tempMoveChoice[a], tempMoveChoice[b]].WAttack == 0
						if dim == tDim
							temp += 500
						else
							temp += 50
						end
					end
				end
			end
			a += 2
			b += 2
		end
	elseif tempMoveChoice[1] == 4 || tempMoveChoice[1] == 5
		if temp == -1
			temp = 0
		end
		temp = temp + pieceValTenjiku[chessboard[tempMoveChoice[a], tempMoveChoice[b]].name] - pieceValTenjiku[chessboard[tempMoveChoice[2], tempMoveChoice[3]].name]
		testMove(tempMoveChoice[2], tempMoveChoice[3], tempMoveChoice[a], tempMoveChoice[b])
		if chessboard[tempMoveChoice[a], tempMoveChoice[b]].side == defWhite # check if attack is safe
			if chessboard[tempMoveChoice[a], tempMoveChoice[b]].BAttack == 0
				temp += 500
			end
		elseif chessboard[tempMoveChoice[a], tempMoveChoice[b]].side == defBlack
			if chessboard[tempMoveChoice[a], tempMoveChoice[b]].WAttack == 0
				temp += 500
			end
		end
	end
	if temp > strength
		storeMoveChoice = [tempMoveChoice[2], tempMoveChoice[3], tempMoveChoice[4], tempMoveChoice[5], tempMoveChoice[6], tempMoveChoice[7], tempMoveChoice[8], tempMoveChoice[9], 0]
		strength = temp
		moveChoice = deepcopy(storeMoveChoice)
		println(strength)
		println(moveChoice)
	end
	chessboard = saveChessboard
end

function createBoard()
	global chessboard
	grid = [piece(defEmpty, defDummy, 0, 0, false)]
	temp = deepcopy(grid)
	for i in 1:dim - 1
		temp = vcat(temp, deepcopy(grid))
	end
	chessboard = deepcopy(temp)
	for i in 1:dim -1
		chessboard = hcat(chessboard, deepcopy(temp))
	end
end

function add(srcRow::Int64, srcCol::Int64, piecetype::String, colour::String)
	#chessboard[srcRow, srcCol].display = "X"
	chessboard[srcRow, srcCol].name = piecetype
	chessboard[srcRow, srcCol].side = colour
end

function delete(srcRow::Int64, srcCol::Int64)
	#chessboard[srcRow, srcCol].display = "_"
	chessboard[srcRow,srcCol].name = defEmpty
	chessboard[srcRow,srcCol].side = defDummy
end

function testMove(srcRow::Int64, srcCol::Int64, destRow::Int64, destCol::Int64) # copies move, runs update, modifies global chessboard
	global chessboard
	add(destRow, destCol, chessboard[srcRow, srcCol].name, chessboard[srcRow, srcCol].side)
	if chessboard[destRow, destCol].name == defFireDemon
		demonBurn(srcRow, srcCol, destRow, destCol, 0, "burn")
	end
	delete(srcRow, srcCol)
	moveFunctions("update")
end

function testMoveSingle(srcRow::Int64, srcCol::Int64, destRow::Int64, destCol::Int64)
	global chessboard
	global validateMoveChoice
	add(destRow, destCol, chessboard[srcRow, srcCol].name, chessboard[srcRow, srcCol].side)
	delete(srcRow, srcCol)
	validateMoveChoice = [destRow, destCol, 0, 0, 0, 0, 0, 0]
	for i in 1:dim
		for j in 1:dim
			chessboard[i, j].WAttack = 0
			chessboard[i, j].BAttack = 0
		end
	end
	moveFunctions("single update")
end

######
# FIRE DEMON ONLY
######

function demonBurn(srcRow::Int64, srcCol::Int64, destRow::Int64, destCol::Int64, temp::Int64, option::String)
	global chessboard
	global tempChessboard
	for i in 1:9
		if i != 5
			tempRow = destRow + moveOption[i].row
			tempCol = destCol + moveOption[i].col
			if tempRow <= dim && tempRow >= 1 && tempCol <= dim && tempCol >= 1
				if option == "demon update"
					updatePiece(srcRow, srcCol, tempRow, tempCol, "special update")
				end
				if option == "burn"
					if chessboard[tempRow, tempCol].side != chessboard[destRow, destCol].side && chessboard[tempRow, tempCol].side != defDummy
						delete(tempRow, tempCol)
					end
				end
				if option == "calculate"
					if chessboard[tempRow, tempCol].side != defDummy && chessboard[srcRow, srcCol].side != chessboard[tempRow, tempCol].side
						temp += pieceValTenjiku[chessboard[tempRow, tempCol].name]
						if chessboard[tempRow, tempCol].name == defFireDemon
							return 0
						end
					end
				end
			end
		end
	end
	if option == "calculate"
		return temp
	end
end

######
# MOVE TYPES
######

function step(srcRow::Int64, srcCol::Int64, option::String, destRow::Int64, destCol::Int64)
	global moveChoice
	if destRow <= dim && destRow >= 1 && destCol <= dim && destCol >= 1
		if option == "update" || option == "special update"
			updatePiece(srcRow, srcCol, destRow, destCol, option)
		end
   		if option == "GUI"
      			if chessboard[srcRow, srcCol].side != chessboard[destRow, destCol].side
      				indicateMoveOption(destRow, destCol)
			end
    		end
		if option == "capture"
			if chessboard[srcRow, srcCol].side != chessboard[destRow, destCol].side && chessboard[destRow, destCol].side != defDummy
				tempMoveChoice = [1, srcRow, srcCol, destRow, destCol, 0, 0, 0, 0]
				capture(tempMoveChoice, 0)
			end
		end
		if option == "random"
			if chessboard[srcRow, srcCol].side == defBlack
				if chessboard[destRow, destCol].WAttack == 0 && chessboard[destRow, destCol].side == defDummy
					moveChoice = [srcRow, srcCol, destRow, destCol, 0, 0, 0, 0, 0]
				end
			elseif chessboard[srcRow, srcCol].side == defWhite
				if chessboard[destRow, destCol].BAttack == 0 && chessboard[destRow, destCol].side == defDummy
					moveChoice = [srcRow, srcCol, destRow, destCol, 0, 0, 0, 0, 0]
				end
			end
		end
		if option == "king"
			if chessboard[srcRow, srcCol].side == defBlack
				if chessboard[destRow, destCol].WAttack == 0 && chessboard[destRow, destCol].side == defDummy
					moveChoice = [srcRow, srcCol, destRow, destCol, 0, 0, 0, 0, 0]
				end
			elseif chessboard[srcRow, srcCol].side == defWhite
				if chessboard[destRow, destCol].BAttack == 0 && chessboard[destRow, destCol].side == defDummy
					moveChoice = [srcRow, srcCol, destRow, destCol, 0, 0, 0, 0, 0]
				end
			end
		end
	end
end

function stepMultiple(srcRow::Int64, srcCol::Int64, option::String, tempRow::Int64, tempCol::Int64, jumps::Int64, tempMoveChoice)
	global tempChessboard
	global moveChoice
	a = 0
	b = 0
	if jumps <= 0
		return
	end
	saveMoveChoice = deepcopy(tempMoveChoice)
	for i in 1:9
		if (chessboard[srcRow, srcCol].name == defFreeEagle && (i == 1 || i == 3 || i == 7 || i == 9)) || (chessboard[srcRow, srcCol].name != defFreeEagle && i != 5)
			tempMoveChoice = deepcopy(saveMoveChoice)
			newTempRow = tempRow + moveOption[i].row
			newTempCol = tempCol + moveOption[i].col
			if newTempRow <= dim && newTempRow >= 1 && newTempCol <= dim && newTempCol >= 1
				if option == "special update"
					updatePiece(srcRow, srcCol, newTempRow, newTempCol, option)
				elseif option == "demon update"
					demonBurn(srcRow, srcCol, newTempRow, newTempCol, 0, option)
				end
       				if option == "GUI"
					if chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side
      						indicateMoveOption(newTempRow, newTempCol)
					end
				end
				if option == "capture"
					a = 4
					b = 5
					while tempMoveChoice[a] != 0 && tempMoveChoice[b] != 0
						a += 2
						b += 2
					end
					if tempMoveChoice[1] == 2
						if (a == 4 && b == 5 && chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side && chessboard[newTempRow, newTempCol].side != defDummy)
							tempMoveChoice[a] = newTempRow
							tempMoveChoice[b] = newTempCol
							capture(tempMoveChoice, 0)
						elseif a == 6 && b == 7 && (chessboard[srcRow, srcCol].side != chessboard[tempMoveChoice[4], tempMoveChoice[5]].side && chessboard[tempMoveChoice[4], tempMoveChoice[5]].side != defDummy) || (chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side && chessboard[newTempRow, newTempCol].side != defDummy)
							tempMoveChoice[a] = newTempRow
							tempMoveChoice[b] = newTempCol
							capture(tempMoveChoice, 0)
						end
					end
					if tempMoveChoice[1] == 3 || tempMoveChoice[1] == 4 || tempMoveChoice[1] == 5
						temp = 0
						if chessboard[srcRow, srcCol].name == defFireDemon
							temp = demonBurn(srcRow, srcCol, newTempRow, newTempCol, temp, "calculate")
						end
						if (chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side && chessboard[newTempRow, newTempCol].side != defDummy) || temp != 0
							tempMoveChoice[a] = newTempRow
							tempMoveChoice[b] = newTempCol
							capture(tempMoveChoice, temp)
						end
					end
				end
				if option == "match"
					a = 4
					b = 5
					while tempMoveChoice[a] != 0 && tempMoveChoice[b] != 0
						a += 2
						b += 2
					end
					tempMoveChoice[a] = newTempRow
					tempMoveChoice[b] = newTempCol
					if newTempRow == moveChoice[3] && newTempCol == moveChoice[4]
						jumps = 1
						moveChoice = [tempMoveChoice[2], tempMoveChoice[3], tempMoveChoice[4], tempMoveChoice[5], tempMoveChoice[6], tempMoveChoice[7], tempMoveChoice[8], tempMoveChoice[9], 0]
					end
				end
				if (chessboard[srcRow, srcCol].name == defLion || chessboard[srcRow, srcCol].name == defLionHawk) && chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side
					stepMultiple(srcRow, srcCol, option, newTempRow, newTempCol, jumps - 1, tempMoveChoice)
				elseif chessboard[newTempRow, newTempCol].side == defDummy
					stepMultiple(srcRow, srcCol, option, newTempRow, newTempCol, jumps - 1, tempMoveChoice)
				end
			end
		end
	end
end

function stepMultipleLinear(srcRow::Int64, srcCol::Int64, option::String, tempRow::Int64, tempCol::Int64, jumps::Int64, index::Int64, tempMoveChoice)
	global tempChessboard
	a = 0
	b = 0
	if jumps == 0
		return
	end
	saveMoveChoice = deepcopy(tempMoveChoice)
	if jumps == 2
		tempMoveChoice = deepcopy(saveMoveChoice)
		newTempRow = tempRow + moveOption[index].row
		newTempCol = tempCol + moveOption[index].col
		if newTempRow <= dim && newTempRow >= 1 && newTempCol <= dim && newTempCol >= 1
			tempMoveChoice[4] = newTempRow
			tempMoveChoice[5] = newTempCol
			if option == "special update" || option == "update"
				updatePiece(srcRow, srcCol, newTempRow, newTempCol, option)
			end
      			if option == "GUI"
				if chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side
      					indicateMoveOption(newTempRow, newTempCol)
				end
     			end
			if option == "capture"
				if chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side && chessboard[newTempRow, newTempCol].side != defDummy
					capture(tempMoveChoice, 0)
				end
			end
			stepMultipleLinear(srcRow, srcCol, option, newTempRow, newTempCol, jumps - 1, index, tempMoveChoice)
		end
	elseif jumps == 1
		newTempRow = tempRow - moveOption[index].row # igui
		newTempCol = tempCol - moveOption[index].col
			if option == "capture"
				if (chessboard[srcRow, srcCol].side != chessboard[tempMoveChoice[4], tempMoveChoice[5]].side && chessboard[tempMoveChoice[4], tempMoveChoice[5]].side != defDummy) # Check if either has occupied piece.
					tempMoveChoice[6] = newTempRow
					tempMoveChoice[7] = newTempCol
					capture(tempMoveChoice, 0)
				end
			end
		if chessboard[srcRow, srcCol].name != defHeavenlyTetrarch
			newTempRow = tempRow + moveOption[index].row
			newTempCol = tempCol + moveOption[index].col
			if newTempRow <= dim && newTempRow >= 1 && newTempCol <= dim && newTempCol >= 1
				if option == "update"
					updatePiece(srcRow, srcCol, newTempRow, newTempCol, option)
				end
				if option == "capture"
					if (chessboard[srcRow, srcCol].side != chessboard[tempMoveChoice[4], tempMoveChoice[5]].side && chessboard[tempMoveChoice[4], tempMoveChoice[5]].side != defDummy) || (chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side && chessboard[newTempRow, newTempCol].side != defDummy)
						tempMoveChoice[6] = newTempRow
						tempMoveChoice[7] = newTempCol
						capture(tempMoveChoice, 0)
					end
				end
			end
		end
	end
end

function rangeJump(srcRow::Int64, srcCol::Int64, option::String, index::Int64)
	local moveBlock = 0
	tempRow = srcRow
	tempCol = srcCol
	while true
		tempRow = tempRow + moveOption[index].row
		tempCol = tempCol + moveOption[index].col
		if tempRow > dim || tempRow < 1 || tempCol > dim || tempCol < 1
			break
		end
		if chessboard[tempRow, tempCol].side != defDummy
			moveBlock = 1
		end
		if (option == "update" || option == "special update")
			if moveBlock == 0 || (moveBlock == 1 && chessboard[tempRow, tempCol].side != defDummy && chessboard[srcRow, srcCol].side != chessboard[tempRow, tempCol].side)
				updatePiece(srcRow, srcCol, tempRow, tempCol, option)
			end
		end
    		if option == "GUI"
			if moveBlock == 0 || (moveBlock == 1 && chessboard[tempRow, tempCol].side != defDummy && chessboard[srcRow, srcCol].side != chessboard[tempRow, tempCol].side)
     				indicateMoveOption(tempRow, tempCol)
			end
   		end
		if chessboard[srcRow, srcCol].side != chessboard[tempRow, tempCol].side && chessboard[tempRow, tempCol].side != defDummy
			if option == "capture"
				tempMoveChoice = [1, srcRow, srcCol, tempRow, tempCol, 0, 0, 0, 0]
				capture(tempMoveChoice, 0)
			end
		end
		if option == "random"
			if chessboard[srcRow, srcCol].side == defBlack
				if chessboard[tempRow, tempCol].WAttack == 0 && chessboard[tempRow, tempCol].side == defDummy && moveBlock == 0
					moveChoice = [srcRow, srcCol, tempRow, tempCol, 0, 0, 0, 0, 0]
				end
			elseif chessboard[srcRow, srcCol].side == defWhite
				if chessboard[destRow, destCol].BAttack == 0 && chessboard[tempRow, tempCol].side == defDummy && moveBlock == 0
					moveChoice = [srcRow, srcCol, tempRow, tempCol, 0, 0, 0, 0, 0]
				end
			end
		end
		if rangeJumpPriority[chessboard[srcRow, srcCol].name] <= rangeJumpPriority[chessboard[tempRow, tempCol].name] # Not jumpable
			break
		end
	end
end

function range(srcRow::Int64, srcCol::Int64, option::String, tempRow::Int64, tempCol::Int64, index::Int64)
	local tempMoveChoice
	newTempRow = tempRow
	newTempCol = tempCol
	while true
		newTempRow = newTempRow + moveOption[index].row
		newTempCol = newTempCol + moveOption[index].col
		if newTempRow > dim || newTempRow < 1 || newTempCol > dim || newTempCol < 1
			break
		end
		if option == "update" || option == "special update"
			updatePiece(srcRow, srcCol, newTempRow, newTempCol, option)
		elseif option == "demon update"
			demonBurn(srcRow, srcCol, newTempRow, newTempCol, 0, option)
		end
   		if option == "GUI"
			if chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side
      				indicateMoveOption(newTempRow, newTempCol)
			end
    		end
		temp = 0
		if option == "capture"
			if chessboard[srcRow, srcCol].name == defFireDemon
				temp = demonBurn(srcRow, srcCol, newTempRow, newTempCol, temp, "calculate")
			end
			if (chessboard[srcRow, srcCol].side != chessboard[newTempRow, newTempCol].side && chessboard[newTempRow, newTempCol].side != defDummy) || temp != 0
				if chessboard[srcRow, srcCol].name == defFireDemon
					tempMoveChoice = [4, srcRow, srcCol, newTempRow, newTempCol, 0, 0, 0, 0]
				else
					tempMoveChoice = [1, srcRow, srcCol, newTempRow, newTempCol, 0, 0, 0, 0]
				end
				capture(tempMoveChoice, temp)
			end
		end
		if option == "random"
			if chessboard[srcRow, srcCol].side == defBlack
				if chessboard[newTempRow, newTempCol].WAttack == 0 && chessboard[newTempRow, newTempCol].side == defDummy
					moveChoice = [srcRow, srcCol, newTempRow, newTempCol, 0, 0, 0, 0]
				end
			elseif chessboard[srcRow, srcCol].side == defWhite
				if chessboard[newTempRow, newTempCol].BAttack == 0 && chessboard[newTempRow, newTempCol].side == defDummy
					moveChoice = [srcRow, srcCol, newTempRow, newTempCol, 0, 0, 0, 0]
				end
			end
		end
		if chessboard[newTempRow, newTempCol].side != defDummy
			break
		end
	end
end

######
# PROMOTiONS
######

function prPromote(destRow::Int64, destCol::Int64)
  println("once")
  chessboard[destRow,destCol].name = chessboard[destRow,destCol].name *" promoted"
  chessboard[destRow,destCol].promote = true
end

function canPromote(destRow::Int64, destCol::Int64)
  targetPie = chessboard[destRow,destCol]
  if !(targetPie.promote) #not promoted
    if dim == tDim && targetPie.name != defFireDemon && targetPie.name != defFreeEagle &&
      targetPie.name != defGreatGeneral && targetPie.name != defKing && targetPie.name != defLionHawk &&
      targetPie.name != defViceGeneral
      if targetPie.side == defWhite
        if destRow <= tPrZoneW
          return true
        end
      elseif targetPie.side == defBlack
        if destRow >= tPrZoneB
          return true
        end
      else
        return false
      end
    elseif dim == cDim && targetPie.name != defKing && targetPie.name != defQueen && targetPie.name != defLion
      if targetPie.side == defWhite
        if destRow <= cPrZoneW
          return true
        end
      elseif targetPie.side == defBlack
        if destRow >= cPrZoneB
          return true
        end
      else
        return false
      end
    elseif dim == sDim && get(prStandard,targetPie.name,"none") != "none"
      if targetPie.side == defWhite
        if destRow <= sPrZoneW
          return true
        end
      elseif targetPie.side == defBlack
        if destRow >= sPrZoneB
          return true
        end
      else
        return false
      end
    elseif dim == mDim && get(prStandard,targetPie.name,"none") != "none"
      if targetPie.side == defWhite
        if destRow <= mPrZoneW
          return true
        end
      elseif targetPie.side == defBlack
        if destRow >= mPrZoneB
          return true
        end
      else
        return false
      end
    end
  end
	return false
end
#

function autoPromote(destRow::Int64, destCol::Int64)  # Run function after pawn, lance or knight move. Check if auto promote.
	if chessboard[destRow, destCol].name == defPawn || chessboard[destRow, destCol].name == defLance
		if chessboard[destRow, destCol].side == defWhite
			if destRow == 1
			  prPromote(destRow, destCol)
				return true
			end
		elseif chessboard[destRow, destCol].side == defBlack
			if destRow == dim
				prPromote(destRow, destCol)
				return true
			end
		else
			return false
		end
	elseif dim != cDim && chessboard[destRow, destCol].name == defKnight
		if chessboard[destRow, destCol].side == defWhite
			if destRow <= 2
				prPromote(destRow, destCol)
				return true
			end
		elseif chessboard[destRow, destCol].side == defBlack
			if destRow >= dim - 1
				prPromote(destRow, destCol)
				return true
			end
		else
			return false
		end
	else
		return false
	end
	return false
end

######
# PIECE MOVES
######

function defKingMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 5
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defDrunkElephantMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if chessboard[srcRow, srcCol].side == defWhite && (i != 5 && i != 8) || chessboard[srcRow, srcCol].side == defBlack && (i != 2 && i != 5)
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defViceGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	global tempChessboard
	if option == "update"
		option = "special update"
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	for i in 1:9
		if i == 1 || i == 3 || i == 7 || i == 9
			rangeJump(srcRow, srcCol, option, i)
		end
	end
	tempMoveChoice = [3, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
	stepMultiple(srcRow, srcCol, option, srcRow, srcCol, 3, tempMoveChoice)
	if option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defGreatGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 5
			rangeJump(srcRow, srcCol, option, i)
		end
	end
end

function defBishopGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 1 || i == 3 || i == 7 || i == 9
			rangeJump(srcRow, srcCol, option, i)
		end
	end
end

function defRookGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 4 || i == 6 || i == 8
			rangeJump(srcRow, srcCol, option, i)
		end
	end
end

function defHornedFalconMove(srcRow::Int64, srcCol::Int64, option::String)
	global tempChessboard
	if option == "update"
		option = "special update"
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	for i in 1:9
		if i != 5 && ((chessboard[srcRow, srcCol].side == defWhite && i != 2) || (chessboard[srcRow, srcCol].side == defBlack && i != 8))
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif (chessboard[srcRow, srcCol].side == defWhite && i == 2) || (chessboard[srcRow, srcCol].side == defBlack && i == 8)
			tempMoveChoice = [2, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
			stepMultipleLinear(srcRow, srcCol, option, srcRow, srcCol, 2, i, tempMoveChoice)
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
		end
	end
	if option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defSoaringEagleMove(srcRow::Int64, srcCol::Int64, option::String)
	global tempChessboard
	if option == "update"
		option = "special update"
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	for i in 1:9
		if i != 5 && ((chessboard[srcRow, srcCol].side == defWhite && i != 1 && i != 3) || (chessboard[srcRow, srcCol].side == defBlack && i != 7 && i != 9))
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif (chessboard[srcRow, srcCol].side == defWhite && (i == 1 || i == 3)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 7 || i == 9))
			tempMoveChoice = [2, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
			stepMultipleLinear(srcRow, srcCol, option, srcRow, srcCol, 2, i, tempMoveChoice)
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
		end
	end
	if option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defDragonHorseMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 1 || i == 3 || i == 7 || i == 9
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 2 || i == 4 || i == 6 || i == 8
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defDragonKingMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 4 || i == 6 || i == 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 1 || i == 3 || i == 7 || i == 9
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defBishopMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 1 || i == 3 || i == 7 || i == 9
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defRookMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 4 || i == 6 || i == 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defFerociousLeopardMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 4 && i != 5 && i != 6
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defGoldGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && (i != 5 && i != 7 && i != 9)) || (chessboard[srcRow, srcCol].side == defBlack && (i != 1 && i != 3 && i != 5))
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defPawnMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && i == 2) || (chessboard[srcRow, srcCol].side == defBlack && i == 8)
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defGoBetweenMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defFireDemonMove(srcRow::Int64, srcCol::Int64, option::String)
	global tempChessboard
	if option == "update" || option == "capture"
		if option == "update" && demonPressure == 0
			option = "demon update"
		elseif option == "update" && demonPressure == 1
			option = "special update"
		end
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	for i in 1:9
		if i != 2 && i != 5 && i != 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
	tempMoveChoice = [5, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
	stepMultiple(srcRow, srcCol, option, srcRow, srcCol, 3, tempMoveChoice)
	if option == "demon update" || option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defHeavenlyTetrarchMove(srcRow::Int64, srcCol::Int64, option::String) # Need Exceptions
	for i in 1:9
		if i != 5
			tempMoveChoice = [2, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
			stepMultipleLinear(srcRow, srcCol, option, srcRow, srcCol, 2, i, tempMoveChoice)
		end
		if i != 4 && i != 5 && i != 6
			range(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col, i)
		elseif i == 4 || i == 6
			tempRow = srcRow + 2*moveOption[i].row
			tempCol = srcCol + 2*moveOption[i].col
			step(srcRow, srcCol, option, tempRow, tempCol)
			if tempRow <= dim && tempRow >= 1 && tempCol <= dim && tempCol >= 1
				if chessboard[tempRow, tempCol].side == defDummy
					step(srcRow, srcCol, option, srcRow + 3*moveOption[i].row, srcCol + 3*moveOption[i].col)
				end
			end
		end
	end
end

function defWaterBuffaloMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 2 && i != 5 && i != 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 2 || i == 8
			tempRow = srcRow + moveOption[i].row
			tempCol = srcCol + moveOption[i].col
			step(srcRow, srcCol, option, tempRow, tempCol)
			if tempRow <= dim && tempRow >= 1 && tempCol <= dim && tempCol >= 1
				if chessboard[tempRow, tempCol].side == defDummy
					step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
				end
			end
		end
	end
end

function defChariotSoldierMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 4 && i != 5 && i != 6
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 4 || i == 6
			tempRow = srcRow + moveOption[i].row
			tempCol = srcCol + moveOption[i].col
			step(srcRow, srcCol, option, tempRow, tempCol)
			if tempRow <= dim && tempRow >= 1 && tempCol <= dim && tempCol >= 1
				if chessboard[tempRow, tempCol].side == defDummy
					step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
				end
			end
		end
	end
end

function defSideSoldierMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 4 || i == 6
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 2 || i == 8
			tempRow = srcRow + moveOption[i].row
			tempCol = srcCol + moveOption[i].col
			step(srcRow, srcCol, option, tempRow, tempCol)
			if tempRow <= dim && tempRow >= 1 && tempCol <= dim && tempCol >= 1
				if chessboard[tempRow, tempCol].side == defDummy && ((chessboard[srcRow, srcCol].side == defWhite && i == 2) || (chessboard[srcRow, srcCol].side == defBlack && i == 8))
					step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
				end
			end
		end
	end
end

function defVerticalSoldierMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && i == 2) || (chessboard[srcRow, srcCol].side == defBlack && i == 8)
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 4 || i == 6 || i == 8
			tempRow = srcRow + moveOption[i].row
			tempCol = srcCol + moveOption[i].col
			step(srcRow, srcCol, option, tempRow, tempCol)
			if tempRow <= dim && tempRow >= 1 && tempCol <= dim && tempCol >= 1
				if chessboard[tempRow, tempCol].side == defDummy && (i == 4 || i == 6)
					step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
				end
			end
		end
	end
end

function defKnightMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 10:13
		if (chessboard[srcRow, srcCol].side == defWhite && (i == 10 || i == 11)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 12 || i == 13))
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defIronGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && (i == 1 || i == 2 || i == 3)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 7 || i == 8 || i == 9))
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defFreeEagleMove(srcRow::Int64, srcCol::Int64, option::String) # Need Exceptions
	global tempChessboard
	if option == "update"
		option = "special update"
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	tempMoveChoice = [2, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
	stepMultiple(srcRow, srcCol, option, srcRow, srcCol, 2, tempMoveChoice)
	for i in 1:9
		if i != 5
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
	if option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defLionHawkMove(srcRow::Int64, srcCol::Int64, option::String)
	global tempChessboard
	if option == "update"
		option = "special update"
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	tempMoveChoice = [2, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
	stepMultiple(srcRow, srcCol, option, srcRow, srcCol, 2, tempMoveChoice)
	for i in 1:17
		if i >= 1 && i <= 9 && i != 5
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
		elseif i >= 10 && i <= 17
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
		if i == 1 || i == 3 || i == 7 || i == 9
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
	if option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defQueenMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 5
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defLionMove(srcRow::Int64, srcCol::Int64, option::String)
	global tempChessboard
	if option == "update"
		option = "special update"
		tempChessboard = deepcopy(chessboard)
		for i in 1:dim
			for j in 1:dim
				tempChessboard[i, j].WAttack = 0
				tempChessboard[i, j].BAttack = 0
			end
		end
	end
	tempMoveChoice = [2, srcRow, srcCol, 0, 0, 0, 0, 0, 0]
	stepMultiple(srcRow, srcCol, option, srcRow, srcCol, 2, tempMoveChoice)
	for i in 1:17
		if i >= 1 && i <= 9 && i != 5
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
		elseif i >= 10 && i <= 17
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
	if option == "special update"
		for i in 1:dim
			for j in 1:dim
				if i == srcRow && j == srcCol
				elseif chessboard[srcRow, srcCol].side == defWhite && tempChessboard[i, j].WAttack >= 1
					chessboard[i, j].WAttack += 1
				elseif chessboard[srcRow, srcCol].side == defBlack && tempChessboard[i, j].BAttack >= 1
					chessboard[i, j].BAttack += 1
				end
			end
		end
	end
end

function defPhoenixMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 4 || i == 6 || i == 8
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		elseif i == 1 || i == 3 || i == 7 || i == 9
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
		end
	end
end

function defKirinMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 1 || i == 3 || i == 7 || i == 9
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		elseif i == 2 || i == 4 || i == 6 || i == 8
			step(srcRow, srcCol, option, srcRow + 2*moveOption[i].row, srcCol + 2*moveOption[i].col)
		end
	end
end

function defFreeBoarMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 2 && i != 5 && i != 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defFlyingOxMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 4 && i != 5 && i != 6
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defSideMoverMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 4 || i == 6
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 2 || i == 8
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defVerticalMoverMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i == 4 || i == 6
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defCopperGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8 || (chessboard[srcRow, srcCol].side == defWhite && (i == 1 || i == 3)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 7 || i == 9))
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defSilverGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (i != 4 && i != 5 && i != 6) && (chessboard[srcRow, srcCol].side == defWhite && i != 8) || (i != 4 && i != 5 && i != 6) && (chessboard[srcRow, srcCol].side == defBlack && i != 2)
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defMultiGeneralMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && (i == 2 || i == 7 || i == 9)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 1 || i == 3 || i == 8))
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defFlyingStagMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		elseif i != 5
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defDogMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && (i == 2 || i == 7 || i == 9)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 1 || i == 3 || i == 8))
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defBlindTigerMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i != 5 && ((chessboard[srcRow, srcCol].side == defWhite && i != 2) || (chessboard[srcRow, srcCol].side == defBlack && i != 8))
			step(srcRow, srcCol, option, srcRow + moveOption[i].row, srcCol + moveOption[i].col)
		end
	end
end

function defWhiteHorseMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8 || (chessboard[srcRow, srcCol].side == defWhite && (i == 1 || i == 3)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 7 || i == 9))
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defWhaleMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8 || (chessboard[srcRow, srcCol].side == defWhite && (i == 7 || i == 9)) || (chessboard[srcRow, srcCol].side == defBlack && (i == 1 || i == 3))
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defLanceMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if (chessboard[srcRow, srcCol].side == defWhite && i == 2) || (chessboard[srcRow, srcCol].side == defBlack && i == 8)
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

function defReverseChariotMove(srcRow::Int64, srcCol::Int64, option::String)
	for i in 1:9
		if i == 2 || i == 8
			range(srcRow, srcCol, option, srcRow, srcCol, i)
		end
	end
end

######
# TEST FUNCTIONS
######

function printBoard()
	for i in 1:dim
		for j in 1:dim
			stringTest = chessboard[i,j].display
			print(" $stringTest")
		end
		println("")
	end
end

function printBoardBAttack()
	for i in 1:dim
		for j in 1:dim
			stringTest = chessboard[i,j].BAttack
			print(" $stringTest")
		end
		println("")
	end
end

function printBoardWAttack()
	for i in 1:dim
		for j in 1:dim
			stringTest = chessboard[i,j].WAttack
			print(" $stringTest")
		end
		println("")
	end
end

######
# BOARD MODIFYING FUNCTIONS
######
function prDrop(srcRow::Int64, srcCol::Int64, prPiece::piece)
  validDrop::Bool = true
  if chessboard[srcRow, srcCol].name == defEmpty
    if prPiece.side == defBlack #black case
      if ((prPiece.name == defPawn || prPiece.name == defLance) && srcRow == 1)  #if pawn or lance can't move i.e. last row
        validDrop = false
      elseif (prPiece.name == defKnight && srcRow <= 2)    #if knight can't move i.e. last two rows
        validDrop = false
      elseif (prPiece.name == defPawn && chessboard[srcRow-1,srcCol].name == defKing) #check checkmate
        setTile(srcRow,srcCol,prPiece.name,prPiece.side)
        updatePiece()
        validDrop = checkCheckMate(defBlack) #Will need to change this to match up
        if (!validDrop)     #if it wasn't valid clear it
          clearTile(srcRow,srcCol)
        end
      elseif (prPiece.name == defPawn)
        if (checkColPawn(srcCol,prPiece.side))
          validDrop = false
        end
      end
    elseif prPiece.side == defWhite #white
      if ((prPiece.name == defPawn || prPiece.name == defLance) && srcRow == dim)
        validDrop = false
      elseif (prPiece.name == defKnight && srcRow >= dim-1)
        validDrop = false
      elseif (prPiece.name == defPawn && chessboard[srcRow+1,srcCol].name == defKing)
        setTile(srcRow,srcCol,prPiece.name,prPiece.side)
        updatePiece()
        validDrop = checkCheckMate(defWhite) #Will need to change this to match up
        if (!validDrop)
          clearTile(srcRow,srcCol)
        end
      elseif (prPiece.name == defPawn)
        if (checkColPawn(srcCol,prPiece.side))
          validDrop = false
        end
      end
		end
  else
    validDrop = false
  end
	return validDrop
end

function arrayDatabaseRowExchange(srcY)
	#assuming we have a global dim based on db metadata shogi? minishogi?
	row = abs(srcY-dim)+1
	return row
end

#populate board with shogi piece in ohashi order
function populateBoardShogi()
	#added king
	add(1,5,defKing,defBlack)
	add(9,5,defKing,defWhite)
	#added gold general
	add(1,6,defGoldGeneral,defBlack)
	add(9,4,defGoldGeneral,defWhite)
	add(1,4,defGoldGeneral,defBlack)
	add(9,6,defGoldGeneral,defWhite)
	#added silver general
	add(1,7,defSilverGeneral,defBlack)
	add(9,3,defSilverGeneral,defWhite)
	add(1,3,defSilverGeneral,defBlack)
	add(9,7,defSilverGeneral,defWhite)
	#added knight
	add(1,8,defKnight,defBlack)
	add(9,2,defKnight,defWhite)
	add(1,2,defKnight,defBlack)
	add(9,8,defKnight,defWhite)
	#added lancer
	add(1,9,defLance,defBlack)
	add(9,1,defLance,defWhite)
	add(1,1,defLance,defBlack)
	add(9,9,defLance,defWhite)
	#added bishop
	add(2,8,defBishop,defBlack)
	add(8,2,defBishop,defWhite)
	#added rook
	add(2,2,defRook,defBlack)
	add(8,8,defRook,defWhite)
	#added pawn on respective position
	pawnWhiteRow=3
	pawnBlackRow=7
	j=9
	while j > 0
		add(pawnWhiteRow,j,defPawn,defBlack)
		# 10-j needed to offset the different place to preserve ohashi order
		add(pawnBlackRow,(10-j),defPawn,defWhite)
		j-=1
	end
end

function populateBoardMiniShogi()
	#added king
	add(1,5,defKing,defBlack)
	add(5,1,defKing,defWhite)
	#added gold general
	add(1,4,defGoldGeneral,defBlack)
	add(5,2,defGoldGeneral,defWhite)
	#added silver general
	add(1,3,defSilverGeneral,defBlack)
	add(5,3,defSilverGeneral,defWhite)
	#added bishop
	add(1,2,defBishop,defBlack)
	add(5,4,defBishop,defWhite)
	#added rook
	add(1,1,defRook,defBlack)
	add(5,5,defRook,defWhite)
	#added pawn
	add(2,5,defPawn,defBlack)
	add(4,1,defPawn,defWhite)
end

function populateBoardChuShogi()
	#adding black pieces for row 1 (using our definition for rows, not Karol's)
    add(1,1,defLance,defBlack)
    add(1,2,defFerociousLeopard,defBlack)
    add(1,3,defCopperGeneral,defBlack)
    add(1,4,defSilverGeneral,defBlack)
    add(1,5,defGoldGeneral,defBlack)
    add(1,6,defKing,defBlack)
    add(1,7,defDrunkElephant,defBlack)
    add(1,8,defGoldGeneral,defBlack)
    add(1,9,defSilverGeneral,defBlack)
    add(1,10,defCopperGeneral,defBlack)
    add(1,11,defFerociousLeopard,defBlack)
    add(1,12,defLance,defBlack)

    #adding black pieces for row 2
    add(2,1,defReverseChariot,defBlack)
    add(2,3,defBishop,defBlack)
    add(2,5,defBlindTiger,defBlack)
    add(2,6,defKirin,defBlack)
    add(2,7,defPhoenix,defBlack)
    add(2,8,defBlindTiger,defBlack)
    add(2,10,defBishop,defBlack)
    add(2,12,defReverseChariot,defBlack)

    #adding black pieces for row 3
    add(3,1,defSideMover,defBlack)
    add(3,2,defVerticalMover,defBlack)
    add(3,3,defRook,defBlack)
    add(3,4,defDragonHorse,defBlack)
    add(3,5,defDragonKing,defBlack)
    add(3,6,defLion,defBlack)
    add(3,7,defQueen,defBlack)
    add(3,8,defDragonKing,defBlack)
    add(3,9,defDragonHorse,defBlack)
    add(3,10,defRook,defBlack)
    add(3,11,defVerticalMover,defBlack)
    add(3,12,defSideMover,defBlack)

    #adding black pieces for row 4 (pawns)
    for j in 1:cDim
        add(4,j,defPawn,defBlack)
    end

    #adding black pieces for row 5 (go-between)
    add(5,4,defGoBetween,defBlack)
    add(5,9,defGoBetween,defBlack)

    #adding white pieces for row 12 (using our definition for rows, not Karol's)
    add(12,1,defLance,defWhite)
    add(12,2,defFerociousLeopard,defWhite)
    add(12,3,defCopperGeneral,defWhite)
    add(12,4,defSilverGeneral,defWhite)
    add(12,5,defGoldGeneral,defWhite)
    add(12,6,defDrunkElephant,defWhite)
    add(12,7,defKing,defWhite)
    add(12,8,defGoldGeneral,defWhite)
    add(12,9,defSilverGeneral,defWhite)
    add(12,10,defCopperGeneral,defWhite)
    add(12,11,defFerociousLeopard,defWhite)
    add(12,12,defLance,defWhite)

    #adding white pieces for row 11
    add(11,1,defReverseChariot,defWhite)
    add(11,3,defBishop,defWhite)
    add(11,5,defBlindTiger,defWhite)
    add(11,6,defPhoenix,defWhite)
    add(11,7,defKirin,defWhite)
    add(11,8,defBlindTiger,defWhite)
    add(11,10,defBishop,defWhite)
    add(11,12,defReverseChariot,defWhite)

    #adding white pieces for row 10
    add(10,1,defSideMover,defWhite)
    add(10,2,defVerticalMover,defWhite)
    add(10,3,defRook,defWhite)
    add(10,4,defDragonHorse,defWhite)
    add(10,5,defDragonKing,defWhite)
    add(10,6,defQueen,defWhite)
    add(10,7,defLion,defWhite)
    add(10,8,defDragonKing,defWhite)
    add(10,9,defDragonHorse,defWhite)
    add(10,10,defRook,defWhite)
    add(10,11,defVerticalMover,defWhite)
    add(10,12,defSideMover,defWhite)

    #adding white pieces for row 9 (pawns)
    for j in 1:cDim
        add(9,j,defPawn,defWhite)
    end

    #adding white pieces for row 8 (go-between)
    add(8,4,defGoBetween,defWhite)
    add(8,9,defGoBetween,defWhite)
end

function populateBoardTenjikuShogi()
	#adding black pieces for row 1 (using our definition for rows, not Karol's)
    add(1,1,defLance,defBlack)
    add(1,2,defKnight,defBlack)
    add(1,3,defFerociousLeopard,defBlack)
    add(1,4,defIronGeneral,defBlack)
    add(1,5,defCopperGeneral,defBlack)
    add(1,6,defSilverGeneral,defBlack)
    add(1,7,defGoldGeneral,defBlack)
    add(1,8,defDrunkElephant,defBlack)
    add(1,9,defKing,defBlack)
    add(1,10,defGoldGeneral,defBlack)
    add(1,11,defSilverGeneral,defBlack)
    add(1,12,defCopperGeneral,defBlack)
    add(1,13,defIronGeneral,defBlack)
    add(1,14,defFerociousLeopard,defBlack)
    add(1,15,defKnight,defBlack)
    add(1,16,defLance,defBlack)

    #adding black pieces for row 2
    add(2,1,defReverseChariot,defBlack)
    add(2,3,defChariotSoldier,defBlack)
    add(2,4,defChariotSoldier,defBlack)
    add(2,6,defBlindTiger,defBlack)
    add(2,7,defPhoenix,defBlack)
    add(2,8,defQueen,defBlack)
    add(2,9,defLion,defBlack)
    add(2,10,defKirin,defBlack)
    add(2,11,defBlindTiger,defBlack)
    add(2,13,defChariotSoldier,defBlack)
    add(2,14,defChariotSoldier,defBlack)
    add(2,16,defReverseChariot,defBlack)

    #adding black pieces for row 3
    add(3,1,defSideSoldier,defBlack)
    add(3,2,defVerticalSoldier,defBlack)
    add(3,3,defBishop,defBlack)
    add(3,4,defDragonHorse,defBlack)
    add(3,5,defDragonKing,defBlack)
    add(3,6,defWaterBuffalo,defBlack)
    add(3,7,defFireDemon,defBlack)
    add(3,8,defFreeEagle,defBlack)
    add(3,9,defLionHawk,defBlack)
    add(3,10,defFireDemon,defBlack)
    add(3,11,defWaterBuffalo,defBlack)
    add(3,12,defDragonKing,defBlack)
    add(3,13,defDragonHorse,defBlack)
    add(3,14,defBishop,defBlack)
    add(3,15,defVerticalSoldier,defBlack)
    add(3,16,defSideSoldier,defBlack)

    #adding black pieces for row 4
    add(4,1,defSideMover,defBlack)
    add(4,2,defVerticalMover,defBlack)
    add(4,3,defRook,defBlack)
    add(4,4,defHornedFalcon,defBlack)
    add(4,5,defSoaringEagle,defBlack)
    add(4,6,defBishopGeneral,defBlack)
    add(4,7,defRookGeneral,defBlack)
    add(4,8,defViceGeneral,defBlack)
    add(4,9,defGreatGeneral,defBlack)
    add(4,10,defRookGeneral,defBlack)
    add(4,11,defBishopGeneral,defBlack)
    add(4,12,defSoaringEagle,defBlack)
    add(4,13,defHornedFalcon,defBlack)
    add(4,14,defRook,defBlack)
    add(4,15,defVerticalMover,defBlack)
    add(4,16,defSideMover,defBlack)

    #adding black pieces for row 5 (pawns)
    for j in 1:tDim
        add(5,j,defPawn,defBlack)
    end

    #adding black pieces for row 6 (dog)
    add(6,5,defDog,defBlack)
    add(6,12,defDog,defBlack)

    #adding white pieces for row 16 (using our definition for rows, not Karol's)
    add(16,1,defLance,defWhite)
    add(16,2,defKnight,defWhite)
    add(16,3,defFerociousLeopard,defWhite)
    add(16,4,defIronGeneral,defWhite)
    add(16,5,defCopperGeneral,defWhite)
    add(16,6,defSilverGeneral,defWhite)
    add(16,7,defGoldGeneral,defWhite)
    add(16,8,defDrunkElephant,defWhite)
    add(16,9,defKing,defWhite)
    add(16,10,defGoldGeneral,defWhite)
    add(16,11,defSilverGeneral,defWhite)
    add(16,12,defCopperGeneral,defWhite)
    add(16,13,defIronGeneral,defWhite)
    add(16,14,defFerociousLeopard,defWhite)
    add(16,15,defKnight,defWhite)
    add(16,16,defLance,defWhite)

    #adding white pieces for row 15
    add(15,1,defReverseChariot,defWhite)
    add(15,3,defChariotSoldier,defWhite)
    add(15,4,defChariotSoldier,defWhite)
    add(15,6,defBlindTiger,defWhite)
    add(15,7,defPhoenix,defWhite)
    add(15,8,defQueen,defWhite)
    add(15,9,defLion,defWhite)
    add(15,10,defKirin,defWhite)
    add(15,11,defBlindTiger,defWhite)
    add(15,13,defChariotSoldier,defWhite)
    add(15,14,defChariotSoldier,defWhite)
    add(15,16,defReverseChariot,defWhite)

    #adding white pieces for row 14
    add(14,1,defSideSoldier,defWhite)
    add(14,2,defVerticalSoldier,defWhite)
    add(14,3,defBishop,defWhite)
    add(14,4,defDragonHorse,defWhite)
    add(14,5,defDragonKing,defWhite)
    add(14,6,defWaterBuffalo,defWhite)
    add(14,7,defFireDemon,defWhite)
    add(14,8,defFreeEagle,defWhite)
    add(14,9,defLionHawk,defWhite)
    add(14,10,defFireDemon,defWhite)
    add(14,11,defWaterBuffalo,defWhite)
    add(14,12,defDragonKing,defWhite)
    add(14,13,defDragonHorse,defWhite)
    add(14,14,defBishop,defWhite)
    add(14,15,defVerticalSoldier,defWhite)
    add(14,16,defSideSoldier,defWhite)

    #adding black pieces for row 13
    add(13,1,defSideMover,defWhite)
    add(13,2,defVerticalMover,defWhite)
    add(13,3,defRook,defWhite)
    add(13,4,defHornedFalcon,defWhite)
    add(13,5,defSoaringEagle,defWhite)
    add(13,6,defBishopGeneral,defWhite)
    add(13,7,defRookGeneral,defWhite)
    add(13,8,defViceGeneral,defWhite)
    add(13,9,defGreatGeneral,defWhite)
    add(13,10,defRookGeneral,defWhite)
    add(13,11,defBishopGeneral,defWhite)
    add(13,12,defSoaringEagle,defWhite)
    add(13,13,defHornedFalcon,defWhite)
    add(13,14,defRook,defWhite)
    add(13,15,defVerticalMover,defWhite)
    add(13,16,defSideMover,defWhite)

    #adding white pieces for row 12 (pawns)
    for j in 1:tDim
        add(12,j,defPawn,defWhite)
    end

    #adding white pieces for row 11 (dog)
    add(11,5,defDog,defWhite)
    add(11,12,defDog,defWhite)
end

function clearTile(srcRow::Int64, srcCol::Int64)
  if(srcRow <= dim || srcCol <= dim || srcRow >= 1 || srcCol >= 1)
    chessboard[srcRow,srcCol].name = defEmpty
    chessboard[srcRow,srcCol].side = defDummy
  end
end

function setTile(srcRow::Int64, srcCol::Int64, pName::String, pSide, pPromote)
  if(srcRow <= dim || srcCol <= dim || srcRow >= 1 || srcCol >= 1)
    chessboard[srcRow,srcCol].name = pName
    chessboard[srcRow,srcCol].side = pSide
    chessboard[srcRow,srcCol].promote = pPromote
  end
end

######
# PIECE MODIFYING FUNCTIONS
######
function dropChoice()
	global whitePrison
	global blackPrison
	global chessboard
	local sizePrison # Stores size of the prison
	local prisonType # Stores which prison to take from
	topVal = 0 # Stores value of most powerful piece
	pieceLocation = 0 # Stores index of prison that piece is at
	if currTurn == defWhite
		sizePrison = length(whitePrison)
		prisonType = whitePrison
	elseif currTurn == defBlack
		sizePrison = length(blackPrison)
		prisonType = blackPrison
	end
	if sizePrison == 0
		return false
	end
	for i in 1:sizePrison
		if pieceVal[prisonType[i]] > topVal
			topVal = pieceVal[whitePrison[i]]
			pieceLocation = i
		end
	end
	totalSquares = dim * dim
	canDrop = false
	counter = totalSquares
	while canDrop == false && counter > 0
		i = rand(1:totalSquares)
		if currTurn == defWhite
			if chessboard[i].BAttack == 0
				canDrop = true
			end
		elseif currTurn == defBlack
			if chessboard[i].WAttack == 0
				canDrop = true
			end
		end
		xyVal = coordinates(i)
		if prisonType[pieceLocation] == "pawn"
			for row in 1:dim
				if chessboard[row, xyVal[i]].side == currTurn && chessboard[row, xyVal[i]].name == defPawn
					canDrop = false
					break
				end
			end
		end
		counter -= 1
	end
	add(xyVal[1], xyVal[2], prisonType[pieceLocation], currTurn)
	return true
end

function updateRoyalty()
  global royaltyTaken
  global remainingRoyaltyBlack
  global remainingRoyaltyWhite
  global currTurn

  if royaltyTaken == true
    if currTurn == defBlack
      remainingRoyaltyWhite-= 1
      if remainingRoyaltyWhite == 0
        #return true if all royalty taken
        return true
      end
    elseif currTurn == defWhite
      remainingRoyaltyBlack-= 1
      if remainingRoyaltyBlack == 0
        #return true if all royalty taken
        return true
      end
    end
  end
  #return false if there is remaining royalty
  return false
end

function isCheckOnKing(kingRow::Int64, kingCol::Int64)
  if currTurn == defBlack && chessboard[kingRow,kingCol].WAttack >0
		if isCheckMateKing(kingRow,kingCol) == true
      global resign = true
      return true
    end
    return true

  elseif currTurn == defWhite && chessboard[kingRow,kingCol].BAttack >0
    if isCheckMateKing(kingRow,kingCol) == true
      global resign = true
      return true
    end
    return true
  else
    return false
  end
end

function blockAndDangerCheck(row,col,currTurn)
  if currTurn == defBlack
    #threatened by enemy piece or occupied by a piece that cannot be eaten
    if chessboard[row,col].WAttack > 0 || ((chessboard[row,col].name != defEmpty) && (chessboard[row,col].side ==defBlack))
      return true
    else
      return false
    end
  elseif currTurn == defWhite
    #threatened by enemy piece or occupied by a piece that cannot be eaten
    if chessboard[row,col].BAttack >0 || ((chessboard[row,col].name != defEmpty) && (chessboard[row,col].side =defWhite))
      return true
    else
      return false
    end
  end
end

function isCheckMateKing(kingRow,kingCol)
  #for black piece
  if kingRow == dim && kingCol == dim
    if (blockAndDangerCheck(kingRow-1,kingCol,currTurn)
      && blockAndDangerCheck(kingRow-1,kingCol-1,currTurn)
      && blockAndDangerCheck(kingRow,kingCol-1,currTurn))
      return true
 	  else
      return false
	  end
  elseif kingRow == dim && kingCol == 1
    if (blockAndDangerCheck(kingRow-1,kingCol,currTurn)
      && blockAndDangerCheck(kingRow-1,kingCol+1,currTurn)
      && blockAndDangerCheck(kingRow,kingCol+1,currTurn))
      return true
 	  else
      return false
	  end
  elseif kingRow == 1 && kingCol == 1
    if (blockAndDangerCheck(kingRow+1,kingCol,currTurn)
      && blockAndDangerCheck(kingRow+1,kingCol+1,currTurn)
      && blockAndDangerCheck(kingRow,kingCol+1,currTurn))
      return true
    else
      return false
    end
  elseif kingRow == 1 && kingCol == dim
    if (blockAndDangerCheck(kingRow+1,kingCol,currTurn)
      && blockAndDangerCheck(kingRow+1,kingCol-1,currTurn)
      && blockAndDangerCheck(kingRow,kingCol-1,currTurn))
      return true
    else
      return false
    end
  elseif kingRow == dim
      if (blockAndDangerCheck(kingRow,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol-1,currTurn)
        && blockAndDangerCheck(kingRow,kingCol-1,currTurn))
        return true
      else
        return false
      end
    elseif kingRow == 1
      if (blockAndDangerCheck(kingRow+1,kingCol,currTurn)
        && blockAndDangerCheck(kingRow+1,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow,kingCol-1,currTurn)
        && blockAndDangerCheck(kingRow+1,kingCol-1,currTurn))
        return true
      else
        return false
      end
    elseif kingCol == dim
      if (blockAndDangerCheck(kingRow+1,kingCol,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol-1,currTurn)
        && blockAndDangerCheck(kingRow,kingCol-1,currTurn)
        && blockAndDangerCheck(kingRow+1,kingCol-1,currTurn))
        return true
      else
        return false
      end
    elseif kingCol == 1
      if (blockAndDangerCheck(kingRow+1,kingCol,currTurn)
        && blockAndDangerCheck(kingRow+1,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol+1,currTurn)
        && blockAndDangerCheck(kingRow-1,kingCol,currTurn))
        return true
      else
        return false
      end
  else
    if (blockAndDangerCheck(kingRow+1,kingCol,currTurn)
      && blockAndDangerCheck(kingRow+1,kingCol+1,currTurn)
      && blockAndDangerCheck(kingRow,kingCol+1,currTurn)
      && blockAndDangerCheck(kingRow-1,kingCol+1,currTurn)
      && blockAndDangerCheck(kingRow-1,kingCol,currTurn)
      && blockAndDangerCheck(kingRow-1,kingCol-1,currTurn)
      && blockAndDangerCheck(kingRow,kingCol-1,currTurn)
      && blockAndDangerCheck(kingRow+1,kingCol-1,currTurn))
      return true
 	  else
      return false
	  end
  end
end

function searchForPiece(pieceName::String,pieceSide::AbstractString)
  for i = 1:dim
    for j = 1:dim
      if chessboard[i,j].name == pieceName && chessboard[i,j].side == pieceSide
        pieceLoc = i,j
        return pieceLoc
      end
    end
  end
end

######
# DATABASE RELATED FUNCTIONS
######

#For inserting a move to the database (no promotion)
function insertMove(dbFile, sourcex::Int64, sourcey::Int64, targetx::Int64, targety::Int64)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
  println(currTurn)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, sourcex, sourcey, targetx, targety) VALUES ($newMoveNumber, 'move', $sourcex, $sourcey, $targetx, $targety);")
  mvT = typeof(newMoveNumber)
  println("1newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
  println("iMove currTurn: $currTurn")
end

#For inserting a move to the database (promotion after move is completed)
function insertMove(dbFile, sourcex::Int64, sourcey::Int64, targetx::Int64, targety::Int64, isPromoted)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, sourcex, sourcey, targetx, targety, promote) VALUES ($newMoveNumber, 'move', $sourcex, $sourcey, $targetx, $targety, $isPromoted);")
  mvT = typeof(newMoveNumber)
  println("2newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end

#For inserting a move(2move) to the database (no promotion)
function insertMove(dbFile, sourcex::Int64, sourcey::Int64, targetx::Int64, targety::Int64, targetx2::Int64, targety2::Int64)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, sourcex, sourcey, targetx, targety, targetx2, targety2) VALUES ($newMoveNumber, 'move', $sourcex, $sourcey, $targetx, $targety, $targetx2, $targety2);")
  mvT = typeof(newMoveNumber)
  println("3newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end

#For inserting a move(2move) to the database (promotion after move is completed)
function insertMove(dbFile, sourcex::Int64, sourcey::Int64, targetx::Int64, targety::Int64, targetx2::Int64, targety2::Int64, isPromoted)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, sourcex, sourcey, targetx, targety, targetx2, targety2, promote) VALUES ($newMoveNumber, 'move', $sourcex, $sourcey, $targetx, $targety, $targetx2, $targety2, $isPromoted);")
  mvT = typeof(newMoveNumber)
  println("4newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end

#For inserting a move(3move) to the database (no promotion)
function insertMove(dbFile, sourcex::Int64, sourcey::Int64, targetx::Int64, targety::Int64, targetx2::Int64, targety2::Int64, targetx3::Int64, targety3::Int64)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, sourcex, sourcey, targetx, targety, targetx2, targety2, targetx3, targety3) VALUES ($newMoveNumber, 'move', $sourcex, $sourcey, $targetx, $targety, $targetx2, $targety2, $targetx3, $targety3);")
  mvT = typeof(newMoveNumber)
  println("5newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end

#For inserting a move(3move) to the database (promotion after move is completed)
function insertMove(dbFile, sourcex::Int64, sourcey::Int64, targetx::Int64, targety::Int64, targetx2::Int64, targety2::Int64, targetx3::Int64, targety3::Int64, isPromoted)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, sourcex, sourcey, targetx, targety, targetx2, targety2, targetx3, targety3, promote) VALUES ($newMoveNumber, 'move', $sourcex, $sourcey, $targetx, $targety, $targetx2, $targety2, $targetx3, $targety3, $isPromoted);")
  mvT = typeof(newMoveNumber)
  println("6newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end

#For inserting a drop to the database
function insertDrop(dbFile, targetx, targety, pieceName)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type, targetx, targety, option) VALUES ($newMoveNumber, 'drop', $targetx, $targety, '$pieceName');")
  mvT = typeof(newMoveNumber)
  println("7newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end

#For inserting a resign to the database
function insertResign(dbFile)
  global currTurn
	#tempDB = SQLite.DB(dbFile)
	lastMoveNumber = SQLite.query(dbFile,"SELECT max(move_number) FROM moves")
	#Getting the int value from the nullableArray data type
	newMoveNumber = get(lastMoveNumber[1][1], 0) + 1
	SQLite.query(dbFile, "INSERT INTO moves (move_number, move_type) VALUES ($newMoveNumber, 'resign');")
  mvT = typeof(newMoveNumber)
  println("8newMoveNumber: $newMoveNumber type: $mvT")
  currTurn = transMoveNumber(newMoveNumber+1)
end
######
# MENU GUI RELATED FUNCTIONS
######
function destroyWins()
     destroy(win1)
     destroy(win2)
     destroy(gameTypeWin)
     destroy(timeYesNoWin)
     destroy(timeOptnWin)
     destroy(timeAddWin)
     destroy(diffWin)
     destroy(rouletteWin)
     destroy(goFirstWin)
     destroy(AiCheatWin)
     destroy(portNumWin)
     destroy(oldGameWin)
     destroy(localOrEmailWin)
     destroy(getFileNameWin)
end

function callbackAiCheat(path)
     msg = get_value(AiCheatRb)
     if msg == "YES"
          global isCheat = true
          println("AI cheating")
     else
          global isCheat = false
          println("AI not cheating")
     end
     loadToFile()
     destroyWins()
end

function AiCheat()
     set_visible(goFirstWin, false)
     set_visible(AiCheatWin, true)
     pack(AiCheatFr, expand = true, fill = "both")
     lbl = Label(AiCheatFr, "Would you like to let AI cheat?")
     okBtn = Button(AiCheatFr, "OK")
     map(u -> pack(u, anchor = "w"), (lbl, AiCheatRb, okBtn))
     bind(okBtn, "command", callbackAiCheat)
end

function callbackGoFirst(path)
     msg = get_value(goFirstRb)
     if msg == "YES"
          global isBlack = true
          println("Go first chosen")
          if (isAi)
               AiCheat()
          else
               destroyWins()
          end
     else
          global isBlack = false
          println("Go last chosen")
          if (isAi)
               AiCheat()
          else
               destroyWins()
          end
     end
end

function goFirst()
     set_visible(rouletteWin, false)
     set_visible(goFirstWin, true)
     pack(goFirstFr, expand = true, fill = "both")
     lbl = Label(goFirstFr, "Would you like to make the first move?")
     okBtn = Button(goFirstFr, "OK")
     map(u -> pack(u, anchor = "w"), (lbl, goFirstRb, okBtn))
     bind(okBtn, "command", callbackGoFirst)
     global isAi
     if isAi == false
       loadToFile()
     end
end

function callbackRoul(path)
     msg = get_value(rouletteRb)
     if msg == "YES"
          global isRoulette = true
          println("roulette mode on")
          goFirst()
     else
          global isRoulette = false
          println("roulette mode off")
          goFirst()
     end
end

function rouletteMode()
     set_visible(diffWin, false)
     set_visible(rouletteWin, true)
     pack(rouletteFr, expand = true, fill = "both")
     lbl = Label(rouletteFr, "Turn Japanese roulette mode on?")
     okBtn = Button(rouletteFr, "OK")
     map(u -> pack(u, anchor = "w"), (lbl, rouletteRb, okBtn))
     bind(okBtn, "command", callbackRoul)
end

function difficultyAI()
     set_visible(timeAddWin, false)
     set_visible(diffWin, true)
     diffFr = Frame(diffWin)
     pack(diffFr, expand = true, fill = "both")
     btnDiffArr = Array{Any}(5)
     btnDiffArr[1] = Button(diffFr, "Normal")
     btnDiffArr[2] = Button(diffFr, "Hard")
     btnDiffArr[3] = Button(diffFr, "Suicidal")
     btnDiffArr[4] = Button(diffFr, "Protracted death")
     btnDiffArr[5] = Button(diffFr, "Random AI")
     for i in 1:5
          grid(btnDiffArr[i], i , 1)
     end
     for j in 1:5
          bind(btnDiffArr[j], "<Button-1>") do path
               if j == 1
                    global aiDiffLvl = "N"
                    println("normal chosen")
                    rouletteMode()
               elseif j == 2
                    global aiDiffLvl = "H"
                    println("hard chosen")
                    rouletteMode()
               elseif j == 3
                    global aiDiffLvl = "S"
                    println("suicidal chosen")
                    rouletteMode()
               elseif j == 4
                    global aiDiffLvl = "P"
                    println("protracted death chosen")
                    rouletteMode()
               elseif j == 5
                    global aiDiffLvl = "R"
                    println("random AI chosen")
                    rouletteMode()
               end
          end
     end
end

function callbackTimeInc(path)
     global intIncVal
     incVal = get_value(timeIncInput)
     try
          intIncVal = parse(Int64, incVal)
          if intIncVal <= 0
               Messagebox(timeAddWin, title="Warning", message = "Invalid input. Re-enter time increment")
          else
               intIncVal = incVal
               if isAi == true
                    difficultyAI()
               else
                    set_visible(timeAddWin, false)
                    rouletteMode()
               end
          end
     catch
          Messagebox(timeAddWin, title = "Warning", message = "Invalid Input. Re-enter time limit")
     end
end

function timeAdd()
     set_visible(timeOptnWin, false)
     set_visible(timeAddWin, true)
     pack(timeAddFr, expand = true, fill = "both")
     okBtn = Button(timeAddFr, "OK")
     formlayout(timeIncInput, "Enter time increment in positive integer")
     formlayout(okBtn, nothing)
     focus(timeIncInput)
     bind(okBtn, "command", callbackTimeInc)
     bind(okBtn, "<Return>", callbackTimeInc)
     bind(timeIncInput, "<Return>", callbackTimeInc)
end

function callbackTimeOptn(path)
     global intTimeVal
     timeVal = get_value(timeLimitInput)
     try
          intTimeVal = parse(Int64, timeVal)
          if intTimeVal <= 0
               Messagebox(timeOptnWin, title="Warning", message = "Invalid input. Re-enter time limit")
          else
               intTimeVal = timeVal
               timeAdd()
          end
     catch
          Messagebox(timeOptnWin, title = "Warning", message = "Invalid Input. Re-enter time limit")
     end
end

function callbackTime(path)
     msg = (get_value(timeYesNoRb))
     if msg == "YES"
          println("Using time limits...")
          global isTimeLimit = true
          set_visible(timeYesNoWin, false)
          set_visible(timeOptnWin, true)
          pack(timeOptnFr, expand = true, fill = "both")
          okBtn = Button(timeOptnFr, "OK")
          formlayout(timeLimitInput, "Enter Time limit in positive integer")
          formlayout(okBtn, nothing)
          focus(timeLimitInput)
          bind(okBtn, "command", callbackTimeOptn)
          bind(okBtn, "<Return>", callbackTimeOptn)
          bind(timeLimitInput, "<Return>", callbackTimeOptn)
     else
          println("Not using time limits...")
          global isTimeLimit = false
          set_visible(timeYesNoWin, false)
          rouletteMode()
     end
end

function timeYesNoHelper()
     set_visible(timeYesNoWin, true)
     pack(timeYesNoFr, expand = true, fill = "both")
     timeYesNoLbl = Label(timeYesNoFr, "Use the time limits?")
     okBtn = Button(timeYesNoFr, "OK")
     map(u -> pack(u, anchor = "w"), (timeYesNoLbl, timeYesNoRb, okBtn))
     bind(okBtn, "command", callbackTime)
end

function callbackMini(path)
     println("Starting Mini Shogi...")
     global gameType = "minishogi"
     set_visible(gameTypeWin, false)
     timeYesNoHelper()
end

function callbackStd(path)
     println("Starting Standard Shogi...")
     global gameType = "standard"
     set_visible(gameTypeWin, false)
     timeYesNoHelper()
end

function callbackChu(path)
     println("Starting Chu Shogi...")
     global gameType = "chu"
     set_visible(gameTypeWin, false)
     timeYesNoHelper()
end

function callbackTen(path)
     println("Starting Tenjiku Shogi...")
     global gameType = "ten"
     set_visible(gameTypeWin, false)
     timeYesNoHelper()
end

function gameTypeHelper()
     gameTypeFr = Frame(gameTypeWin)
     pack(gameTypeFr, expand = true, fill = "both")
     variantBtns = Array{Any}(4)
     variantBtns[1] = Button(gameTypeFr, "Mini Shogi")
     variantBtns[2] = Button(gameTypeFr, "Standard Shogi")
     variantBtns[3] = Button(gameTypeFr, "Chu Shogi")
     variantBtns[4] = Button(gameTypeFr, "Tenjiku Shogi")
     for i in 1:4
          grid(variantBtns[i], i, 1)
     end
     bind(variantBtns[1], "command", callbackMini)
     bind(variantBtns[2], "command", callbackStd)
     bind(variantBtns[3], "command", callbackChu)
     bind(variantBtns[4], "command", callbackTen)
end

function callbackPortNum(path)
     temPortNum = get_value(portNumInput)
     try
          global portNumber = parse(Int64, temPortNum)
          if portNumber < 0
               Messagebox(portNumWin, title="Warning", message = "Invalid input. Re-enter port number")
          else
               set_visible(portNumWin, false)
               set_visible(gameTypeWin, true)
               gameTypeHelper()
          end
     catch
          Messagebox(portNumWin, title = "Warning", message = "Invalid Input. Re-enter port number")
     end
end

function portNum()
     pack(portNumFr, expand = true, fill = "both")
     okBtn = Button(portNumFr, "OK")
     formlayout(portNumInput, "Enter the port number(preferably between 8000 and 8099)")
     formlayout(okBtn, nothing)
     focus(portNumInput)
     bind(okBtn, "command", callbackPortNum)
     bind(okBtn, "<Return>", callbackPortNum)
     bind(portNumInput, "<Return>", callbackPortNum)
end

function callback1_1(path)
     println("starting a game against AI.")
     global isAi = true
     set_visible(win2, false)
     set_visible(gameTypeWin, true)
     gameTypeHelper()
end

function callback2_1(path)
     println("Starting a game against another user.")
     global isAi = false
     set_visible(win2, false)
     set_visible(gameTypeWin, true)
     gameTypeHelper()
end

function callback3_1(path)
     println("Joining a game against a remote program.")
     global isRemote = true
     global isHost = false
     set_visible(win2, false)
     set_visible(portNumWin, true)
     portNum()
end

function callback4_1(path)
     println("Hosting a game. AI is playing.")
     global isRemote = true
     global isHost = true
     global isAi = true
     set_visible(win2, false)
     set_visible(portNumWin, true)
     portNum()
end

function callback5_1(path)
     println("Hosting a game. The user is playing.")
     global isRemote = true
     global isHost = true
     global isAi = false
     set_visible(win2, false)
     set_visible(portNumWin, true)
     portNum()
end

function callback6_1(path)
     println("Starting a new game over email.")
     global isEmail = true
     set_visible(win2, false)
     set_visible(gameTypeWin, true)
     gameTypeHelper()
end

function fileNotExistWinHelper()
     pack(fileNotExistFr, expand = true, fill = "both")
     lbl = Label(fileNotExistFr, "File does not exist. What would you like to do?")
     okBtn = Button(fileNotExistFr, "OK")
     map(u -> pack(u, anchor = "w"), (lbl, fileNotExistRb, okBtn))
     bind(okBtn, "command", callbackFileNotExist)
end

function oldGame2()
     set_visible(oldGameWin, false)
     set_visible(fileNotExistWin, true)
end

function callbackFileNotExist(path)

     msg = get_value(fileNotExistRb)
     if msg == "Re-enter file name"
          #destroy(fileNotExistWin)
          set_visible(fileNotExistWin, false)
          set_visible(oldGameWin, true)
     else
          set_visible(fileNotExistWin, false)
          startMenu()
     end
end

function callbackOldGame2(path)
     temOldGameName = get_value(oldGameInput)
     isFileHere = isfile("$temOldGameName")
     println("file name is: $temOldGameName")
     if (isFileHere)
          set_visible(oldGameWin, false)
          global fileNameInput = temOldGameName
          println("Continuing $fileNameInput")
          loadFromFile()
          destroyWins()
     else
          if (isFirstNotFound)
               global isFirstNotFound = false
               set_visible(oldGameWin, false)
               set_visible(fileNotExistWin, true)
               fileNotExistWinHelper()
          else
               set_visible(oldGameWin, false)
               set_visible(fileNotExistWin, true)
          end
     end
end

function callBackFinishedGame(path)
     set_visible(oldGameWin, false)
     oldGameName = get_value(oldGameInput)
     println("Replaying $oldGameName")
     destroyWins()
end

function callbackGetFileName(path)
     global fileNameInput = get_value(getFileNameInput)
     println("The game file name is $fileNameInput")
     newGameSelect()
end

function newGameSelect()
     set_visible(getFileNameWin, false)
     set_visible(win2, true)
     frm2 = Frame(win2)
     pack(frm2, expand = true, fill = "both")
     btnArr2 = Array{Any}(6)
     btnArr2[1] = Button(frm2, "Start a game against the AI")
     btnArr2[2] = Button(frm2, "Start a game against a human on the this computer")
     btnArr2[3] = Button(frm2, "Join a game against a remote program")
     btnArr2[4] = Button(frm2, "Host a game. Your AI is the player")
     btnArr2[5] = Button(frm2, "Host a game. A human as the player")
     btnArr2[6] = Button(frm2, "Start a new game over email")
     for i in 1:6
          grid(btnArr2[i], i, 1)
     end
     bind(btnArr2[1], "command", callback1_1)
     bind(btnArr2[2], "command", callback2_1)
     bind(btnArr2[3], "command", callback3_1)
     bind(btnArr2[4], "command", callback4_1)
     bind(btnArr2[5], "command", callback5_1)
     bind(btnArr2[6], "command", callback6_1)
end

function callbackOldGame1(path)
     println("Continuing an old game.")
     set_visible(localOrEmailWin, false)
     set_visible(oldGameWin, true)
     pack(oldGameFr, expand = true, fill = "both")
     okBtn = Button(oldGameFr, "OK")
     formlayout(oldGameInput, "Enter the file name with the .db extension")
     formlayout(okBtn, nothing)
     focus(oldGameInput)
     bind(okBtn, "command", callbackOldGame2)
     bind(okBtn, "<Return>", callbackOldGame2)
     bind(oldGameInput, "<Return>", callbackOldGame2)
end

function callbackEmail(path)
     println("Taking a turn in an email game.")
     set_visible(localOrEmailWin, false)
     set_visible(oldGameWin, true)
     pack(oldGameFr, expand = true, fill = "both")
     okBtn = Button(oldGameFr, "OK")
     formlayout(oldGameInput, "Enter the file name with the .db the extension")
     formlayout(okBtn, nothing)
     focus(oldGameInput)
     bind(okBtn, "command", callbackOldGame2)
     bind(okBtn, "<Return>", callbackOldGame2)
     bind(oldGameInput, "<Return>", callbackOldGame2)
end

function callback1(path)
     println("Starting a new game...")
     set_visible(win1, false)
     set_visible(getFileNameWin, true)
     pack(getFileNameFr, expand = true, fill = "both")
     okBtn = Button(getFileNameFr, "OK")
     formlayout(getFileNameInput, "Enter the file name")
     formlayout(okBtn, nothing)
     focus(getFileNameInput)
     global gameStart = "N"
     bind(okBtn, "command", callbackGetFileName)
     bind(okBtn, "<Return>", callbackGetFileName)
     bind(getFileNameInput, "<Return>", callbackGetFileName)
end

function oldGameOptn()
     set_visible(blackOrWhiteWin, false)
     set_visible(localOrEmailWin, true)
     pack(localOrEmailFr, expand = true, fill = "both")
     global gameStart = "C"
     btnArr = Array{Any}(2)
     btnArr[1] = Button(localOrEmailFr, "Continue a local game")
     btnArr[2] = Button(localOrEmailFr, "Take a turn in an email game")
     for i in 1:2
          grid(btnArr[i], i, 1)
     end
     bind(btnArr[1], "command", callbackOldGame1)
     bind(btnArr[2], "command", callbackEmail)
end

function callbackBlackOrWhite(path)
     msg = get_value(blackOrWhiteRb)
     if msg == "Black"
          global isBlack = true
          println("Black team")
     else
          global isBlack = false
          println("White team")
     end
     oldGameOptn()
end

function blackOrWhite()
     set_visible(oldGameAIorNotWin, false)
     set_visible(blackOrWhiteWin, true)
     pack(blackOrWhiteFr, expand = true, fill = "both")
     lbl = Label(blackOrWhiteFr, "Which side where you playing as black or white")
     okBtn = Button(blackOrWhiteFr, "OK")
     map(u -> pack(u, anchor = "w"), (lbl, blackOrWhiteRb, okBtn))
     bind(okBtn, "command", callbackBlackOrWhite)
end

function callbackOldGameAIorNot(path)
     msg = get_value(oldGameAIorNotRb)
     if msg == "AI"
          global isAi = true
          println("Playing against AI")
     else
          global isAi = false
          println("playing against another player")
     end
     blackOrWhite()
end

function callback2(path)
     set_visible(win1, false)
     set_visible(oldGameAIorNotWin, true)
     pack(oldGameAIorNotFr, expand = true, fill = "both")
     lbl = Label(oldGameAIorNotFr, "Who were you playing against?")
     okBtn = Button(oldGameAIorNotFr, "OK")
     map(u -> pack(u, anchor = "w"), (lbl, oldGameAIorNotRb, okBtn))
     bind(okBtn, "command", callbackOldGameAIorNot)
end

function callback3(path)
     println("Replaying a finished game")
     set_visible(win1, false)
     set_visible(oldGameWin, true)
     pack(oldGameFr, expand = true, fill = "both")
     okBtn = Button(oldGameFr, "OK")
     formlayout(oldGameInput, "Enter the file name with the .db extension")
     formlayout(okBtn, nothing)
     focus(oldGameInput)
     global gameStart = "F"
     bind(okBtn, "command", callBackFinishedGame)
     bind(okBtn, "<Return>", callBackFinishedGame)
     bind(oldGameInput, "<Return>", callBackFinishedGame)
end

function callback4(path)
     println("Quitting...")
     destroyWins()
end

function startMenu()
     set_visible(win1, true)
     pack(frm1, expand = true, fill = "both")
     btnArr1 = Array{Any}(4)
     btnArr1[1] = Button(frm1, "Start a new game")
     btnArr1[2] = Button(frm1, "Continue an old game")
     btnArr1[3] = Button(frm1, "Replay a finished game")
     btnArr1[4] = Button(frm1, "Quit")
     for i in 1:4
          grid(btnArr1[i], i, 1)
     end
     bind(btnArr1[1], "command", callback1)
     bind(btnArr1[2], "command", callback2)
     bind(btnArr1[3], "command", callback3)
     bind(btnArr1[4], "command", callback4)
end

function loadFromFile()
  global fileName = SQLite.DB(fileNameInput)
  println(fileName)
  metaTable = SQLite.query(fileName,"SELECT key,value FROM meta")
  metaDict = Dict{String,String}(get(metaTable[1][i]) => get(metaTable[2][i]) for i = 1:length(metaTable[1]))

  global gameType = metaDict["type"]

  if metaDict["legality"] == "cheating"
    isCheat = true
  elseif metaDict["legality"] == "legal"
    isCheat = false
  end

  if metaDict["timed"] == "yes"
    isTimeLimit = true
    global intIncVal = metaDict["time_add"]
  elseif metaDict["legality"] == "no"
    isTimeLimit = false
  end



  #sente and gote time not yet implemented
end

function loadToFile()
  global fileName
  global fileNameInput
  global gameType
  global isCheat
  global isTimeLimit
  global intTimeVal
  global intIncVal

  gameSeed = round(Int64, time()*1000000000)
  rm(fileNameInput; force=true)
  fileName = SQLite.DB(fileNameInput)

  #Creates the db file
  SQLite.query(fileName, "CREATE TABLE meta(key varchar(255) PRIMARY KEY, value varchar(255));")
  SQLite.query(fileName, "CREATE TABLE moves(move_number int PRIMARY KEY, move_type varchar(6), sourcex int, sourcey int, targetx int, targety int, option varchar(4), i_am_cheating bit, targetx2 int, targety2 int, targetx3 int, targety3 int);")

  if gameType == "standard"
    SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','standard');")
  elseif gameType == "minishogi"
    SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','minishogi');")
  elseif gameType == "chu"
    SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','chu');")
  elseif gameType == "ten"
    SQLite.query(fileName, "INSERT INTO meta (key, value) VALUES ('type','ten');")
  end

  if isCheat == true
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('legality', 'cheating');")
  else
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('legality', 'legal');")
  end

  #If the user didn't specify a time limit or set the limit to 0, the game is not timed
  #The time_add, sente_time, and gote_time rows are only inserted if there is a time limit
  if isTimeLimit == true
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('timed', 'yes');")
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('time_add', '$intIncVal');")
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('sente_time', '$intTimeVal');")
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('gote_time', '$intTimeVal');")
  else
    SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('timed', 'no');")
  end


  SQLite.query(fileName, "INSERT INTO meta(key, value) VALUES ('seed', $gameSeed);")
end


######
# BOARD GUI RELATED FUNCTIONS
######

function shortenPieceName(pieceName::String)
  nameArray = split(pieceName)
  if length(nameArray) > 1
    firstWord = ucfirst(nameArray[1])
    secondWord = ucfirst(nameArray[2])
    if firstWord[1] == 'G'
      shortName = "$(firstWord[1:2])$(secondWord[1])"
    else
      shortName = "$(firstWord[1])$(secondWord[1])"
    end
  else
    firstWord = ucfirst(nameArray[1])
    if firstWord[1] == 'K' || firstWord[1] == 'P' || firstWord[1] == 'L'
      if firstWord == "King"
        shortName = "$(firstWord[1])"
      else
        shortName = "$(firstWord[1:2])"
      end
    else
      shortName = "$(firstWord[1])"
    end
  end
  return shortName
end
#function to create the GUI board
function createBoardGUI()
  for i in 1:dim
    grid_rowconfigure(fr,i, weight = 1)
    for j in 1:dim
		  lblBrdArray[i,j] = Frame(fr,width = 50, height = 50, borderwidth =7, relief = "sunken")
      grid(lblBrdArray[i,j],i,j, sticky = "nsew")
      grid_columnconfigure(fr,j, weight = 1)
    end
  end
end
#function to populate the GUI board
function populateBoardGUI()
	for i in 1:dim
		for j in 1:dim
			stringTest = chessboard[i,j].name
			#if no piece in it set label that will be needed to indicate for move option with button handling
			if stringTest == defEmpty
        lblPieArray[i,j] = Label(fr,text = stringTest,font="Arial 8 ",background = "red")
				bind(lblPieArray[i,j],"<Button-1>") do path
			    optionClicked(i,j)
			  end
				#if there is piece create the piece
			else
				if chessboard[i,j].side == defWhite
					lblPieArray[i,j] = Label(fr,text = shortenPieceName(stringTest),font="Arial 8 ", image = pieceImgWhite ,compound = "center")
				elseif chessboard[i,j].side == defBlack
					lblPieArray[i,j] = Label(fr,text = shortenPieceName(stringTest),font="Arial 8 ", image = pieceImgBlack ,compound = "center")
				end
				# if the piece is king change the letter colour to yellow
				if stringTest == defKing
					configure(lblPieArray[i,j], foreground = "yellow")
				end
				grid(lblPieArray[i,j],i,j)
				#button handling for indicating move option
				bind(lblPieArray[i,j],"<Button-1>") do path
					pieceClicked(i,j)
				end
      end
		end
	end
end

function createPromotionPrompt(destRow,destCol)
  prWindow = Toplevel()
  prFr = Frame(prWindow)
  pack(prFr,expand = true, fill = "both")


  Lbl = Label(prFr, text = "Would you like to promote this piece ?")
  pack(Lbl,expand = true, fill = "both")
  yesButton = Button(prFr, text = "Yes")
  pack(yesButton,expand = true, fill = "x",side = "left")
  noButton = Button(prFr, text = "No")
  pack(noButton,expand = true, fill = "x",side = "left")

  bind(yesButton,"<Button-1>") do path
    prPromote(destRow,destCol)
    promoteGUI(destRow,destCol)
    set_visible(prWindow,false)
  end
  bind(noButton,"<Button-1>") do path
    set_visible(prWindow,false)
  end
end

function createMultipleMovePrompt(destRow,destCol,pieceName)
  global multipleMoveCounter
  if userTurn == true
    mWindow = Toplevel()
    mFr = Frame(mWindow)
    pack(mFr,expand = true, fill = "both")


    Lbl = Label(mFr, text = "Would you like to move one more time ?")
    pack(Lbl,expand = true, fill = "both")
    yesButton = Button(mFr, text = "Yes")
    pack(yesButton,expand = true, fill = "x",side = "left")
    noButton = Button(mFr, text = "No")
    pack(noButton,expand = true, fill = "x",side = "left")

    bind(yesButton,"<Button-1>") do path
      moveMultipleGUIMove(destRow,destCol,pieceName)
      set_visible(mWindow,false)
    end
    bind(noButton,"<Button-1>") do path
      if multipleMoveCounter == 1
        insertMove(fileName,arrayDatabaseRowExchange(pieGUImovedX),pieGUImovedY,arrayDatabaseRowExchange(destRow),destCol)
      elseif multipleMoveCounter == 3
        multipleMoveCounter = 0
        insertMove(fileName,arrayDatabaseRowExchange(previousMoveGUI[3]),previousMoveGUI[4],arrayDatabaseRowExchange(pieGUImovedX),pieGUImovedY,arrayDatabaseRowExchange(destRow),destCol)
      end
      global multipleMoveCounter = 0
      set_visible(mWindow,false)
    end
  elseif aiTurn == true
    if multipleMoveCounter == 1
      if moveChoice[5] != 0 && moveChoice[6] != 0
        moveMultipleGUIMove(destRow,destCol,pieceName)
        sleep(2)
        optionClicked(moveChoice[5],moveChoice[6])
      end
    elseif multipleMoveCounter == 3
      if moveChoice[7] != 0 && moveChoice[8] != 0
        moveMultipleGUIMove(destRow,destCol,pieceName)
        sleep(2)
        optionClicked(moveChoice[7],moveChoice[8])
      end
    end
  end
end

function promoteGUI(destRow,destCol)
  if dim == sDim || dim == mDim
    promotedName = prStandard[chessboard[destRow,destCol].name]
  elseif dim == cDim || dim == tDim
    promotedName = prTenjiku[chessboard[destRow,destCol].name]
  end
  configure(pieceGUImoved, text = shortenPieceName(promotedName))
end

#function that sort the move option for drop clicked
function dropClicked()
	global pieGUImovedX = 0
	global pieGUImovedY = 0
  #loop to search the place where you can drop
	for i in 1:dim
		for j in 1:dim
			stringTest = cget(lblPieArray[i,j],"text")
			#if no piece in it set label that will be needed to indicate for move option to drop the piece with button handling
			if stringTest == "_"
        indicateMoveOption(i,j)
			end
		end
	end
end
#function that sort the move option for piece clicked
function pieceClicked(srcRow,srcCol)
	global pieGUImovedX = srcRow
	global pieGUImovedY = srcCol
	global pieceGUImoved = lblPieArray[srcRow,srcCol]

  pieceName = cget(lblPieArray[srcRow,srcCol],"text")
  #shogi piece
  if pieceName == shortenPieceName(defKing)
    defKingMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defPawn)
		defPawnMove(srcRow,srcCol,"GUI")
	elseif pieceName == shortenPieceName(defKnight)
		defKnightMove(srcRow,srcCol,"GUI")
	elseif pieceName == shortenPieceName(defLance)
		defLanceMove(srcRow,srcCol,"GUI")
	elseif pieceName == shortenPieceName(defRook)
		defRookMove(srcRow,srcCol,"GUI")
	elseif pieceName == shortenPieceName(defBishop)
		defBishopMove(srcRow,srcCol,"GUI")
	elseif pieceName == shortenPieceName(defSilverGeneral)
		defSilverGeneralMove(srcRow,srcCol,"GUI")
	elseif pieceName == shortenPieceName(defGoldGeneral)
		defGoldGeneralMove(srcRow,srcCol,"GUI")
    # chu shogi exclusive piece
  elseif pieceName == shortenPieceName(defFerociousLeopard)
    defFerociousLeopardMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defCopperGeneral)
    defCopperGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defKirin)
    defKirinMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defFerociousLeopard)
    defFerociousLeopardMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defDrunkElephant)
    defDrunkElephantMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defReverseChariot)
    defReverseChariotMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defBlindTiger)
    defBlindTigerMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defPhoenix)
    defPhoenixMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defSideMover)
    defSideMoverMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defVerticalMover)
    defVerticalMoverMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defDragonHorse)
    defDragonHorseMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defDragonKing)
    defDragonKingMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defLion)
    defLionMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defQueen)
    defQueenMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defGoBetween)
    defGoBetweenMove(srcRow,srcCol,"GUI")
    # tenjiku shogi exclusive piece
  elseif pieceName == shortenPieceName(defBishopGeneral)
    defBishopGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defCopperGeneral)
    defCopperGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defChariotSoldier)
    defChariotSoldierMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defDog)
    defDogMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defFireDemon)
    defFireDemonMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defFreeEagle)
    defFreeEagleMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defGreatGeneral)
    defGreatGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defHornedFalcon)
    defHornedFalconMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defIronGeneral)
    defIronGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defBishopGeneral)
    defBishopGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defLionHawk)
    defLionHawkMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defRookGeneral)
    defRookGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defSoaringEagle)
    defSoaringEagleMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defSideSoldier)
    defSideSoldierMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defViceGeneral)
    defViceGeneralMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defVerticalSoldier)
    defVerticalSoldierMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defWaterBuffalo)
    defWaterBuffaloMove(srcRow,srcCol,"GUI")
    # promoted exclusive piece
  elseif pieceName == shortenPieceName(defFlyingOx)
      defFlyingOxMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defFlyingStag)
      defFlyingStagMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defFreeBoar)
      defFreeBoarMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defHeavenlyTetrarch)
      defHeavenlyTetrarchMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defMultiGeneral)
      defMultiGeneral(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defPrince)
      defKingMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defWhale)
      defWhaleMove(srcRow,srcCol,"GUI")
  elseif pieceName == shortenPieceName(defWhiteHorse)
      defWhiteHorseMove(srcRow,srcCol,"GUI")
	end


  #added binding so it can cancel the move
	bind(lblPieArray[srcRow,srcCol],"<Button-1>") do path
		resetMoveIndicator()
		bind(lblPieArray[srcRow,srcCol],"<Button-1>") do path
			pieceClicked(srcRow,srcCol)
		end
	end
end
#function that actualy activate the tile for move option corresponding the piece
function indicateMoveOption(row,col)
	#if the move option tile is empty set the option to be visible
	if cget(lblPieArray[row,col],"text") == "_"
  	grid(lblPieArray[row,col],row,col)
		#putting it the row and col to an array so it can be made invisible again after piece moved
		push!(indicateMoveArray,row)
		push!(indicateMoveArray,col)
	else
		configure(lblPieArray[row,col],background = "red")
		bind(lblPieArray[row,col],"<Button-1>") do path
			optionClicked(row,col)
		end
		#putting the row and col to an array so it can be made invisible again after piece moved
		push!(indicateMoveArray,row)
		push!(indicateMoveArray,col)
	end
end

function resetMoveIndicator()
	for i in 1:2:length(indicateMoveArray)
		#taking the info for tile to turn invisible
		col = pop!(indicateMoveArray)
		row = pop!(indicateMoveArray)

		if cget(lblPieArray[row,col],"text") == "_"
			#make it invisible
			grid_forget(lblPieArray[row,col])
		else
			#remove the red border
			configure(lblPieArray[row,col],background = "white")
			#re bind piece to a proper binding
			bind(lblPieArray[row,col],"<Button-1>") do path
				pieceClicked(row,col)
			end
		end
	end
end

function moveMultipleGUICheck(pieceName,destRow,destCol)
  global multipleMoveCounter += 1
  rowDiff = destRow - pieGUImovedX
  colDiff = destCol - pieGUImovedY

  if (pieceName == shortenPieceName(defLion) || pieceName == shortenPieceName(defLionHawk))
    if multipleMoveCounter < 2
      rowDiff = abs(rowDiff)
      colDiff = abs(colDiff)
      if rowDiff < 2 && colDiff < 2
        createMultipleMovePrompt(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -1
    end
  elseif pieceName == shortenPieceName(defHornedFalcon)
    if multipleMoveCounter < 2
      if chessboard[destRow,destCol].side == defBlack && ((rowDiff == 1) && (colDiff == 0))
        createMultipleMovePrompt(destRow,destCol,pieceName)
      elseif chessboard[destRow,destCol].side == defWhite && ((rowDiff == -1) && (colDiff == 0))
        createMultipleMovePrompt(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -1
    end
  elseif pieceName == shortenPieceName(defSoaringEagle)
    if multipleMoveCounter < 2
      if chessboard[destRow,destCol].side == defBlack && ((rowDiff == 1) && (colDiff != 0))
        createMultipleMovePrompt(destRow,destCol,pieceName)
      elseif chessboard[destRow,destCol].side == defWhite && ((rowDiff == -1) && (colDiff != 0))
        createMultipleMovePrompt(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -1
    end
  elseif pieceName == shortenPieceName(defHeavenlyTetrarch)
    if multipleMoveCounter < 2
      rowDiff = abs(rowDiff)
      colDiff = abs(colDiff)
      if rowDiff < 2 && colDiff < 2
        Messagebox(window, title="Invalid move", message="Have to do igui if you move to adjecent tile")
        moveMultipleGUIMove(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -1
    end
  elseif pieceName == shortenPieceName(defFreeEagle)
    if multipleMoveCounter < 2
      if ((rowDiff == 1) && (colDiff != 0))
        createMultipleMovePrompt(destRow,destCol,pieceName)
      elseif ((rowDiff == -1) && (colDiff != 0))
        createMultipleMovePrompt(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -1
    end
  elseif (pieceName == shortenPieceName(defFireDemon) || pieceName == shortenPieceName(defViceGeneral))
    if multipleMoveCounter <2 #since the counter on top got added twice so to counter it
      rowDiff = abs(rowDiff)
      colDiff = abs(colDiff)
      if rowDiff < 2 && colDiff < 2
        createMultipleMovePrompt(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -1
    end
    if multipleMoveCounter >2 && multipleMoveCounter < 4
      rowDiff = abs(rowDiff)
      colDiff = abs(colDiff)
      if rowDiff < 2 && colDiff < 2
        createMultipleMovePrompt(destRow,destCol,pieceName)
      else
        multipleMoveCounter = 0
      end
    else
      multipleMoveCounter = -2
    end
  else
    multipleMoveCounter = 0
  end
end

function moveMultipleGUIMove(destRow,destCol,pieceName)
  global pieGUImovedX
  global pieGUImovedY
  global multipleMoveCounter += 1
  global previousMoveGUI

  pieBeforeX = pieGUImovedX
  pieBeforeY = pieGUImovedY
  pieGUImovedX = destRow
  pieGUImovedY = destCol
  diffRow = pieGUImovedX - pieBeforeX
  diffCol = pieGUImovedY - pieBeforeY

  if pieceName == shortenPieceName(defLion) || pieceName == shortenPieceName(defLionHawk) || pieceName == shortenPieceName(defFireDemon) || pieceName == shortenPieceName(defViceGeneral)
    defKingMove(pieGUImovedX,pieGUImovedY,"GUI")
  elseif pieceName == shortenPieceName(defHornedFalcon)
    indicateMoveOption(pieBeforeX,pieBeforeY)
    if chessboard[destRow,destCol].side == defBlack
      indicateMoveOption(pieGUImovedX+1,pieGUImovedY)
    elseif chessboard[destRow,destCol].side == defWhite
      indicateMoveOption(pieGUImovedX-1,pieGUImovedY)
    end
  elseif pieceName == shortenPieceName(defSoaringEagle)
    indicateMoveOption(pieBeforeX,pieBeforeY)
    if chessboard[destRow,destCol].side == defBlack
      if diffCol == 1
        indicateMoveOption(pieGUImovedX+1,pieGUImovedY+1)
      elseif diffCol == -1
        indicateMoveOption(pieGUImovedX+1,pieGUImovedY-1)
      end
    elseif chessboard[destRow,destCol].side == defWhite
      if diffCol == 1
        indicateMoveOption(pieGUImovedX-1,pieGUImovedY+1)
      elseif diffCol == -1
        indicateMoveOption(pieGUImovedX-1,pieGUImovedY-1)
      end
    end
  elseif pieceName == shortenPieceName(defHeavenlyTetrarch)
      indicateMoveOption(pieBeforeX,pieBeforeY)
  elseif pieceName == shortenPieceName(defFreeEagle)
    indicateMoveOption(pieGUImovedX+1,pieGUImovedY+1)
    indicateMoveOption(pieGUImovedX+1,pieGUImovedY-1)
    indicateMoveOption(pieGUImovedX-1,pieGUImovedY+1)
    indicateMoveOption(pieGUImovedX-1,pieGUImovedY-1)
  end
  if multipleMoveCounter == 2
    previousMoveGUI[3] = pieBeforeX
    previousMoveGUI[4] = pieBeforeY
  elseif multipleMoveCounter == 4
    previousMoveGUI[1] = pieBeforeX
    previousMoveGUI[2] = pieBeforeY
  end
end

function emptySourceTile(destRow,destCol)
	srcRow = deepcopy(pieGUImovedX)
	srcCol = deepcopy(pieGUImovedY)
	if cget(lblPieArray[destRow,destCol],"text") == "_"
		#moving empty space label to source tile
		lblPieArray[srcRow,srcCol] = lblPieArray[destRow,destCol]
		bind(lblPieArray[srcRow,srcCol],"<Button-1>") do path
			optionClicked(srcRow,srcCol)
		end
		#updated the chessboard
		gameOver = movePiece(pieGUImovedX,pieGUImovedY,destRow,destCol)
	else
		#removing the piece captured from GUI
		grid_forget(lblPieArray[destRow,destCol])
		#create a new empty space label to fill the source tile
		lblPieArray[srcRow,srcCol] = Label(fr,text = "_",font="Arial 8 ",background = "red")
		bind(lblPieArray[srcRow,srcCol],"<Button-1>") do path
			optionClicked(srcRow,srcCol)
		end
		#updated the chessboard
		gameOver = movePiece(pieGUImovedX,pieGUImovedY,destRow,destCol)
    if cget(lblPieArray[srcRow,srcCol],"text") == shortenPieceName(defFireDemon)
      println("why")
      global multipleMoveCounter = 3
    end
	end
  #check for promotion
  if autoPromote(destRow,destCol)
    #no prPromote needed since autoPromote already autoPromote it if it is true
    promoteGUI(destRow,destCol)
  elseif canPromote(destRow,destCol)
    createPromotionPrompt(destRow,destCol)
  end
  #updating the prison
	configure(cmbBox1, values = whitePrison)
	configure(cmbBox2, values = blackPrison)
end

function movePieGUI(destRow,destCol)
  global multipleMoveCounter
	println(pieGUImovedX,pieGUImovedY,chessboard[pieGUImovedX,pieGUImovedY].side)
	println(destRow,destCol,chessboard[destRow,destCol].side)
	if chessboard[pieGUImovedX,pieGUImovedY].side != chessboard[destRow,destCol].side
	#making the tile not picked invisible again after piece moved
		resetMoveIndicator()
	#setting the source tile where the piece moved into empty space
		emptySourceTile(destRow,destCol)

		#the process of actually moving the piece in the GUI
		lblPieArray[destRow,destCol] = pieceGUImoved
		grid(lblPieArray[destRow,destCol],destRow,destCol)
		#rebinding to update the row and col
		bind(lblPieArray[destRow,destCol],"<Button-1>") do path
			pieceClicked(destRow,destCol)
		end
    pieceName = cget(pieceGUImoved,"text")
    moveMultipleGUICheck(pieceName,destRow,destCol)
    if multipleMoveCounter == 0
		  insertMove(fileName,arrayDatabaseRowExchange(pieGUImovedX),pieGUImovedY,arrayDatabaseRowExchange(destRow),destCol)
    elseif multipleMoveCounter == -1
      multipleMoveCounter = 0
      insertMove(fileName,arrayDatabaseRowExchange(previousMoveGUI[3]),previousMoveGUI[4],arrayDatabaseRowExchange(pieGUImovedX),pieGUImovedY,arrayDatabaseRowExchange(destRow),destCol)
    elseif multipleMoveCounter == -2
      multipleMoveCounter = 0
      insertMove(fileName,arrayDatabaseRowExchange(previousMoveGUI[1]),previousMoveGUI[2],arrayDatabaseRowExchange(previousMoveGUI[3]),previousMoveGUI[4],arrayDatabaseRowExchange(pieGUImovedX),pieGUImovedY,arrayDatabaseRowExchange(destRow),destCol)
    end
	else
		Messagebox(window, title="Invalid move", message="Can't capture you own piece")
	end

end

function dropPieGUI(destRow,destCol)
	pieceToDrop = cget(pieceGUImoved,"text")
	resetMoveIndicator()
	# since currTurn represent the last move on DB the next move made should be made by side other than currTurn
	if currTurn == defWhite
		#removing the white piece previously taken into black prison as it is now droped as black piece in the board
		for i in eachindex(blackPrison)
			if (blackPrison[i] == pieceToDrop)
				splice!(blackPrison, i)
				break #Avoids removing multiple pieces of the same name, like pawns
			end
		end
		chessboard[destRow,destCol].name = pieceToDrop
		chessboard[destRow,destCol].side = defBlack

	else
		#removing the white piece previously taken into black prison as it is now droped as black piece in the board
		for i in eachindex(whitePrison)
			if (whitePrison[i] == pieceToDrop)
				splice!(whitePrison, i)
				break #Avoids removing multiple pieces of the same name, like pawns
			end
		end
		chessboard[destRow,destCol].name = pieceToDrop
		chessboard[destRow,destCol].side = defWhite
	end
	lblPieArray[destRow,destCol] = pieceGUImoved
	grid(lblPieArray[destRow,destCol],destRow,destCol)
	#rebinding to update the row and col
	bind(lblPieArray[destRow,destCol],"<Button-1>") do path
		pieceClicked(destRow,destCol)
	end
	#updating the prison
	#set_value(cmbBox1,nothing)
	#set_value(cmbBox2,nothing)
	configure(cmbBox1, values = whitePrison)
	configure(cmbBox2, values = blackPrison)
	insertDrop(fileName,arrayDatabaseRowExchange(destRow),destCol,pieceToDrop)
end

function optionClicked(destRow,destCol)
	if pieGUImovedX == 0 && pieGUImovedY == 0
		dropPieGUI(destRow,destCol)
	else
		movePieGUI(destRow,destCol)
	end
end

function aiMoveGUI()
  global userTurn = false
  global aiTurn = true
  move()
  println(moveChoice)
  pieceClicked(moveChoice[1],moveChoice[2])
  update(window)
  sleep(2)
  optionClicked(moveChoice[3],moveChoice[4])
  global aiTurn = false
  global userTurn = true
end
#####################################################################################################
########################END OF FUNCTIONS, IMPORTANT GLOBAL VARIABLES, ETC############################
#####################################################################################################
using Tk

global sqlFile
global gameStart = " "
global fileNameInput = " "

global isAi = false
global isRemote = false
global isHost = false
global isEmail = false

global gameType = " "
global intTimeVal = 0
global intIncVal = 0
global aiDiffLvl = " "
global isRoulette = false
global isBlack = false
global isCheat = false
global portNumber = 0

global isFirstNotFound = true
disPos = [200, 200]

win1 = Toplevel("win1")
set_position(win1, 200, 200)
set_visible(win1, false)
frm1 = Frame(win1)

win2 = Toplevel("Options")
set_position(win2, disPos[1], disPos[2])
set_visible(win2, false)

localOrEmailWin = Toplevel("local/email")
set_position(localOrEmailWin, disPos[1], disPos[2])
set_visible(localOrEmailWin, false)
localOrEmailFr = Frame(localOrEmailWin)

gameTypeWin = Toplevel("Choose a game type")
set_position(gameTypeWin, disPos[1], disPos[2])
set_visible(gameTypeWin, false)

timeYesNoWin = Toplevel("Time option")
set_position(timeYesNoWin, disPos[1], disPos[2])
set_visible(timeYesNoWin, false)

timeOptnWin = Toplevel("Time limit")
set_position(timeOptnWin, disPos[1], disPos[2])
set_visible(timeOptnWin, false)
timeYesNoFr = Frame(timeYesNoWin)
timeYesNoRb = Radio(timeYesNoFr, ["YES", "NO"])
timeOptnFr = Frame(timeOptnWin)
timeLimitInput = Entry(timeOptnFr)

timeAddWin = Toplevel("Time increment")
set_position(timeAddWin, disPos[1], disPos[2])
set_visible(timeAddWin, false)
timeAddFr = Frame(timeAddWin)
timeIncInput = Entry(timeAddFr)

diffWin = Toplevel("Choose a difficulty")
set_position(diffWin, disPos[1], disPos[2])
set_visible(diffWin, false)

rouletteWin = Toplevel("roulette mode")
set_position(rouletteWin, disPos[1], disPos[2])
set_visible(rouletteWin, false)
rouletteFr = Frame(rouletteWin)
rouletteRb = Radio(rouletteFr, ["YES", "NO"])

goFirstWin = Toplevel("goFirst")
set_position(goFirstWin, disPos[1], disPos[2])
set_visible(goFirstWin, false)
goFirstFr = Frame(goFirstWin)
goFirstRb = Radio(goFirstFr, ["YES", "NO"])

AiCheatWin = Toplevel("AI Cheat")
set_position(AiCheatWin, disPos[1], disPos[2])
set_visible(AiCheatWin, false)
AiCheatFr = Frame(AiCheatWin)
AiCheatRb = Radio(AiCheatFr, ["YES", "NO"])

portNumWin = Toplevel("Port Number")
set_position(portNumWin, disPos[1], disPos[2])
set_visible(portNumWin, false)
portNumFr = Frame(portNumWin)
portNumInput = Entry(portNumFr)

oldGameWin = Toplevel("Old game")
set_position(oldGameWin, disPos[1], disPos[2])
set_visible(oldGameWin, false)
oldGameFr = Frame(oldGameWin)
oldGameInput = Entry(oldGameFr)

getFileNameWin = Toplevel("File name")
set_position(getFileNameWin, disPos[1], disPos[2])
set_visible(getFileNameWin, false)
getFileNameFr = Frame(getFileNameWin)
getFileNameInput = Entry(getFileNameFr)

fileNotExistWin = Toplevel("Invalid file name")
set_position(fileNotExistWin, disPos[1], disPos[2])
set_visible(fileNotExistWin, false)
fileNotExistFr = Frame(fileNotExistWin)
fileNotExistRb = Radio(fileNotExistFr, ["Re-enter file name", "Go back to main menu"])

oldGameAIorNotWin = Toplevel("AI or not")
set_position(oldGameAIorNotWin, disPos[1], disPos[2])
set_visible(oldGameAIorNotWin, false)
oldGameAIorNotFr = Frame(oldGameAIorNotWin)
oldGameAIorNotRb = Radio(oldGameAIorNotFr, ["AI", "Human"])

blackOrWhiteWin = Toplevel("black or white")
set_position(blackOrWhiteWin, disPos[1], disPos[2])
set_visible(blackOrWhiteWin, false)
blackOrWhiteFr = Frame(blackOrWhiteWin)
blackOrWhiteRb = Radio(blackOrWhiteFr, ["Black", "White"])



startMenu()
tcl("tkwait", "window", win1)


if gameType == "standard"
	dim = sDim
	createBoard()
	populateBoardShogi()
	#printBoard()
elseif gameType == "minishogi"
	dim = mDim
	createBoard()
	populateBoardMiniShogi()
	#printBoard()
elseif gameType == "chu"
	dim = cDim
	createBoard()
	populateBoardChuShogi()
	#printBoard()
elseif gameType == "ten"
  dim = tDim
  createBoard()
  populateBoardTenjikuShogi()
  #printBoard()
end


lastMoveNumberTable = SQLite.query(fileName,"SELECT max(move_number) FROM moves")
#Getting the int value from the nullableArray data type
currentMoveNumber = get(lastMoveNumberTable[1][1], 0)

moveNumber = 1
gameIsOver = false
global userTurn
global aiTurn
global isCurrentMoveValid
while moveNumber <= currentMoveNumber
	global isCurrentMoveValid
  global validateMoveChoice
	isCurrentMoveValid= true
	if isodd(moveNumber)
		currTurn = defBlack
	else
		currTurn = defWhite
	end
		#check the board position on white player turn so far, hence -1 since current move is not yet made
		#repetition start at 1 since when and equal board is found there is 2 cause, current and the 1 equal value found
		println("Move Number : $moveNumber")
		println("Is game is over :$gameIsOver")
	if gameIsOver == false
  	moveTypeTable = SQLite.query(fileName,"SELECT move_type FROM moves WHERE move_number=$moveNumber")
  	if get(moveTypeTable[1][1]) == "move"
    	xSource = arrayDatabaseRowExchange(get((SQLite.query(fileName,"SELECT  sourcex FROM moves WHERE move_number=$moveNumber"))[1][1]))
    	ySource = get((SQLite.query(fileName,"SELECT  sourcey FROM moves WHERE move_number=$moveNumber"))[1][1])
    	xTarget = arrayDatabaseRowExchange(get((SQLite.query(fileName,"SELECT  targetx FROM moves WHERE move_number=$moveNumber"))[1][1]))
    	yTarget = get((SQLite.query(fileName,"SELECT  targety FROM moves WHERE move_number=$moveNumber"))[1][1])

      #need to be checked before the actuall move because it use the source Tile
      #setting the actual info needed to do the check
      validateMoveChoice[1] = xSource
      validateMoveChoice[2] = ySource
      validateMoveChoice[3] = xTarget
      validateMoveChoice[4] = yTarget
      #did the actual check
			isCurrentMoveValid = moveFunctions("check")
			println(isCurrentMoveValid)
			if chessboard[xSource,ySource].side != currTurn
				isCurrentMoveValid =false
			end

			royaltyTaken = movePiece(xSource,ySource,xTarget,yTarget)
      gameIsOver = updateRoyalty()

			#need to be checked after the move because it use the destination Tile
			if isnull((SQLite.query(fileName,"SELECT  option FROM moves WHERE move_number=$moveNumber"))[1][1])
				#when the database says no Promotion check if the piece is supposed the auto promote
				#if it is means the current move is invalid
	      if autoPromote(xTarget,yTarget)
					isCurrentMoveValid = false
				end
	    else
				#when the database says Promotion check if the piece can promote
	      if prPromote(xTarget,yTarget)
					#when the promote is valid do nothing, the prPromote function already promote the piece while checking
				else
					#when the promote is invalid, registes current move as invalid
					isCurrentMoveValid = false
				end
	    end
			if isCurrentMoveValid == true
				if !(isnull((SQLite.query(fileName,"SELECT  targetx2 FROM moves WHERE move_number=$moveNumber"))[1][1])) & !(isnull((SQLite.query(fileName,"SELECT  targety2 FROM moves WHERE move_number=$moveNumber"))[1][1]))

					xTarget2 = arrayDatabaseRowExchange(get((SQLite.query(fileName,"SELECT  targetx2 FROM moves WHERE move_number=$moveNumber"))[1][1]))
					yTarget2 = get((SQLite.query(fileName,"SELECT  targety2 FROM moves WHERE move_number=$moveNumber"))[1][1])

          validateMoveChoice[5] = xTarget2
          validateMoveChoice[6] = yTarget2
					isCurrentMoveValid = moveFunctions("check")
					royaltyTaken = movePiece(xTarget,yTarget,xTarget2,yTarget2)
          gameIsOver = updateRoyalty()
		    end
			end
    	#the check if the move involve a king (king is moving or king is being captured)
			println("is current move valid: $isCurrentMoveValid")
  	elseif get(moveTypeTable[1][1]) == "drop"
    	xTarget = arrayDatabaseRowExchange(get((SQLite.query(fileName,"SELECT  targetx FROM moves WHERE move_number=$moveNumber"))[1][1]))
    	yTarget = get((SQLite.query(fileName,"SELECT  targety FROM moves WHERE move_number=$moveNumber"))[1][1])
    	#the extra [1] is there because SQLite always return as string not char, so [1] is there to make it as char even though the string is only 1 character
			#making new piece for drop
			pieceToDrop = (get((SQLite.query(fileName,"SELECT  option FROM moves WHERE move_number=$moveNumber"))[1][1]))

			#check if the piece is available for drop
			if currTurn == defBlack
				pieceFound = false
				#removing the white piece previously taken into black prison as it is now droped as black piece in the board
				for i in eachindex(blackPrison)
			    if blackPrison[i] == pieceToDrop
						pieceFound = true
			      splice!(blackPrison, i)
			      break #Avoids removing multiple pieces of the same name, like pawns
			    end
			  end
				if pieceFound == false
					isCurrentMoveValid = false
				end
	    else
				pieceFound = false
				#removing the black piece previously taken into white prison as it is now droped as white piece in the board
				for i in eachindex(whitePrison)
			    if whitePrison[i] == pieceToDrop
						pieceFound = true
			      splice!(whitePrison, i)
			      break #Avoids removing multiple pieces of the same name, like pawns
			    end
			  end
				if pieceFound == false
					isCurrentMoveValid = false
				end
	    end
			isCurrentMoveValid = prDrop(xTarget,yTarget,piece(pieceToDrop,currTurn,0,0,false))
			chessboard[xTarget,yTarget].name = pieceToDrop
    	chessboard[xTarget,yTarget].side = currTurn
	  else
	    #move type is resign, need clarification if display.jl still need to update the board when there is still move number even if resign is done or keep updating
			#Karol clarifies it doesn't matter wheter you stop or keep going but, you can stop when they resign
	    #1 side resigned, game is over
	    gameIsOver = true
			#Indicate player resigned
			if currTurn == defBlack
	      println("R")
	    else
	      println("r")
	    end
				#changing moveNumber = currentMove Number so it stop the loop after the increment
			moveNumber = currentMoveNumber
	  end
		if isCurrentMoveValid == false
			println("move ID = #",moveNumber)
			break
		end
	end
  moveNumber+=1
end



#creating top level window and the frame for top level
window = Toplevel()
topFr = Frame(window)
pack(topFr,expand = true, fill = "both")

#creating frame and widget containing the white prison and packing it left
frLbl1 = Labelframe(topFr, text = "White Prison")
pack(frLbl1,expand = true, fill = "both", side = "left")
cmbBox1 = Combobox(frLbl1,whitePrison)
pack(cmbBox1,expand = true, fill = "x",anchor= "n")
dropButton1 = Button(frLbl1, text = "Drop")
pack(dropButton1,expand = true, fill = "x",anchor= "s")
bind(dropButton1, "command") do path  ## do style
	drop_value = get_value(cmbBox1)
	if drop_value == nothing
		Messagebox(window, title="Invalid move", message="No piece to drop yet")
	else
			global pieceGUImoved = Label(fr,text = drop_value,font="Arial 8 ", image = pieceImgWhite ,compound = "center")
      dropClicked()
	end
end

#creating frame that will contain the board and packing it left
fr = Frame(topFr)
pack(fr,expand = true, fill = "both", side = "left")

#creating frame and widget containing the black prison and packing it left
frLbl2 = Labelframe(topFr, text = "Black Prison")
pack(frLbl2,expand = true, fill = "both", side = "left")
cmbBox2 = Combobox(frLbl2,blackPrison)
pack(cmbBox2,expand = true, fill = "x", anchor= "n")#(grid(lsBox2,2,3,sticky ="nsew")
dropButton2 = Button(frLbl2, text = "Drop")
pack(dropButton2,expand = true, fill = "x",anchor= "s")
bind(dropButton2, "command") do path  ## do style
	drop_value = get_value(cmbBox2)
	if drop_value == nothing
		Messagebox(window, title="Invalid move", message="No piece to drop yet")
	else
			global pieceGUImoved = Label(fr,text = drop_value,font="Arial 8 ", image = pieceImgBlack ,compound = "center")
      dropClicked()
	end
end

if gameType == "chu" || gameType == "ten"
	configure(dropButton1, state = "disabled")
  configure(dropButton2, state = "disabled")
end

#initializing some variable that needed for some function
global lblBrdArray = Array{Any}(dim,dim)
global lblPieArray = Array{Any}(dim,dim)

createBoardGUI()
populateBoardGUI()
update(window)


if isRemote == true
  #put code for remote play
elseif isEmail == true
  #put code for remote play
else
  #check for whose turn to move
  println(isAi)
  if isAi == true
    aiFrame = Frame(topFr)
    pack(aiFrame,expand = true, fill = "both", side = "bottom")
    aiTurnButton = Button(aiFrame, text = "Finish Turn")
    pack(aiTurnButton,expand = true, fill = "x")
    bind(aiTurnButton, "command") do path  ## do style
    	aiMoveGUI()
      global previousMoveGUI
      previousMoveGUI[1]=0
      previousMoveGUI[2]=0
      previousMoveGUI[3]=0
      previousMoveGUI[4]=0
    end
  end
  #no need to make special case of user vs user since the button handling will handle itself
end
println("still running")
tcl("tkwait", "window", window)