예제 #1
0
파일: Main.cs 프로젝트: sander2/draughts
        public static void Main(string[] args)
        {
            Board b = new Board ();

            Player player1 = null;
            foreach (var a in args)
            {
                if (a.Contains("human"))
                    player1 = new HumanPlayer(b);
            }

            if (player1 == null)
                player1 = new AI(b, 10000);
            Player player2 = new AI(b, 10000);

            Player currentPlayer = player1;
            while (true)
            {
                b.PrintBoard();
                Move m = currentPlayer.GetMove();
                if (m == null)
                    break;
                m.Apply(b);
                b.currentColor = (b.currentColor == Color.White ? Color.Black : Color.White);
                currentPlayer = (currentPlayer == player1 ? player2 : player1);
            }
        }
예제 #2
0
파일: AI.cs 프로젝트: sander2/draughts
 /// <summary>
 /// Calculates the hash.
 /// </summary>
 /// <returns>The hash.</returns>
 public ulong CalculateHash(Board brd)
 {
     ulong hash = 0;
     for (int i = 0; i < 50; i++)
         if (brd.pieces1D[i].color != Color.None)
             hash ^= (ulong)AI.zobristPieceMask[i, brd.pieces1D[i].HashCode];
     if (brd.currentColor == Color.Black)
         hash ^= AI.zobristColorMask;
     return hash;
 }
예제 #3
0
파일: Move.cs 프로젝트: sander2/draughts
        public override ulong Apply(Board b, ulong hash = 0)
        {
#if CHECK_APPLY_UNDO
            for (int q = 0; q < 10; q++)
                for (int j = 0; j < 10; j++)
                    if (b.pieces[q,j] != null)
                        pieces2[q,j] = new Piece(q,j,b.pieces[q,j].color, b.pieces[q,j].type);
#endif


            typePriorToApply = b.pieces [x, y].type;
            int len = hops.Count;
            
            // remove origin
            hash ^= AI.zobristPieceMask[b.pieces[x, y].squareNumIndex, b.pieces [x, y].HashCode];

            // update origin and destination
            // required to do in steps for the case when begin == end
            Color c = b.pieces [x, y].color;
            b.pieces [x, y].color = Color.None; // dont care what the type is if it in not occupied
            b.pieces [hops [len - 1].targetX, hops [len - 1].targetY].color = c;
            b.pieces [hops [len - 1].targetX, hops [len - 1].targetY].type = typePriorToApply;

            // Promotion:
            if (hops [len - 1].targetY == (c == Color.White ? 9 : 0))
                b.pieces [hops [len - 1].targetX, hops [len - 1].targetY].type = Piece.Type.Dam;

            // add destination
            hash ^= AI.zobristPieceMask[b.pieces[hops [len - 1].targetX, hops [len - 1].targetY].squareNumIndex, 
                                   b.pieces [hops [len - 1].targetX, hops [len - 1].targetY].HashCode];


            // remove victims
            for (int i = 0; i < len; i++)
            {
#if DEBUG
                if (b.pieces [hops [i].victimX, hops [i].victimY].color == Color.None)
                    throw new Exception();
#endif
                hash ^= AI.zobristPieceMask[b.pieces[hops [i].victimX, hops [i].victimY].squareNumIndex, 
                                       b.pieces [hops [i].victimX, hops [i].victimY].HashCode];

                b.pieces [hops [i].victimX, hops [i].victimY].color = Color.None;
            }

#if CHECK_APPLY_UNDO
            for (int q = 0; q < 10; q++)
                for (int j = 0; j < 10; j++)
                    if (b.pieces[q,j] != null)
                        pieces4[q,j] = new Piece(q, j, b.pieces[q,j].color, b.pieces[q,j].type);
#endif
            return hash;
        }
예제 #4
0
파일: AI.cs 프로젝트: sander2/draughts
        public AI(Board b, int time)
        {
            this.b = b;
            this.time = time;
            Random rand = new Random();
            if (zobristPieceMask == null)
            {
                zobristPieceMask = new ulong[50, 4];
                for (int i = 0; i < 50; i++)
                    for (int j = 0; j < 4; j++)
                        zobristPieceMask[i,j] = ((ulong)rand.Next()) << 32 | (ulong)rand.Next();
                zobristColorMask = ((ulong)rand.Next()) << 32 | (ulong)rand.Next();
            }

            ClearHashes();
        }
예제 #5
0
파일: AI.cs 프로젝트: sander2/draughts
 public HumanPlayer(Board b)
 {
     this.b = b;
 }
예제 #6
0
파일: Piece.cs 프로젝트: sander2/draughts
        public bool GetAllMoves(Board b, MoveSet moveset, TakingMove tm = null, int depth = 0, bool needClone = false)
        {
            if (color == Color.None)
                return false;
            bool childNeedsClone = false;
            bool foundNewMove = false;

            //int direction = color == Color.White ? 1 : -1;
            int maxSteps = type == Type.Dam ? 10 : 1;
            for (int yDirection = -1; yDirection <= 1; yDirection += 2)
            {
                for (int xDirection = -1; xDirection <= 1; xDirection += 2)
                {
                    for (int i = 1; i < maxSteps+1; i++)
                    {
                        int targetX = x + i * xDirection;
                        int targetY = y + i * yDirection;
                        if (targetX < 0 || targetX > 9 || targetY < 0 || targetY > 9)
                            break;

                        if (b.pieces [targetX, targetY].color == this.color) { // a piece of our own army
                            break;
                        }
                        else if (b.pieces [targetX, targetY].color == Color.None)
                        {
                            // normal move, need to check y direction
                            if ((type == Type.Dam || (yDirection == (color == Color.White ? 1 : -1))) &&
                                tm == null && moveset.minScore == 0)
                            {
                                moveset.moves.Add (new Move(x, y, targetX, targetY)); // normal move, not taking anything
                            }
                        }
                        else // pieces of of opponent
                        {
                            if (b.pieces[targetX, targetY].taken || b.pieces[targetX, targetY] == this ||
                                targetX +xDirection < 0 || targetX + xDirection > 9 ||
                                targetY + yDirection < 0 || targetY + yDirection > 9)
                                break;
                            if (b.pieces [x + (i+1) * xDirection, y + (i+1) * yDirection].color != Color.None)
                                break;

                            foundNewMove = true;

                            // we can take it!
                            Color c = this.color;
                            this.color = Color.None;

                            int victimX = targetX;
                            int victimY = targetY;
                            bool z = b.pieces[victimX, victimY].taken;
                            // mark it as taken so we cantb.pieces[victimX, victimY].taken jump over it again
                            b.pieces[victimX, victimY].taken = true;

                            // We need to find moves depth-first, or our taken scheme will not work
                            do
                            {
                                targetX += xDirection;
                                targetY += yDirection;
                                if (targetX < 0 || targetX > 9 || targetY < 0 || targetY > 9 ||
                                                b.pieces [targetX,targetY].color != Color.None)
                                    break;
                                if (tm == null)
                                {
                                    tm = new TakingMove(x, y);
                                }
                                else if (needClone)
                                {
                                    tm = tm.Clone(depth);
                                }

            #if DEBUG
                                if (b.pieces[victimX,victimY].color == Color.None)
                                    throw new Exception();
            #endif
                                tm.AddHop(targetX,targetY, victimX, victimY, b.pieces [victimX, victimY].type);

                                b.pieces [targetX,targetY].color = c;
                                //TODO: type!!!
                                b.pieces[targetX, targetY].type = type;
                                childNeedsClone |= b.pieces [targetX,targetY].GetAllMoves(b, moveset, tm, depth + 1, childNeedsClone);
                                b.pieces [targetX,targetY].color = Color.None;
                                needClone = true;

                            }
                            while (++i < maxSteps);

            #if DEBUG
                            if (b.pieces[victimX, victimY].taken == false)
                                throw new Exception();
            #endif
                            b.pieces[victimX, victimY].taken = false;
                            this.color = c;
                        }
                    }
                }
            }
            if (!foundNewMove && tm != null && tm.numTaken >= moveset.minScore)
            {
                moveset.moves.Add(tm);
                moveset.minScore = tm.numTaken;
            }
            return foundNewMove;
        }
예제 #7
0
파일: Move.cs 프로젝트: sander2/draughts
 public virtual void Undo(Board b, ulong hash = 0)
 {
     b.pieces [x, y].color = b.pieces [targetX, targetY].color;
     b.pieces [x, y].type = typePriorToApply;
     b.pieces [targetX, targetY].color = Color.None;
 }
예제 #8
0
파일: Move.cs 프로젝트: sander2/draughts
        public virtual ulong Apply(Board b, ulong hash = 0)
        {
            typePriorToApply = b.pieces [x, y].type;
            b.pieces [targetX, targetY].color = b.pieces [x, y].color;
            b.pieces [targetX, targetY].type = b.pieces [x, y].type;
            if (targetY == (b.pieces [targetX, targetY].color == Color.White ? 9 : 0))
                b.pieces [targetX, targetY].type = Piece.Type.Dam;

            // update hash
            hash ^= AI.zobristPieceMask[ToHumanReadablePos(x, y) - 1, b.pieces [x, y].HashCode];
            hash ^= AI.zobristPieceMask[ToHumanReadablePos(targetX, targetY) - 1, b.pieces [targetX, targetY].HashCode];

            b.pieces [x, y].color = Color.None;

            return hash;
        }
예제 #9
0
파일: Move.cs 프로젝트: sander2/draughts
        /// <summary>
        /// Undo the move
        /// </summary>
        /// <param name="b">the board.</param>
        /// <param name="hash">Hash.</param>
        public override void Undo(Board b, ulong hash = 0)
        {
            #if CHECK_APPLY_UNDO
                
                Piece[,] pieces3 = new Piece[10,10];
                for (int q = 0; q < 10; q++)
                    for (int j = 0; j < 10; j++)
                        if (b.pieces[q,j] != null)
                            pieces3[q,j] = new Piece(q, j, b.pieces[q,j].color, b.pieces[q,j].type);

                for (int q = 0; q < 10; q++)
                    for (int j = 0; j < 10; j++)
                        if (b.pieces [q, j] != null)
                            if (pieces4 [q, j].color != b.pieces [q, j].color || (pieces4 [q, j].color != Color.None && b.pieces [q, j].type != pieces4 [q, j].type))
                            {
                                b.PrintBoard();
                                int qewqwe = 5;
                            }
            #endif

            int len = hops.Count;

            // required to do in steps for the case when begin == end
            
            Color c = b.pieces [hops [len - 1].targetX, hops [len - 1].targetY].color;
            b.pieces [hops [len - 1].targetX, hops [len - 1].targetY].color = Color.None;
            b.pieces [x, y].color = c;
            b.pieces [x, y].type = typePriorToApply;

            Color victimColor = (c == Color.Black ? Color.White : Color.Black);
            for (int i = 0; i < len; i++)
            {
                b.pieces [hops [i].victimX, hops [i].victimY].color = victimColor;
                b.pieces [hops [i].victimX, hops [i].victimY].type = hops[i].victimType;
            }

#if CHECK_APPLY_UNDO
            for (int q = 0; q < 10; q++)
                for (int j = 0; j < 10; j++)
                    if (b.pieces [q, j] != null)
                        if (pieces2 [q, j].color != b.pieces [q, j].color || (pieces2 [q, j].color != Color.None && b.pieces [q, j].type != pieces2 [q, j].type))
                        {
                            b.PrintBoard();
                            int qewqwe = 5;
                        }
#endif
        }