Click here to Skip to main content
15,886,137 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to build an application where part of it has the computer fire at my own grid by selecting a random x and y coordinate and painting the square blue or red after I click on the computers grid. I am having trouble getting it to work when I click on the computers grid the computer highlights the entire first row of the grid and does nothing else on subsequent clicks of mine. I need it to select a random row and column and only paint that square after I click.
private void shotToGridMe()
    {

        Random random;
        random = new Random();

        for (int i = 0; i < row; i++)
        {
            for (int j = 0; j < col; j++)
            {
                var x = random.Next(0, 10);
                var y = random.Next(0, 10);

                if (MyArrayPlace[x, y] == 1)
                {

                    ((Button)gridMe.Children[i]).Background = Brushes.Red;
                }
                else
                {
                    ((Button)gridMe.Children[i]).Background = Brushes.Blue;
                }
            }

        }

    }


This is the function where I click on the enemy grid and contains the shotToGridMe() function
private void ButtonEnemy_Click(object sender, RoutedEventArgs e)
       {
           for (int i = 0; i < row; i++)
           {
               for (int j = 0; j < col; j++)
               {
                   if (EnemyArrayPlace[i, j] == 1)
                   {
                       ((Button)sender).Background = Brushes.Red;
                   }
                   else
                   {
                       ((Button)sender).Background = Brushes.Blue;
                   }
               }
           }
           shotToGridMe();
       }


What I have tried:

I have tried putting X and Y in different places and the loop differently but it still only hits the entire first row. Thanks
Posted
Updated 17-Dec-22 5:32am
Comments
[no name] 17-Dec-22 6:21am    
There really is no point to your "for loops" as shown here; the "initialization" should happen somewhere else (during "startup"). Your "click" and "shot" methods would then be a lot simpler. What you're doing here is not a reflection of the final game - you don't "reinitialize" everything when you click a button; there such a thing as maintaining "state".

The following is adapted from a WPF implementation of the 2048 game. I used a UniformGrid and filled it with Buttons. The buttons were styled to appear as blank coloured tiles. A converter was used to convert the Button.Tag property value to a Fill colour so that the colour of the tile could be changed by simply changing the Tag value.

C#
public partial class MainWindow : Window
    {
        private readonly List<Button> tiles = new();
        private Random random = new();
        private int lastSelectedIndex;
        public MainWindow()
        {
            InitializeComponent();
          //  var viewModel = new GameViewModel();
          //  viewModel.TilesUpdatedEvent += TilesUpdatedEventhandler;
            AddEmptyTilesToCollection();
            lastSelectedIndex = 0;
          //  DataContext = viewModel;
          //  viewModel.StartGame();
        }

        private void AddEmptyTilesToCollection()
        {
            var style = (Style)FindResource("TileButton");

            for (int id = 0; id < 16; id++)
            {
                var tile = new Button
                {
                    Style = style,
                    Tag = 0                 
                  
                };
                tile.Click += OnTileClick;
                tiles.Add(tile);
                Board.Children.Add(tile);
            }

        }
        private void OnTileClick(object sender, RoutedEventArgs e)
        {
            int index = random.Next(tiles.Count);
            var selectedTile = tiles[index];
            tiles[lastSelectedIndex].Tag = 0;
            selectedTile.Tag = 1;
            lastSelectedIndex = index;
        }
    }

The MainWindow.xaml is simply
C#
<Window x:Class="ColouredTiles.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ColouredTiles"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <UniformGrid Margin="2" Grid.Row="0" Rows="4" Columns="4"  Name="Board" Background="White"  Width="{Binding RelativeSource={RelativeSource Self}, Path=ActualHeight}" >

        </UniformGrid>
    </Grid>
</Window>

The Buttons are styled in app.xaml
C#
<Application x:Class="ColouredTiles.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:ColouredTiles"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:IntToBrushConverter x:Key="intToBrushConverter"/>
        <Style x:Key="TileButton" TargetType="Button">
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="Margin" Value="5"/>
            <Setter Property="Background" Value="LightGray"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid >
                            <Rectangle Fill="{TemplateBinding Tag,Converter={StaticResource intToBrushConverter}}"
                                         Stroke="{TemplateBinding BorderBrush}"
                                         StrokeThickness="6" 
                                Height="100"
                                       Width="100"     
                                         />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Application.Resources>
</Application>

The int to Brush converter is defined as
C
public class IntToBrushConverter : IValueConverter
   {//always check for null as this may be called at startup with a null value
       public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
       {
           if (value == null)
           {
               return new SolidColorBrush();//colourless
           }

           int index = (int)value;
           return index > tileColours.Length - 1 ? new SolidColorBrush() : new SolidColorBrush(tileColours[index]);
       }

       public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
       {
           throw new NotImplementedException();
       }
       private readonly Color[] tileColours =
  {
           Colors.LightGray,     // 0
           Colors.Yellow,        // 1
           Colors.Red,           // 2
           Colors.Green,         // 3
           Colors.Orange,        // 4
           Colors.LightBlue,     // 5
           Colors.Magenta,       // 6
           Colors.LightPink,     // 7
           Colors.Goldenrod,     // 8
           Colors.Aquamarine,    // 9
           Colors.Blue,          // 10
            Colors.LightGreen,   // 11
           Colors.DarkRed,       // 12
           Colors.DarkBlue,      // 13
           Colors.DarkOrange,    // 14
           Colors.Black          // 15
       };


   }

There is a large choice of colours as 2048 tiles are multi coloured but I am sure you can adapt that to your needs. As it stands clicking on the grid will place a random yellow tile. I hope this is useful

 
Share this answer
 
v2
For starters, don't create a Random instance each time you need one: create one instance at class level and reuse it each time you need a random value. Since the Ransom class is initialized from the system clock when it is created, modern processors make it far too easy to get the same sequence repeated!

Then use the debugger to see exactly what is going on: Put a breakpoint on the first line in the function, and run your code through the debugger. Then look at your code, and at your data and work out what should happen manually. Then single step each line checking that what you expected to happen is exactly what did. When it isn't, that's when you have a problem, and you can back-track (or run it again and look more closely) to find out why.

Sorry, but we can't do that for you - time for you to learn a new (and very, very useful) skill: debugging!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900