Complicating code in C#

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Joost Buijs wrote: Fri Dec 11, 2020 1:13 pm
Henk wrote: Fri Dec 11, 2020 12:44 pm
Henk wrote: Fri Dec 11, 2020 12:06 pm Yes its efficiency.
enum won't work when N players play a game with M different pieces where N, M large.
So again end up with an int or a subrange of int to make it generic.
I really don't understand what you are trying to achieve, why complicate matters so much, it is all a piece of cake.
I don't like to rewrite code that has large reference counts.(Makes me crazy) For I can't change it. So the types I use there should be as generic as possible.
I think I just use interfaces for any type and assuming the least. Don't care about efficiency. Might be I loose factor two of efficiency.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

I have many pieces of similar code. One for white and one for black.

Taking days or weeks to repair that.

And what about implementing four player chess ?
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

More generic nonsense.
Can't use square. In 3D chess it is a cube.

Code: Select all


   public interface IBoardShapes
    {
        IShape this[ICoord coord]
        {
            get;
        }

        ICoordSet[] Slice(int dimension);
    }
 
User avatar
lithander
Posts: 881
Joined: Sun Dec 27, 2020 2:40 am
Location: Bremen, Germany
Full name: Thomas Jahn

Re: Complicating code in C#

Post by lithander »

I'm not sure if you're joking or not? If you're not planning to code a 3D chess why worry about cubes?

On my left hand I got YAGNI tattooed and on my right hand it reads KISS and my colleagues have been so much happier with my commits ever since! :wink:
Minimal Chess (simple, open source, C#) - Youtube & Github
Leorik (competitive, in active development, C#) - Github & Lichess
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Currently my throat is DRY. (Don't repeat yourself)

It is true I doubt if i would ever implement 4D chess.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

I even don't understand why I should not use a template or what is it called in c#

Code: Select all

  public interface IBoard<T>
    {
        T this[ICoord coord]
        {
            get;
        }

        ICoordSet[] Slice(int dimension);
    }
 
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Henk wrote: Mon Jan 04, 2021 1:55 pm Currently my throat is DRY. (Don't repeat yourself)

It is true I doubt if i would ever implement 4D chess.
https://en.wikipedia.org/wiki/Three-dimensional_chess

5D chess
https://en.wikipedia.org/wiki/5D_Chess_ ... ime_Travel.
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Already forgotten how magic bitboards work.
Maybe better not have used it. I don't know.

Code: Select all


        public enum coord
        {
            a1, b1, c1, d1, e1, f1, g1, h1,
            a2, b2, c2, d2, e2, f2, g2, h2,
            a3, b3, c3, d3, e3, f3, g3, h3,
            a4, b4, c4, d4, e4, f4, g4, h4,
            a5, b5, c5, d5, e5, f5, g5, h5,
            a6, b6, c6, d6, e6, f6, g6, h6,
            a7, b7, c7, d7, e7, f7, g7, h7,
            a8, b8, c8, d8, e8, f8, g8, h8
        };


Per Square:
 coord coord;

 Index = (int)coord;

 int StraightNShift = 64 - MagicKeyLenStraight[Index];


 public Dictionary<ulong, ulong> StraightMovesDict = new Dictionary<ulong, ulong>();
 ulong straightMoves =
                            MoveGenerationHelper.Moves(u & RightMoves, leftShift, 1, RightMoves) |
                            MoveGenerationHelper.Moves(u & LeftMoves,  rightShift, 1, LeftMoves) |
                            MoveGenerationHelper.Moves(u & UpMoves,    leftShift, 8, UpMoves) |
                            MoveGenerationHelper.Moves(u & DownMoves,  rightShift, 8, DownMoves);
 StraightMovesDict[u] = straightMoves;
 
 
 foreach (var pair in StraightMovesDict)
 {
      int index = MagicKey(pair.Key, StraightMagic, StraightNBits);
      StraightMovesArr[index] = pair.Value;
 }
 
 public int MagicKey(ulong occupancy, ulong magic, int nBits)
 {
      var ind = occupancy * magic;
      var index = (int)(ind >> (64 - nBits));
      return index;
 }
 
 
 public ulong StraightMoves(ulong occupiers) => 
     StraightMovesArr[*(StraightOcc & occupiers) * StraightMagic) >> StraightNShift];

 public bool SelfTest()
 {
      foreach (var pair in StraightMovesDict)
       {
                int index = MagicKey(pair.Key, StraightMagic, StraightNBits);
                if (StraightMovesArr[index] != pair.Value) return false;
       }
       return true;
 }
 
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

Code: Select all

Per square:


ulong StraightMagic = MagicArrStraight[Index];
int StraightNBits = MagicKeyLenStraight[Index];
int StraightNShift = 64 - StraightNBits;


class MagicNumbers64
{
        public static ulong[] MagicArrStraight = {

            3183468377726550016,
            1496929397988867150,
            ... etc
            
        public static int[] MagicKeyLenStraight = {

            14,
            13,
            ... etc.
 }
Henk
Posts: 7220
Joined: Mon May 27, 2013 10:31 am

Re: Complicating code in C#

Post by Henk »

More ugly code (used in magic bitboards move generation). It generates all possible (sub-)occupancies of a start maximum source occupancy or something. I think it generates some duplicates as well.

Code: Select all

       IList<ulong> GenOccupancies(ulong occSource, ulong occInProgress)
        {
            var res = new List<ulong>();
            if (occSource == 0)
            {             
                res.Add(occInProgress);
                return res;
            }
            else
            {
                var bit = First(occSource);
                var restBits = Rest(occSource);

                var t1 = GenOccupancies(restBits, occInProgress + bit);
                var t2 = GenOccupancies(restBits, occInProgress);

                res.AddRange(t1);
                res.AddRange(t2);
            }
            return res;
        }
  
This is how it is used. Efficiency not important here.

Code: Select all

 // per Square[64]
        public void InitMoves( IBoardSquares pos)
        {

            ...
            StraightOcc = StraightOccupancy(pos);
            DiagonalOcc = DiagonalOccupancy(pos);
            
            var straightOccupancies = GenOccupancies(StraightOcc, 0);
            foreach (var occupancy in straightOccupancies)
            {
                StraightMovesDict[occupancy] = GenerateStraightMoves(occupancy);
            }

            var diagonalOccupancies = GenOccupancies(DiagonalOcc, 0);
            foreach (var occupancy in diagonalOccupancies)
            {
                DiagonalMovesDict[occupancy] = GenerateDiagonalMoves(occupancy);
            }
        }