Checkers Indicator

Ever get tired of waiting for a good trading setup?

Wait no longer.

you can play CHECKERS directly on your chart while you wait for your next setup.

Trade when it’s time to trade. Play checkers when the market makes you wait.

1 Like

#region Using declarations
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;
using NinjaTrader.Gui.Chart;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.DrawingTools;
#endregion

namespace NinjaTrader.NinjaScript.Indicators
{
public class WTCheckersSetupGameV2 : Indicator
{
private EMA fastEma;
private EMA slowEma;

    private Grid gameButtonGrid;
    private Button gameButton;
    private WTCheckersWindowV2 gameWindow;

    private bool longLatched;
    private bool shortLatched;

    protected override void OnStateChange()
    {
        if (State == State.SetDefaults)
        {
            Description              = "Checkers V2 with GAME, APPEARANCE, and SETUP ALERTS tabs.";
            Name                     = "WTCheckersSetupGameV2";
            Calculate                = Calculate.OnEachTick;
            IsOverlay                = true;
            DisplayInDataBox         = false;
            DrawOnPricePanel         = true;
            PaintPriceMarkers        = false;
            IsSuspendedWhileInactive = false;
            BarsRequiredToPlot       = 21;
        }
        else if (State == State.DataLoaded)
        {
            fastEma = EMA(9);
            slowEma = EMA(21);
        }
        else if (State == State.Historical)
        {
            AddGameButton();
        }
        else if (State == State.Terminated)
        {
            RemoveGameButtonAndWindow();
        }
    }

    private void AddGameButton()
    {
        if (ChartControl == null)
            return;

        ChartControl.Dispatcher.InvokeAsync(() =>
        {
            if (gameButtonGrid != null && UserControlCollection.Contains(gameButtonGrid))
                return;

            gameButtonGrid = new Grid
            {
                HorizontalAlignment = HorizontalAlignment.Right,
                VerticalAlignment = VerticalAlignment.Top,
                Margin = new Thickness(0, 42, 12, 0)
            };

            gameButton = new Button
            {
                Content = "CHECKERS",
                Width = 110,
                Height = 32,
                Padding = new Thickness(8, 2, 8, 2),
                Background = new SolidColorBrush(Color.FromRgb(31, 31, 31)),
                Foreground = Brushes.White,
                BorderBrush = new SolidColorBrush(Color.FromRgb(96, 96, 96)),
                FontWeight = FontWeights.SemiBold
            };

            gameButton.Click += GameButton_Click;
            gameButtonGrid.Children.Add(gameButton);
            UserControlCollection.Add(gameButtonGrid);
        });
    }

    private void GameButton_Click(object sender, RoutedEventArgs e)
    {
        if (gameWindow != null)
        {
            if (gameWindow.WindowState == WindowState.Minimized)
                gameWindow.WindowState = WindowState.Normal;

            gameWindow.Activate();
            return;
        }

        gameWindow = new WTCheckersWindowV2();
        gameWindow.Closed += (s, args) => gameWindow = null;

        Window owner = Window.GetWindow(ChartControl);
        if (owner != null)
            gameWindow.Owner = owner;

        gameWindow.Show();
    }

    private void RemoveGameButtonAndWindow()
    {
        if (ChartControl == null)
            return;

        ChartControl.Dispatcher.InvokeAsync(() =>
        {
            if (gameWindow != null)
            {
                try { gameWindow.Close(); }
                catch { }
                gameWindow = null;
            }

            if (gameButton != null)
            {
                gameButton.Click -= GameButton_Click;
                gameButton = null;
            }

            if (gameButtonGrid != null)
            {
                if (UserControlCollection.Contains(gameButtonGrid))
                    UserControlCollection.Remove(gameButtonGrid);

                gameButtonGrid.Children.Clear();
                gameButtonGrid = null;
            }
        });
    }

    protected override void OnBarUpdate()
    {
        if (CurrentBar < 21)
            return;

        // ------------------------------------------------------------
        // PLACEHOLDER TRADING SETUP
        // Replace only this block later with your own setup logic.
        // LONG  = EMA 9 crosses above EMA 21
        // SHORT = EMA 9 crosses below EMA 21
        // ------------------------------------------------------------
        bool longSignal = CrossAbove(fastEma, slowEma, 1);
        bool shortSignal = CrossBelow(fastEma, slowEma, 1);

        if (longSignal && !longLatched)
        {
            longLatched = true;
            TriggerSetup("LONG", Close[0]);
        }

        if (shortSignal && !shortLatched)
        {
            shortLatched = true;
            TriggerSetup("SHORT", Close[0]);
        }

        if (!longSignal)
            longLatched = false;

        if (!shortSignal)
            shortLatched = false;
    }

    private void TriggerSetup(string direction, double price)
    {
        string instrumentName = Instrument != null ? Instrument.FullName : "Instrument";

        Draw.TextFixed(
            this,
            "WTCheckersSetupAlert",
            direction + " SETUP DETECTED\n" + instrumentName + " @ " + price.ToString("0.00"),
            TextPosition.TopLeft,
            direction == "LONG" ? Brushes.LimeGreen : Brushes.Red,
            new NinjaTrader.Gui.Tools.SimpleFont("Segoe UI", 18) { Bold = true },
            Brushes.Transparent,
            new SolidColorBrush(Color.FromArgb(185, 15, 15, 15)),
            12
        );

        try
        {
            PlaySound(NinjaTrader.Core.Globals.InstallDir + @"\sounds\Alert1.wav");
        }
        catch { }

        if (gameWindow != null)
        {
            gameWindow.Dispatcher.InvokeAsync(() =>
            {
                if (gameWindow != null)
                    gameWindow.ShowSetupAlert(direction, price, instrumentName);
            });
        }
    }
}

public class WTCheckersWindowV2 : Window
{
    // 0 empty
    // 1 player red man
    // 2 player red king
    // -1 opponent black man
    // -2 opponent black king
    private readonly int[,] board = new int[8, 8];

    private Grid boardGrid;
    private ComboBox themeSelector;
    private TabControl topTabs;
    private CheckBox pauseOnSetupCheck;
    private CheckBox bringToFrontCheck;
    private CheckBox setupSoundCheck;
    private Button soundButton;
    private Button modeButton;
    private Button undoButton;
    private Button hintButton;
    private Button resignButton;
    private CheckBox alwaysOnTopCheck;

    private TextBlock statusText;
    private TextBlock turnValue;
    private TextBlock timerValue;
    private TextBlock capturedValue;
    private TextBlock monitorText;
    private TextBlock setupRuleText;
    private TextBlock clockText;
    private Border setupBanner;
    private TextBlock setupBannerText;

    private int selectedRow = -1;
    private int selectedCol = -1;
    private int forcedAiRow = -1;
    private int forcedAiCol = -1;

    private bool playerTurn = true;
    private bool gameOver;
    private bool pausedForSetup;
    private bool soundEnabled = true;
    private bool vsCpu = true;

    private int capturedByPlayer;
    private int capturedByOpponent;

    private DateTime gameStarted;
    private TimeSpan accumulatedBeforePause = TimeSpan.Zero;
    private DateTime currentRunStarted;

    private readonly Random rng = new Random();
    private readonly DispatcherTimer aiTimer;
    private readonly DispatcherTimer uiTimer;

    private string currentTheme = "Classic Red";

    private readonly Stack<GameSnapshot> undoStack = new Stack<GameSnapshot>();

    private class Move
    {
        public int FromRow;
        public int FromCol;
        public int ToRow;
        public int ToCol;
        public int CaptureRow = -1;
        public int CaptureCol = -1;

        public bool IsCapture
        {
            get { return CaptureRow >= 0 && CaptureCol >= 0; }
        }
    }

    private class GameSnapshot
    {
        public int[,] Board;
        public bool PlayerTurn;
        public int CapturedByPlayer;
        public int CapturedByOpponent;
    }

    private class ThemeColors
    {
        public Color LightSquare;
        public Color DarkSquare;
        public Color PlayerPiece;
        public Color PlayerStroke;
        public Color OpponentPiece;
        public Color OpponentStroke;
        public Color Accent;
    }

    public WTCheckersWindowV2()
    {
        Title = "Wizard Trends - Checkers V2";
        Width = 860;
        Height = 940;
        MinWidth = 720;
        MinHeight = 780;
        WindowStartupLocation = WindowStartupLocation.CenterOwner;
        Background = new SolidColorBrush(Color.FromRgb(17, 17, 17));

        aiTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromMilliseconds(420)
        };
        aiTimer.Tick += AiTimer_Tick;

        uiTimer = new DispatcherTimer
        {
            Interval = TimeSpan.FromSeconds(1)
        };
        uiTimer.Tick += UiTimer_Tick;
        uiTimer.Start();

        BuildInterface();
        NewGame();

        Closing += (s, e) =>
        {
            aiTimer.Stop();
            uiTimer.Stop();
        };
    }

    private void BuildInterface()
    {
        Grid root = new Grid();
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });  // header
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });  // top tabs
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });  // setup banner
        root.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); // board
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });  // game info
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });  // monitor
        root.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });  // footer
        Content = root;

        BuildHeader(root);
        BuildTopTabs(root);
        BuildSetupBanner(root);
        BuildBoard(root);
        BuildGameInfo(root);
        BuildMonitorRow(root);
        BuildFooter(root);
    }

    private void BuildHeader(Grid root)
    {
        Border header = new Border
        {
            Background = new SolidColorBrush(Color.FromRgb(23, 23, 23)),
            BorderBrush = new SolidColorBrush(Color.FromRgb(55, 55, 55)),
            BorderThickness = new Thickness(0, 0, 0, 1),
            Padding = new Thickness(16, 12, 16, 12)
        };
        Grid.SetRow(header, 0);
        root.Children.Add(header);

        Grid g = new Grid();
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        header.Child = g;

        StackPanel titlePanel = new StackPanel
        {
            VerticalAlignment = VerticalAlignment.Center
        };
        titlePanel.Children.Add(new TextBlock
        {
            Text = "CHECKERS V2",
            Foreground = Brushes.White,
            FontSize = 24,
            FontWeight = FontWeights.Bold
        });
        titlePanel.Children.Add(new TextBlock
        {
            Text = "Trading setup monitor remains active",
            Foreground = new SolidColorBrush(Color.FromRgb(185, 185, 185)),
            FontSize = 12
        });
        titlePanel.Children.Add(new TextBlock
        {
            Text = "GAME | APPEARANCE | SETUP ALERTS are directly below",
            Foreground = new SolidColorBrush(Color.FromRgb(235, 125, 55)),
            FontSize = 11,
            FontWeight = FontWeights.SemiBold
        });
        Grid.SetColumn(titlePanel, 0);
        g.Children.Add(titlePanel);

        StackPanel themePanel = new StackPanel
        {
            Margin = new Thickness(14, 0, 8, 0),
            VerticalAlignment = VerticalAlignment.Center
        };
        themePanel.Children.Add(new TextBlock
        {
            Text = "THEME:",
            Foreground = new SolidColorBrush(Color.FromRgb(190, 190, 190)),
            FontSize = 11,
            Margin = new Thickness(0, 0, 0, 3)
        });

        themeSelector = new ComboBox
        {
            Width = 150,
            Height = 30,
            Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80)),
            Padding = new Thickness(6, 2, 6, 2)
        };

        themeSelector.Items.Add("Classic Red");
        themeSelector.Items.Add("Green & Ivory");
        themeSelector.Items.Add("Blue & Silver");
        themeSelector.Items.Add("Purple & Gold");
        themeSelector.Items.Add("Orange & Charcoal");
        themeSelector.SelectedItem = currentTheme;

        themeSelector.SelectionChanged += (s, e) =>
        {
            if (themeSelector.SelectedItem != null)
            {
                currentTheme = themeSelector.SelectedItem.ToString();
                RenderBoard();
                UpdateAccentControls();
            }
        };

        themePanel.Children.Add(themeSelector);
        Grid.SetColumn(themePanel, 1);
        g.Children.Add(themePanel);

        soundButton = MakeHeaderButton("SOUND ON", 88);
        soundButton.Click += (s, e) =>
        {
            soundEnabled = !soundEnabled;
            soundButton.Content = soundEnabled ? "SOUND ON" : "SOUND OFF";
        };
        Grid.SetColumn(soundButton, 2);
        g.Children.Add(soundButton);

        Button newGameButton = MakeHeaderButton("NEW GAME", 105);
        newGameButton.Click += (s, e) => NewGame();
        Grid.SetColumn(newGameButton, 3);
        g.Children.Add(newGameButton);

        modeButton = MakeHeaderButton("VS CPU", 105);
        modeButton.Click += (s, e) =>
        {
            vsCpu = !vsCpu;
            modeButton.Content = vsCpu ? "VS CPU" : "2 PLAYER";
            NewGame();
        };
        Grid.SetColumn(modeButton, 4);
        g.Children.Add(modeButton);
    }

    private Button MakeHeaderButton(string text, double width)
    {
        return new Button
        {
            Content = text,
            Width = width,
            Height = 38,
            Margin = new Thickness(6, 4, 0, 4),
            Background = new SolidColorBrush(Color.FromRgb(35, 35, 35)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(88, 88, 88)),
            FontWeight = FontWeights.SemiBold
        };
    }

    private void BuildTopTabs(Grid root)
    {
        topTabs = new TabControl
        {
            Margin = new Thickness(12, 6, 12, 2),
            Background = new SolidColorBrush(Color.FromRgb(20, 20, 20)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(65, 65, 65))
        };

        // GAME TAB
        TabItem gameTab = new TabItem
        {
            Header = "GAME"
        };

        StackPanel gamePanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Margin = new Thickness(10, 8, 10, 8)
        };

        TextBlock modeLabel = new TextBlock
        {
            Text = "Mode:",
            Foreground = new SolidColorBrush(Color.FromRgb(190, 190, 190)),
            VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 8, 0)
        };
        gamePanel.Children.Add(modeLabel);

        Button cpuButton = new Button
        {
            Content = "VS CPU",
            Width = 85,
            Height = 28,
            Margin = new Thickness(0, 0, 6, 0),
            Background = new SolidColorBrush(Color.FromRgb(38, 38, 38)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85))
        };
        cpuButton.Click += (s, e) =>
        {
            if (!vsCpu)
            {
                vsCpu = true;
                if (modeButton != null)
                    modeButton.Content = "VS CPU";
                NewGame();
            }
        };
        gamePanel.Children.Add(cpuButton);

        Button twoPlayerButton = new Button
        {
            Content = "2 PLAYER",
            Width = 90,
            Height = 28,
            Margin = new Thickness(0, 0, 14, 0),
            Background = new SolidColorBrush(Color.FromRgb(38, 38, 38)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85))
        };
        twoPlayerButton.Click += (s, e) =>
        {
            if (vsCpu)
            {
                vsCpu = false;
                if (modeButton != null)
                    modeButton.Content = "2 PLAYER";
                NewGame();
            }
        };
        gamePanel.Children.Add(twoPlayerButton);

        gamePanel.Children.Add(new TextBlock
        {
            Text = "Game controls remain below the board.",
            Foreground = new SolidColorBrush(Color.FromRgb(145, 145, 145)),
            VerticalAlignment = VerticalAlignment.Center
        });

        gameTab.Content = gamePanel;

        // APPEARANCE TAB
        TabItem appearanceTab = new TabItem
        {
            Header = "APPEARANCE"
        };

        StackPanel appearancePanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Margin = new Thickness(10, 8, 10, 8)
        };

        appearancePanel.Children.Add(new TextBlock
        {
            Text = "Board / Chips:",
            Foreground = new SolidColorBrush(Color.FromRgb(190, 190, 190)),
            VerticalAlignment = VerticalAlignment.Center,
            Margin = new Thickness(0, 0, 8, 0)
        });

        ComboBox tabThemeSelector = new ComboBox
        {
            Width = 165,
            Height = 28,
            Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80))
        };
        tabThemeSelector.Items.Add("Classic Red");
        tabThemeSelector.Items.Add("Green & Ivory");
        tabThemeSelector.Items.Add("Blue & Silver");
        tabThemeSelector.Items.Add("Purple & Gold");
        tabThemeSelector.Items.Add("Orange & Charcoal");
        tabThemeSelector.SelectedItem = currentTheme;

        tabThemeSelector.SelectionChanged += (s, e) =>
        {
            if (tabThemeSelector.SelectedItem == null)
                return;

            currentTheme = tabThemeSelector.SelectedItem.ToString();

            if (themeSelector != null)
            {
                string headerTheme = themeSelector.SelectedItem == null
                    ? string.Empty
                    : themeSelector.SelectedItem.ToString();

                if (headerTheme != currentTheme)
                    themeSelector.SelectedItem = currentTheme;
            }

            RenderBoard();
            UpdateAccentControls();
        };
        appearancePanel.Children.Add(tabThemeSelector);

        alwaysOnTopCheck = new CheckBox
        {
            Content = "Always on top",
            Foreground = Brushes.White,
            Margin = new Thickness(20, 2, 0, 0),
            VerticalAlignment = VerticalAlignment.Center
        };
        alwaysOnTopCheck.Checked += (s, e) => Topmost = true;
        alwaysOnTopCheck.Unchecked += (s, e) => Topmost = false;
        appearancePanel.Children.Add(alwaysOnTopCheck);

        appearanceTab.Content = appearancePanel;
       // ALERT SETTINGS TAB
        TabItem alertsTab = new TabItem
        {
            Header = "SETUP ALERTS"
        };

        StackPanel alertsPanel = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            Margin = new Thickness(10, 8, 10, 8)
        };

        pauseOnSetupCheck = new CheckBox
        {
            Content = "Pause game on setup",
            IsChecked = true,
            Foreground = Brushes.White,
            Margin = new Thickness(0, 2, 18, 0),
            VerticalAlignment = VerticalAlignment.Center
        };
        alertsPanel.Children.Add(pauseOnSetupCheck);

        bringToFrontCheck = new CheckBox
        {
            Content = "Bring window to front",
            IsChecked = true,
            Foreground = Brushes.White,
            Margin = new Thickness(0, 2, 18, 0),
            VerticalAlignment = VerticalAlignment.Center
        };
        alertsPanel.Children.Add(bringToFrontCheck);

        setupSoundCheck = new CheckBox
        {
            Content = "Play setup sound",
            IsChecked = true,
            Foreground = Brushes.White,
            Margin = new Thickness(0, 2, 0, 0),
            VerticalAlignment = VerticalAlignment.Center
        };
        alertsPanel.Children.Add(setupSoundCheck);

        alertsTab.Content = alertsPanel;

        topTabs.Items.Add(gameTab);
        topTabs.Items.Add(appearanceTab);
        topTabs.Items.Add(alertsTab);
        topTabs.SelectedIndex = 0;

        Grid.SetRow(topTabs, 1);
        root.Children.Add(topTabs);
    }

    private void BuildSetupBanner(Grid root)
    {
        setupBannerText = new TextBlock
        {
            Foreground = Brushes.White,
            FontSize = 15,
            FontWeight = FontWeights.Bold,
            VerticalAlignment = VerticalAlignment.Center
        };

        Button resumeButton = new Button
        {
            Content = "RESUME GAME",
            Width = 125,
            Height = 30,
            Margin = new Thickness(14, 0, 0, 0),
            Background = Brushes.White,
            Foreground = Brushes.Black,
            FontWeight = FontWeights.SemiBold
        };
        resumeButton.Click += (s, e) => ResumeAfterSetup();

        StackPanel row = new StackPanel
        {
            Orientation = Orientation.Horizontal,
            HorizontalAlignment = HorizontalAlignment.Center
        };
        row.Children.Add(setupBannerText);
        row.Children.Add(resumeButton);

        setupBanner = new Border
        {
            Visibility = Visibility.Collapsed,
            Background = new SolidColorBrush(Color.FromRgb(130, 40, 40)),
            Padding = new Thickness(10),
            Child = row
        };

        Grid.SetRow(setupBanner, 2);
        root.Children.Add(setupBanner);
    }

    private void BuildBoard(Grid root)
    {
        Border frame = new Border
        {
            Margin = new Thickness(18, 16, 18, 12),
            BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)),
            BorderThickness = new Thickness(2),
            Background = Brushes.Black
        };

        Grid.SetRow(frame, 3);
        root.Children.Add(frame);

        boardGrid = new Grid();

        for (int i = 0; i < 8; i++)
        {
            boardGrid.RowDefinitions.Add(new RowDefinition());
            boardGrid.ColumnDefinitions.Add(new ColumnDefinition());
        }

        frame.Child = boardGrid;
    }

    private void BuildGameInfo(Grid root)
    {
        Border infoBorder = new Border
        {
            Margin = new Thickness(18, 0, 18, 8),
            BorderBrush = new SolidColorBrush(Color.FromRgb(54, 54, 54)),
            BorderThickness = new Thickness(1),
            Background = new SolidColorBrush(Color.FromRgb(21, 21, 21))
        };
        Grid.SetRow(infoBorder, 4);
        root.Children.Add(infoBorder);

        Grid info = new Grid();
        info.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0, GridUnitType.Star) });
        info.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0, GridUnitType.Star) });
        info.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.15, GridUnitType.Star) });
        info.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.2, GridUnitType.Star) });
        info.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0, GridUnitType.Star) });
        info.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1.0, GridUnitType.Star) });
        infoBorder.Child = info;

        turnValue = AddInfoPanel(info, 0, "TURN", "Red");
        timerValue = AddInfoPanel(info, 1, "TIME", "00:00:00");
        capturedValue = AddInfoPanel(info, 2, "CAPTURED", "Red 0   Black 0");

        undoButton = AddActionButton(info, 3, "UNDO MOVE");
        hintButton = AddActionButton(info, 4, "HINT");
        resignButton = AddActionButton(info, 5, "RESIGN");

        undoButton.Click += (s, e) => UndoMove();
        hintButton.Click += (s, e) => ShowHint();
        resignButton.Click += (s, e) => ResignGame();
    }

    private TextBlock AddInfoPanel(Grid parent, int column, string label, string value)
    {
        Border b = new Border
        {
            BorderBrush = new SolidColorBrush(Color.FromRgb(55, 55, 55)),
            BorderThickness = new Thickness(column == 0 ? 0 : 1, 0, 0, 0),
            Padding = new Thickness(10, 10, 10, 10)
        };

        StackPanel sp = new StackPanel
        {
            HorizontalAlignment = HorizontalAlignment.Center
        };

        sp.Children.Add(new TextBlock
        {
            Text = label,
            Foreground = new SolidColorBrush(Color.FromRgb(190, 190, 190)),
            FontSize = 11,
            HorizontalAlignment = HorizontalAlignment.Center
        });

        TextBlock v = new TextBlock
        {
            Text = value,
            Foreground = Brushes.White,
            FontSize = 14,
            FontWeight = FontWeights.SemiBold,
            Margin = new Thickness(0, 5, 0, 0),
            HorizontalAlignment = HorizontalAlignment.Center
        };

        sp.Children.Add(v);
        b.Child = sp;

        Grid.SetColumn(b, column);
        parent.Children.Add(b);

        return v;
    }

    private Button AddActionButton(Grid parent, int column, string text)
    {
        Button b = new Button
        {
            Content = text,
            Margin = new Thickness(6),
            Background = new SolidColorBrush(Color.FromRgb(31, 31, 31)),
            Foreground = Brushes.White,
            BorderBrush = new SolidColorBrush(Color.FromRgb(75, 75, 75)),
            FontWeight = FontWeights.SemiBold
        };

        Grid.SetColumn(b, column);
        parent.Children.Add(b);
        return b;
    }

    private void BuildMonitorRow(Grid root)
    {
        Border monitor = new Border
        {
            Margin = new Thickness(18, 0, 18, 8),
            Background = new SolidColorBrush(Color.FromRgb(20, 20, 20)),
            BorderBrush = new SolidColorBrush(Color.FromRgb(52, 52, 52)),
            BorderThickness = new Thickness(1),
            Padding = new Thickness(12, 9, 12, 9)
        };
        Grid.SetRow(monitor, 5);
        root.Children.Add(monitor);

        Grid g = new Grid();
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        monitor.Child = g;

        monitorText = new TextBlock
        {
            Text = "●  Market monitor is ACTIVE",
            Foreground = new SolidColorBrush(Color.FromRgb(135, 220, 135)),
            VerticalAlignment = VerticalAlignment.Center
        };
        Grid.SetColumn(monitorText, 0);
        g.Children.Add(monitorText);

        setupRuleText = new TextBlock
        {
            Text = "Setup: EMA 9 / EMA 21 crossover",
            Foreground = new SolidColorBrush(Color.FromRgb(205, 205, 205)),
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center
        };
        Grid.SetColumn(setupRuleText, 1);
        g.Children.Add(setupRuleText);

        clockText = new TextBlock
        {
            Foreground = new SolidColorBrush(Color.FromRgb(205, 205, 205)),
            VerticalAlignment = VerticalAlignment.Center
        };
        Grid.SetColumn(clockText, 2);
        g.Children.Add(clockText);
    }
    private void BuildFooter(Grid root)
    {
        Border footer = new Border
        {
            Background = new SolidColorBrush(Color.FromRgb(24, 24, 24)),
            BorderBrush = new SolidColorBrush(Color.FromRgb(52, 52, 52)),
            BorderThickness = new Thickness(0, 1, 0, 0),
            Padding = new Thickness(18, 10, 18, 10)
        };
        Grid.SetRow(footer, 6);
        root.Children.Add(footer);

        Grid g = new Grid();
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
        g.ColumnDefinitions.Add(new ColumnDefinition { Width = GridLength.Auto });
        footer.Child = g;

        statusText = new TextBlock
        {
            Text = "Setup alerts will pause the game and bring this window to front.",
            Foreground = new SolidColorBrush(Color.FromRgb(190, 190, 190)),
            VerticalAlignment = VerticalAlignment.Center
        };
        Grid.SetColumn(statusText, 0);
        g.Children.Add(statusText);

        TextBlock settingsHint = new TextBlock
        {
            Text = "Use the top tabs for Game, Appearance, and Setup Alert settings.",
            Foreground = new SolidColorBrush(Color.FromRgb(150, 150, 150)),
            VerticalAlignment = VerticalAlignment.Center
        };
        Grid.SetColumn(settingsHint, 1);
        g.Children.Add(settingsHint);
    }

    private void NewGame()
    {
        aiTimer.Stop();
        undoStack.Clear();
        Array.Clear(board, 0, board.Length);

        for (int r = 0; r < 3; r++)
            for (int c = 0; c < 8; c++)
                if ((r + c) % 2 == 1)
                    board[r, c] = -1;

        for (int r = 5; r < 8; r++)
            for (int c = 0; c < 8; c++)
                if ((r + c) % 2 == 1)
                    board[r, c] = 1;

        selectedRow = -1;
        selectedCol = -1;
        forcedAiRow = -1;
        forcedAiCol = -1;

        playerTurn = true;
        gameOver = false;
        pausedForSetup = false;

        capturedByPlayer = 0;
        capturedByOpponent = 0;

        setupBanner.Visibility = Visibility.Collapsed;

        gameStarted = DateTime.Now;
        currentRunStarted = DateTime.Now;
        accumulatedBeforePause = TimeSpan.Zero;

        RenderBoard();
        UpdateGameInfo();
        UpdateAccentControls();

        statusText.Text = vsCpu
            ? "Your turn - Red. Setup alerts will pause the game."
            : "Player 1 turn - Red. Setup alerts will pause the game.";
    }

    public void ShowSetupAlert(string direction, double price, string instrument)
    {
        bool shouldPause = pauseOnSetupCheck == null || pauseOnSetupCheck.IsChecked == true;
        bool shouldFront = bringToFrontCheck == null || bringToFrontCheck.IsChecked == true;
        bool shouldSound = setupSoundCheck == null || setupSoundCheck.IsChecked == true;

        pausedForSetup = shouldPause;
        if (shouldPause)
            aiTimer.Stop();

        setupBannerText.Text =
            direction + " SETUP  |  " + instrument + "  |  " + price.ToString("0.00");

        setupBanner.Background = direction == "LONG"
            ? new SolidColorBrush(Color.FromRgb(28, 115, 61))
            : new SolidColorBrush(Color.FromRgb(150, 40, 40));

        setupBanner.Visibility = Visibility.Visible;

        if (shouldFront)
        {
            if (WindowState == WindowState.Minimized)
                WindowState = WindowState.Normal;

            Activate();
        }

        if (soundEnabled && shouldSound)
        {
            try
            {
                System.Media.SystemSounds.Exclamation.Play();
            }
            catch { }
        }

        statusText.Text = shouldPause
            ? "GAME PAUSED - Trading setup detected."
            : "Trading setup detected - game remains active.";
    }

    private void ResumeAfterSetup()
    {
        pausedForSetup = false;
        setupBanner.Visibility = Visibility.Collapsed;
        UpdateGameInfo();

        if (vsCpu && !playerTurn && !gameOver)
            aiTimer.Start();

        statusText.Text = playerTurn
            ? "Game resumed - Red turn."
            : "Game resumed - Black turn.";
    }

    private void RenderBoard()
    {
        if (boardGrid == null)
            return;

        ThemeColors theme = GetThemeColors();
        boardGrid.Children.Clear();

        HashSet<string> legalTargets = new HashSet<string>();
        if (selectedRow >= 0 && selectedCol >= 0)
        {
            foreach (Move m in GetLegalMovesForPiece(selectedRow, selectedCol, true))
                legalTargets.Add(m.ToRow + "," + m.ToCol);
        }

        for (int r = 0; r < 8; r++)
        {
            for (int c = 0; c < 8; c++)
            {
                int rr = r;
                int cc = c;

                Button square = new Button
                {
                    Padding = new Thickness(0),
                    Margin = new Thickness(0),
                    BorderThickness = new Thickness(0),
                    HorizontalContentAlignment = HorizontalAlignment.Center,
                    VerticalContentAlignment = VerticalAlignment.Center,
                    Background = new SolidColorBrush(
                        (r + c) % 2 == 0 ? theme.LightSquare : theme.DarkSquare)
                };

                if (r == selectedRow && c == selectedCol)
                {
                    square.BorderBrush = new SolidColorBrush(theme.Accent);
                    square.BorderThickness = new Thickness(4);
                }
                else if (legalTargets.Contains(r + "," + c))
                {
                    square.BorderBrush = Brushes.LimeGreen;
                    square.BorderThickness = new Thickness(4);
                }

                if (board[r, c] != 0)
                    square.Content = BuildPiece(board[r, c]);

                square.Click += (s, e) => Square_Click(rr, cc);

                Grid.SetRow(square, r);
                Grid.SetColumn(square, c);
                boardGrid.Children.Add(square);
            }
        }
    }

    private Grid BuildPiece(int piece)
    {
        ThemeColors theme = GetThemeColors();
        bool isPlayer = piece > 0;
        bool isKing = Math.Abs(piece) == 2;

        Grid holder = new Grid
        {
            Width = 62,
            Height = 62,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center
        };

        System.Windows.Shapes.Ellipse outer = new System.Windows.Shapes.Ellipse
        {
            Width = 58,
            Height = 58,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            Fill = new SolidColorBrush(isPlayer ? theme.PlayerPiece : theme.OpponentPiece),
            Stroke = new SolidColorBrush(isPlayer ? theme.PlayerStroke : theme.OpponentStroke),
            StrokeThickness = 3
        };
        holder.Children.Add(outer);

        System.Windows.Shapes.Ellipse inner = new System.Windows.Shapes.Ellipse
        {
            Width = 40,
            Height = 40,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            Fill = Brushes.Transparent,
            Stroke = new SolidColorBrush(isPlayer ? theme.PlayerStroke : theme.OpponentStroke),
            StrokeThickness = 2,
            Opacity = 0.80
        };
        holder.Children.Add(inner);

        System.Windows.Shapes.Ellipse centerRing = new System.Windows.Shapes.Ellipse
        {
            Width = 25,
            Height = 25,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            Fill = Brushes.Transparent,
            Stroke = new SolidColorBrush(isPlayer ? theme.PlayerStroke : theme.OpponentStroke),
            StrokeThickness = 1,
            Opacity = 0.65
        };
        holder.Children.Add(centerRing);

        if (isKing)
        {
            TextBlock king = new TextBlock
            {
                Text = "K",
                Foreground = Brushes.Gold,
                FontSize = 22,
                FontWeight = FontWeights.Bold,
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center
            };
            holder.Children.Add(king);
        }

        return holder;
    }

    private void Square_Click(int row, int col)
    {
        if (gameOver || pausedForSetup)
            return;

        if (vsCpu && !playerTurn)
            return;

        int side = playerTurn ? 1 : -1;
        bool ownPiece = board[row, col] != 0 && Math.Sign(board[row, col]) == side;

        List<Move> sideMoves = GetAllMoves(side);
        if (sideMoves.Count == 0)
        {
            EndGame(playerTurn ? "Black wins." : "Red wins.");
            return;
        }

        bool captureRequired = sideMoves.Any(m => m.IsCapture);

        if (selectedRow < 0)
        {
            if (!ownPiece)
                return;

            List<Move> moves = GetLegalMovesForPiece(row, col, true);
            if (captureRequired)
                moves = moves.Where(m => m.IsCapture).ToList();

            if (moves.Count == 0)
                return;

            selectedRow = row;
            selectedCol = col;
            RenderBoard();
            return;
        }

        if (ownPiece)
        {
            List<Move> moves = GetLegalMovesForPiece(row, col, true);
            if (captureRequired)
                moves = moves.Where(m => m.IsCapture).ToList();

            if (moves.Count > 0)
            {
                selectedRow = row;
                selectedCol = col;
                RenderBoard();
            }
            return;
        }

        List<Move> legal = GetLegalMovesForPiece(selectedRow, selectedCol, true);
        if (captureRequired)
            legal = legal.Where(m => m.IsCapture).ToList();

        Move chosen = legal.FirstOrDefault(m => m.ToRow == row && m.ToCol == col);
        if (chosen == null)
            return;

        PushUndoSnapshot();
        ExecuteMove(chosen);

        if (chosen.IsCapture)
        {
            List<Move> more = GetCapturesForPiece(chosen.ToRow, chosen.ToCol);
            if (more.Count > 0)
            {
                selectedRow = chosen.ToRow;
                selectedCol = chosen.ToCol;
                RenderBoard();
                statusText.Text = "Continue jumping.";
                UpdateGameInfo();
                return;
            }
        }

        selectedRow = -1;
        selectedCol = -1;

        if (CheckForWinner())
            return;

        playerTurn = !playerTurn;
        RenderBoard();
        UpdateGameInfo();

        if (vsCpu && !playerTurn)
        {
            statusText.Text = "Computer thinking...";
            aiTimer.Start();
        }
        else
        {
            statusText.Text = playerTurn ? "Red turn." : "Black turn.";
        }
    }

    private void AiTimer_Tick(object sender, EventArgs e)
    {
        aiTimer.Stop();

        if (gameOver || pausedForSetup || playerTurn || !vsCpu)
            return;

        List<Move> moves = forcedAiRow >= 0
            ? GetCapturesForPiece(forcedAiRow, forcedAiCol)
            : GetAllMoves(-1);

        if (moves.Count == 0)
        {
            forcedAiRow = -1;
            forcedAiCol = -1;
            EndGame("You win.");
            return;
        }

        Move selected = ChooseAiMove(moves);
        PushUndoSnapshot();
        ExecuteMove(selected);

        if (selected.IsCapture)
        {
            List<Move> more = GetCapturesForPiece(selected.ToRow, selected.ToCol);
            if (more.Count > 0)
            {
                forcedAiRow = selected.ToRow;
                forcedAiCol = selected.ToCol;
                RenderBoard();
                UpdateGameInfo();
                aiTimer.Start();
                return;
            }
        }

        forcedAiRow = -1;
        forcedAiCol = -1;

        if (CheckForWinner())
            return;

        playerTurn = true;
        RenderBoard();
        UpdateGameInfo();
        statusText.Text = "Your turn - Red.";
    }

    private Move ChooseAiMove(List<Move> moves)
    {
        List<Move> captures = moves.Where(m => m.IsCapture).ToList();
        if (captures.Count > 0)
            moves = captures;

        List<Move> promotions = moves.Where(m =>
            board[m.FromRow, m.FromCol] == -1 && m.ToRow == 7).ToList();

        if (promotions.Count > 0)
            moves = promotions;

        return moves[rng.Next(moves.Count)];
    }

    private void ExecuteMove(Move move)
    {
        int piece = board[move.FromRow, move.FromCol];
        board[move.FromRow, move.FromCol] = 0;
        board[move.ToRow, move.ToCol] = piece;

        if (move.IsCapture)
        {
            int capturedPiece = board[move.CaptureRow, move.CaptureCol];
            board[move.CaptureRow, move.CaptureCol] = 0;

            if (piece > 0 && capturedPiece < 0)
                capturedByPlayer++;
            else if (piece < 0 && capturedPiece > 0)
                capturedByOpponent++;
        }

        if (piece == 1 && move.ToRow == 0)
            board[move.ToRow, move.ToCol] = 2;
        else if (piece == -1 && move.ToRow == 7)
            board[move.ToRow, move.ToCol] = -2;
    }

    private List<Move> GetAllMoves(int side)
    {
        List<Move> captures = new List<Move>();
        List<Move> normal = new List<Move>();

        for (int r = 0; r < 8; r++)
        {
            for (int c = 0; c < 8; c++)
            {
                if (board[r, c] == 0 || Math.Sign(board[r, c]) != side)
                    continue;

                captures.AddRange(GetCapturesForPiece(r, c));
                normal.AddRange(GetNormalMovesForPiece(r, c));
            }
        }

        return captures.Count > 0 ? captures : normal;
    }

    private List<Move> GetLegalMovesForPiece(int row, int col, bool obeyGlobalCaptureRule)
    {
        if (!Inside(row, col) || board[row, col] == 0)
            return new List<Move>();

        int side = Math.Sign(board[row, col]);
        List<Move> captures = GetCapturesForPiece(row, col);

        if (captures.Count > 0)
            return captures;

        if (obeyGlobalCaptureRule)
        {
            for (int r = 0; r < 8; r++)
            {
                for (int c = 0; c < 8; c++)
                {
                    if (board[r, c] != 0 &&
                        Math.Sign(board[r, c]) == side &&
                        GetCapturesForPiece(r, c).Count > 0)
                        return new List<Move>();
                }
            }
        }

        return GetNormalMovesForPiece(row, col);
    }

    private List<Move> GetNormalMovesForPiece(int row, int col)
    {
        List<Move> moves = new List<Move>();
        int piece = board[row, col];

        if (piece == 0)
            return moves;

        foreach (int dr in GetDirections(piece))
        {
            foreach (int dc in new int[] { -1, 1 })
            {
                int nr = row + dr;
                int nc = col + dc;

                if (Inside(nr, nc) && board[nr, nc] == 0)
                {
                    moves.Add(new Move
                    {
                        FromRow = row,
                        FromCol = col,
                        ToRow = nr,
                        ToCol = nc
                    });
                }
            }
        }

        return moves;
    }

    private List<Move> GetCapturesForPiece(int row, int col)
    {
        List<Move> moves = new List<Move>();
        int piece = board[row, col];

        if (piece == 0)
            return moves;

        int side = Math.Sign(piece);

        foreach (int dr in GetDirections(piece))
        {
            foreach (int dc in new int[] { -1, 1 })
            {
                int midR = row + dr;
                int midC = col + dc;
                int toR = row + dr * 2;
                int toC = col + dc * 2;

                if (!Inside(midR, midC) || !Inside(toR, toC))
                    continue;

                if (board[midR, midC] != 0 &&
                    Math.Sign(board[midR, midC]) == -side &&
                    board[toR, toC] == 0)
                {
                    moves.Add(new Move
                    {
                        FromRow = row,
                        FromCol = col,
                        ToRow = toR,
                        ToCol = toC,
                        CaptureRow = midR,
                        CaptureCol = midC
                    });
                }
            }
        }

        return moves;
    }

    private IEnumerable<int> GetDirections(int piece)
    {
        if (Math.Abs(piece) == 2)
            return new int[] { -1, 1 };

        return piece > 0 ? new int[] { -1 } : new int[] { 1 };
    }

    private bool CheckForWinner()
    {
        bool redExists = false;
        bool blackExists = false;

        for (int r = 0; r < 8; r++)
        {
            for (int c = 0; c < 8; c++)
            {
                if (board[r, c] > 0)
                    redExists = true;
                else if (board[r, c] < 0)
                    blackExists = true;
            }
        }

        if (!redExists || GetAllMoves(1).Count == 0)
        {
            EndGame("Black wins.");
            return true;
        }

        if (!blackExists || GetAllMoves(-1).Count == 0)
        {
            EndGame("Red wins.");
            return true;
        }

        return false;
    }

    private void EndGame(string message)
    {
        gameOver = true;
        aiTimer.Stop();
        selectedRow = -1;
        selectedCol = -1;
        forcedAiRow = -1;
        forcedAiCol = -1;

        RenderBoard();
        UpdateGameInfo();
        statusText.Text = message + "  Press NEW GAME to play again.";

        if (soundEnabled)
        {
            try { System.Media.SystemSounds.Asterisk.Play(); }
            catch { }
        }
    }

    private void PushUndoSnapshot()
    {
        int[,] copy = new int[8, 8];
        Array.Copy(board, copy, board.Length);

        undoStack.Push(new GameSnapshot
        {
            Board = copy,
            PlayerTurn = playerTurn,
            CapturedByPlayer = capturedByPlayer,
            CapturedByOpponent = capturedByOpponent
        });
    }

    private void UndoMove()
    {
        if (undoStack.Count == 0 || pausedForSetup)
            return;

        aiTimer.Stop();

        // In CPU mode, try to step back through the CPU reply and the player's move.
        int steps = vsCpu && undoStack.Count >= 2 && playerTurn ? 2 : 1;
        GameSnapshot snapshot = null;

        for (int i = 0; i < steps && undoStack.Count > 0; i++)
            snapshot = undoStack.Pop();

        if (snapshot == null)
            return;

        Array.Copy(snapshot.Board, board, board.Length);
        playerTurn = snapshot.PlayerTurn;
        capturedByPlayer = snapshot.CapturedByPlayer;
        capturedByOpponent = snapshot.CapturedByOpponent;

        selectedRow = -1;
        selectedCol = -1;
        forcedAiRow = -1;
        forcedAiCol = -1;
        gameOver = false;

        RenderBoard();
        UpdateGameInfo();
        statusText.Text = "Move undone.";
    }

    private void ShowHint()
    {
        if (gameOver || pausedForSetup)
            return;

        int side = playerTurn ? 1 : -1;

        if (vsCpu && side == -1)
            return;

        List<Move> moves = GetAllMoves(side);
        if (moves.Count == 0)
            return;

        Move hint = moves.FirstOrDefault(m => m.IsCapture) ?? moves[0];

        selectedRow = hint.FromRow;
        selectedCol = hint.FromCol;
        RenderBoard();

        statusText.Text =
            "Hint: move from " +
            SquareName(hint.FromRow, hint.FromCol) +
            " to " +
            SquareName(hint.ToRow, hint.ToCol) +
            (hint.IsCapture ? " (capture)" : "");
    }

    private void ResignGame()
    {
        if (gameOver)
            return;

        EndGame(playerTurn ? "Red resigned. Black wins." : "Black resigned. Red wins.");
    }

    private string SquareName(int row, int col)
    {
        char file = (char)('A' + col);
        int rank = 8 - row;
        return file.ToString() + rank.ToString();
    }

    private void UpdateGameInfo()
    {
        if (turnValue != null)
            turnValue.Text = playerTurn ? "Red" : "Black";

        if (capturedValue != null)
            capturedValue.Text =
                "Red " + capturedByPlayer +
                "   Black " + capturedByOpponent;
    }

    private void UiTimer_Tick(object sender, EventArgs e)
    {
        if (clockText != null)
            clockText.Text = DateTime.Now.ToString("hh:mm:ss tt");

        if (timerValue == null)
            return;

        TimeSpan elapsed = DateTime.Now - gameStarted;
        timerValue.Text = elapsed.ToString(@"hh\:mm\:ss");
    }

    private void UpdateAccentControls()
    {
        ThemeColors theme = GetThemeColors();

        if (modeButton != null)
            modeButton.BorderBrush = new SolidColorBrush(theme.Accent);

        if (themeSelector != null)
            themeSelector.BorderBrush = new SolidColorBrush(theme.Accent);
    }

    private ThemeColors GetThemeColors()
    {
        switch (currentTheme)
        {
            case "Green & Ivory":
                return new ThemeColors
                {
                    LightSquare = Color.FromRgb(239, 234, 210),
                    DarkSquare = Color.FromRgb(53, 105, 74),
                    PlayerPiece = Color.FromRgb(34, 160, 86),
                    PlayerStroke = Color.FromRgb(167, 245, 193),
                    OpponentPiece = Color.FromRgb(235, 231, 214),
                    OpponentStroke = Color.FromRgb(85, 92, 72),
                    Accent = Color.FromRgb(54, 190, 104)
                };

            case "Blue & Silver":
                return new ThemeColors
                {
                    LightSquare = Color.FromRgb(214, 221, 229),
                    DarkSquare = Color.FromRgb(58, 77, 105),
                    PlayerPiece = Color.FromRgb(40, 123, 205),
                    PlayerStroke = Color.FromRgb(155, 208, 255),
                    OpponentPiece = Color.FromRgb(195, 201, 212),
                    OpponentStroke = Color.FromRgb(72, 78, 88),
                    Accent = Color.FromRgb(69, 145, 224)
                };

            case "Purple & Gold":
                return new ThemeColors
                {
                    LightSquare = Color.FromRgb(232, 217, 187),
                    DarkSquare = Color.FromRgb(83, 51, 103),
                    PlayerPiece = Color.FromRgb(127, 61, 170),
                    PlayerStroke = Color.FromRgb(222, 179, 255),
                    OpponentPiece = Color.FromRgb(216, 169, 43),
                    OpponentStroke = Color.FromRgb(255, 228, 135),
                    Accent = Color.FromRgb(215, 161, 43)
                };

            case "Orange & Charcoal":
                return new ThemeColors
                {
                    LightSquare = Color.FromRgb(205, 198, 184),
                    DarkSquare = Color.FromRgb(58, 58, 58),
                    PlayerPiece = Color.FromRgb(228, 106, 30),
                    PlayerStroke = Color.FromRgb(255, 189, 120),
                    OpponentPiece = Color.FromRgb(32, 32, 32),
                    OpponentStroke = Color.FromRgb(175, 175, 175),
                    Accent = Color.FromRgb(242, 108, 20)
                };

            default:
                return new ThemeColors
                {
                    LightSquare = Color.FromRgb(232, 216, 181),
                    DarkSquare = Color.FromRgb(114, 55, 38),
                    PlayerPiece = Color.FromRgb(210, 35, 22),
                    PlayerStroke = Color.FromRgb(255, 145, 125),
                    OpponentPiece = Color.FromRgb(28, 28, 28),
                    OpponentStroke = Color.FromRgb(150, 150, 150),
                    Accent = Color.FromRgb(232, 76, 18)
                };
        }
    }

    private bool Inside(int row, int col)
    {
        return row >= 0 && row < 8 && col >= 0 && col < 8;
    }
}

}

#region NinjaScript generated code. Neither change nor remove.

namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private WTCheckersSetupGameV2 cacheWTCheckersSetupGameV2;
public WTCheckersSetupGameV2 WTCheckersSetupGameV2()
{
return WTCheckersSetupGameV2(Input);
}

	public WTCheckersSetupGameV2 WTCheckersSetupGameV2(ISeries<double> input)
	{
		if (cacheWTCheckersSetupGameV2 != null)
			for (int idx = 0; idx < cacheWTCheckersSetupGameV2.Length; idx++)
				if (cacheWTCheckersSetupGameV2[idx] != null &&  cacheWTCheckersSetupGameV2[idx].EqualsInput(input))
					return cacheWTCheckersSetupGameV2[idx];
		return CacheIndicator<WTCheckersSetupGameV2>(new WTCheckersSetupGameV2(), input, ref cacheWTCheckersSetupGameV2);
	}
}

}

namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.WTCheckersSetupGameV2 WTCheckersSetupGameV2()
{
return indicator.WTCheckersSetupGameV2(Input);
}

	public Indicators.WTCheckersSetupGameV2 WTCheckersSetupGameV2(ISeries<double> input )
	{
		return indicator.WTCheckersSetupGameV2(input);
	}
}

}

namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.WTCheckersSetupGameV2 WTCheckersSetupGameV2()
{
return indicator.WTCheckersSetupGameV2(Input);
}

	public Indicators.WTCheckersSetupGameV2 WTCheckersSetupGameV2(ISeries<double> input )
	{
		return indicator.WTCheckersSetupGameV2(input);
	}
}

}

#endregion

1 Like