C#: Shift given rows of jagged array to the top - c#

I make a tetris game where i need to clear lines. I collect the full rows and make them empty by doing:
for (var i = 0; i < playingGrid.Length; i++) //get rows
{
if (!playingGrid[i].Contains(0)) //check if all colls are filled
{
playingGrid[i] = new int[10]; //make the row empty
//Here i need to push this row to the top of the jagged array
}
}
//playingGrid:
public int[][] playingGrid = new int[20][];
for (var i = 0; i < 20; i++)
{
playingGrid[i] = new int[10];
}
My question is how can i get the row that i cleared at the top of the jagged array?

You should play with indexes to move full rows. Also, no need to use int array as the cell (column) can have only 2 states which is the perfect case for using bool:
var rowsCount = 20;
var columnsInRowCount = 10;
var playingGrid = new bool[rowsCount][];
for (var rowIndex = 0; rowIndex < playingGrid.Length; rowIndex++)
{
playingGrid[rowIndex] = new bool[columnsInRowCount];
}
var rowIndexesToMove = new List<int>(rowsCount);
var firstNonEmptyRowIndex = Array.FindIndex(playingGrid, row => row.Contains(true));
// save full row indexes (start from first non-empty one, no need to check top empty rows)
for (var rowIndex = firstNonEmptyRowIndex; rowIndex < playingGrid.Length; rowIndex++)
{
var row = playingGrid[rowIndex];
if (!row.Contains(false))
{
rowIndexesToMove.Add(rowIndex);
}
}
// move full rows to top
for (var fullRowIndex = 0; fullRowIndex < rowIndexesToMove.Count; fullRowIndex++)
{
for (var rowIndex = rowIndexesToMove[fullRowIndex]; rowIndex >= firstNonEmptyRowIndex + fullRowIndex; rowIndex--)
{
for (var c = 0; c < playingGrid[firstNonEmptyRowIndex + fullRowIndex].Length; c++)
{
playingGrid[rowIndex][c] = false;
}
if (rowIndex > 0)
{
var temp = playingGrid[rowIndex];
playingGrid[rowIndex] = playingGrid[rowIndex - 1];
playingGrid[rowIndex - 1] = temp;
}
}
}

Related

Average of of 2 coordinates

So I am making a graph of the average between to lists of coordinates.
So I have been looking all over and can't seem to find any information on how I can find the average of the 2 lists of values. When I try I get an error "the index was outside the matrix boundaries" and when I got it to work I just made a graph where the years where extremely high and the graph itself were looking insane. What i do is importing 2 parts of(data/data2) information with Json.
//
// Data
//
int tal = dataSet.dataset.value.Count;
//Add items in the listview
int[] yData = new int[tal];
int[] xData = new int[tal];
int k = 0;
foreach (var item in dataSet.dataset.dimension.Tid.category.label)
{
xData[k++] = int.Parse(item.Value.ToString());
}
for (int i = 0; i < tal; i++)
{
yData[i] = dataSet.dataset.value[i];
}
//
// Data2
//
int tal2 = dataSet2.dataset.value.Count;
int[] y2Data = new int[tal2];
int[] x2Data = new int[tal2];
int j = 0;
foreach (var item in
dataSet2.dataset.dimension.Tid.category.label)
{
x2Data[j++] = int.Parse(item.Value.ToString());
}
for (int p = 0; p < tal2; p++)
{
y2Data[p] = dataSet2.dataset.value[p];
}
This is the part
///////////////////////////////////////////////////////////
int[] ySum = new int[xData.Length];
for (int i = 0; i < xData.Length; i++)
{
ySum[i] = (yData[i] + y2Data[i]) / 2;
}
///////////////////////////////////////////////////////////
List<int> GenUd = new List<int>(yData.ToList());
textBoxGenUd.Text = GenUd.Average().ToString();
List<int> GenInd = new List<int>(y2Data.ToList());
textBoxGenInd.Text = GenInd.Average().ToString();
chartArea1.Name = "ChartArea1";
chart2.ChartAreas.Add(chartArea1);
chart2.Dock = DockStyle.Fill;
for (int i = 0; i <xData.Count(); i++)
{
series1.Points.AddXY(ySum[i], x2Data[i]);
}
MySecChart2 mc3 = new MySecChart2(series1);
mc3.ShowDialog();
mine is just an educated guess - if the exception occurs at the following:
This is the part
///////////////////////////////////////////////////////////
int[] ySum = new int[xData.Length];
for (int i = 0; i < xData.Length; i++)
{
ySum[i] = (yData[i] + y2Data[i]) / 2;
}
///////////////////////////////////////////////////////////
My diagnosis would be that yData[i] and y2Data[i] they dont have the same length and of xData.Length define into the loop definition.
Was perhaps supposed to be yData.Length in the loop definition?

Add row to specific column by header name/text

I have a column named "HeaderText_Name" and in this column, I want to add a row that has the text "Row" under that column.
I attempted to write some pseudo-code for it
databaseGridView.Rows["HeaderText_Name"].Add("Row");
If I do
databaseGridView.Rows.Add("Row");
It adds it to the first column no matter what. I also can't do something like
databaseGridView.Rows.Add("","","Row");
Then it adds blanks to the first two columns and I also don't know how which index the column is. So I would be more helpful if it was by Name or text.
Here is the actual code I have so far..
for (int i = 0; i < completeInfoMatches.Count; i++) {
databaseGridView.Rows.Add();
databaseGridView.Rows[0].Cells[e.Node.Text].Value = completeInfoMatches[i].Groups[1].ToString();
}
Now, completeInfoMatches has more than 1 match because it's regex. How can I change the 0 to make it work?
UPDATE
int currentRowIndex = 0;
databaseGridView.Columns.Add(e.Node.Text.Replace(" ", string.Empty), e.Node.Text);
for (int i = 0; i < completeInfoMatches.Count; i++) {
databaseGridView.Rows.Add();
databaseGridView.Rows[currentRowIndex].Cells[e.Node.Text.Replace(" ", string.Empty)].Value = completeInfoMatches[i].Groups[1].ToString();
currentRowIndex = currentRowIndex + 1;
}
I'm getting a lot of extra blank rows because of Row.Add
Try something like this:
foreach(int i = 0; i < completeInfoMatches.Count; i++){
var index = databaseGridView.Rows.Add();
databaseGridView.Rows[index].Cells[e.Node.Text].Value = completeInfoMatches[i].Groups[1].ToString();
}
With the help of #Forlani ...
int currentRowIndex = 0;
int actualRowIndex = databaseGridView.Rows.Count;
for (int i = 0; i < completeInfoMatches.Count; i++) {
var index = 0;
if (actualRowIndex < completeInfoMatches.Count) {
index = databaseGridView.Rows.Add();
}
databaseGridView.Rows[currentRowIndex].Cells[e.Node.Text.Replace(" ", string.Empty)].Value = completeInfoMatches[i].Groups[1].ToString();
currentRowIndex = currentRowIndex + 1;
}

Counting rows on a datagrid and adding it as a new column

I want to basically go this is row 1, row 2, 3, 4...until the last row and add that as a new column on my datagrid table, I am not trying to find the total amount of rows.
Here is my current code (I think this is terribly wrong but this is a lot of new code):
for (int i = 0; i < table.Rows.Count; i++)
{
string rowNum = table.Rows[i].ToString();
table.Columns.Add("Book num", typeof(string), rowNum);
}
The following code will add 1 new column to your table, and then populate each row in that column with the index number of that row.
If you don't want to start with 0, just change int i = 0; to int i = 1;
table.Columns.Add("Book num", typeof(string));
int i = 0;
foreach (DataRow dr in table.Rows)
{
dr["Book num"] = i;
i++;
}
Try for total rows,
int TotalRows = 0;
for (int i = 0; i < table.Rows.Count; i++)
{
if(i == 0)
{
TotalRows = 1;
}
else
{
TotalRows + = i;
}
string rowNum = table.Rows[i].ToString();
table.Columns.Add("Book num", typeof(string), rowNum);
}

How to remove duplicate row from datagridview in c#?

this is my datagrid
i tried the following code for removing the duplicate row in datagridview
public static DataTable items = new DataTable();
items.Columns.Add("Backsn");
items.Columns.Add("Oprn Name");
for (int i = 0; i < dataGridView1.Rows.Count;i++ )
{
DataRow rw = items.NewRow();
rw[0] = dataGridView1.Rows[i].Cells[2].Value.ToString();
rw[1] = dataGridView1.Rows[i].Cells[8].Value.ToString();
items.Rows.Add(rw);
}
dataGridView2.DataSource = items;
for (int i = 0; i < dataGridView2.Rows.Count; i++)
{
int k = 0;
for (int j = 0; j < dataGridView2.Rows.Count; j++)
{
if (dataGridView2.Rows[i].Cells[0].Value == dataGridView2.Rows[j].Cells[0].Value && dataGridView2.Rows[i].Cells[1].Value == dataGridView2.Rows[j].Cells[1].Value)
{
if (k != 0)
{
items.Rows.RemoveAt(j);
dataGridView2.DataSource = items;
}
k= k+1;
}
}
}
But no luck. I should get result like below.Please help me to solve.
In case, it is bounded with the DataTable, you don't need to make changes in the datagridview, in spite of, you should apply removing the duplicate rows in the dataTable itlsef. and here's you can try one way-
DataTable items = new DataTable();
items.Columns.Add("Backsn");
items.Columns.Add("Oprn Name");
for (int i = 0; i < dataGridView1.Rows.Count;i++ )
{
DataRow rw = items.NewRow();
rw[0] = dataGridView1.Rows[i].Cells[2].Value.ToString();
rw[1] = dataGridView1.Rows[i].Cells[8].Value.ToString();
if (!items.Rows.Cast<DataRow>().Any(row => row["Backsn"].Equals(rw["Backsn"]) && row["Oprn Name"].Equals(rw["Oprn Name"])))
items.Rows.Add(rw);
}
Replace if your condition with below code
if (dataGridView2.Rows[i].Cells["Backsn"].Value == dataGridView2.Rows[j].Cells["Backsn"].Value && dataGridView2.Rows[i].Cells["Opm Name"]].Value == dataGridView2.Rows[j].Cells["Opm Name"].Value)`
{
If your DataGrid is displaying data bound to any kind of DataSource, you ought to try to eliminate the duplicates at the datasource before the data is even bound.
For example, if your items is a collection of any kind of class T, you can have the class implement IEquatable<T> and redefine your DataSource as the IEnumerable<T>.Distinct() values from the collection, or convert your collections source to a HashSet<T>.
If you are bound to some sort of database query result or table, you can convert the binding to a view which eliminates duplicate rows.
int RowSpan = 2;
for (int i = grdGroup.Rows.Count - 2; i >= 0; i--)
{
GridViewRow currRow = grdGroup.Rows[i];
GridViewRow prevRow = grdGroup.Rows[i + 1];
if (currRow.Cells[0].Text == prevRow.Cells[0].Text)
{
currRow.Cells[0].RowSpan = RowSpan;
prevRow.Cells[0].Visible = false;
RowSpan += 1;
}
else
{
RowSpan = 2;
}
}
for another column in same grid
for (int i = grdGroup.Rows.Count - 2; i >= 0; i--)
{
GridViewRow currRow = grdGroup.Rows[i];
GridViewRow prevRow = grdGroup.Rows[i + 1];
if ((currRow.Cells[2].Text == prevRow.Cells[2].Text) && (currRow.Cells[0].Text == prevRow.Cells[0].Text))
{
currRow.Cells[2].RowSpan = RowSpan;
prevRow.Cells[2].Visible = false;
RowSpan += 1;
}
else
{
RowSpan = 2;
}
}

How to get DataGridView data in a 2d array?

In my application i am trying to get datagridview (5rows and 5columns)data to a 2d array,can anybody
help to get data in to array...
int countColumn = dataGridView1.ColumnCount -1;
int j=0,k=0;
string dataFromGrid = "";
foreach (DataGridViewRow i in dataGridView1.Rows)
{
if (!i.IsNewRow)
{
//dataFromGrid = r.Cells[0].Value.ToString();
for ( j = 0; j <= countColumn; j++)
{
dataFromGrid = dataFromGrid + i.Cells[j].Value.ToString();
}
}
var[k,j], Convert.ToInt32(dataFromGrid)
k=k+1;
If you fancy the foreach loop, you could do this:
var array = new object[dataGridView1.RowCount,dataGridView1.ColumnCount];
foreach (DataGridViewRow i in dataGridView1.Rows)
{
if (i.IsNewRow) continue;
foreach (DataGridViewCell j in i.Cells)
{
array[j.RowIndex, j.ColumnIndex] = j.Value;
}
}
object[,] arr2d = new object[dataGridView1.Rows.Count,dataGridView1.Columns.Count];
for (int x = 0; x < arr2d.GetLength(0); x++)
for (int i = 0; i < arr2d.GetLength(1); i++)
arr2d[x, i] = dataGridView1.Rows[x].Cells[i].Value;
This should work
//first of all create a 2D array varialble and count the rows and //column of data grid view
string[,] dataValue = new string[gridViewBillingItems.Rows.Count, gridViewBillingItems.Columns.Count];
//loop through the rows of data grid view
foreach (DataGridViewRow row in gridViewBillingItems.Rows)
{
//getting index of row
int i = row.Index;
//loop through the column of data grid view
foreach (DataGridViewColumn col in gridViewBillingItems.Columns)
{
//getting index of column
int j = col.Index;
//add all the rows and column to 2D Array
dataValue[row.Index, col.Index] = gridViewBillingItems.Rows[i].Cells[j].Value.ToString();
}
}

Categories