예제 #1
0
 //выбирает ход для выбранного игрока с глубиной не более maxDeep
 public Step SelectMove(Player p, int maxDeep, Board board)
 {
     Count = 0;
     _maxDeep = maxDeep;
     _threadsResults.Clear();
     var nBoard = new Board(board);
     var game = new Game(nBoard);
     var moves = game.getAllLegalMoves(p);
     var b = moves.Batch(moves.Count/ThreadCount).ToList();
     var thraads = new Thread[b.Count];
     var n = 0;
     foreach (var curMoves in b)
     {
         var args = new TheadArg
         {
             board = new Board(board),
             startPlayer = p,
             steps = curMoves.ToList()
         };
         var thread = new Thread(Process) {IsBackground = true};
         thread.Start(args);
         thraads[n++] = thread;
     }
     while (thraads.Any(x => x.IsAlive))
     {
         Thread.Sleep(100);
     }
     var res = _threadsResults.MaxBy(x => x.Score);
     return res.Step;
 }
예제 #2
0
        //посчитать счет черных (пока не самым оптимальный способ)
        static int calculateScoreBlack(Board board, Game game)
        {
            var sum = 0;
            var enemys = new List<Figure>();
            foreach (var figure in board.Figures)
            {
                if (figure != null && figure.Player == Player.White)
                    enemys.Add(figure);
            }
            foreach (var figure in board.Figures)
            {
                if (figure != null && figure.Player == Player.Black)
                {
                    sum += figure.Cost;
                    var attCount = 0;
                    for (int i = 0; i < enemys.Count; i++)
                    {
                        if (figure.AttackTarget(enemys[i]))
                            attCount++;
                    }
                    sum += (attCount - 1) * ((int)(figure.Cost * 0.3));
                    if (figure is Queen || figure is Bishop || figure is Knight)
                    {
                        if ((figure.X == 4 || figure.X == 5) && (figure.Y == 5 || figure.Y == 4))
                            sum += (int)(figure.X * 1.2);
                    }
                    if (figure is Pawn)
                    {

                    }
                }
            }
            var kingAtt = game.KingAlert(Player.Black);
            if (kingAtt == 1)
                sum -= 400;
            else if (kingAtt > 1)
                sum -= 800;
            return sum;
        }
예제 #3
0
        static void Main(string[] args)
        {
            Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
               var board = new Board();
            //Создаем пешек
            //for (int i = 0; i < 8; i++)
            //{
            //    new Pawn(Player.White, 1, i);
            //    new Pawn(Player.Black, 6, i);
            //}
            //new Rook(Player.White, 0, 0);
            //new Rook(Player.Black, 7, 0);
            //new Knight(Player.White, 0, 1);
            //new Knight(Player.Black, 7, 1);
            //new Bishop(Player.White, 0, 2);
            //new Bishop(Player.Black, 7, 2);
            //new Queen(Player.White, 0, 3);
            //new Queen(Player.Black, 7, 3);
            //new King(Player.White, 0, 4);
            //new King(Player.Black, 7, 4);
            //new Bishop(Player.White, 0, 5);
            //new Bishop(Player.Black, 7, 5);
            //new Knight(Player.White, 0, 6);
            //new Knight(Player.Black, 7, 6);
            //new Rook(Player.White, 0, 7);
            //new Rook(Player.Black, 7, 7);

            var g = new Game(board);
            var ai = new AI();
            var s = State.Calm;

            while (s != State.Checkmate)
            {
                PrintBoard(board.Figures);
                Console.WriteLine();

                Console.Write("Введите ваш ход({0}): ", g.Player);
                Step st;
                if (g.Player == Player.White)
                {
                    var step = Console.ReadLine();
                    st = Step.StringToStep(step);
                }
                else
                {
                    var tim = new Stopwatch();
                    tim.Start();
                    st = ai.SelectMove(g.Player, 6, board);
                    tim.Stop();
                    Console.WriteLine(tim.ElapsedMilliseconds);
                    Console.WriteLine();
                }
                try
                {
                        g.doMove(st);
                    s = g.calcState();
                }
                catch (ErrorStepExveption)
                {
                    Console.WriteLine("Не коректный ход");
                }
            }
        }
예제 #4
0
 private void Process(object obj)
 {
     var args = obj as TheadArg;
     var game = new Game(args.board);
     var bMoves = new int[args.steps.Count];
     if (args.startPlayer == Player.White)
     {
         var i = 0;
         foreach (var x in args.steps)
         {
             DoMove(x, args.board);
             var res = AlphaBetaBlackWS(int.MinValue, Int32.MaxValue, _maxDeep - 1, game);
             BackMove(args.board);
             bMoves[i++] = res;
         }
     }
     else
     {
         var i = 0;
         foreach (var x in args.steps)
         {
             DoMove(x, args.board);
             int res = AlphaBetaWhiteBS(int.MinValue, Int32.MaxValue, _maxDeep - 1, game);
             BackMove(args.board);
             bMoves[i++] = res;
         }
     }
     var max = bMoves.Max();
     var arrMoves = args.steps;
     var bestSteps = new List<Step>();
     for (var i = 0; i < bMoves.Length; i++)
     {
         if (bMoves[i] == max)
             bestSteps.Add(arrMoves[i]);
     }
     var rand = new Random();
     this._threadsResults.Add(new StepWithScore
     {
         Score = max,
         Step = bestSteps[rand.Next() % bestSteps.Count]
     });
 }
예제 #5
0
 private int AlphaBetaWhiteWS(int alpha, int beta, int depth, Game game)
 {
     Count++;
     var max = Int32.MinValue;
     if (depth <= 0) return calculateScoreWhite(game._board, game) - calculateScoreBlack(game._board, game);
     var moves = game.getAllLegalMoves(Player.White);
     if (moves.Count() != 0)
         foreach (var x in moves)
         {
             DoMove(x, game._board);
             var tmp = AlphaBetaBlackWS(alpha, beta, depth - 1, game);
             BackMove(game._board);
             if (tmp > max) max = tmp;
             if (tmp > alpha) alpha = tmp;
             if (max >= beta) return max;
         }
     else
     {
         var state = game.calcState();
         if (state == State.Checkmate)
             return 0;
         else return -10000;
     }
     return max;
 }
예제 #6
0
 private int AlphaBetaWhiteBS(int alpha, int beta, int depth, Game game)
 {
     Count++;
     var min = Int32.MaxValue;
     if (depth <= 0)
     {
         var state = game.calcState(Player.White);
         switch (state)
         {
             case State.Calm:
                 return calculateScoreWhite(game._board, game) - calculateScoreBlack(game._board, game);
             case State.Check:
                 return calculateScoreWhite(game._board, game) - calculateScoreBlack(game._board, game) - 300 ;
             case State.Checkmate:
                 return Int32.MinValue;
             case State.Draw:
                 return 0;
         }
     }
     var moves = game.getAllLegalMoves(Player.White);
     foreach (var x in moves)
     {
         DoMove(x, game._board);
         var tmp = AlphaBetaBlackBS(alpha, beta, depth - 1, game);
         BackMove(game._board);
         if (tmp < min) min = tmp;
         if (tmp < beta) beta = tmp;
         if (min <= alpha) return min;
     }
     return min;
 }
예제 #7
0
 private int AlphaBetaBlackWS(int alpha, int beta, int depth, Game game)
 {
     Count++;
     var min = int.MaxValue;
     if (depth <= 0) return calculateScoreBlack(game._board, game) - calculateScoreWhite(game._board, game);
     var moves = game.getAllLegalMoves(Player.Black);
     if (moves.Count() != 0)
         foreach (var x in moves)
         {
             DoMove(x, game._board);
             var tmp = AlphaBetaWhiteWS(alpha, beta, depth - 1, game);
             BackMove(game._board);
             if (tmp < min) min = tmp;
             if (tmp < beta) beta = tmp;
             if (min <= alpha) return min;
         }
     else
     {
         var state = game.calcState();
         return state == State.Checkmate ? 0 : 10000;
     }
     return min;
 }
예제 #8
0
 private int AlphaBetaBlackBS(int alpha, int beta, int depth, Game game)
 {
     Interlocked.Increment(ref Count);
     var max = Int32.MinValue;
     if (depth <= 0)
     {
         var state = game.calcState(Player.White);
         switch (state)
         {
             case State.Calm:
                 return calculateScoreBlack(game._board, game) - calculateScoreWhite(game._board, game);
             case State.Check:
                 return calculateScoreBlack(game._board, game)- 300-calculateScoreWhite(game._board, game);
             case State.Checkmate:
                 return Int32.MaxValue;
             case State.Draw:
                 return 0;
         }
     }
     var moves = game.getAllLegalMoves(Player.Black);
     foreach (var x in moves)
     {
         DoMove(x, game._board);
         var tmp = AlphaBetaWhiteBS(alpha, beta, depth - 1, game);
         BackMove(game._board);
         if (tmp > max) max = tmp;
         if (tmp > alpha) alpha = tmp;
         if (max >= beta) return max;
     }
     return max;
 }