Example #1
0
        public static void Execute()
        {
            using (var vmClient = new VmClient())
            using (var mouseClient = new MouseClient(VmIp))
            {
                var printIndex = new Dictionary<ScreenPrint, int>();

                for (;;)
                {
                    var bmp = GetScreenImage(vmClient.GameScreenRect);
                    var img = bmp.ToIplImage();
                    var vBmp = new Mat(img, false).CvtColor(ColorConversion.RgbToHsv).Split()[2];
                    //vBmp.ToBitmap().Save("v.png");
                    //vBmp.Resize(new OpenCvSharp.CPlusPlus.Size(16, 16)).ToBitmap().Save("v.16.png");
                    //vBmp.Resize(new OpenCvSharp.CPlusPlus.Size(128, 128)).ToBitmap().Save("v.128.png");

                    var small = vBmp.Resize(new OpenCvSharp.CPlusPlus.Size(4, 4));
                    //Console.WriteLine(small.ElemSize());
                    //Console.WriteLine(vBmp.ElemSize());
                    //return;
                    var print = new ScreenPrint(ColorCut(ToByteArray(small)));
                    var index = printIndex.FindValue(print);
                    if (index == null)
                    {
                        index = (printIndex.Count > 0 ? printIndex.Values.Max() : 0) + 1;
                        printIndex[print] = index.Value;
                    }
                    Console.WriteLine(index);

                    GC.Collect();
                    System.Threading.Thread.Sleep(TimeSpan.FromSeconds(1));
                }
            }
        }
Example #2
0
        static void Main(string[] args)
        {
            if (args.FirstOrDefault() == "--test-mouse-client")
            {
                using (var client = new MouseClient("169.254.200.106"))
                {
                    client.MouseEvent(MouseEventFlags.MOVE, 100, 100);
                }
                return;
            }

            Zuma.Execute();
        }
Example #3
0
        public static NitroBolt.Wui.HtmlResult <HElement> HView(object _state, JsonData[] jsons, HContext context)
        {
            var state = _state.As <MainState>() ?? new MainState();

            foreach (var json in jsons.OrEmpty())
            {
                switch (json.JPath("data", "command")?.ToString())
                {
                case "mouse-event":
                {
                    var x = ConvertHlp.ToInt(json.JPath("data", "x"));
                    var y = ConvertHlp.ToInt(json.JPath("data", "y"));
                    if (x != null && y != null)
                    {
                        using (var client = new MouseClient(Zuma.VmIp))
                        {
                            client.MoveTo(x.Value, y.Value, 800, 600);
                        }
                    }
                }
                break;

                case "reset":
                {
                    using (var client = new MouseClient(Zuma.VmIp))
                    {
                        client.Reset();
                    }
                }
                break;

                case "screenshot":
                {
                    new VmClient().Screenshot().Save(context.HttpContext.Server.MapPath($"~/App_Data/{DateTime.UtcNow.Ticks}.png"));
                }
                break;

                default:
                    break;
                }
            }

            var page = Page(state);

            return(new NitroBolt.Wui.HtmlResult <HElement>
            {
                Html = page,
                State = state,
            });
        }
Example #4
0
        public static NitroBolt.Wui.HtmlResult<HElement> HView(object _state, JsonData[] jsons, HContext context)
        {
            var state = _state.As<MainState>() ?? new MainState();

            foreach (var json in jsons.OrEmpty())
            {
                switch (json.JPath("data", "command")?.ToString())
                {
                    case "mouse-event":
                        {
                            var x = ConvertHlp.ToInt(json.JPath("data", "x"));
                            var y = ConvertHlp.ToInt(json.JPath("data", "y"));
                            if (x != null && y != null)
                            {
                                using (var client = new MouseClient(Zuma.VmIp))
                                {
                                    client.MoveTo(x.Value, y.Value, 800, 600);
                                }
                            }
                        }
                        break;
                    case "reset":
                        {
                            using (var client = new MouseClient(Zuma.VmIp))
                            {
                                client.Reset();
                            }
                        }
                        break;
                    case "screenshot":
                        {
                            new VmClient().Screenshot().Save(context.HttpContext.Server.MapPath($"~/App_Data/{DateTime.UtcNow.Ticks}.png"));
                        }
                        break;
                    default:
                        break;
                }
            }

            var page = Page(state);
            return new NitroBolt.Wui.HtmlResult<HElement>
            {
                Html = page,
                State = state,
            };
        }
Example #5
0
        public static void Execute()
        {
            using (var vmClient = new VmClient())
                using (var mouseClient = new MouseClient(VmIp))
                {
                    var printIndex = new Dictionary <ScreenPrint, int>();

                    int?prev = null;

                    for (;;)
                    {
                        var bmp  = GetScreenImage(vmClient.GameScreenRect);
                        var img  = bmp.ToIplImage();
                        var vBmp = new Mat(img, false).CvtColor(ColorConversion.RgbToHsv).Split()[2];
                        //vBmp.ToBitmap().Save("v.png");
                        //vBmp.Resize(new OpenCvSharp.CPlusPlus.Size(16, 16)).ToBitmap().Save("v.16.png");
                        //vBmp.Resize(new OpenCvSharp.CPlusPlus.Size(128, 128)).ToBitmap().Save("v.128.png");

                        var small = vBmp.Resize(new OpenCvSharp.CPlusPlus.Size(4, 4));
                        //Console.WriteLine(small.ElemSize());
                        //Console.WriteLine(vBmp.ElemSize());
                        //return;
                        var print = new ScreenPrint(ColorCut(ToByteArray(small)));
                        var index = printIndex.FindValue(print);
                        if (index == null)
                        {
                            index             = (printIndex.Count > 0 ? printIndex.Values.Max() : 0) + 1;
                            printIndex[print] = index.Value;
                        }
                        if (prev != index)
                        {
                            Console.WriteLine(index);
                        }
                        prev = index;

                        GC.Collect();
                        System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.1));
                    }
                }
        }
Example #6
0
        public static void Execute2()
        {
            var frogRect = new Rectangle(320, 218, 150, 150);

            if (OtherOperation(frogRect))
            {
                return;
            }

            var screenChecks = ScreenChecks();

            screenChecks = ResolveChecks(screenChecks, @"..\..\Zuma.Data");

            Func <Bitmap, string> check = image => screenChecks.Where(_check => image.Check(_check.Points)).Select(_check => _check.Name).FirstOrDefault();


            var vmClient = new VmClient();

            var gameScreenRect = vmClient.GameScreenRect;

            var game_width  = gameScreenRect.Width;
            var game_height = gameScreenRect.Height;


            //var startButtonPoint = new Point(950, 430);
            //var startMissionPoint = new Point(600, 750);
            var startButtonPoint  = new Point(950, 520);
            var startMissionPoint = new Point(180, 360);
            var endChallengePoint = new Point(320, 590);

            var vm_host = VmIp;

            var client = new MouseClient(vm_host);


            var background     = LoadBitmap("../../Zuma.Data/background.png");
            var hsv_background = new Mat(background.ToIplImage(), true).CvtColor(ColorConversion.RgbToHsv).Split();


            if (false)
            {
                var fireflyImage     = LoadBitmap(@"p:\Projects\_Other\Cs10\Gamering\bin\Release\FireFlies.h\46.png");
                var hsv_fireflyImage = new Mat(fireflyImage.ToIplImage(), true).CvtColor(ColorConversion.RgbToHsv).Split();
                //for (var i = 0; i < 3; ++i)
                //{
                //  hsv_fireflyImage[i].Absdiff(hsv_background[i]).ImWrite(string.Format("ff{0}.png", i));
                //}

                var hsv_v = hsv_fireflyImage[2].Absdiff(hsv_background[2]);
                hsv_v.Rectangle(new Rect(frogRect.X, frogRect.Y, frogRect.Width, frogRect.Height), new Scalar(0), -1);
                hsv_v = hsv_v.Threshold(80, 255, ThresholdType.Binary);
                hsv_v.ImWrite("ff_v.png");
                return;
            }


            foreach (var file in System.IO.Directory.GetFiles("History"))
            {
                System.IO.File.Delete(file);
            }

            string prevScreenName      = null;
            string prevKnownScreenName = null;
            var    history             = new List <Bitmap>();
            var    isSave = false;

            var lastActionTime = DateTime.UtcNow;

            for (var tick = 0; ; tick++)
            {
                try
                {
                    var bmp = GetScreenImage(gameScreenRect);

                    if (Console.KeyAvailable)
                    {
                        var keyInfo = Console.ReadKey();
                        if (keyInfo.Key == ConsoleKey.Escape)
                        {
                            break;
                        }
                        else if (keyInfo.Key == ConsoleKey.Spacebar)
                        {
                            bmp.Save("0.png");
                            for (var i = 0; i < history.Count; ++i)
                            {
                                history[i].Save(string.Format("{0}.png", i + 1));
                            }
                            Console.WriteLine("save");
                        }
                    }

                    var screenName = check(bmp);
                    //var screenName = "action";
                    Console.Write("{0}: {1}{2}", tick, screenName, new string(' ', 20) + new string('\x8', 40));
                    switch (screenName)
                    {
                    case "main":
                        Console.WriteLine("main");
                        client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, startButtonPoint.X * 65536 / game_width, startButtonPoint.Y * 65536 / game_height);
                        System.Threading.Thread.Sleep(400);
                        client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                        System.Threading.Thread.Sleep(150);
                        client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                        System.Threading.Thread.Sleep(50);
                        System.Threading.Thread.Sleep(4000);
                        break;

                    case "challenge":
                        client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, startMissionPoint.X * 65536 / game_width, startMissionPoint.Y * 65536 / game_height);
                        System.Threading.Thread.Sleep(400);
                        client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                        System.Threading.Thread.Sleep(150);
                        client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                        System.Threading.Thread.Sleep(50);
                        break;

                    case "end_challenge":
                        client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, endChallengePoint.X * 65536 / game_width, endChallengePoint.Y * 65536 / game_height);
                        System.Threading.Thread.Sleep(400);
                        client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                        System.Threading.Thread.Sleep(150);
                        client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                        System.Threading.Thread.Sleep(50);
                        break;
                    //case "action":
                    //  mouse_event(MouseEventFlags.LEFTDOWN, 0, 0);
                    //  System.Threading.Thread.Sleep(150);
                    //  mouse_event(MouseEventFlags.LEFTUP, 0, 0);
                    //  System.Threading.Thread.Sleep(50);

                    //  break;
                    case "action":
                        //if (prevScreenName == "mission" && screenName == "action")
                        //{
                        //  for (var i = 0; i < 100; ++i)
                        //  {
                        //    GetScreenImage(gameScreenRect).Save(string.Format("FireFlies/{0}.png", i));
                        //    System.Threading.Thread.Sleep(1);
                        //  }
                        //}

                        if (!isSave)
                        {
                            bmp.Save("b.png");
                        }
                        isSave = true;
                        client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, (frogRect.X + frogRect.Width / 2) * 65536 / game_width, 580 * 65536 / game_height);
                        System.Threading.Thread.Sleep(150);
                        if (lastActionTime.AddSeconds(5) < DateTime.UtcNow)
                        {
                            client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                            System.Threading.Thread.Sleep(100);
                            client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                            System.Threading.Thread.Sleep(10);
                            lastActionTime = DateTime.UtcNow;
                            continue;
                        }

                        var ballPoint     = new Point(75, 105);
                        var leftEyePoint  = new Point(50, 57);
                        var rightEyePoint = new Point(100, 57);
                        var frogCenter    = new Point(frogRect.X + 75, frogRect.Y + 75);

                        var frogBmp       = GetScreenImage(new Rectangle(gameScreenRect.X + frogRect.X, gameScreenRect.Y + frogRect.Y, frogRect.Width, frogRect.Height));
                        var frogChannels  = new Mat(frogBmp.ToIplImage(), true).CvtColor(ColorConversion.RgbToHsv).Split();
                        int ballColor     = AverageColor(frogChannels[0], ballPoint, 2);
                        var leftEyeColor  = AverageColor(frogChannels[1], leftEyePoint, 2);
                        var rightEyeColor = AverageColor(frogChannels[1], rightEyePoint, 2);
                        //Console.WriteLine("{0}, {1}, {2}", ballColor, leftEyeColor, rightEyeColor);

                        if (leftEyeColor != 25 || rightEyeColor != 25)
                        {
                            continue;
                        }
                        bmp = GetScreenImage(gameScreenRect);

                        var frogBallPoint = new Point(frogRect.X + ballPoint.X, frogRect.Y + ballPoint.Y);

                        var mat       = new Mat(bmp.ToIplImage(), true);
                        var hsv       = mat.CvtColor(ColorConversion.RgbToHsv).Split();
                        var hsv_diff  = hsv.Zip(hsv_background, (ch, bg_ch) => ch.Absdiff(bg_ch)).ToArray();
                        var s_diff_th = hsv_diff[1].Threshold(25, 255, ThresholdType.Binary);
                        s_diff_th.Rectangle(new Rect(frogRect.X, frogRect.Y, frogRect.Width, frogRect.Height), new Scalar(0), -1);

                        var balls   = DetectBalls(s_diff_th, hsv[0]);
                        var minBall = balls.Where(ball => Math.Abs(ball.H - ballColor) < 10).OrderBy(ball => Distance2(ball.Point, frogCenter)).FirstOrDefault();
                        if (minBall != null)
                        {
                            var targetPoint = RotatePointAroundCenter(minBall.Point, frogCenter, -8);

                            client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, targetPoint.X * 65536 / game_width, targetPoint.Y * 65536 / game_height);
                            System.Threading.Thread.Sleep(150);

                            client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                            System.Threading.Thread.Sleep(100);
                            client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                            System.Threading.Thread.Sleep(10);
                            lastActionTime = DateTime.UtcNow;
                        }
                        if (true)
                        {
                            var ballwidth  = 36;
                            var ballwidth3 = ballwidth / 3;

                            var displayBmp = new Bitmap(bmp);
                            using (var g = Graphics.FromImage(displayBmp))
                            {
                                g.DrawImageUnscaled(frogBmp, new Point(frogRect.X, frogRect.Y));
                                //g.DrawImageUnscaled(frogBmp, 0, 0);
                                foreach (var ball in balls)
                                {
                                    g.DrawEllipse(Pens.Orange, ball.Point.X - ballwidth / 2, ball.Point.Y - ballwidth / 2, ballwidth, ballwidth);
                                    g.DrawString(ball.H.ToString(), SystemFonts.DefaultFont, Brushes.Black, ball.Point.X - ballwidth / 2, ball.Point.Y - ballwidth / 2);
                                }
                                if (true)
                                {
                                    g.DrawEllipse(Pens.Red, frogBallPoint.X - ballwidth / 2, frogBallPoint.Y - ballwidth / 2, ballwidth, ballwidth);
                                    g.DrawString(ballColor.ToString(), SystemFonts.DefaultFont, Brushes.Black, frogBallPoint.X - ballwidth / 2, frogBallPoint.Y - ballwidth / 2);
                                }
                                if (minBall != null)
                                {
                                    g.DrawEllipse(new Pen(Color.Green, 2), minBall.Point.X - ballwidth / 2, minBall.Point.Y - ballwidth / 2, ballwidth, ballwidth);
                                    var targetPoint = RotatePointAroundCenter(minBall.Point, frogCenter, -8);
                                    g.DrawEllipse(new Pen(Color.LightBlue, 2), targetPoint.X - ballwidth / 2, targetPoint.Y - ballwidth / 2, ballwidth, ballwidth);
                                }
                            }
                            var prefix = string.Format("History/{0}.", tick);
                            displayBmp.Save(prefix + "detect.png");
                            //hsv_diff[0].ImWrite(prefix + "detect.h.png");
                            //s_diff_th.ImWrite(prefix + "detect.s diff.png");
                            //frogChannels[0].ImWrite(prefix + "frog h.png");
                            //frogChannels[1].ImWrite(prefix + "frog s.png");
                            //frogChannels[2].ImWrite(prefix + "frog v.png");
                        }


                        break;

                    case null:
                        foreach (var _check in screenChecks)
                        {
                            Console.WriteLine(_check.Name);
                            bmp.Display(_check.Points);
                        }
                        bmp.Save("unknown.png");
                        break;
                    }
                    prevScreenName = screenName;
                    history.Insert(0, bmp);
                    const int maxHistoryLength = 10;
                    if (history.Count > maxHistoryLength)
                    {
                        history.RemoveRange(maxHistoryLength, history.Count - maxHistoryLength);
                    }
                    if (screenName != null)
                    {
                        prevKnownScreenName = screenName;
                    }
                }
                catch (Exception exc)
                {
                    Console.WriteLine(exc);
                }
            }
        }
Example #7
0
        public static void Execute2()
        {
            var frogRect = new Rectangle(320, 218, 150, 150);

            if (OtherOperation(frogRect))
                return;

            var screenChecks = ScreenChecks();
            screenChecks = ResolveChecks(screenChecks, @"..\..\Zuma.Data");

            Func<Bitmap, string> check = image => screenChecks.Where(_check => image.Check(_check.Points)).Select(_check => _check.Name).FirstOrDefault();


            var vmClient = new VmClient();

            var gameScreenRect = vmClient.GameScreenRect;

            var game_width = gameScreenRect.Width;
            var game_height = gameScreenRect.Height;


            //var startButtonPoint = new Point(950, 430);
            //var startMissionPoint = new Point(600, 750);
            var startButtonPoint = new Point(950, 520);
            var startMissionPoint = new Point(180, 360);
            var endChallengePoint = new Point(320, 590);

            var vm_host = VmIp;

            var client = new MouseClient(vm_host);


            var background = LoadBitmap("../../Zuma.Data/background.png");
            var hsv_background = new Mat(background.ToIplImage(), true).CvtColor(ColorConversion.RgbToHsv).Split();


            if (false)
            {
                var fireflyImage = LoadBitmap(@"p:\Projects\_Other\Cs10\Gamering\bin\Release\FireFlies.h\46.png");
                var hsv_fireflyImage = new Mat(fireflyImage.ToIplImage(), true).CvtColor(ColorConversion.RgbToHsv).Split();
                //for (var i = 0; i < 3; ++i)
                //{
                //  hsv_fireflyImage[i].Absdiff(hsv_background[i]).ImWrite(string.Format("ff{0}.png", i));
                //}

                var hsv_v = hsv_fireflyImage[2].Absdiff(hsv_background[2]);
                hsv_v.Rectangle(new Rect(frogRect.X, frogRect.Y, frogRect.Width, frogRect.Height), new Scalar(0), -1);
                hsv_v = hsv_v.Threshold(80, 255, ThresholdType.Binary);
                hsv_v.ImWrite("ff_v.png");
                return;
            }


            foreach (var file in System.IO.Directory.GetFiles("History"))
                System.IO.File.Delete(file);

            string prevScreenName = null;
            string prevKnownScreenName = null;
            var history = new List<Bitmap>();
            var isSave = false;

            var lastActionTime = DateTime.UtcNow;

            for (var tick = 0; ; tick++)
            {
                try
                {
                    var bmp = GetScreenImage(gameScreenRect);

                    if (Console.KeyAvailable)
                    {
                        var keyInfo = Console.ReadKey();
                        if (keyInfo.Key == ConsoleKey.Escape)
                            break;
                        else if (keyInfo.Key == ConsoleKey.Spacebar)
                        {
                            bmp.Save("0.png");
                            for (var i = 0; i < history.Count; ++i)
                                history[i].Save(string.Format("{0}.png", i + 1));
                            Console.WriteLine("save");
                        }
                    }

                    var screenName = check(bmp);
                    //var screenName = "action";
                    Console.Write("{0}: {1}{2}", tick, screenName, new string(' ', 20) + new string('\x8', 40));
                    switch (screenName)
                    {
                        case "main":
                            Console.WriteLine("main");
                            client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, startButtonPoint.X * 65536 / game_width, startButtonPoint.Y * 65536 / game_height);
                            System.Threading.Thread.Sleep(400);
                            client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                            System.Threading.Thread.Sleep(150);
                            client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                            System.Threading.Thread.Sleep(50);
                            System.Threading.Thread.Sleep(4000);
                            break;
                        case "challenge":
                            client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, startMissionPoint.X * 65536 / game_width, startMissionPoint.Y * 65536 / game_height);
                            System.Threading.Thread.Sleep(400);
                            client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                            System.Threading.Thread.Sleep(150);
                            client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                            System.Threading.Thread.Sleep(50);
                            break;
                        case "end_challenge":
                            client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, endChallengePoint.X * 65536 / game_width, endChallengePoint.Y * 65536 / game_height);
                            System.Threading.Thread.Sleep(400);
                            client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                            System.Threading.Thread.Sleep(150);
                            client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                            System.Threading.Thread.Sleep(50);
                            break;
                        //case "action":
                        //  mouse_event(MouseEventFlags.LEFTDOWN, 0, 0);
                        //  System.Threading.Thread.Sleep(150);
                        //  mouse_event(MouseEventFlags.LEFTUP, 0, 0);
                        //  System.Threading.Thread.Sleep(50);

                        //  break;
                        case "action":
                            //if (prevScreenName == "mission" && screenName == "action")
                            //{
                            //  for (var i = 0; i < 100; ++i)
                            //  {
                            //    GetScreenImage(gameScreenRect).Save(string.Format("FireFlies/{0}.png", i));
                            //    System.Threading.Thread.Sleep(1);
                            //  }
                            //}

                            if (!isSave)
                                bmp.Save("b.png");
                            isSave = true;
                            client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, (frogRect.X + frogRect.Width / 2) * 65536 / game_width, 580 * 65536 / game_height);
                            System.Threading.Thread.Sleep(150);
                            if (lastActionTime.AddSeconds(5) < DateTime.UtcNow)
                            {
                                client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                                System.Threading.Thread.Sleep(100);
                                client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                                System.Threading.Thread.Sleep(10);
                                lastActionTime = DateTime.UtcNow;
                                continue;
                            }

                            var ballPoint = new Point(75, 105);
                            var leftEyePoint = new Point(50, 57);
                            var rightEyePoint = new Point(100, 57);
                            var frogCenter = new Point(frogRect.X + 75, frogRect.Y + 75);

                            var frogBmp = GetScreenImage(new Rectangle(gameScreenRect.X + frogRect.X, gameScreenRect.Y + frogRect.Y, frogRect.Width, frogRect.Height));
                            var frogChannels = new Mat(frogBmp.ToIplImage(), true).CvtColor(ColorConversion.RgbToHsv).Split();
                            int ballColor = AverageColor(frogChannels[0], ballPoint, 2);
                            var leftEyeColor = AverageColor(frogChannels[1], leftEyePoint, 2);
                            var rightEyeColor = AverageColor(frogChannels[1], rightEyePoint, 2);
                            //Console.WriteLine("{0}, {1}, {2}", ballColor, leftEyeColor, rightEyeColor);

                            if (leftEyeColor != 25 || rightEyeColor != 25)
                                continue;
                            bmp = GetScreenImage(gameScreenRect);

                            var frogBallPoint = new Point(frogRect.X + ballPoint.X, frogRect.Y + ballPoint.Y);

                            var mat = new Mat(bmp.ToIplImage(), true);
                            var hsv = mat.CvtColor(ColorConversion.RgbToHsv).Split();
                            var hsv_diff = hsv.Zip(hsv_background, (ch, bg_ch) => ch.Absdiff(bg_ch)).ToArray();
                            var s_diff_th = hsv_diff[1].Threshold(25, 255, ThresholdType.Binary);
                            s_diff_th.Rectangle(new Rect(frogRect.X, frogRect.Y, frogRect.Width, frogRect.Height), new Scalar(0), -1);

                            var balls = DetectBalls(s_diff_th, hsv[0]);
                            var minBall = balls.Where(ball => Math.Abs(ball.H - ballColor) < 10).OrderBy(ball => Distance2(ball.Point, frogCenter)).FirstOrDefault();
                            if (minBall != null)
                            {
                                var targetPoint = RotatePointAroundCenter(minBall.Point, frogCenter, -8);

                                client.MouseEvent(MouseEventFlags.MOVE | MouseEventFlags.ABSOLUTE, targetPoint.X * 65536 / game_width, targetPoint.Y * 65536 / game_height);
                                System.Threading.Thread.Sleep(150);

                                client.MouseEvent(MouseEventFlags.LEFTDOWN, 0, 0);
                                System.Threading.Thread.Sleep(100);
                                client.MouseEvent(MouseEventFlags.LEFTUP, 0, 0);
                                System.Threading.Thread.Sleep(10);
                                lastActionTime = DateTime.UtcNow;
                            }
                            if (true)
                            {
                                var ballwidth = 36;
                                var ballwidth3 = ballwidth / 3;

                                var displayBmp = new Bitmap(bmp);
                                using (var g = Graphics.FromImage(displayBmp))
                                {
                                    g.DrawImageUnscaled(frogBmp, new Point(frogRect.X, frogRect.Y));
                                    //g.DrawImageUnscaled(frogBmp, 0, 0);
                                    foreach (var ball in balls)
                                    {
                                        g.DrawEllipse(Pens.Orange, ball.Point.X - ballwidth / 2, ball.Point.Y - ballwidth / 2, ballwidth, ballwidth);
                                        g.DrawString(ball.H.ToString(), SystemFonts.DefaultFont, Brushes.Black, ball.Point.X - ballwidth / 2, ball.Point.Y - ballwidth / 2);
                                    }
                                    if (true)
                                    {
                                        g.DrawEllipse(Pens.Red, frogBallPoint.X - ballwidth / 2, frogBallPoint.Y - ballwidth / 2, ballwidth, ballwidth);
                                        g.DrawString(ballColor.ToString(), SystemFonts.DefaultFont, Brushes.Black, frogBallPoint.X - ballwidth / 2, frogBallPoint.Y - ballwidth / 2);
                                    }
                                    if (minBall != null)
                                    {
                                        g.DrawEllipse(new Pen(Color.Green, 2), minBall.Point.X - ballwidth / 2, minBall.Point.Y - ballwidth / 2, ballwidth, ballwidth);
                                        var targetPoint = RotatePointAroundCenter(minBall.Point, frogCenter, -8);
                                        g.DrawEllipse(new Pen(Color.LightBlue, 2), targetPoint.X - ballwidth / 2, targetPoint.Y - ballwidth / 2, ballwidth, ballwidth);
                                    }

                                }
                                var prefix = string.Format("History/{0}.", tick);
                                displayBmp.Save(prefix + "detect.png");
                                //hsv_diff[0].ImWrite(prefix + "detect.h.png");
                                //s_diff_th.ImWrite(prefix + "detect.s diff.png");
                                //frogChannels[0].ImWrite(prefix + "frog h.png");
                                //frogChannels[1].ImWrite(prefix + "frog s.png");
                                //frogChannels[2].ImWrite(prefix + "frog v.png");
                            }


                            break;
                        case null:
                            foreach (var _check in screenChecks)
                            {
                                Console.WriteLine(_check.Name);
                                bmp.Display(_check.Points);
                            }
                            bmp.Save("unknown.png");
                            break;
                    }
                    prevScreenName = screenName;
                    history.Insert(0, bmp);
                    const int maxHistoryLength = 10;
                    if (history.Count > maxHistoryLength)
                        history.RemoveRange(maxHistoryLength, history.Count - maxHistoryLength);
                    if (screenName != null)
                        prevKnownScreenName = screenName;
                }
                catch (Exception exc)
                {
                    Console.WriteLine(exc);
                }
            }
        }