Complicating code in C#

Discussion of chess software programming and technical issues.

Moderators: hgm, Dann Corbit, Harvey Williamson

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
User avatar
mvanthoor
Posts: 963
Joined: Wed Jul 03, 2019 2:42 pm
Location: Netherlands
Full name: Marcel Vanthoor
Contact:

Re: Complicating code in C#

Post by mvanthoor » Fri Feb 05, 2021 11:05 am

A board (or squares) in its simplest form is just an array of 64 bytes holding a number that represents the piece that is in there.
Author of Rustic.
Releases | Code | Docs

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Fri Feb 05, 2021 11:12 am

Need not be an array. Might be a set when array is sparse. May be useful in irregular chess variations.

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Fri Feb 05, 2021 11:49 am

mvanthoor wrote:
Fri Feb 05, 2021 11:05 am
A board (or squares) in its simplest form is just an array of 64 bytes holding a number that represents the piece that is in there.
Don't know if you are going to implement bitboards by the way. Bitboards start of all misery. Means much more code to maintain.

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Sat Feb 06, 2021 1:55 pm

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.

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Wed Feb 10, 2021 12:29 pm

Really terrible to make it work/compile

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.

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Thu Feb 11, 2021 9:31 am

Did not work. Still need extra class to assign movegeneration data per square.
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);
            }
        }
   }

User avatar
mvanthoor
Posts: 963
Joined: Wed Jul 03, 2019 2:42 pm
Location: Netherlands
Full name: Marcel Vanthoor
Contact:

Re: Complicating code in C#

Post by mvanthoor » Thu Feb 11, 2021 9:53 am

To some extend, this topic is becoming hilarious. What engine is this by the way? Is it private, open source, can it be found in the CCRL-list, and/or is the code somewhere online?
Author of Rustic.
Releases | Code | Docs

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Thu Feb 11, 2021 11:09 am

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.

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Fri Feb 12, 2021 12:18 pm

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.

Henk
Posts: 6819
Joined: Mon May 27, 2013 8:31 am

Re: Complicating code in C#

Post by Henk » Fri Feb 12, 2021 12:56 pm

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;

        }
        

Post Reply