Complicating code in C#
Moderators: hgm, Rebel, chrisw
-
- Posts: 1784
- Joined: Wed Jul 03, 2019 4:42 pm
- Location: Netherlands
- Full name: Marcel Vanthoor
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Need not be an array. Might be a set when array is sparse. May be useful in irregular chess variations.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Don't know if you are going to implement bitboards by the way. Bitboards start of all misery. Means much more code to maintain.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Maybe better say that coordinate and square are the same thing.
So all properties I assigned to square might have been assigned to coordinate as well.
In case you don't use bitboards you don't need perfect hash key data per coordinate for move generation.
And what about a PieceCoordinateTable.
In plain movegeneration I don't need access to eval properties per coord.
In evaluation I don't need acces to move generation properties per coord.
So all properties I assigned to square might have been assigned to coordinate as well.
In case you don't use bitboards you don't need perfect hash key data per coordinate for move generation.
And what about a PieceCoordinateTable.
In plain movegeneration I don't need access to eval properties per coord.
In evaluation I don't need acces to move generation properties per coord.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Really terrible to make it work/compile
Before this I used new T() instead of a squarebuilder and added a new constraint to the class signature.
But then I could not create a ISquares<ISquareEval> but only a ISquares<SquareEval>. And if I only could create ISquares<SquareEval> I had to repair another zillion of compile errors.
That is the advantage from re-starting from scratch: you don't need to repair zillions compile errors when you make a mistake. Although when restarting from scratch you have to re-type, re-copy, re-invent the wheel.
Code: Select all
public class Squares<T> : ISquares<T> where T : ISquare
{
..
public IList<T> BuildSquares(ISquareBuilder<T> squareBuilder)
{
var board = new List<T>();
for (int i = 0; i <= NSQUARES -1; i++)
{
var square = squareBuilder.BuildSquare();
board.Add(square);
square.Init((coord)i);
}
return board;
}
Before this I used new T() instead of a squarebuilder and added a new constraint to the class signature.
But then I could not create a ISquares<ISquareEval> but only a ISquares<SquareEval>. And if I only could create ISquares<SquareEval> I had to repair another zillion of compile errors.
That is the advantage from re-starting from scratch: you don't need to repair zillions compile errors when you make a mistake. Although when restarting from scratch you have to re-type, re-copy, re-invent the wheel.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Did not work. Still need extra class to assign movegeneration data per square.
Ugly! Something went wrong.
Ugly! Something went wrong.
Code: Select all
public class BoardSquaresMoveGen : Squares<ISquareMoveGen>
{
public BoardSquaresMoveGen(): base(new SquareMoveGenBuilder(), 8, 8)
{
InitAllMoves();
}
/// <summary>
/// Assumes all squares are initialized
/// </summary>
public void InitAllMoves()
{
for (int i = 0; i <= NSQUARES - 1; i++)
{
var field = this[i];
field.InitMoves(this);
}
}
}
-
- Posts: 1784
- Joined: Wed Jul 03, 2019 4:42 pm
- Location: Netherlands
- Full name: Marcel Vanthoor
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
It's about Skipper. Private engine. Only used for testing some software development ideas.
Maybe best not to recommend writing generic code. For there are always exceptions that don't fit in.
Perhaps generic code only possible for lowest level.
For movegeneration you need to know the bordersquares of the board. So it looks like can't do it per square.
Maybe best not to recommend writing generic code. For there are always exceptions that don't fit in.
Perhaps generic code only possible for lowest level.
For movegeneration you need to know the bordersquares of the board. So it looks like can't do it per square.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Maybe only argument to use properties is to reduce length of paramerlist.
But I don't like it that a class/structure/record contains methods that do not use all its properties.
Properties behaving as bad as semi global variables. At least they should be all immutable.
So maybe make a method static unless number of parameters greater than three and some methods share the same parameter. In that case create a class with that parameter as a property.
By the way biggest problem is methods being too long. So I should repair that first.
But I don't like it that a class/structure/record contains methods that do not use all its properties.
Properties behaving as bad as semi global variables. At least they should be all immutable.
So maybe make a method static unless number of parameters greater than three and some methods share the same parameter. In that case create a class with that parameter as a property.
By the way biggest problem is methods being too long. So I should repair that first.
-
- Posts: 7220
- Joined: Mon May 27, 2013 10:31 am
Re: Complicating code in C#
Here an example of bad code to be rewritten. Man you can spend weeks/months/years on rewriting source code.
Code: Select all
public static IImmutableList<IMoveBase> ComputePawnDirectionMoves(ICoord coord, IPieceColor color,
IMoveFactory mvFactory, ISquares<ISquareMoveGen> boardSquares, PawnDirection dir)
{
var nColumns = boardSquares.nColumns;
var pieceSort = ConvertToPieceSort(Kind.Pawn_Kind, color);
var firstRow = color == White() ? 0 : LASTROW;
var lastRow = color == White() ? LASTROW : 0;
var epRow = color == White() ? 4 : 3;
var square = boardSquares[coord];
int rowNr2 = square.RowNr;
if (rowNr2 == 0 || rowNr2 == lastRow)
return null;
var dirMoves = CreateBuilder<IMoveBase>();
var colorValue = ABSearch.Eval(color);
if (dir == LEFT || dir == EP_LEFT)
{
if (square.ColNr > 0 &&
Less(color, square.RowNr, lastRow)
)
{
int newPos = (int)square.Coord + colorValue * nColumns - 1;
if (dir == LEFT)
{
if (Less(color, square.RowNr, lastRow - ABSearch.Eval(color)))
{
var mv = mvFactory.BuildMove(square.Coord2, boardSquares[(int)newPos].Coord2, pieceSort);
dirMoves.Add(mv);
}
else
{
AddPromotionMoves(square, mvFactory, pieceSort, boardSquares, dirMoves, newPos);
}
}
else
{
Debug.Assert(dir == EP_LEFT);
if (square.RowNr == epRow)
{
var mv = mvFactory.BuildEPMove(square.Coord2, boardSquares[(int)newPos].Coord2, pieceSort);
dirMoves.Add(mv);
}
}
}
}
else if (dir == FRONT)
{
int rowNr = square.RowNr;
if (rowNr == lastRow - colorValue
)
{
int newPos = (int)square.Coord + colorValue * nColumns;
AddPromotionMoves(square, mvFactory, pieceSort, boardSquares, dirMoves, newPos);
}
else
{
int nSteps = 1;
if (rowNr == firstRow + colorValue)
{
nSteps = 2;
}
for (int i = 1; i <= nSteps; i++)
{
int newPos = (int)square.Coord + i * colorValue * nColumns;
var field = boardSquares[newPos];
dirMoves.Add(PawnFrontMove(boardSquares, mvFactory, pieceSort, square.Coord2, field.Coord2));
}
}
}
else if (dir == RIGHT || dir == EP_RIGHT)
{
if (square.ColNr < LASTCOLUMN
&& Less(color, square.RowNr, lastRow))
{
int newPos = (int)square.Coord + colorValue * nColumns + 1;
if (dir == RIGHT)
{
if (Less(color, square.RowNr, lastRow - colorValue))
dirMoves.Add(mvFactory.BuildMove(square.Coord2, boardSquares[(int)newPos].Coord2, pieceSort));
else
{
AddPromotionMoves(square, mvFactory, pieceSort, boardSquares, dirMoves, newPos);
}
}
else if (square.RowNr == epRow)
{
var mv = mvFactory.BuildEPMove(square.Coord2, boardSquares[(int)newPos].Coord2, pieceSort);
dirMoves.Add(mv);
}
}
}
return dirMoves.ToImmutableList();
bool Less(IPieceColor color2, int x, int y)
=>
color2 == White() ? x < y : x > y;
}