Displaying mutiple instances of an image in a 2d array - c#

This is what i have decided to start with a winForm & 1 button called btnCreate and I have 2 images 35px X 35px floor.bmp and wall.bmp
public partial class Form1 : Form
{
int x;
int y;
int[] Row0 = new int[10] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[] Row1 = new int[10] { 1, 1, 1, 1, 0, 0, 1, 1, 0, 1 };
int[] Row2 = new int[10] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
int[] Row3 = new int[10] { 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 };
int[] Row4 = new int[10] { 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 };
int[] Row5 = new int[10] { 1, 0, 0, 1, 0, 0, 0, 1, 0, 1 };
int[] Row6 = new int[10] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
int[] Row7 = new int[10] { 1, 1, 1, 1, 0, 0, 1, 1, 0, 1 };
int[] Row8 = new int[10] { 1, 1, 0, 0, 0, 0, 1, 1, 0, 1 };
int[] Row9 = new int[10] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[,] LevelA = new int[10,10];
private void Form1_Load(object sender, EventArgs e)
{
for (x = 0; x < 10; x++)
{
//load all arrays
LevelA[0, x] = Row0[x];
LevelA[1, x] = Row1[x];
LevelA[2, x] = Row2[x];
LevelA[3, x] = Row3[x];
LevelA[4, x] = Row4[x];
LevelA[5, x] = Row5[x];
LevelA[6, x] = Row6[x];
LevelA[7, x] = Row7[x];
LevelA[8, x] = Row8[x];
LevelA[9, x] = Row9[x];
}
}
private void btnCreate_Click(object sender, EventArgs e)
{
for (int X = 0; X < 10; X++)
{
for (int Y = 0; Y < 10; Y++)
{
//the following is the idea of what I would like to accomplish
//if (LevelA[Y,X] == 0)
//{
//Bitmap myBmp = new Bitmap(Image.FromFile(#"C:\My Documents\floor2.bmp"));
//myBmp.Top == Y * 35;
//myBmp.left == X * 35;
//}
}
}
}
}
Would the CODE above work as I intend it too >? or would the end of the for-loop only display the last tile as it would keep replacing(destroying) the previous one with a new one? In witch case I would need to have 100 myBmp's for a 10 by 10 grid?

You can get the bitmap of an image file by creating a Bitmap object.
Bitmap bmp = new Bitmap(Image.FromFile(#"D:\MyImageFile.bmp"));
You can place that or draw that anywhere as long as you get hold of a Graphics instance.
You can find asimple example here about that.

Related

My sudoku solving program always returning unsolved grid

My program uses backtracking for solving sudoku puzzles. Below is my full code of the class. In this puzzle I am expecting two results. In the solve() function there I print the grid just to verify it works, which works and all fields are correctly used. The problems begin, where I need my program to save the grid at that point into the solvedGrids list. Where I then just in the solveSudoku() function (which is run from Main()) just print every grid in the list, but it returns the unsolved grid. I don't know why it does that, because where I first print the grid it does it correctly. (print() and print2() are the same, the print2() looks better). But when I try to add it in a list all progress goes to a loss. Below will also be an example of what I get after running the program and the Program.cs file
Solver.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SudokuConsole
{
public class Solver
{
private int[][] grid;
private int[][] grid2;
private List<int[][]> solvedGrids;
public Solver()
{
grid = new int[9][];
grid[0] = new int[] { 5, 3, 0, 0, 7, 0, 0, 0, 0 };
grid[1] = new int[] { 6, 0, 0, 1, 9, 5, 0, 0, 0 };
grid[2] = new int[] { 0, 9, 8, 0, 0, 0, 0, 6, 0 };
grid[3] = new int[] { 8, 0, 0, 0, 6, 0, 0, 0, 3 };
grid[4] = new int[] { 4, 0, 0, 8, 0, 3, 0, 0, 1 };
grid[5] = new int[] { 7, 0, 0, 0, 2, 0, 0, 0, 6 };
grid[6] = new int[] { 0, 6, 0, 0, 0, 0, 2, 8, 0 };
grid[7] = new int[] { 0, 0, 0, 4, 1, 9, 0, 0, 5 };
//grid[8] = new int[] { 0, 0, 0, 0, 8, 0, 0, 7, 9 };
grid[8] = new int[] { 0, 0, 0, 0, 8, 0, 0, 0, 0 };
solvedGrids = new List<int[][]>();
}
public void print()
{
Console.Write("[");
for (int x = 0; x < grid.Length; x++)
{
Console.Write("[");
for (int y = 0; y < grid[x].Length; y++)
{
Console.Write(grid[x][y]);
if (y + 1 < grid[x].Length)
Console.Write(", ");
}
Console.Write("]");
if (x + 1 < grid.Length)
Console.Write(", ");
}
Console.Write("]\n");
}
public void print2(int[][] grid2)
{
Console.Write("[");
for (int x = 0; x < grid2.Length; x++)
{
if (x != 0)
Console.Write(" ");
Console.Write("[");
for (int y = 0; y < grid2[x].Length; y++)
{
Console.Write(grid2[x][y]);
if (y + 1 < grid2[x].Length)
Console.Write(" ");
}
Console.Write("]");
if (x + 1 < grid2.Length)
Console.Write("\n");
}
Console.Write("]\n");
}
public bool possible(int y, int x, int n)
{
for (int i = 0; i < 9; i++)
{
if (grid[y][i] == n)
return false;
}
for (int i = 0; i < 9; i++)
{
if (grid[i][x] == n)
return false;
}
double x0d = x / 3;
double y0d = y / 3;
int x0 = (Convert.ToInt32(Math.Floor(x0d))) * 3;
int y0 = (Convert.ToInt32(Math.Floor(y0d))) * 3;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (grid[y0 + i][x0 + j] == n)
return false;
}
}
return true;
}
public void solve()
{
for (int y = 0; y < 9; y++)
{
for (int x = 0; x < 9; x++)
{
if (grid[y][x] == 0)
{
for (int n = 1; n < 10; n++)
{
if (possible(y, x, n))
{
grid[y][x] = n;
solve();
grid[y][x] = 0;
}
}
return;
}
}
}
print(); //Here I print, just to see that it works.
solvedGrids.Add(grid); //Adding the solved grid to the list
}
public void solveSudoku()
{
solve();
foreach (int[][] x in solvedGrids)
{
print2(x); //Printing out the solved grid.
}
}
}
}
Program.cs
using System;
namespace SudokuConsole
{
internal class Program
{
static void Main(string[] args)
{
Solver solver = new Solver();
solver.solveSudoku();
}
}
}
And here is what I get:
[[5, 3, 4, 6, 7, 8, 1, 9, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 9, 7, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 7, 1, 9]]
[[5, 3, 4, 6, 7, 8, 9, 1, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 7, 9, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 1, 7, 9]]
[[5 3 0 0 7 0 0 0 0]
[6 0 0 1 9 5 0 0 0]
[0 9 8 0 0 0 0 6 0]
[8 0 0 0 6 0 0 0 3]
[4 0 0 8 0 3 0 0 1]
[7 0 0 0 2 0 0 0 6]
[0 6 0 0 0 0 2 8 0]
[0 0 0 4 1 9 0 0 5]
[0 0 0 0 8 0 0 0 0]]
[[5 3 0 0 7 0 0 0 0]
[6 0 0 1 9 5 0 0 0]
[0 9 8 0 0 0 0 6 0]
[8 0 0 0 6 0 0 0 3]
[4 0 0 8 0 3 0 0 1]
[7 0 0 0 2 0 0 0 6]
[0 6 0 0 0 0 2 8 0]
[0 0 0 4 1 9 0 0 5]
[0 0 0 0 8 0 0 0 0]]

Save a matrix of zero and one as a sequence of bits

I have a binary matrix 8x8 represented as an one-dimensional array
byte[] m = { 0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 0, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1 };
Is there a way how to save it in to binary file which would have total size of 8 bytes? Each 0 and 1 zero would be a 1 bit size.
You can use the following function to compress an array of 0s and 1s to an array of bytes:
IEnumerable<byte> Compress(byte[] a)
{
for (var i = 0; i < a.Length / 8f; i++)
{
var slice = a.Skip(i * 8).Take(8);
byte b = 0;
foreach (var s in slice)
{
b <<= 1;
if (s == 1)
b |= 1;
}
yield return b;
}
}
Then save to file using File.WriteAllBytes.
For example:
var result = Compress(m).ToArray();
File.WriteAllBytes(#"d:\test.bin", result);

Solve non square linear system with Math.net

I'm trying to solve a non square linear system with Math.net.
But I get an error Matrix dimensions must agree: 3x7.
Here is some example code:
using MathNet.Numerics.LinearAlgebra;
var mBuilder = Matrix<double>.Build;
var vBuilder = Vector<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
var b = vBuilder.DenseOfArray(new double[] { -3, -5, -2 });
Vector<double> x;
x = A.Solve(b);
Cleary the system has a solution (e.g. X = {0, 0, 0, 0, 3, 5, 2}).
How can I solve such a system with Math.Net?
You can not use the Matrix.Solve function with a non-square matrix because there is no inverse and no unique solutions for a rectangular matrix. Google "inverse of rectangular matrix" for explanations galore. You can use pseudoinverse however, as shown below.
var mBuilder = Matrix<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
Matrix<double> b = Matrix<double>.Build.Dense(3, 1);
b[0, 0] = -3.0;
b[1, 0] = -5.0;
b[2, 0] = -2.0;
var p = A.PseudoInverse();
var x = p * b;
// verify
var o = A * x;

C# naming array names on the fly

I am trying to create a two dimensional array of random 1 and 0. These will be used to switch on or off I/O lines on an Arduino. The number of arrays (height) to create will come from a textbox on the UI as will the number of items (width) in each array.
This means I do not know how many arrays I will have so what I want to do is have a loop in which I name each array e.g. a0 then a1 then a2 etc.
I have tried to name them but as you can see below have not been able to get it right. What do I need to do?
private int[][] build_data(int height, int width)
{
Random randNum = new Random();
int Min = 0, Max = 2;
var array_name = "a";
rch_txtbx.AppendText(height.ToString() + "\r");
rch_txtbx.AppendText(width.ToString() + "\r");
for (int j = 0; j <= height; j++) //create a0 to ax
{
array_name = "a" + j; //this creates the name I want
int[] a = new int[width]; //need to initialise each array in turn but how?
for (int i = 0; i <= width; i++) //create number of items in each array
{
a[i] = randNum.Next(Min, Max);
}
}
/* This is what I am trying to create arayys of random 0 and 1
int[] a1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] a2 = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[] a3 = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0 };
int[] a4 = { 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0 };
int[] a5 = { 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 };
int[] a6 = { 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0 };
int[] a7 = { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0 };
int[] a8 = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0 };
int[] a9 = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0 };
int[] a10 = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 };
int[] a11 = { 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0 };
int[] a12 = { 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0 };
int[] a13 = { 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0 };
int[] a14 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
*/
//get data ready to send back
int[][] arr = { a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
return arr;
}
Instead of trying to dynamically create variables and then add them into the array just at the end of each outer loop iteration set the value of that array:
int[][] array = new int[height][];
for (int i = 0; i < height; i++)
{
int[] innerArray = new int[width];
for (int j = 0; j < width; j++)
innerArray[j] = r.Next(min, max);
array[i] = innerArray;
}
You can also replace the above for loops with Linq:
// Creates an enumerable with N
var array = Enumerable.Repeat(0, height) items
// For each item create an enumerable with M items
.Select(i => Enumerable.Repeat(0, width)
// Set the value of each inner item to a
// random number
.Select(j => r.Next(min,max))
// Convert to an array
.ToArray())
.ToArray();
You can use a multidimensional array:
int[,] random2dArray = new int[width, height];
for (int j = 0; j <= random2dArray.GetLength(0); j++)
{
for (int i = 0; i <= random2dArray.GetLength(1); i++)
{
random2dArray[j, i] = randNum.Next(Min, Max);
}
}
For more info you can look at MSDN.
According to the signature
private int[][] build_data(int height, int width)
you actually want to create an array of array int[][] (aka jagged array). You can do it quite direct:
// Simplest, but not thread-safe
private static Random s_Gen = new Random();
// static: there's no need in "this"
private static int[][] build_data(int height, int width) {
int[][] result = new int[height][];
for (int i = 0; i < result.Length; ++i) {
int[] line = new int[width];
for (int j = 0; j < line.Length; ++j)
line[j] = s_Gen.Next(2);
result[i] = line;
}
return result;
}
In case you want to have a collection of named arrays, I suggest using Dictionary<string, int[]> as a returned type:
private static Dictionary<string, int[]> build_named_data(int height, int width) {
Dictionary<string, int[]> result = new Dictionary<string, int[]>();
for (int i = 1; i <= height; ++i) {
int[] line = new int[width];
for (int j = 0; j < line.Length; ++j)
line[j] = s_Gen.Next(2);
result.Add($"a{i}", line);
}
return result;
}
....
var myData = build_named_data(15, 20);
int[] array = build_named_data["a3"];

Take slice from 2D array (int[ , ]) using LINQ in C#

I am not C# expert, and total LINQ beginner, having searched a bit in SO and Google without discovering how to do the following:
If I have, say, int[10,10] array, how can I get a 2D slice from it?
For example, if the values in the said array were dependent on their position (a[2,3] = 23, a[4,8] = 48, etc.), I'd like to perform the following pseudocode:
int[3,3] a_slice = slicer_method(a, 3, 6, 2, 5) // or anything equivalent to this
> [[ 32, 33, 34],
[ 42, 43, 44],
[ 52, 53, 54]]
It doesn't have specifically to use LINQ, but I've seen LINQ used in every similar operation I've come across lately.
#JaredPar is correct, there is no intrinsic way to do slices - that said, you can craft up an extension method to do so:
public static class Ext
{
public static T[] Slice<T>(this T[] source, int fromIdx, int toIdx)
{
T[] ret = new T[toIdx - fromIdx + 1];
for(int srcIdx=fromIdx, dstIdx = 0; srcIdx <= toIdx; srcIdx++)
{
ret[dstIdx++] = source[srcIdx];
}
return ret;
}
public static T[,] Slice<T>(this T[,] source, int fromIdxRank0, int toIdxRank0, int fromIdxRank1, int toIdxRank1)
{
T[,] ret = new T[toIdxRank0 - fromIdxRank0 + 1, toIdxRank1 - fromIdxRank1 + 1];
for(int srcIdxRank0=fromIdxRank0, dstIdxRank0 = 0; srcIdxRank0 <= toIdxRank0; srcIdxRank0++, dstIdxRank0++)
{
for(int srcIdxRank1=fromIdxRank1, dstIdxRank1 = 0; srcIdxRank1 <= toIdxRank1; srcIdxRank1++, dstIdxRank1++)
{
ret[dstIdxRank0, dstIdxRank1] = source[srcIdxRank0, srcIdxRank1];
}
}
return ret;
}
}
And a test:
void Main()
{
var singleArr = new int[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
singleArr.Slice(2, 4).Dump();
var doubleArr = new int[,]
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
};
doubleArr.Slice(2, 4, 2, 4).Dump();
}
There is no way to do this on the CLR because it doesn't support the notion of array slices. They best you can do is create a wrapper type over arrays that simulates slices
You can try something like this:
public T[,] Slice<T>(T[,] a, int x1, int y1, int x2, int y2)
{
var result = new T[x2 - x1, y2 - y1];
for (var i = x1; i < x2; i++)
{
for (var j = y1; j < y2; j++)
{
result[i - x1, j - y1] = a[i,j];
}
}
return result;
}
sample
public class MyArraySlice<T> where T:struct {
public MyArraySlice(T[,] array, int xMin, int xMax, int yMin, int yMax) {
Array = array;
XMin = xMin; XMax = xMax;
YMin = yMin; YMax = yMax;
}
public T this[int i, int j] { get {
if (XMin <= i && i < XMax && YMin <= j && j < YMax)
return Array[i+XMin, j+YMin];
throw new ArgumentOutOfRangeException();
}
}
T[,] Array;
int XMin;
int XMax;
int YMin;
int YMax;
}

Categories

Resources