I'm trying to script a C# game of Draughts/Checkers. I'm at the point of taking user input and validating it. I first check the input of current x and y coords to see they are numbers, then check the coord pair against the board. Then repeat for target coords. I end up with a really long function that has repetition, but can't figure out how to refactor it down.
The code for this function is:
public static Board MovePiece(Board board, Player player)
{
bool CanContinue = false;
bool validNumber = false;
int number = 0;
int xCurrent = 0;
int yCurrent = 0;
int xTarget = 0;
int yTarget = 0;
int validationStage = 0;
while (!CanContinue)
{
validNumber = false;
requestXCoord(validationStage);
while (!validNumber)
{
if (Int32.TryParse(Console.ReadLine(), out number))
{
xCurrent = number;
validNumber = true;
}
else
{
Console.WriteLine(Message.notValidNumber);
requestXCoord(validationStage);
validNumber = false;
}
}
validNumber = false;
requestYCoord(validationStage);
while (!validNumber)
{
if (Int32.TryParse(Console.ReadLine(), out number))
{
yCurrent = number;
validNumber = true;
}
else
{
Console.WriteLine(Message.notValidNumber);
requestYCoord(validationStage);
validNumber = false;
}
}
if (validatePosition(board, player, xCurrent, yCurrent, validationStage))
{
CanContinue = true;
}
else
{
CanContinue = false;
}
}
validationStage = 1;
CanContinue = false;
while (!CanContinue)
{
validNumber = false;
requestXCoord(validationStage);
while (!validNumber)
{
if (Int32.TryParse(Console.ReadLine(), out number))
{
xTarget = number;
validNumber = true;
}
else
{
Console.WriteLine(Message.notValidNumber);
requestXCoord(validationStage);
validNumber = false;
}
}
validNumber = false;
requestYCoord(validationStage);
while (!validNumber)
{
if (Int32.TryParse(Console.ReadLine(), out number))
{
yTarget = number;
validNumber = true;
}
else
{
Console.WriteLine(Message.notValidNumber);
requestYCoord(validationStage);
validNumber = false;
}
}
if (validatePosition(board, player, xTarget, yTarget, validationStage))
{
CanContinue = true;
}
else
{
CanContinue = false;
}
}
PerformMove(board, player, xCurrent, yCurrent, xTarget, yTarget);
return board;
}
The other called functions are:
private static Board PerformMove(Board board, Player player, int xCurrent, int yCurrent, int xTarget, int yTarget)
{
if (canMakeMove(board, player, xCurrent, yCurrent, xTarget, yTarget))
{
switchOwnership(board, player, xCurrent, yCurrent, xTarget, yTarget);
return board;
}
return null;
}
private static void switchOwnership(Board board, Player player, int xCurrent, int yCurrent, int xTarget, int yTarget)
{
board.tiles[xTarget, yTarget].OwnedBy = player;
board.tiles[xCurrent, yCurrent].OwnedBy = null;
}
private static bool canMakeMove(Board board, Player player, int xCurrent, int yCurrent, int xTarget, int yTarget)
{
return board.tiles[xCurrent, yCurrent].OwnedBy == player
&& board.tiles[xTarget, yTarget].OwnedBy == null;
}
private static void requestXCoord(int step)
{
var xCoord = step > 0 ? Message.targetX : Message.currentX;
Console.Write(xCoord);
}
private static void requestYCoord(int step)
{
var yCoord = step > 0 ? Message.targetY : Message.currentY;
Console.Write(yCoord);
}
private static bool validatePosition(Board board, Player player, int x, int y, int step)
{
if (x < 0 || y < 0 || x > 7 || y > 7)
{
Console.WriteLine(Message.outOfBounds);
return false;
}
else if (board.tiles[x, y].OwnedBy == null && step == 0)
{
Console.WriteLine(Message.emptySpace);
return false;
}
else if (board.tiles[x, y].OwnedBy == null && step == 1)
{
return true;
}
else if (board.tiles[x, y].OwnedBy == player && step == 1)
{
Console.WriteLine(Message.youOwnThis);
return false;
}
else if (board.tiles[x, y].OwnedBy != player)
{
Console.WriteLine(Message.opponentOwns);
return false;
}
return true;
}