Exemplo n.º 1
0
        private string MakeAnswer(SnakeAction snakeAction)
        {
            switch (snakeAction)
            {
            case SnakeAction.Down:
                return("DOWN");

            case SnakeAction.Left:
                return("LEFT");

            case SnakeAction.Right:
                return("RIGHT");

            case SnakeAction.Up:
                return("UP");

            case SnakeAction.ActDown:
                return("ACT,DOWN");

            case SnakeAction.ActLeft:
                return("ACT,LEFT");

            case SnakeAction.ActRight:
                return("ACT,RIGHT");

            case SnakeAction.ActUp:
                return("ACT,UP");

            default:
                break;
            }

            return("");
        }
Exemplo n.º 2
0
        private static void TestMyMovement()
        {
            var         gameBoard = new GameBoard(Boards.Current);
            SnakeAction lastmove  = SnakeAction.Left;

            while (true)
            {
                Movement.MakeEnemyMove(gameBoard);

                Console.Clear();
                Graphical.WriteField(gameBoard);
                Console.WriteLine($"{gameBoard.Head.X}:{gameBoard.Head.Y}:{gameBoard.HeadType}: {gameBoard.MyLength} {gameBoard.EvilTicks} {gameBoard.HasStone}");

                bool        possible = false;
                SnakeAction action   = SnakeAction.ActDown;
                Element     newHead  = new Element(-1, -1);
                do
                {
                    var key = Console.ReadKey();
                    switch (key.Key)
                    {
                    case ConsoleKey.UpArrow:
                        action = SnakeAction.Up;
                        break;

                    case ConsoleKey.DownArrow:
                        action = SnakeAction.Down;
                        break;

                    case ConsoleKey.LeftArrow:
                        action = SnakeAction.Left;
                        break;

                    case ConsoleKey.RightArrow:
                        action = SnakeAction.Right;
                        break;

                    default:
                        continue;
                    }

                    if (!PossiblyFilter.IsMovePossible(gameBoard, action, lastmove, true, out newHead))
                    {
                        Console.WriteLine("Impossible");
                    }
                    else
                    {
                        possible = true;
                    }
                }while (!possible);

                lastmove = action;

                gameBoard = new GameBoard(gameBoard);
                Movement.MakeMyMove(gameBoard, action, ref newHead);
            }
        }
        public SnakeAction Move(GameStatus state)
        {
            var response = new SnakeAction();
            var snake    = state.Snakes.FirstOrDefault(s => s.Id == state.You);

            if (snake != null)
            {
                response.Move = snake.Update(state);
            }
            return(response);
        }
Exemplo n.º 4
0
        internal static bool IsDirectionBaff(SnakeAction action, ref Element head, ref Element tail)
        {
            switch ((SnakeAction)((int)action & 0x0F))
            {
            case SnakeAction.Up:
                return(tail.Y > head.Y);

            case SnakeAction.Down:
                return(tail.Y < head.Y);

            case SnakeAction.Left:
                return(tail.X > head.X);

            case SnakeAction.Right:
                return(tail.X < head.X);
            }

            return(false);
        }
Exemplo n.º 5
0
        internal static bool IsNearNyamkaBaff(SnakeAction action, ref Element head, ref Element nyamka)
        {
            switch ((SnakeAction)((int)action & 0x0F))
            {
            case SnakeAction.Up:
                return(nyamka.Y < head.Y);

            case SnakeAction.Down:
                return(nyamka.Y > head.Y);

            case SnakeAction.Left:
                return(nyamka.X < head.X);

            case SnakeAction.Right:
                return(nyamka.X > head.X);
            }

            return(false);
        }
Exemplo n.º 6
0
        public static void MakeMyMove(GameBoard gameBoard, SnakeAction action, ref Element newHead)
        {
            //Console.Clear();
            //Graphical.WriteField(gameBoard);

            //-----rage-----
            if (newHead.type == BoardElement.FuryPill)
            {
                gameBoard.EvilTicks += 9;
            }

            //clean enemies
            EnemyEraser.CleanEnemyShake(gameBoard, newHead.X, newHead.Y);
            var dontMoveTail = MeEraser.CleanMe(gameBoard, newHead.X, newHead.Y);

            MoveMyHead(gameBoard, ref newHead);

            if (!dontMoveTail && newHead.type != BoardElement.Apple)
            {
                MoveMyTail(gameBoard, ref newHead, false);
            }
            if (newHead.type == BoardElement.Apple)
            {
                gameBoard.MyLength++;
            }
            if (newHead.type == BoardElement.Stone)
            {
                gameBoard.HasStone = true;
                if (gameBoard.EvilTicks == 0)
                {
                    MoveMyTail(gameBoard, ref newHead, false);
                    MoveMyTail(gameBoard, ref newHead, false);
                    MoveMyTail(gameBoard, ref newHead, false);
                    gameBoard.MyLength -= 3;
                }
            }

            if (gameBoard.EvilTicks != 0)
            {
                gameBoard.EvilTicks--;
            }
        }
Exemplo n.º 7
0
        internal static void SetState(BoardElement eatedElement, SnakeAction action)
        {
            if (eatedElement == BoardElement.FuryPill)
            {
                rageCount += 9;
            }
            else if (rageCount > 0)
            {
                rageCount--;
            }

            if ((int)action >= 0x10)
            {
                hasStone = false;
            }

            if (eatedElement == BoardElement.Stone)
            {
                hasStone = true;
            }

            LastMove = action;
        }
Exemplo n.º 8
0
        public static bool IsMovePossible(GameBoard gameBoard, SnakeAction actionS, SnakeAction lastMoveS, bool real, out Element newHead)
        {
            var action   = (int)actionS & 0x0F;
            var lastMove = (int)lastMoveS & 0x0F;

            newHead = new Element(-1, -1);

            //180 degrees
            switch (gameBoard.HeadType)
            {
            case BoardElement.HeadUp:
                if (action == (int)SnakeAction.Down)
                {
                    return(false);
                }
                break;

            case BoardElement.HeadLeft:
                if (action == (int)SnakeAction.Right)
                {
                    return(false);
                }
                break;

            case BoardElement.HeadRight:
                if (action == (int)SnakeAction.Left)
                {
                    return(false);
                }
                break;

            case BoardElement.HeadDown:
                if (action == (int)SnakeAction.Up)
                {
                    return(false);
                }
                break;

            case BoardElement.HeadEvil:
                switch (lastMove & 0x0F)
                {
                case (int)SnakeAction.Up:
                    if (action == (int)SnakeAction.Down)
                    {
                        return(false);
                    }
                    break;

                case (int)SnakeAction.Left:
                    if (action == (int)SnakeAction.Right)
                    {
                        return(false);
                    }
                    break;

                case (int)SnakeAction.Right:
                    if (action == (int)SnakeAction.Left)
                    {
                        return(false);
                    }
                    break;

                case (int)SnakeAction.Down:
                    if (action == (int)SnakeAction.Up)
                    {
                        return(false);
                    }
                    break;
                }
                break;

            case BoardElement.HeadDead:
                return(false);
            }

            //over field
            newHead = gameBoard.Head.MakeMovement(actionS, gameBoard.Size);
            if (newHead.X == -1)
            {
                return(false);
            }

            //stones
            newHead.type = gameBoard.Board[newHead.X, newHead.Y];

            if (newHead.type == BoardElement.StartFloor || newHead.type == BoardElement.Wall)
            {
                return(false);
            }

            if (gameBoard.EvilTicks == 0 && gameBoard.MyLength < 5 && newHead.type == BoardElement.Stone)
            {
                return(false);
            }

            //enemies
            if (Lists.IsEnemyHead(newHead.type) || (Lists.IsEnemyBody(newHead.type) && Helpers.IsNear(gameBoard, newHead.X, newHead.Y, Lists.enemyHeads)))
            {
                var enemyAgro = newHead.type == BoardElement.EnemyHeadEvil || Helpers.IsNear(gameBoard, newHead.X, newHead.Y, BoardElement.EnemyHeadEvil);

                //--правила для головы--
                //Если текущая змейка не в ярости, а вражеская в ярости - то текущая змейка умирает.
                if (gameBoard.EvilTicks == 0 && enemyAgro)
                {
                    return(false);
                }
                //Если обе змейки в ярости или обе не в ярости - то от каждой отрезаем длину другой змейки.
                //То есть, если столкнулись две змейки длиной в 5 и в 7 единиц, то змейка длиной в пять погибает, так как 5-7<2, а змейка длиной в 7 принимает длину 2 единицы.
                else if ((gameBoard.EvilTicks != 0) == enemyAgro)
                {
                    var(headLength, tailLength, _) = EnemyDetector.GetEnemyShake(gameBoard, newHead.X, newHead.Y);

                    if (gameBoard.MyLength - (headLength + tailLength + 1) < 2)
                    {
                        return(false);
                    }
                }
            }
            else if (Lists.IsEnemyBody(newHead.type) || Lists.IsEnemyTail(newHead.type))
            {
                if (gameBoard.EvilTicks == 0)
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 9
0
        // Call recursively
        private static async Task <long> GetActionWeight(GameBoard gameBoard, Element newHead, SnakeAction action, int depth)
        {
            long currentRate = Rates.GetElementRate(gameBoard, ref newHead);

            if (currentRate == long.MinValue)
            {
                return(long.MinValue);
            }

            //investigate new position
            //if (gameBoard.EvilTicks == 0)
            //{
            //    var (_, _, isEvilNear) = MeDetector.GetMe(gameBoard, gameBoard.Head.X, gameBoard.Head.Y);
            //    if (isEvilNear)
            //        currentRate -= 10;
            //}

            currentRate *= (15 - depth);

            if (depth == maxDeep)
            {
                return(currentRate);
            }

            //move me
#if DEBUG
            try
            {
#endif
            Movement.MakeMyMove(gameBoard, action, ref newHead);

            //add enemy predictions

#if DEBUG
        }
        catch (Exception)
        {
            Graphical.WriteToLog(gameBoard);
            throw;
        }
#endif

            Movement.MakeEnemyMove(gameBoard);

            //calculate my variants
            var tasks = new List <Task <long> >();
            for (int i = 0; i < 4; i++)
            {
                SnakeAction a        = (SnakeAction)i;
                var         newBoard = new GameBoard(gameBoard);

                if (PossiblyFilter.IsMovePossible(newBoard, a, action, false, out var newNewHead))
                {
                    tasks.Add(GetActionWeight(newBoard, newNewHead, a, depth + 1));
                }
            }

            if (tasks.Count == 0)
            {
                return(long.MinValue);
            }

            var myVariantsScore = long.MinValue;
            do
            {
                var completedTask = await Task.WhenAny(tasks);

                tasks.Remove(completedTask);
#if DEBUG
                if (completedTask.IsFaulted)
                {
                    Graphical.WriteToLog(gameBoard);
                    throw completedTask.Exception;
                }
#endif
                if (!completedTask.IsFaulted && completedTask.Result != long.MinValue && myVariantsScore < completedTask.Result)
                {
                    myVariantsScore = completedTask.Result;
                }
            } while (tasks.Count > 0);

            if (myVariantsScore == long.MinValue)
            {
                return(long.MinValue);
            }

            currentRate += myVariantsScore;

            return(currentRate);
        }
Exemplo n.º 10
0
        public static async Task <SnakeAction?> GetOptimalActionAsync(GameBoard gameBoard, SnakeAction lastMove)
        {
            var tasks = new Dictionary <Task <long>, SnakeAction>();

            for (int i = 0; i < 4; i++)
            {
                SnakeAction action   = (SnakeAction)i;
                var         newBoard = new GameBoard(gameBoard);

                if (PossiblyFilter.IsMovePossible(newBoard, action, lastMove, true, out Element newHead))
                {
                    tasks.Add(GetActionWeight(newBoard, newHead, action, 0), action);
                }
            }

            if (tasks.Count == 0)
            {
                return(null);
            }

            bool        first  = true;
            SnakeAction result = SnakeAction.Down;
            long        score  = 0;

            do
            {
                var completedTask = await Task.WhenAny(tasks.Keys);

                var  action = tasks[completedTask];
                long weight;
                if (completedTask.IsFaulted)
                {
                    weight = long.MinValue;
#if DEBUG
                    Graphical.WriteToLog(gameBoard);
#endif
                }
                else
                {
                    weight = completedTask.Result;
                }

                if (Helpers.IsDirectionBaff(action, ref gameBoard.Head, ref gameBoard.Tail))
                {
                    weight += 1;
                }

                if (Helpers.IsNearNyamkaBaff(action, ref gameBoard.Head, ref gameBoard.Nyamka))
                {
                    weight += 10;
                }

                if (first || score < weight)
                {
                    first  = false;
                    result = action;
                    score  = weight;
                }

                tasks.Remove(completedTask);
            } while (tasks.Count > 0);

            return(result);
        }