473,386 Members | 1,795 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

"Eight Queens" program

I will be grateful if someone explians this part

colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

of the code below. I don't understand how this marks the downward and
upward diagonals. How does downfree[row-c+7] mark the diagonal?
Regards,
Matt

#include <stdio.h>
#include <stdlib.h>

typedef enum boolean_tag
{ FALSE, TRUE } Boolean_type;

void WriteBoard(void);
void AddQueen(void);

int col[8]; /* column with the queen*/
Boolean_type colfree[8]; /* is the column free? */
Boolean_type upfree[15]; /*is the upward diagonal
free?*/
Boolean_type downfree[15];/*is the downward diagonal
free?*/

int row = -1;/*row whose queen is currently placed*/
int boards = 0; /*number of positions investigated*/
int sol = 0; /* number of solutions found */

/* solve Eight Queens problem */
void main(void) {
int i;

for (i = 0; i < 8; i++)
colfree[i] = TRUE;
for (i = 0; i < 15; i++) {
upfree[i] = TRUE;
downfree[i] = TRUE;
}
AddQueen();

printf("%d positions investigated.\n", boards);
printf("%d solutions found.\n", sol);
}

/* AddQueen: attempt to place a queen */
void AddQueen(void)
{
int c; /* column being tried for the queen */

boards++;
row++;
for (c = 0; c < 8; c++)
if (colfree[c] && upfree[row+c] && downfree[row-c+7]) {
col[row] = c; /* put a queen in (row,c)*/
colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

if (row == 7) /* termination condition*/
WriteBoard();
else
AddQueen(); /* proceed recursively */

colfree[c] = TRUE; /* now backtrack by
removing the queen */
upfree[row+c] = TRUE;
downfree[row-c+7] = TRUE;
}
row--;
}

/* WriteBoard: print a solution */
void WriteBoard(void) {
int c;
int i, j;

sol++;
printf("solution %d\n", sol);
printf("-----------------\n");
for (i = 0; i < 8; i++) {
for (j = 0; j < col[i]; j++)
printf(" -");
printf(" Q");
for (j++; j < 8; j++)
printf(" -");
printf("\n");
}
printf("-----------------\n");
printf("Press <enter> to continue.");
scanf("%c", &c);
}
--
comp.lang.c.moderated - moderation address: cl**@plethora.net
Nov 14 '05 #1
5 6722
"Matt" <ma********@hotmail.com> wrote in message
news:cl****************@plethora.net...
I will be grateful if someone explians this part

colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

of the code below. I don't understand how this marks the downward and
upward diagonals. How does downfree[row-c+7] mark the diagonal?
Regards,
Matt

#include <stdio.h>
#include <stdlib.h>

typedef enum boolean_tag
{ FALSE, TRUE } Boolean_type;

void WriteBoard(void);
void AddQueen(void);

int col[8]; /* column with the queen*/
Boolean_type colfree[8]; /* is the column free? */
Boolean_type upfree[15]; /*is the upward diagonal
free?*/
Boolean_type downfree[15];/*is the downward diagonal
free?*/

int row = -1;/*row whose queen is currently placed*/
int boards = 0; /*number of positions investigated*/
int sol = 0; /* number of solutions found */

/* solve Eight Queens problem */
void main(void) {
int i;

for (i = 0; i < 8; i++)
colfree[i] = TRUE;
for (i = 0; i < 15; i++) {
upfree[i] = TRUE;
downfree[i] = TRUE;
}
AddQueen();

printf("%d positions investigated.\n", boards);
printf("%d solutions found.\n", sol);
}

/* AddQueen: attempt to place a queen */
void AddQueen(void)
{
int c; /* column being tried for the queen */

boards++;
row++;
for (c = 0; c < 8; c++)
if (colfree[c] && upfree[row+c] && downfree[row-c+7]) {
col[row] = c; /* put a queen in (row,c)*/
colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

if (row == 7) /* termination condition*/
WriteBoard();
else
AddQueen(); /* proceed recursively */

colfree[c] = TRUE; /* now backtrack by
removing the queen */
upfree[row+c] = TRUE;
downfree[row-c+7] = TRUE;
}
row--;
}

/* WriteBoard: print a solution */
void WriteBoard(void) {
int c;
int i, j;

sol++;
printf("solution %d\n", sol);
printf("-----------------\n");
for (i = 0; i < 8; i++) {
for (j = 0; j < col[i]; j++)
printf(" -");
printf(" Q");
for (j++; j < 8; j++)
printf(" -");
printf("\n");
}
printf("-----------------\n");
printf("Press <enter> to continue.");
scanf("%c", &c);
}
--
comp.lang.c.moderated - moderation address: cl**@plethora.net


I sat down, with a piece of paper and pencil. Draw out a chess board (eight
by eight squares obviously, colour doesn't matter, so all white :-) ). Also
draw out three columns of squares: one eight deep, and two fifteen deep. The
three columns will represent colfree, upfree and downfree. Assume if their
entries are blank, they are true.

Mentally, step through the program. So, entering AddQueen, row++ makes
row=0.
For col=0...
If... all statements initially are TRUE, so we execute the contents of the
if statement: colfree[0] = FALSE (mark this in the colfree column).
upfree[0+0] = FALSE (mark this), downfree [0 + 0 + 7] = FALSE (mark).
Recurse into AddQueen
row++ makes row=1
For col=0...
If... colfree[0] is FALSE, skip the if statement.
For statement makes col=1.
If ... Here we start to see what upfree and downfree represent: upfree[1+1]
is TRUE but downfree[1-1+7] is FALSE.

So, upfree seems to represent the diagonals going from bottom right to top
left, and downfree represents thos going from bottom left to top right.
(Note that the drawing produced by the program is upside down to me). Each
diagonal is numbered.
Upfree numbers them as 0 being the single square at the bottom left corner;
1 is the diagonal formed by two squares (row,column) (0,1) and (1,0); 2
formed by (0,2), (1,1), (2,0) etc. The largest diagonal in upfree is
(0,7),(1,6)...(7,0) i.e. bottom right corner to top left corner.
Downfree is similar: its numbering is
0 is formed by the single square (7,0)
1 by (6,0), (7,1)
and its largest diagonal is bottom left to top right.
In both cases there are fifteen diagonals.

So, the very first square tested is on upfree[0] and downfree[7] (downfree's
largest diagonal).
The next square tested (row=1, column=0) is on upfree[1] and downfree[6]
(but the column is occupied).
The next tested (row=1, column=1) is on upfree[2] and downfree[7]
(occupied).
The next (row=1, column=2) is on upfree[3] and downfree[8], so a queen is
placed here.

I hope this rambling helps a bit. All you need is to sit down and think
about it, you don't even need a computer (except of course to read this
posting).

Cheers
JS
--
comp.lang.c.moderated - moderation address: cl**@plethora.net
Nov 14 '05 #2
On 18 Aug 2004 03:32:17 GMT in comp.lang.c.moderated,
ma********@hotmail.com (Matt) wrote:
I will be grateful if someone explians this part

colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

of the code below. I don't understand how this marks the downward and
upward diagonals. How does downfree[row-c+7] mark the diagonal?


Those two expressions generate indexes to the diagonals from the row
and column indexes, best illustrated by a couple of tables:

r+c r+7-c
c 0 1 2 3 4 5 6 7 c 0 1 2 3 4 5 6 7
r r
0 0 1 2 3 4 5 6 7 0 7 6 5 4 3 2 1 0
1 1 2 3 4 5 6 7 8 1 8 7 6 5 4 3 2 1
2 2 3 4 5 6 7 8 9 2 9 8 7 6 5 4 3 2
3 3 4 5 6 7 8 9 10 3 10 9 8 7 6 5 4 3
4 4 5 6 7 8 9 10 11 4 11 10 9 8 7 6 5 4
5 5 6 7 8 9 10 11 12 5 12 11 10 9 8 7 6 5
6 6 7 8 9 10 11 12 13 6 13 12 11 10 9 8 7 6
7 7 8 9 10 11 12 13 14 7 14 13 12 11 10 9 8 7

The terms upward and downward are misleading as diagonals could by
definition be considered up and down or right and left.
Calling them something like indexes from upper left to bottom right
i_ul_br and indexes from upper right to bottom left i_ur_bl would be
more accurate, or the opposite for the directions the diagonals run:
d_ur_bl and d_ul_br.

As the expressions appear in a few places, using a couple of macros
may make things cleaner and clearer:

#define I_UL_BR(r,c) ((r)+(c))
#define I_UR_BL(r,c) ((r)+7-(c))

and it would be better to name the variables more consistently
as r and c, or row and col, rather than mixing row and c.

--
Thanks. Take care, Brian Inglis Calgary, Alberta, Canada

Br**********@CSi.com (Brian dot Inglis at SystematicSw dot ab dot ca)
fake address use address above to reply
--
comp.lang.c.moderated - moderation address: cl**@plethora.net
Nov 14 '05 #3
"Matt" <ma********@hotmail.com> wrote in message
news:cl****************@plethora.net...
I will be grateful if someone explians this part

colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

of the code below. I don't understand how this marks the downward and
upward diagonals. How does downfree[row-c+7] mark the diagonal?


There are 15 diagonals going from lower left to upper right and 15 diagonals
going from upper left to lower right. For any row and column, the formulas
'row+c' and 'row-c+7' computes the diagonal number for each direction as
shown below.

The 15 'upward' diagonals, in direction lower left to upper right corner,
are defined like this (in [row,col] format):

Diagonal 0 (row+col = 0): [0,0]
Diagonal 1 (row+col = 1): [0,1] [1,0]
Diagonal 2 (row+col = 2): [0,2] [1,1] [2,0]
Diagonal 3 (row+col = 3): [0,3] [1,2] [2,1] [3,0]
Diagonal 4 (row+col = 4): [0,4] [1,3] [2,2] [3,1] [4,0]
Diagonal 5 (row+col = 5): [0,5] [1,4] [2,3] [3,2] [4,1] [5,0]
Diagonal 6 (row+col = 6): [0,6] [1,5] [2,4] [3,3] [4,2] [5,1] [6,0]
Diagonal 7 (row+col = 7): [0,7] [1,6] [2,5] [3,4] [4,3] [5,2] [6,1]
[7,0]
Diagonal 8 (row+col = 8): [1,7] [2,6] [3,5] [4,4] [5,3] [6,2] [7,1]
Diagonal 9 (row+col = 9): [2,7] [3,6] [4,5] [5,4] [6,3] [7,2]
Diagonal 10 (row+col = 10): [3,7] [4,6] [5,5] [6,4] [7,3]
Diagonal 11 (row+col = 11): [4,7] [5,6] [6,5] [7,4]
Diagonal 12 (row+col = 12): [5,7] [6,6] [7,5]
Diagonal 13 (row+col = 13): [6,7] [7,6]
Diagonal 14 (row+col = 14): [7,7]

These are the 15 'downward' diagonals, in direction upper left to lowerer
right corner:

Diagonal 0 (row-col+7 = 0): [0,7]
Diagonal 1 (row-col+7 = 1): [0,6] [1,7]
Diagonal 2 (row-col+7 = 2): [0,5] [1,6] [2,7]
Diagonal 3 (row-col+7 = 3): [0,4] [1,5] [2,6] [3,7]
Diagonal 4 (row-col+7 = 4): [0,3] [1,4] [2,5] [3,6] [4,7]
Diagonal 5 (row-col+7 = 5): [0,2] [1,3] [2,4] [3,5] [4,6] [5,7]
Diagonal 6 (row-col+7 = 6): [0,1] [1,2] [2,3] [3,4] [4,5] [5,6] [6,7]
Diagonal 7 (row-col+7 = 7): [0,0] [1,1] [2,2] [3,3] [4,4] [5,5] [6,6]
[7,7]
Diagonal 8 (row-col+7 = 8): [1,0] [2,1] [3,2] [4,3] [5,4] [6,5] [7,6]
Diagonal 9 (row-col+7 = 9): [2,0] [3,1] [4,2] [5,3] [6,4] [7,5]
Diagonal 10 (row-col+7 = 10): [3,0] [4,1] [5,2] [6,3] [7,4]
Diagonal 11 (row-col+7 = 11): [4,0] [5,1] [6,2] [7,3]
Diagonal 12 (row-col+7 = 12): [5,0] [6,1] [7,2]
Diagonal 13 (row-col+7 = 13): [6,0] [7,1]
Diagonal 14 (row-col+7 = 14): [7,0]

Thanks for the program. I remember doing this a long time ago.

Dag
--
comp.lang.c.moderated - moderation address: cl**@plethora.net
Nov 14 '05 #4
Matt wrote:
I will be grateful if someone explians this part

colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

of the code below. I don't understand how this marks the downward and
upward diagonals. How does downfree[row-c+7] mark the diagonal?
Regards,
Matt

As a beginner I just made a try to replay.

#include <stdio.h>
#include <stdlib.h>

typedef enum boolean_tag
{ FALSE, TRUE } Boolean_type;

void WriteBoard(void);
void AddQueen(void);

int col[8]; /* column with the queen*/
Boolean_type colfree[8]; /* is the column free? */
Boolean_type upfree[15]; /*is the upward diagonal
free?*/
Boolean_type downfree[15];/*is the downward diagonal
free?*/

int row = -1;/*row whose queen is currently placed*/
int boards = 0; /*number of positions investigated*/
int sol = 0; /* number of solutions found */

/* solve Eight Queens problem */
void main(void) {
int i;

for (i = 0; i < 8; i++)
colfree[i] = TRUE;
for (i = 0; i < 15; i++) {
upfree[i] = TRUE;
downfree[i] = TRUE;
}
AddQueen();

printf("%d positions investigated.\n", boards);
printf("%d solutions found.\n", sol);
}

/* AddQueen: attempt to place a queen */
void AddQueen(void)
{
int c; /* column being tried for the queen */

boards++;
row++;
for (c = 0; c < 8; c++)
if (colfree[c] && upfree[row+c] && downfree[row-c+7]) {
col[row] = c; /* put a queen in (row,c)*/
colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE;

if (row == 7) /* termination condition*/
WriteBoard();
else
AddQueen(); /* proceed recursively */

colfree[c] = TRUE; /* now backtrack by
removing the queen */
upfree[row+c] = TRUE;
downfree[row-c+7] = TRUE;
}
row--;
}

<OT>
I think that this is the way the bit board works in chess engine. The
whole array is
made up of *imagination* (Virtual space). That is why the

colfree[c] = TRUE; /* now backtrack by
removing the queen */
upfree[row+c] = TRUE;
downfree[row-c+7] = TRUE;

is said to be back tracking. That means the squares given space to
hold the Queen.
I cannot understand why there is a recursive call for AddQueen() function.
I can say that the arrays are squares which traverse through each
square during
the for loop. But I cannot understand about the 92 different solutions.
If you either try the newsgroups such as comp.programming or
rec.games.chess.computers would
be a correct place. You can also get good replays in

www.talkchess.com

(under the message board computer-chess club. But you have to
register yourself which is free of cost).

If you get the correct replay please don't forget to give a summary in
the clc.
BTW where did you get this code from?

</OT>
/* WriteBoard: print a solution */
void WriteBoard(void) {
int c;
int i, j;

sol++;
printf("solution %d\n", sol);
printf("-----------------\n");
for (i = 0; i < 8; i++) {
for (j = 0; j < col[i]; j++)
printf(" -");
printf(" Q");
for (j++; j < 8; j++)
printf(" -");
printf("\n");
}
printf("-----------------\n");
printf("Press <enter> to continue.");
scanf("%c", &c);
}

Thanks,
N.Sathyashrayan

--
"Combination is the heart of chess"
A.Alekhine
Mail to:
sathyashrayan25 AT yahoo DOT com
(remove the AT and DOT)
--
comp.lang.c.moderated - moderation address: cl**@plethora.net
Nov 14 '05 #5
In comp.lang.c Matt <ma********@hotmail.com> wrote:
I will be grateful if someone explians this part

colfree[c] = FALSE;
upfree[row+c] = FALSE;
downfree[row-c+7] = FALSE; of the code below. I don't understand how this marks the downward and
upward diagonals. How does downfree[row-c+7] mark the diagonal?


Just draw yourself a chess board and draw all diagonals. Then label
the diagonals that go upwards with the number that you get when you
add the row and column number (each going from 0 to 7) of a field the
diagonal is going through. You will see that you get the same number
(one between 0 an 14) for each field the diagonal crosses. So it's a
useful scheme to label the upward diagonals. Now do the same for the
downward diagonals, but label them with the difference between the
row number and the column number, incremented by seven. Again, each
diagonal gets a number that is the same for each field it crosses
and all numbers are in the range from 0 to 14. So, again, you have
a useful scheme for labeling the downward diagonals. And finding a
labeling scheme is the only tricky part about the algorithm.

Now in your program you have an array for free columns and two for
free diagonals. If you place a queen on a certain field you must
mark the column where you put it in the array of free columns as
used up (that's the first line, "colfree[c] = FALSE;") as well as
the upward and downward going diagonals crossing that field (that's
the next two lines). Now you can in further iterations check if
a certain field can be used for another queen or not just from
the fields coordinates.

BTW, main() is a function that must return an int. And if you have

int c;
scanf("%c", &c);

then you need "%d" as the format specifier, "%c" is for chars.

Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
--
comp.lang.c.moderated - moderation address: cl**@plethora.net
Nov 14 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Toto | last post by:
Gray Davis is a desperate man. Facing recall, he has just put the safety of California motorists at risk in a naked bid to buy Hispanic votes. Davis signed into law a bill he had twice rejected, to...
26
by: Chris Potter | last post by:
Hello everyone. I am taking my first course in C and in one of my assignments i need to print out an array that could have anywhere from 0 to 100 positive integers in it (a negative integer is...
4
by: John Devereux | last post by:
Hi, I would like some advice on whether I should be using plain "chars" for strings. I have instead been using "unsigned char" in my code (for embedded systems). In general the strings contain...
48
by: Frederick Gotham | last post by:
The "toupper" function takes an int as an argument. That's not too irrational given that a character literal is of type "int" in C. (Although why it isn't of type "char" escapes me... ) The...
93
by: jacob navia | last post by:
In this group there is a bunch of people that call themselves 'regulars' that insist in something called "portability". Portability for them means the least common denominator. Write your code...
4
by: Bubba | last post by:
Has anyone ever run into a problem converting a text version of number to it's whole number equivalent? If so, can someone please post an example in 2005 of how this is handled? ex. "Four" to 4...
3
by: Crash_beta | last post by:
Let me show u what I have,, I need to make this work with comma's in the numbers like 123,000.45 Not just 123000.45 <script type="text/javascript"> <!-- Begin
8
by: situ | last post by:
Hello all, i have Database1 and database2, is it possible to make database connection to database2 by running stored procedure on database1. Thanks and Regards Situ
25
by: Peng Yu | last post by:
Hi, It is possible to change the length of "\t" to a number other than 8. std::cout << "\t"; Thanks, Peng
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.