2

I'm working on an assignment concerning the Eight Queen Puzzle in chess. The exercise is as follows:

Given an arrangement of the 8 queens on the chessboard, write a C program which will evaluate the arrangement and inform the user if this arrangement is a solution of the puzzle.

Now, because there are 92 possible solutions, it's not practical to compare the user input with a solution list, so I'm solving the problem like this:

I consider an 8x8 array. Representing an empty square with 0 and a square with a queen with 1, all I need to check in order for the solution to be correct is:

The sum of each row, column and possible diagonal line must not exceed 1.

And here is my problem: I've covered the rows and columns, but I can' t find a method to add the diagonals. For clarification:

Sums

Every diagonal line represents the squares that must be summed every time. The result of each line will be stored in an array. This happens for both directions.

Code so far:

#include <stdio.h>

int check(int array[8][8])
{
    int i, j;
    int rowsum[8] = {0, 0, 0, 0, 0, 0, 0, 0};
    int colsum[8] = {0, 0, 0, 0, 0, 0, 0, 0};

    for (i = 0; i <= 7; i++) //test if are 2 queens on the same row (i: row, j: column)
    {
        for (j = 0; j <= 7; j++)
        {
            rowsum[i] += array[i][j]; /*since they are represented by 0s and 1s,
                                if a row's sum is bigger than 1
                                there is more than 1 queen on that particular row
                                here the row doesn't change until all
                                columns are accessed (we get a row sum)*/
        }
    }


    for (i = 0; i <= 7; i++) //same as before, but for columns
    {
        for (j = 0; j <= 7; j++)
        {
            colsum[i] += array[j][i]; //here the col. doesn't change until all rows are accessed (we get a col. sum)
        }
    }
}

int main(void)
{
    int i = 1; //counter for the input
    int row = 0;
    int column = 0; //row and column numbers

    int board[8][8] = {
        {0, 0, 0, 0, 0, 0, 0, 0},   //here we initialize an empty board as an 8x8 array
        {0, 0, 0, 0, 0, 0, 0, 0},   //from now on: a 0 is an empty square, a 1 is a queen
        {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, 0, 0}
    };

    while (i <= 8) //we fill our board with queens
    {
        printf("Queen #%d row:", i);
        scanf("%d", &row);
        printf("Queen #%d column:", i);
        scanf("%d", &column);
        board[row - 1][column - 1] = 1;
        i++;
    }

    check(board);
}

Any help would be greatly appreciated.

EDIT: Solved it. Many thanks to @Yunnosch for pointing me to the right direction! FYI about the final solution: You can find it here, with comments for clarification: Solution

EDIT-2: You can find the whole code here, also commented.

@Yunnosch: It might not be elegant or even efficient, but it works well. Quick question: Was this method the one you had in mind or is this an innovation? :P

  • 1
    Your function `check` has a return type of `int`, but it doesn't return any values and you don't check the value anyway, so why bother calling it? – Chris Turner Dec 18 '17 at 13:47
  • The exercise explicitly wants the evaluating logic in a separate function. – lightspot21 Dec 19 '17 at 07:54
  • 1
    I bet the exercise also wants the separate function to actually return a value for the rest of the code to check too – Chris Turner Dec 19 '17 at 09:39
  • Yep, but I haven't actually written the code for that yet. I'll solve the problem with the array first, the rest are a for loop and a condition away ;) – lightspot21 Dec 19 '17 at 10:22
  • Answer to the question directed personally at me (still a comment for not answering the main question): I never had a method in mind. I just helped you think through the decent one you had outlined from start. I do not know whether it was a new invention. At a guess (and hoping not to hurt you), nobody will bother, because it is indeed not particularily efficient. At least the arrays could be optimised away. But hey, your actual goal was learning, wasn't it? I think you nailed that objective thoroughly. I checked briefly and found the topics I mentioned covered. Congratulations. – Yunnosch Dec 21 '17 at 21:17

1 Answers1

2

Since this is a assignment, I follow the compromise for handling homework questions. I.e. I will not provide a solution. Instead here is a first hint at how you should approach the problem.

Hint1:
There are 15 diagonals of each direction. Their length is from 1 to 8. All lengths exist twice, except the length 8.

Hint2:
You have an array with counts for columns and one array with counts for rows, both are of size 8, because there are 8 rows and 8 columns.
You are lacking an array with counts for / diagonals and an array with counts for \ diagonals.
Introduce them and fill them with counts, similarily to how you fill the row and column arrays. Counting has to keep the varying lengths of diagonals in mind.

Let me know how much that helps.
I might hint the next step.

(policy is described here: How do I ask and answer homework questions? )

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Could you please clarify just a little bit? I've been trying to figure it out the whole day and still no dice. Thanks – lightspot21 Dec 19 '17 at 10:39
  • I am happy to note that I seem to have helped you. Would you like to add your own answer with the final code you have created? I would enjoy seeing how things turned out. Also I am pretty sure that you won't get downvotes. – Yunnosch Dec 21 '17 at 20:58
  • Be careful not to post too much of a wall of code. Stick to the [answer] recommendations. – Yunnosch Dec 21 '17 at 21:04
  • It's up on pastebin. Did you really think I'd clutter people's screens with a 200-line block of code? :P – lightspot21 Dec 21 '17 at 21:08