Я пытаюсь сделать игру жизни Conway в C# с XAML. Окно позволяет пользователю указывать количество строк и столбцов моего 2D-массива ячеек с помощью ползунка. Когда моя Единая сетка - идеальный квадрат (10x10, 20x20 или даже 16x16), симуляции работают без проблем. Однако, когда пользователь пытается указать прямоугольную равномерную сетку (13x14, 15x26, 24x14), ячейки выбрасываются разностью (т. Е. В сетке 33x27, разность = 6, поэтому ячейка идет соответствующим образом вверх, но отбрасывается (слева/справа) на разницу). Я сузился, что это происходит только на оси х; клетки никогда не отбрасываются по оси y. ВОПРОС: Почему мой массив отбрасывает мою ось x? С этим что-то не так?Game of Life 2D-карты не выстраиваются в линию
Насколько я могу судить, все должно работать нормально. Я создал журнал для проверки размеров моих 2D-массивов и моей единой сетки. Я не уверен, что не так, и я смотрел и отлаживал буквально ДНИ. Я нахожусь на своем пути. Пожалуйста, помогите, я надеюсь, что есть что-то, что я просто не поймаю.
Код: unigridOfCells является единой сеткой в XAML. slideWidth/slideHeight - ползунки. Кроме того, я использую конвертер из моего ресурса, который преобразует свойство isAlive в SolidColorBrush.
private Cell[,] cells;
private Cell[,] nextGenCells;
private int codeColumn, codeRow, difference, secondDiff;
public MainWindow()
{
InitializeComponent();
unigridOfCells.Height = 500;
unigridOfCells.Width = 500;
setCellsOnGrid(10, 10);
}
//Sets all the cells on the grid, as well as setting the number of columns and rows to be reset for all arrays in the application
public void setCellsOnGrid(int column, int row)
{
unigridOfCells.Rows = row;
unigridOfCells.Columns = column;
codeColumn = column;
codeRow = row;
time = new Timer(3000);
cells = new Cell[codeColumn, codeRow];
nextGenCells = new Cell[codeColumn, codeRow];
for (int i = 0; i < codeColumn; i++)
{
for (int j = 0; j < codeRow; j++)
{
cells[i, j] = new Cell();
Rectangle block = new Rectangle();
block.Height = 10;
block.Width = 10;
block.DataContext = cells[i, j];
block.MouseLeftButtonDown += cells[i, j].ParentClicked;
//block.MouseLeftButtonDown += blockSpace;
Binding b = new Binding();
b.Source = cells[i, j];
b.Path = new PropertyPath("isAlive");
b.Converter = (BoolColorConverter)Application.Current.FindResource("cellLifeSwitch");
block.SetBinding(Rectangle.FillProperty, b);
unigridOfCells.Children.Add(block);
}
}
}
public void blockSpace(object sender, MouseButtonEventArgs e)
{
int spot = 0;
int pick = 0;
for (int i = 0; i < codeColumn; i++)
{
for (int j = 0; j < codeRow; j++)
{
spot = unigridOfCells.Children.IndexOf((Rectangle)sender);
}
}
MessageBox.Show("" + spot + " : " + pick);
}
//Updates the cells. This is where the rules are applied and the isAlive property is changed (if it is).
public void updateCells()
{
for (int n = 0; n < codeColumn; n++)
{
for (int m = 0; m < codeRow; m++)
{
nextGenCells[n, m] = new Cell();
bool living = cells[n, m].isAlive;
int count = GetLivingNeighbors(n, m);
bool result = false;
if (living && count < 2)
{
result = false;
}
if (living && (count == 2 || count == 3))
{
result = true;
}
if (living && count > 3)
{
result = false;
}
if (!living && count == 3)
{
result = true;
}
nextGenCells[n, m].isAlive = result;
}
}
setNextGenCells();
}
//Resets all the cells in a time step
public void setNextGenCells()
{
for (int f = 0; f < codeColumn; f++)
{
for (int k = 0; k < codeRow; k++)
{
cells[f, k].isAlive = nextGenCells[f, k].isAlive;
}
}
}
//Checks adjacent cells to the cell in the position that was passed in
public int GetLivingNeighbors(int x, int y)
{
int count = 0;
// Check cell on the right.
if (x != codeColumn - 1)
if (cells[x + 1, y].isAlive)
count++;
// Check cell on the bottom right.
if (x != codeColumn - 1 && y != codeRow - 1)
if (cells[x + 1, y + 1].isAlive)
count++;
// Check cell on the bottom.
if (y != codeRow - 1)
if (cells[x, y + 1].isAlive)
count++;
// Check cell on the bottom left.
if (x != 0 && y != codeRow - 1)
if (cells[x - 1, y + 1].isAlive)
count++;
// Check cell on the left.
if (x != 0)
if (cells[x - 1, y].isAlive)
count++;
// Check cell on the top left.
if (x != 0 && y != 0)
if (cells[x - 1, y - 1].isAlive)
count++;
// Check cell on the top.
if (y != 0)
if (cells[x, y - 1].isAlive)
count++;
// Check cell on the top right.
if (x != codeColumn - 1 && y != 0)
if (cells[x + 1, y - 1].isAlive)
count++;
return count;
}
//Fires when the next generation button is clicked. Simply makes the board go through the algorithm
private void nextGenerationClick(object sender, RoutedEventArgs e)
{
updateCells();
}
//Fired when the "Reset Grid" button is pressed, resets EVERYTHING with the new values from the sliders
private void resetGrid(object sender, RoutedEventArgs e)
{
MessageBox.Show("First Slide (width) value: " + slideWidth.Value + "\nSecond Slide (length) value: " + slideHeight.Value + "\nDifference: " + (codeColumn - codeRow) + "\nColumns: " + unigridOfCells.Columns + " \nRows: " + unigridOfCells.Rows + "\nChildren count: " + unigridOfCells.Children.Count + " \nLengths: "
+ "\n\tOf 1D of cells: " + cells.GetLength(0) + "\n\tOf 1D of nextGenCells: " + nextGenCells.GetLength(0) + "\n\tUniform Grid Columns: " + unigridOfCells.Columns + " \nWidths: "
+ "\n\tOf 2D of cells: " + cells.GetLength(1) + "\n\tOf 2D of nextGenCells: " + nextGenCells.GetLength(1) + "\n\tUniform Grid Rows: " + unigridOfCells.Rows);
unigridOfCells.Children.Clear();
setCellsOnGrid((int)slideWidth.Value, (int)slideHeight.Value);
}
Hi Carlos. Кстати, я недавно [задал вопрос] (http://stackoverflow.com/questions/16642461/brushes-white-slows-graphics-demo-down) о демо-версии жизни в C#/XAML/WPF. Полный код опубликован, вам интересно узнать о другом подходе. – dharmatech
Несколько снимков экрана помогут здесь много. – RBarryYoung
Попробуйте изменить значения строк/столбцов для 'uniGridOfCells':' unigridOfCells.Rows = column; 'и' unigridOfCells.Columns = row; '. Это классический случай, когда логика x/y путается (скриншот был бы хорош, как сказал RBarryYoung) - является ли это всей проблемой или нет, вы в настоящее время добавляете первый столбец в первую очередь, который заполняет первую строку (и doesn ' t вполне подходит) в Единой сетке (она заполняется сверху, затем на следующий ряд и т. д.) – VisualMelon