Pattern Flood Fill Algorithm - c

I have implemented a flood fill algorithm that is working correctly for solid color fills. Now I´m working on a pattern fill and decided to add a flag to see how to fill the area ( with a color or with a pattern). However when using the the algorithm with pattern fill gets stuck while painting the area.
This is my original code that works with solid colors:
void floodFillStack(int x, int y, byte newColor, byte oldColor) {
int y1;
if (oldColor == newColor) return;
if (get_pixel(x, y) != oldColor) return;
//draw current scanline from start position to the top
y1 = y;
while (y1 < h && get_pixel(x, y1) == oldColor) {
plot_pixel(x, y1, newColor);
y1++;
}
//draw current scanline from start position to the bottom
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == oldColor) {
plot_pixel(x, y1, newColor);
y1--;
}
//test for new scanlines to the left
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor);
}
y1--;
}
//test for new scanlines to the right
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x < w - 1 && get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 &&get_pixel(x, y1) == newColor) {
if (x < w - 1 && get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor);
}
y1--;
}
}
And here is with the pattern modification (it still works with solid colors).
int pattern1[6][6] = { {0,1,0,1,0,1},
{1,0,1,0,1,0},
{0,1,0,1,0,1},
{1,0,1,0,1,0},
{0,1,0,1,0,1},
{1,0,1,0,1,0} };
int pattern2[6][6] = { {0,0,1,1,0,0},
{0,1,0,0,1,0},
{1,0,0,0,0,1},
{1,0,0,0,0,1},
{0,1,0,0,1,0},
{0,0,1,1,0,0} };
void floodFillStack(int x, int y, byte newColor, byte oldColor, int pattern_fill) {
int y1;
if (oldColor == newColor) return;
if (get_pixel(x, y) != oldColor) return;
//draw current scanline from start position to the top
y1 = y;
while (y1 < h && get_pixel(x, y1) == oldColor) {
if (pattern_fill == 0) {
if (fill_pattern == 1) {
if (pattern1[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
} else {
if (pattern2[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
}
} else {
plot_pixel(x, y1, newColor);
}
y1++;
}
//draw current scanline from start position to the bottom
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == oldColor) {
if (pattern_fill == 0) {
if (fill_pattern == 1) {
if (pattern1[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
} else {
if (pattern2[x%6][y1%6] == 1) {
plot_pixel(x, y1, newColor);
}
}
} else {
plot_pixel(x, y1, newColor);
}
y1--;
}
//test for new scanlines to the left
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor, pattern_fill);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == newColor) {
if (x > 0 && get_pixel(x - 1, y1) == oldColor) {
floodFillStack(x - 1, y1, newColor, oldColor, pattern_fill);
}
y1--;
}
//test for new scanlines to the right
y1 = y;
while (y1 < h && get_pixel(x, y1) == newColor) {
if (x < w - 1 &&get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor, pattern_fill);
}
y1++;
}
y1 = y - 1;
while (y1 >= 0 && get_pixel(x, y1) == newColor) {
if (x < w - 1 && get_pixel(x + 1, y1) == oldColor) {
floodFillStack(x + 1, y1, newColor, oldColor, pattern_fill);
}
y1--;
}
}
Can anyone help me see the problem?
EDIT:
Thanks to WeatherVane for the suggestion. The algorithm is no longer stuck, but it does not cover the entire area. Here´s a picture:

Your floodfill is likely to misfire if you ignore the 0 values in your pattern masks. Instead of that, always fill with one of two colours (both different from the background).
You will also have to change some of your conditional tests. Instead of
(... == newColor)
you could use
(... != oldColor)
or
(... == newColor1 || ... == newColor2)

When you fill with a solid color, every pixel that starts at oldColor gets changed to newColor. This means that a test of that pixel later in the process won't match against it again.
When you try to fill with a pattern, some of those pixels are going to remain as oldColor. You get stuck in an infinite loop, retesting those same pixels over and over.

Related

How to make Bresenham algorithm working backward?

I got an exersise where I would like to draw a line with Bressenham algorithm.
The thing is that it's working perfectly for lines who goes down and on the right, but when the line goes up or backward, it doesn't work anymore ...
Does anybody can help me on that ?
void draw_line(t_data img, int xStart, int yStart, int xEnd, int yEnd)
{
int dx;
int dy;
int pk;
int x;
int y;
dx = xEnd - xStart;
dy = yEnd - yStart;
x = xStart;
y = yStart;
while(x <= xEnd)
{
if(pk >= 0)
{
printf("in if ");
my_mlx_pixel_put(&img, x, y, 0x00FF0000);
y = y + 1;
pk = pk + 2 * dy - 2 * dx;
}
else
{
my_mlx_pixel_put(&img, x, y, 0x00FF0000);
pk = pk + 2 * dy;
}
x = x + 1;
count ++;
}
}
Its working for this
draw_line(img, 300, 300, 400, 360);
But not for this
draw_line(img, 300, 300, 200, 260);
Thanks for your help !!
You are working in the first octant. If you want to draw lines in all direction you have to check the 8 octant.
here is my implentation of bresenham for the 8 octant:
void bresenham(int x1, int y1, int x2, int y2) {
int dx = x2 - x1;
int dy = y2 - y1;
int error;
/** first quarter */
if(dx >= 0 && dy >= 0) {
/** 1st octant */
if (dx >= dy) {
error = -dx;
int y = y1;
for(int x = x1; x < x2; x++) {
draw_pixel(x, y);
error = error + 2 * dy;
if (error >= 0) {
y++;
error = error - 2 * dx;
}
}
}
/** 2nd octant */
else {
error = -dy;
int x = x1;
for(int y = y1; y < y2; y++) {
draw_pixel(x, y);
error = error + 2 * dx;
if (error >= 0) {
x++;
error = error - 2 * dy ;
}
}
}
}
/** second quarter */
else if (dx <= 0 && dy >= 0) {
/** 4th octant */
if(dx < -dy) {
error = dx;
int y = y1;
for(int x = x1; x > x2; x--) {
draw_pixel(x, y);
error = error + 2 * dy;
if (error >= 0) {
y++;
error = error + 2 * dx;
}
}
}
/** 3rd octant */
else {
error = -dy;
int x = x1;
for(int y = y1; y < y2; y++) {
draw_pixel(x, y);
error = error - 2 * dx;
if (error >= 0) {
x--;
error = error - 2 * dy;
}
}
}
}
/** 3rd quarter */
else if (dx <= 0 && dy <= 0) {
/** 5th octant */
if(dx <= dy) {
error = 2 * dx;
int y = y1;
for(int x = x1; x > x2; x--) {
draw_pixel(x, y);
error = error - 2 * dy;
if (error >= 0) {
y--;
error = error + 2 * dx;
}
}
}
/** 6th octant */
else {
error = 2 * dy;
int x = x1;
for(int y = y1; y > y2; y--) {
draw_pixel(x, y);
error = error - 2 * dx;
if (error >= 0) {
x--;
error = error + 2 * dy ;
}
}
}
}
/* 4th quarter */
else if(dx >= 0 && dy <= 0) {
/** 7th octant */
if(dx < -dy) {
error = 2 * dy;
int x = x1;
for(int y = y1; y > y2; y--) {
draw_pixel(x, y);
error = error + 2 * dx;
if (error >= 0) {
x++;
error = error + 2 * dy ;
}
}
}
/** 8th octant */
else {
error = -dx;
int y = y1;
for(int x = x1; x < x2; x++) {
draw_pixel(x, y);
error = error - 2 * dy;
if (error >= 0) {
y--;
error = error - 2 * dx;
}
}
}
}
}

Why does my fruit respawn outside of the boundaries in snake game?

I'm trying to make a snake game in which if the snake eats the first fruit and in 2 seconds eats the second fruit then it's score multiplied by 2. If the snake eats the second fruit in 1 second then the score is multiplied by 3. If the snake eats the second fruit in 3 seconds then the score is increased just by 1 and so on ... But after the snake eats about 5-6 fruits the 7th fruit respawns outside of the boundaries. This the "drawing" function
void make_stage() {
score = 0;
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
for (int i = 1; i <= 17; i++) {
gotoxy(i, 1);
printf("#");
gotoxy(1, i);
printf("#");
gotoxy(17, i);
printf("#");
gotoxy(i, 17);
printf("#");
}
srand(time(NULL));
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(fruitx, fruity);
printf("#");
}
And this is the logic function:
void snake_move() {
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
while (1) {
srand(time(NULL));
if (x == fruitx && y == fruity) {
fruitx = rand() % 17;
fruity = rand() % 17;
score += 1;
gotoxy(fruitx, fruity);
printf("#");
}
input = _getch();
if ((dir == 'w' && input != 's') || (dir == 'a' && input != 'd') || (dir == 's' && input != 'w') || (dir == 'd' && input != 'a')) {
if (input == 'w') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y - 1;
if (y == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'w';
}
if (input == 'a') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x - 1;
if (x == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'a';
}
if (input == 's') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y + 1;
if (y == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 's';
}
if (input == 'd') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x + 1;
if (x == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'd';
}
}
if (input == 'p') {
gameover();
break;
}
}
}
and this is the entire source code just in case!
#include<stdio.h>
#include<windows.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<process.h>
int height = 17, width = 17;
typedef struct RECORD {
char name[100];
int score;
int minute;
int sec;
}record; //이름, 점수, 시간을 저장할 구조체
int score;
int fruitx, fruity;
record nowrec;
int over = 0;
void gotoxy(int x, int y); //Input location
void make_stage(); //stage
int getCommand(); // Keyboard input
void gameover(); //Gameover screen
void startscr(); //Start screen
void snake_move(); //Snake movements
void rank_call(); //Displaying rank
void rankrecord(); //personal records
void cursor(int i); //
void stopwatch(); //stop watch
int main(void) {
startscr();
return 0;
}
void gotoxy(int x, int y) {
COORD pos = { 30 + x * 2, 10 + y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void make_stage() {
score = 0;
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
for (int i = 1; i <= 17; i++) {
gotoxy(i, 1);
printf("#");
gotoxy(1, i);
printf("#");
gotoxy(17, i);
printf("#");
gotoxy(i, 17);
printf("#");
}
srand(time(NULL));
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(fruitx, fruity);
printf("#");
}
int getCommand() {
if (_kbhit()) {
return _getch();
}
return -1;
}
void cursor(int i) {
CONSOLE_CURSOR_INFO cursorInfo = { 0, };
cursorInfo.dwSize = 1;
cursorInfo.bVisible = i;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
void rank_call() {
FILE* rank;
char reading[100];
if (fopen_s(&rank, "rank.txt", "r") != 0) printf("no record\n");
else {
printf("\n");
while ((fgets(reading, 100, rank) != NULL)) printf("%s", reading);
fclose(rank);
printf("\n");
}
}
void rankrecord() {
printf("\npress enter to proceed...\n");
while (getchar() != '\n');
printf("\n\n\n\n\n\npress r to record your ranking...\n");
char input = _getch();
if (input == 'r') {
FILE* rank;
fopen_s(&rank, "rank.txt", "a");
rerun:
printf("enter your name: ");
gets_s(nowrec.name, sizeof(nowrec.name));
if (strlen(nowrec.name) < 3) {
printf("name must be at least 3 words...\n\n");
goto rerun;
}
while (1) {
printf("your name is %s.\nyour score is %d.\nyour clear time is %d : %d.\n\n", nowrec.name, nowrec.score, nowrec.minute, nowrec.sec);
printf("if your name is incorrect, press n to correct\nif not, press y to continue...\n\n");
input = _getch();
if (input == 'n') goto rerun;
else if (input == 'y') break;
else printf("wrong input\n\n");
}
fprintf(rank, "%s %d %d : %d\n", nowrec.name, nowrec.score, nowrec.minute, nowrec.sec);
fclose(rank);
printf("saved!\n");
}
}
void startscr()
{
system("mode con cols=100 lines=40");
start:
system("cls");
printf(" ****** ** * * * * ****** ****** * ** ** ****** \n");
printf(" * * * * * * * * * * * * * * * * * \n");
printf(" ****** * * * ***** **** ****** * *** ***** * * * * ****** \n");
printf(" * * * * * * * * * * * * * * ** * * \n");
printf(" ****** * ** * * * * ****** ****** * * * ** * ****** \n");
printf("\npress s to start game\n");
printf("press r to see ranking\n");
printf("press x to exit\n:");
char input = _getch();
if (input == 's') {
system("cls");
cursor(0);
make_stage();
HANDLE thread1 = _beginthreadex(NULL, 0, (_beginthreadex_proc_type)stopwatch, NULL, 0, NULL);
Sleep(1);
HANDLE thread2 = _beginthreadex(NULL, 0, (_beginthreadex_proc_type)snake_move, NULL, 0, NULL);
WaitForSingleObject(thread2, INFINITE);
}
else if (input == 'r') {
rank_call();
printf("press enter to continue...");
while (getchar() != '\n');
goto start;
}
else if (input == 'x') exit(0);
else {
printf("wrong input\n");
printf("press enter to continue...");
while (getchar() != '\n');
goto start;
}
}
void gameover() {
over = 1;
system("cls");
printf("\n\n\n\n\n\n\n\n\n\n");
printf(" ****** * ** ** ****** **** * * ****** ***** \n");
printf(" * * * * * * * * * * * * * * * \n");
printf(" * *** ***** * * * * ****** * * * * ****** ***** \n");
printf(" * * * * * ** * * * * * * * * * \n");
printf(" ****** * * * ** * ****** **** * ****** * * \n");
cursor(1);
rankrecord();
printf("press any key to back to title...");
_getch();
startscr();
}
void snake_move() {
int x = 9, y = 9;
int x1 = 8, y1 = 9;
int x2 = 7, y2 = 9;
int x3 = 6, y3 = 9;
int x4 = 5, y4 = 9;
char dir = 'd';
char input = 'e';
while (1) {
srand(time(NULL));
if (x == fruitx && y == fruity) {
fruitx = rand() % 17;
fruity = rand() % 17;
score += 1;
gotoxy(fruitx, fruity);
printf("#");
}
input = _getch();
if ((dir == 'w' && input != 's') || (dir == 'a' && input != 'd') || (dir == 's' && input != 'w') || (dir == 'd' && input != 'a')) {
if (input == 'w') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y - 1;
if (y == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'w';
}
if (input == 'a') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x - 1;
if (x == 1) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'a';
}
if (input == 's') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
y = y + 1;
if (y == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 's';
}
if (input == 'd') {
gotoxy(x4, y4);
printf(" ");
x4 = x3; x3 = x2; x2 = x1; x1 = x;
y4 = y3; y3 = y2; y2 = y1; y1 = y;
x = x + 1;
if (x == 17) {
gameover();
break;
}
if (x == x4 && y == y4) {
gameover();
break;
}
gotoxy(x, y);
printf("a");
gotoxy(x1, y1);
printf("*");
gotoxy(x2, y2);
printf("*");
gotoxy(x3, y3);
printf("*");
gotoxy(x4, y4);
printf("*");
dir = 'd';
}
}
if (input == 'p') {
gameover();
break;
}
}
}
void stopwatch() {
clock_t s, n;
s = clock();
while (1) {
n = clock();
cursor(0);
gotoxy(14, 0);
printf(" %d : %d", ((n - s) / 1000) / 60, ((n - s) / 1000) % 60);
if (over == 1) {
break;
}
Sleep(1000);
}
gotoxy(14, 0);
printf(" **** ");
nowrec.minute = ((n - s) / 1000) / 60;
nowrec.sec = ((n - s) / 1000) % 60;
return;
}
Remember that
rand() % x
will give you values in the range [0, x-1].
With this in mind, let's look at
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(fruitx, fruity);
printf("#");
When you feed rand() % 17 into gotoxy() like this, you can expect that goto(0, 0) is possible.
I modified the above code to look like this
fruitx = rand() % 17;
fruity = rand() % 17;
gotoxy(0, 0);
printf("#");
to see what would happen, and the fruit turned up outside the field in the top left.
void gotoxy(int x, int y) {
COORD pos = { 30 + x * 2, 10 + y };
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
The problem is that your definition of gotoxy() is such that feeding it (0, 0) as coordinates puts the cursor outside the boundary to begin with. Furthermore, passing (1, 1) puts it in the corner, making it apart of the wall, which is also illegal I'm guessing.
To fix this, you either need to adjust your mathematics in gotoxy() or make a new function that transforms your field coordinates into global coordinates. This way, (0, 0) would correspond to the actual upper left (just inside the boundary) and so on.
The easiest fix is just to modify it like so
fruitx = 2 + rand() % 15;
fruity = 2 + rand() % 15;
gotoxy(fruitx, fruity);
printf("#");
This should happen everywhere you're spawning fruit.

finding path to all 3 corners on a chess board starting from 0,0 isn't working

#include <stdio.h>
#define SIDE 8
#define VISITED 1
#define NOT_VISITED 0
#define FALSE 0
#define TRUE !FALSE
void printBoard(int board[][SIDE]);
int goHorsie(int board[][SIDE], int x, int y, int step);
int main(void)
{
int board[SIDE][SIDE] = { NOT_VISITED };
goHorsie(board, 0, 0, 1);
printBoard(board);
getchar();
return 0;
}
int goHorsie(int board[][SIDE], int x, int y, int step)
{
int res = FALSE;
int cor1 = 0, cor2 = 0, cor3 = 0;
if (x == 7 && y == 7)
{
cor1 = 1;
}
if (x == 7 && y == 0)
{
cor2 = 1;
}
if (x == 0 && y == 7)
{
cor3 = 1;
}
if (cor1 == 1 && cor2 == 1 && cor3 == 1)
{
printf("FOUND ALL!\n");
res = TRUE;
}
else if (board[x][y] != NOT_VISITED //We were here already!
|| x >= SIDE || y >= SIDE || x < 0 || y < 0)
{
res = FALSE;
}
else
{
board[x][y] = step;
step++;
res =
goHorsie(board, x + 1, y - 2, step) ||
goHorsie(board, x + 2, y + 1, step) ||
goHorsie(board, x + 2, y - 1, step) ||
goHorsie(board, x + 1, y + 2, step) ||
goHorsie(board, x - 2, y + 1, step) ||
goHorsie(board, x - 2, y - 1, step) ||
goHorsie(board, x - 1, y + 2, step) ||
goHorsie(board, x + 1, y - 2, step);
if (!res)
{
board[x][y] = NOT_VISITED;
}
}
return res;
}
/*
Prints the chess board
*/
void printBoard(int board[][SIDE])
{
int i = 0, j = 0;
for (int i = 0; i < SIDE; i++)
{
for (int j = 0; j < SIDE; j++)
{
printf("%3d", board[i][j]);
}
printf("\n");
}
}
im using recursion to find the path to all 3 corners.
i ran the program for about 20min now and it's still didn't get to the solution.
ik why its taking too long but not sure if it will even get me to the answer.
so my question is did i make the function right and will it eventually give me the right answer (the path to all 3 corners).

function to draw a straight line in c

I'm trying to create a function to draw a straight line by reading two points from the user, (x1,y1) where the line begins and (x2,y2) where it ends.
here's my function:
void line(struct pixels* screen)
{
float X, Y;
int i, j, x1, y1, x2, y2, mX, mY;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if ((x1 >= 0 && x1 <= screen->width) && (y1 >= 0 && y1 <= screen->height) && (x2 >= 0 && x2 <= screen->width) && (y2 >= 0 && y2 <= screen->height))
{
X = (x2 - x1);
Y = (y2 - y1);
if (X < 0)
mX = X*(-1);
else
mX = X;
if (Y < 0)
mY = Y*(-1);
else
mY = Y;
if( mX>mY )
{
if (X > 0)
{
for (i = 0; i < X; i++)
{
j = (int)(((i*Y) / X) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
else
{
for (i = 0; i > X; i--)
{
j = (int)(((i*Y) / X) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
}
else
{
if (Y > 0)
{
for (j = 0; j < Y; j++)
{
i = (int)(((j*X) / Y) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
else
{
for (j = 0; j > Y; j--)
{
i = (int)(((j*X) / Y) + 0.5);
screen->pixel[x1 + i][y1 + j] = '*';
}
}
}
}
else
printf("ERROR: coordinates exceed the screen limits\n");
}
the problem is : when the user enters for example line from (1,1) to (10,10) the code works perfectly, but when it's from (10,10) to (1,1) it doesn't work!
Google Bresenham’s Line Drawing Algorithm. There is a fantastic tutorial/explanation of how do to this kind of thing at How OpenGL works: software renderer in 500 lines of code. Your specific question is brought up in the article. Highly recommended.
Here is his C++ implementation:
void line(int x0, int y0, int x1, int y1, TGAImage &image, TGAColor color) {
bool steep = false;
if (std::abs(x0-x1)<std::abs(y0-y1)) {
std::swap(x0, y0);
std::swap(x1, y1);
steep = true;
}
if (x0>x1) {
std::swap(x0, x1);
std::swap(y0, y1);
}
int dx = x1-x0;
int dy = y1-y0;
float derror = std::abs(dy/float(dx));
float error = 0;
int y = y0;
for (int x=x0; x<=x1; x++) {
if (steep) {
image.set(y, x, color);
} else {
image.set(x, y, color);
}
error += derror;
if (error>.5) {
y += (y1>y0?1:-1);
error -= 1.;
}
}
}

Drawing a line with GLUT

I have the next code using OPENGL GLUT, this code draws a line at a cursor position. Once you click the right button of the mouse it captures the coordinates x0, y0 of the line, then when the mouse moves to another pixel while pushing the button the coordinates(x1,y1) change, and finally when the button is released the line is drawn.
#include<windows.h>
#include <gl/glut.h>
float a[90000];
int x0=0,y0=0,xf=0,yf=0;
int print=0;
void init(void)
{
glClearColor(1.0, 1.0, 1.0, 0.0);
glMatrixMode(GL_PROJECTION);
gluOrtho2D(0.0, 300.0, 0.0,300.0);
}
void putpixel(int x,int y)
{
glColor3f(0.0, 0.9,0.7);
glBegin(GL_POINTS);
glVertex2i(x,y);
glEnd();
}
void Bresenham(int x0, int y0, int x1, int y1)
{
int dx,dy,p,x,y,px = 1,py = 1,twoDy_Dx,twoDy,i;
glColor3f(0.0,0.0,1.0);
dx = x1-x0;
dy = y1-y0;
if(dx < 0)
dx = dx*-1;
if(dy < 0)
dy = dy*-1;
if(x1 < x0)
px = -1;
if(y1 < y0)
py = -1;
x = x0;
y = y0;
if( dx > dy )
{
putpixel(x,y);
p = 2 * dy - dx;
twoDy_Dx = 2 * ( dy - dx );
twoDy = 2 * dy;
for( i = 0; i < dx; i++ )
{
if( p >= 0 )
{
y += py;
p += twoDy_Dx;
}
else
p += twoDy;
x += px;
putpixel(x,y);
}
}
else
{
putpixel(x,y);
p = 2*dx - dy;
twoDy_Dx = 2 * ( dx - dy );
twoDy = 2*dx;
for( i = 0; i < dy; i++ )
{
if( p >= 0 )
{
x += px;
p += twoDy_Dx;
}
else
p += twoDy;
y += py;
putpixel(x,y);
}
}
glFlush();
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
if(print==1)
glDrawPixels(300,300,GL_RGB,GL_UNSIGNED_BYTE,a);
Bresenham(x0,y0,xf,yf);
glutSwapBuffers();
glFlush();
}
void onMotion(int x,int y)
{
xf=x;
yf=300-y;
glutPostRedisplay();
}
void onMouse(int button, int e, int x, int y)
{
if((button == GLUT_LEFT_BUTTON) && (e == GLUT_DOWN))
{
x0 = x;
y0 = abs(300-y);
print = 1;
}
if( (button == GLUT_RIGHT_BUTTON) && (e==GLUT_DOWN))
{
print=0;
}
if ( (button == GLUT_LEFT_BUTTON || button == GLUT_RIGHT_BUTTON) && (e == GLUT_UP) )
{
print=0;
}
}
void onPassive(int x,int y)
{
x0=-1;y0=-1;xf=-1;yf=-1;
glReadPixels( 0.0, 0.0,300.0,300.0,GL_RGB,GL_UNSIGNED_BYTE,a);
}
int main(int argc, char** argv)
{
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowPosition(100, 100);
glutInitWindowSize(300, 300);
glutCreateWindow("Line");
init();
glutDisplayFunc(display);
glutMotionFunc(onMotion);
glutMouseFunc(onMouse);
glutPassiveMotionFunc(onPassive);
glutMainLoop();
}
The problem that I have is that when the button is pushed and while the final coordinates are changing, the line should be drawn as a pointed line: ---------
but when it reaches the final coordinates, the line should be drawn like this: _________. How can I do this?

Resources