Linear algorithm to fill a contour - c

I am trying to make an algorithm that will fill a contour in linear complexity. I know such an algorithm exists. I've read somewhere that it has to do with the number of crossings, but there is a special case that I haven't had great luck in solving yet.
So far I have tried using the following algorithm. Note that I can't access previous elements (to the left) because they will/may be overwritten:
for (int y = blob->miny; y < blob->maxy; ++y)
{
int NumberOfBorderCrossings = 0;
unsigned int NextElem = 0;
unsigned int NextNextElem = 0;
for (int x = blob->minx-1; x < blob->maxx-1; ++x)
{
NextElem = CV_IMAGE_ELEM(labelimg,unsigned int,y,x+1);
NextNextElem = CV_IMAGE_ELEM(labelimg,unsigned int,y,x+2);
if (CV_IMAGE_ELEM(labelimg,unsigned int,y,x) != label)
{
if (NextElem == label && NextNextElem != label)
++NumberOfBorderCrossings;
else
if (NumberOfBorderCrossings%2)
CV_IMAGE_ELEM(labelimg,unsigned int,y,x) = label;
}
}
}
The result I get is the following. The input is to the right (all non-black pixels must be copied), and the erroneous output is to the left. Note again that I only have the contour of the image to the right (not rendered).

It appears that you're looking for a general Polygon filling algorithm. Your line crossing counting algorithm will break where it hits single points and horizontal and vertical lines. Have a look at Quickfill for a possible alternative.

Related

Graphic buffer - horizontal and vertical filling, performace

I wonder if it is possible to solve a certain problem.
In short: get optimal performance by filling the buffer not only line by line but also column by column.
Description below:
A graphic buffer is given (i.e. intended to hold a bitmap)
#define WIDTH 320
#define HEIGHT 256
typedef struct
{
unsigned char r,g,b,a;
}sRGBA;
sRGBA* bufor_1;
main()
{
bufor_1 = (sRGBA*)malloc(WIDTH*HEIGHT*sizeof(sRGBA));
}
There is no problem with filling it horizontally line by line, because it is a 'cache friendly' case, which is the best one, e.g. floor and ceiling rycasting:
main()
{
bufor_1 = (sRGB*)malloc(WIDTH*HEIGHT*sizeof(sRGB));
for (int y = 0; y < HEIGHT; ++y)
{
for (int x = 0; x < WIDTH; ++x)
{
bufor_1[x+y*WIDTH].r = 100;
}
}
}
The difference in performance appears when we want to supplement such a buffer vertically, i.e. column by column, e.g. wall regeneration, which is done in this way, i.e.
main()
{
bufor_1 = (sRGB*)malloc(WIDTH*HEIGHT*sizeof(sRGB));
for (int x = 0; x < WIDTH; ++x)
{
for (int y = 0; y < HEIGHT; ++y)
{
bufor_1[x+y*WIDTH].r = 100;
}
}
}
The question that arises is whether it is possible to somehow combine efficient line-by-line and column-by-column completion.
From a few tests that I have performed, it turned out that if the buffer is presented as two-dimensional, i.e.
column-by-column filling is even faster than line-by-line in a one-dimensional one - but then it is the other way around, i.e. filling such a two-dimensional buffer line by line will be inefficient.
Solutions I was thinking about:
rotate the buffer 90 degrees, unfortunately it takes too much time, at least with the algorithms that I checked,
unless there is some mega-fast N (1) way
some sort of buffer remapping so that some table contains pointers to the next pixels in the column, but it probably won't be 'cache friendly' or even worse - I haven't checked anyway

Most memory efficient algorithm for finding a path on a grid

What is the most memory efficient algorithm that can be used to find a path from one grid square to another? The grid may have obstacles that cannot be crossed. Being the shortest path is not necessary, but certainly, is a bonus. The algorithm is going to be coded in C (C++ is available, but I am avoiding it to reduce memory usage) and run on an ATmega328 chip with only 2048 bytes of SRAM. CPU efficiency is not of paramount importance.
EDIT: The grid is 16 by 32 squares, each represented by one bit. The total memory usage is therefore 64 bytes. The grid is stored as a 2D array of unsigned chars and all of the 2048 bytes are available. The output would be an array of integers referencing the squares that should be taken.
If there is an obstacle in a square, the array of squares would have a 1 instead of a zero. These squares should be treated like walls.
This is an unfinished idea for an algorithm which may fit into 2048 bytes, that I came up with while trying to find a non-recursive flood-fill variant.
The first step is to create an additional 32×16 array of 8-bit values; this uses 512 bytes. You then iterate over the grid horizontally, and number the runs of adjacent reachable squares as in the image below:
For a 32×16 grid, the maximum number of runs is 256 (e.g. with a checkerboard pattern, or vertical stripes), so this numbering fits into 8-bit values.
The second step is to iterate over the grid vertically, and group the runs that are adjacent:
After checking vertical line 1:
{0A,11,1A}
{2E}
{44,50,5C}
{72}
{87,8F,98}
After checking vertical line 2:
{0A,11,1A,00,24}
{2E}
{44,50,5C,37,69}
{72}
{87,8F,98,7C}
After checking vertical line 2:
{0A,11,1A,00,24,12,2F}
{2E}
{44,50,5C,37,69,51,73}
{72}
{87,8F,98,7C,90}
... and so on, merging groups if they are linked by adjacent runs. If, at the end, the number of the start and target squares are in the same group, that means there is a path.
Now, if you store the groups as simple lists, like in the example above, this doesn't really give you a path; it just tells you which squares are reachable from the start and target squares, but a path may not need to cross all these squares.
If you stored the groups in a data structure where you know which runs are connected to each other, then it becomes a "shortest path through graph" problem in a smaller space. I'm not sure which data structure would best fit into the remaining 1536 bytes.
(Anyone is welcome to try and take this idea further.)
This method could be used to simplify the grid before running another algorithm. Firstly, the grouping of the runs identifies unreachable parts of the grid; these could be marked as walls in the original grid or a copy of it. Secondly, it identifies dead ends; runs which are only connected to one other run (and which don't contain the start or target square) are unnecessary detours and can also be marked as such. (This should be repeated: removing a singly-connected run may reveal another run to be singly-connected.)
Grid simplified by removing unreachable and singly-linked runs
Running the algorithm again, but with vertical runs and horizontal grouping, could remove additional dead ends.
The JavaScript snippet below is a simple code example for the first part of the algorithm: using the example grid in the images, it numbers the runs, assigns them to groups, merges groups when necessary, and then checks whether the start and target square are in the same group, i.e. whether there is a path.
The grouping method may not be the most efficient, especially when merging groups, but it uses a fixed-size array of maximum 256 bytes (number of runs × 8-bit values), which is probably best in a limited-memory situation.
function gridPath(grid, x1, y1, x2, y2) {
var runs = [], rcount = 0;
for (var i = 0; i < 16; i++) { // number runs
var start = true; runs[i] = [];
for (var j = 0; j < 32; ++j) {
if (grid[i][j] == 0) { // found empty cell
if (start) ++rcount; // start of new run
runs[i][j] = rcount - 1;
start = false;
}
else start = true; // found blocked cell
}
}
var groups = [], gcount = 0;
for (var i = 0; i < rcount; i++) groups[i] = 0xFF;
for (var j = 0; j < 32; ++j) { // assign runs to groups
var g = [];
for (var i = 0; i < 16; ++i) {
if (grid[i][j] == 0) g.push(runs[i][j]);
if ((grid[i][j] == 1 || i == 15) && g.length > 0) {
insertGroup(g);
g = [];
}
}
}
return groups[runs[y1][x1]] == groups[runs[y2][x2]];
function insertGroup(g) {
var matches = [];
for (var i = 0; i < g.length; i++) { // check if runs are already in group
if (groups[g[i]] != 0xFF && matches.indexOf(groups[g[i]]) < 0) {
matches.push(groups[g[i]]);
}
}
if (matches.length == 0) matches.push(gcount++); // start new group
for (var i = 0; i < g.length; i++) { // add runs to group
groups[g[i]] = matches[0];
}
if (matches.length > 1) { // merge groups
for (var i = 0; i < rcount; i++) {
if (matches.indexOf(groups[i]) > 0) groups[i] = matches[0];
}
}
}
}
var grid = [[1,0,1,0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,0,1,0,0,0],
[0,0,0,1,0,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,0,0,0,0,1,0,0,1,0],
[0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0],
[0,0,1,0,1,0,1,0,1,0,0,1,0,0,1,1,1,1,1,0,0,1,0,0,0,1,1,0,1,0,0,1],
[1,0,0,1,0,0,0,1,0,1,1,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0],
[0,1,0,0,0,1,0,0,0,0,1,0,1,0,0,1,1,1,0,0,1,0,1,1,0,0,0,0,0,1,0,1],
[1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,1,0,1,0,0,1,1,1,1,0,1,0],
[0,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0,0,0],
[0,1,0,0,0,1,0,0,0,1,1,0,1,0,0,1,0,0,1,0,1,0,1,0,1,0,1,0,0,0,1,0],
[0,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,1,0,1,0,0,1,0,1,0,0],
[1,0,0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,0,0,1,0,0,1,0,0,0,1,0,1,0,0,1],
[0,1,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,1,0],
[1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,0,0,0,1,0,1,0,1,0,0,1],
[0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0],
[0,1,0,0,0,1,0,0,0,1,0,0,1,1,1,1,1,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0],
[0,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,0,0]];
document.write(gridPath(grid, 0, 15, 15, 7));
If you only want to find the target, but do not care about remembering the path that was taken, then random search is pretty much optimal memory wise. It does not need to remember anything about previous states, so the memory use is constant. (Time complexity on the other hand is unbounded, which is not great, but isn't excluded by your requirements)
If you do need to remember the taken path, then you cannot go below linear space complexity with an algorithm that is complete - i.e always finds a path if it exists. Both breadth and depth first searches have linear space complexity, so they would be asymptotically in the same class as the optimal complete algorithm.
Since the memory is very limited, you might prefer to use a memory bounded algorithm, that gives you constant upper bound for memory use, but is not guaranteed to find a path that might exist. I recommend Simplified Memory Bounded A*.
I looked into using Dijkstra (as suggested by Weather Vane), which would require that for each grid cell the distance to the starting point and the direction from the previous cell is stored.
Unfortunately, it is possible for paths on a 32x16 grid to have a distance greater than 255; the longest path I found has distance 319 (see image below, left). This means that the distances won't fit in 8-bits, and the distance matrix has a size of 1024 bytes.
Left: longest path (distance=319). Right: largest number of equidistant cells (72 cells at distance 16)
However, in a square grid where all distances equal 1, you can simplify Dijkstra to a breadth-first search which doesn't use a distance matrix; if you use a fifo queue, the cells are visited in order of distance to the starting cell, so you cannot find a shorter path to an already visited cell.
The fifo queue will contain every cell at a certain distance, then gradually transition to distance + 1, and so on. The maximum size of the queue depends on how many equidistant cells there can be; the maximum I found is 72 (see image above, right) and during the transition from the previous distance this requires a queue that can hold the coordinates of 76 cells, or 152 bytes.
The path which is returned by the algorithm is an array holding the coordinates of a maximum of 320 cells, so it has a maximum size of 640 bytes. Before constructing this array, the queue can be discarded, so only the direction grid and the path are in memory at the same time.
Below is a code example of the simplified algorithm with only a direction matrix and a fifo queue; it can probably be improved on many points, but it demonstrates the idea. The findPath() function uses a minimum of 664 up to a maximum of 1152 bytes of allocated memory (depending on path length) plus around 20 bytes for additional variables.
This could be further reduced, e.g. by storing the direction matrix as 4-bit nibbles, reducing its size from 512 to 256 bytes (but requiring more calculations), or by returning the path as a sequence of up/right/down/left directions instead of cell coordinates, which would require only 2 bits per step, reducing its maximum size from 640 to 80 bytes.
#include <stdlib.h> // gcc -std=c99
short int findPath(char grid[][32], char x1, char y1, char x2, char y2, char **path) {
char (*dir)[16][32] = calloc(512, 1); // allocate direction matrix: 512 bytes (zeros)
(*dir)[y2][x2] = 5; // mark starting cell as visited (search backwards)
char *queue = malloc(152); // allocate fifo queue: 152 bytes
queue[0] = x2; queue[1] = y2; // put starting cell in queue (search backwards)
unsigned char qRead = 0, qWrite = 2; // queue pointers
char qCurSize = 1, qNextSize = 0; // queue size per distance
short int distance = 0; // distance to current cell
char dx[4] = {0, 1, 0, -1}; // up, right, down, left
while (qRead != qWrite && !(*dir)[y1][x1]) { // until queue empty (fail) or target reached
char x = queue[qRead++], y = queue[qRead++]; // take oldest cell from queue
qRead %= 152; // wrap-around queue pointer
for (char i = 0; i < 4; i++) { // check 4 neighbouring cells
char nx = x + dx[i], ny = y + dx[3 - i]; // coordinates of neighbouring cell
if (nx >= 0 && nx < 32 && ny >= 0 && ny < 16 // coordinates not off-grid
&& !grid[ny][nx] && !(*dir)[ny][nx]) { // traversable unvisited cell
(*dir)[ny][nx] = i + 1; // store direction 1-4
queue[qWrite++] = nx; queue[qWrite++] = ny; // put cell in queue
qWrite %= 152; // wrap-around queue pointer
++qNextSize; // increment queue size for next distance
}
}
if (!--qCurSize || (*dir)[y1][x1]) { // current distance done or target reached
qCurSize = qNextSize; // switch to distance + 1
qNextSize = 0;
++distance;
}
}
free(queue); // free up queue memory for path
if (!(*dir)[y1][x1]) distance = -1; // no path found
else { // path found
*path = malloc(distance * 2 + 2); // allocate path array: 2 bytes per step
(*path)[0] = x1; (*path)[1] = y1; // starting position (forward)
for (short int i = 1; i <= distance; i++) { // retrace steps
char d = (*dir)[y1][x1] - 1; // direction of previous step 0-3
x1 -= dx[d]; y1 -= dx[3 - d]; // go back to previous position
(*path)[i * 2] = x1; (*path)[i * 2 + 1] = y1; // add cell to path
}
}
free(*dir); // discard direction matrix
return distance + 1; // return number of cells in path
}
int main() {
char grid[][32] = // max queue size: 76
{{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}};
char x1 = 31, y1 = 0, x2 = 16, y2 = 7, *path = NULL;
short int steps = findPath(grid, x1, y1, x2, y2, &path);
// do stuff
free(path); // discard path array
return 0;
}

Making edge on Ice Sliding puzzle path finding

[My apology for the title, I just specified the problem I encountered on this puzzle.
I'm making a path finding method with the least distance travelled, depending on the number of asterisks encountered.
The rules of the game is simple, traversing from A to B, but I can only move in a straight line and cannot stop moving in that direction until you hit an asterisk (or the B), as if they were sliding across every zero.
Example, the photo shows the shortest path from A to B with 23 as the total distance travelled.
]1
The first idea that appeared on my mind is making an adjacency matrix, initially, which I have my code here:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
int main()
{
FILE *hehehe = fopen("input.txt","r");
//==========================ADJACENCY MATRIX INITIALIZATION=======================================//
int row, column, i, j;
fscanf(hehehe,"%d",&row);
fscanf(hehehe,"%d",&column);
char c;
c = fgetc(hehehe);
int matrix[row][column];
c = fgetc(hehehe);
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
if (c == '*'){
matrix[i][j] = 1;
c = fgetc(hehehe);
}
else if (c == 'A')
{
matrix[i][j] = 2;
c = fgetc(hehehe);
}
else if (c == 'B')
{
matrix[i][j] = 3;
c = fgetc(hehehe);
}
else{
matrix[i][j] = 0;
c = fgetc(hehehe);
}
if (c == '\n'){c = fgetc(hehehe);}
}
}
for (i = 0; i < row; i++)
{
for (j = 0; j < column; j++)
{
//if (matrix[i][j] == 1) printf("*");
//else printf(" ");
printf("%d ",matrix[i][j]);
}
printf("\n");
}
fclose(hehehe);
}
Any idea or suggestion for continuing for making of edge in every straight line in the photo is high appreciated. Thank you for any help in advance.
In this case, I think a matrix is overdoing it. Because you cannot make a move while sliding, you only need a directed graph.
There are a few things to keep in mind while making your algorithm:
Stopping points are the goal, or any space adjacent to a wall/asterisk.
A vertex should store two values; direction, and location.
For each asterisk or obstacle, add adjacent spaces to the list of vertices (if they don't exist in your graph yet). They only require one direction.
For each B, add a vertex with all possible directions. (Or one vertex for each direction, depending on whether that makes it easier).
For each vertex, find the closest vertex in the direction stored. Draw an edge between both vertices (if it does not already exist).
Run an appropriate search algorithm. If distance matters, use Dijkstra's. If it doesn't, use Breadth-first. If there are special scoring rules, consider A*.
Because your search space doesn't seem so large, I haven't fully optimized the algorithm. This is why I mention checking that vertices and edges aren't already added. Optimizing these is possible, and I can help with that if you need, but if-statements aren't costly enough to warrant premature optimization. Because your search space is easy to simplify, Breadth-first and Dijkstra's algorithm are absolutely perfect; they find the shortest path and their performance cost is nowhere near as high as putting them on a 2D grid.
If you're not sure of how to make your data structures, here's the way I'd approach it.
1.
Graph Structures
Direction // x and y tuple/variable, integer, or string
Point // x and y tuple/variable. Note that you can use this as direction too
Vertex
- Point
- Map < Direction, Edge > // each direction is linked to another vertex
// maps in C can be made with two arrays
// a vertex for each direction may be easier
Edge
- Vertex // you can store both vertices, but you only need to store the one being moved to.
// without OOP, reuse a simple struct before making it complex
Graph
- Vertices // array of vertex
// each vertex stores its edges; the graph doesn't need to
2.
Pathfinder Structures
Node
- Parent // a link to the previous node
// trace the links back to construct a path
- Depth // last node's depth + 1
- Vertex // the vertex hit by the pathfinder
Path
- Nodes // while parent is not null
// add a node to this list
// then read it backward

Filling in random positions in a huge 2D array

Is a there a neat algorithm that I can use to fill in random positions in a huge 2D n x n array with m number of integers without filling in an occupied position? Where , and
Kind of like this pseudo code:
int n;
int m;
void init(int new_n, int new_m) {
n = new_n;
m = new_m;
}
void create_grid() {
int grid[n][n];
int x, y;
for(x = 1; x <= n; x ++) {
for(y = 1; y <= n; y ++) {
grid[x][y] = 0;
}
}
populate_grid(grid);
}
void populate_grid(int grid[][]) {
int i = 1;
int x, y;
while(i <= m) {
x = get_pos();
y = get_pos();
if(grid[x][y] == 0) {
grid[x][y] = i;
i ++;
}
}
}
int get_pos() {
return random() % n + 1;
}
... but more efficient for bigger n's and m's. Specially if m is bigger and more positions are being occupied, it would take longer to generate a random position that isn't occupied.
Unless the filling factor really gets large, you shouldn't worry about hitting occupied positions.
Assuming for instance that half of the cells are already filled, you have 50% of chances to first hit a filled cell; and 25% to hit two filled ones in a row; 12.5% of hitting three... On average, it takes... two attempts to find an empty place ! (More generally, if there is only a fraction 1/M of free cells, the average number of attempts raises to M.)
If you absolutely want to avoid having to test the cells, you can work by initializing an array with the indexes of the free cells. Then instead of choosing a random cell, you choose a random entry in the array, between 1 and L (the lenght of the list, initially N²).
After having chosen an entry, you set the corresponding cell, you move the last element in the list to the random position, and set L= L-1. This way, the list of free positions is kept up-to-date.
Note the this process is probably less efficient than blind attempts.
To generate pseudo-random positions without repeats, you can do something like this:
for (int y=0; y<n; ++y) {
for(int x=0; x<n; ++x) {
int u=x,v=y;
u = (u+hash(v))%n;
v = (v+hash(u))%n;
u = (u+hash(v))%n;
output(u,v);
}
}
for this to work properly, hash(x) needs to be a good pseudo-random hash function that produces positive numbers that won't overflow when you add to a number between 0 and n.
This is a version of the Feistel structure (https://en.wikipedia.org/wiki/Feistel_cipher), which is commonly used to make cryptographic ciphers like DES.
The trick is that each step like u = (u+hash(v))%n; is invertible -- you can get your original u back by doing u = (u-hash(v))%n (I mean you could if the % operator worked with negative numbers the way everyone wishes it did)
Since you can invert the operations to get the original x,y back from each u,v output, each distinct x,y MUST produce a distinct u,v.

How to shift 2d array elements down in C

I am trying to shift the contents of a 2d array down when implementing Tetris in C. This is to move the blocks down. The code works but its not moving elements once only, See the image for the problem(The number in the top left corner is the random number that determines the block type). Any help appreciated.
Below is the array shifting code:
//Declare size of board
int board [22][10] = {};
//Shift down
for(i=2;i<20;i++)
{
for(z=1;z<10;z++)
{
board[i+1][z] = board[i][z];
}
}
http://i61.tinypic.com/xlb58g.jpg
Whenever you shift the contents of an array, you must work in the opposite direction then the shifting. In your case, you need to invert the direction of your outer loop:
int board [22][10] = {};
for(i = 20; i-- > 2; ) {
for(z=1; z<9; z++) {
board[i+1][z] = board[i][z];
}
}
This allows the row of unused values to rise up in the array like a bubble.
Edit:
The code above was written to match the apparent intended behavior of the code posted in the question. If the entire array is to be moved, use this code:
for(i = sizeof(board)/sizeof(*board) - 1; i--; ) {
for(z = 0; z < sizeof(*board)/sizeof(**board); z++) {
board[i+1][z] = board[i][z];
}
}

Resources