COMP1721 - Higher Computing 1B
Higher Computing 1B - Week Laboratory Exercises
/*
* Find a placement of queens on a chessboard such that they
* can't attack each other.
*
* written by Andrew Taylor andrewt@cse.unsw.edu.au
* August 2001 as a COMP1721 lab exercise
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
enum {
EMPTY = '.',
QUEEN = 'q',
BOARD_SIZE = 6,
N_QUEENS = 6
};
void initialize_board(int chessboard[BOARD_SIZE][BOARD_SIZE]);
void place_queens(int chessboard[BOARD_SIZE][BOARD_SIZE], int nQueens);
int no_queens_attack_each_other(int chessboard[BOARD_SIZE][BOARD_SIZE]);
void print_board(int chessboard[BOARD_SIZE][BOARD_SIZE]);
/*
* Find a placment of N_QUEENS queens on a BOARD_SIZE size chessboard
* such that no queen attacks any other.
*
* This is done by generating a placement randomly and testing
* if any two queens can attack each other and repeating this
* until a suitable placement is found
*
* Much more efficient approaches exist to this problem!
*/
int
main(void) {
int board[BOARD_SIZE][BOARD_SIZE];
srand(time(NULL));
while (1) {
initialize_board(board);
place_queens(board, N_QUEENS);
if (no_queens_attack_each_other(board))
break;
}
print_board(board);
return 0;
}
/*
* initialize the squares of the chessboard to EMPTY
*/
void
initialize_board(int chessboard[BOARD_SIZE][BOARD_SIZE]) {
int i, j;
for (i = 0; i < BOARD_SIZE; i++)
for (j = 0; j < BOARD_SIZE; j++)
chessboard[i][j] = EMPTY;
}
/*
* place n_queens in random positions
* on a chessboard.
*/
void
place_queens(int chessboard[BOARD_SIZE][BOARD_SIZE], int n_queens) {
int i, x, y;
i = 0;
while (i < n_queens) {
x = rand() % BOARD_SIZE;
y = rand() % BOARD_SIZE;
if (chessboard[x][y] != EMPTY)
continue;
chessboard[x][y] = QUEEN;
i++;
}
}
/*
* given a chessboard, return false, iff any two queens can attack
* each other, return true otherwise
*
* Two queens can attack each other if they are on
* the same row, the same column or the same diagonal
* of the chessboard.
*/
int
no_queens_attack_each_other(int chessboard[BOARD_SIZE][BOARD_SIZE]) {
int row, column, queens_count, start;
/*
* check rows
* return false iff any contains multiple queens
*/
for (row = 0; row < BOARD_SIZE; row++) {
queens_count = 0;
for (column = 0; column < BOARD_SIZE; column++) {
if (chessboard[row][column] == QUEEN)
queens_count++;
if (queens_count > 1)
return 0;
}
}
/*
* check columns
* return false iff any contains multiple queens
*/
for (column = 0; column < BOARD_SIZE; column++) {
queens_count = 0;
for (row = 0; row < BOARD_SIZE; row++) {
if (chessboard[row][column] == QUEEN)
queens_count++;
if (queens_count > 1)
return 0;
}
}
/*
* check the diagonals where row & column increase together
* return false iff any contains multiple queens
*/
for (start = 1 - BOARD_SIZE; start < BOARD_SIZE; start++) {
queens_count = 0;
for (row = 0; row < BOARD_SIZE; row++) {
column = start + row;
if (column < 0 || column >= BOARD_SIZE)
continue;
if (chessboard[row][column] == QUEEN)
queens_count++;
}
if (queens_count > 1)
return 0;
}
/*
* check the diagonals where column increases as to descreases
* return false iff any contains multiple queens
*/
for (start = 0; start < 2*BOARD_SIZE; start++) {
queens_count = 0;
for (row = 0; row < BOARD_SIZE; row++) {
column = start - row;
if (column < 0 || column >= BOARD_SIZE)
continue;
if (chessboard[row][column] == QUEEN)
queens_count++;
}
if (queens_count > 1)
return 0;
}
return 1;
}
/*
* print the chessboard
*/
void
print_board(int chessboard[BOARD_SIZE][BOARD_SIZE]) {
int i, j;
printf("\n\n");
for (i = 0; i < BOARD_SIZE; i++) {
for (j = 0; j < BOARD_SIZE; j++)
printf("%c ", chessboard[i][j]);
printf("\n\n");
}
printf("\n\n");
}
/*
* Find a placment of queens on a chessboard such that they
* can't attack each other.
*
* written by Andrew Taylor andrewt@cse.unsw.edu.au
* August 2001 as a COMP1721 lab exercise
*/
#include <stdio.h>
#include <stdlib.h>
enum {
EMPTY = '.',
QUEEN = 'q',
};
int place_queens(int rows[], int columns[], int diagonals1[], int diagonals2[], int row, int board_size);
void print_board(int queens[], int board_size);
/*
* Find a placment of N_QUEENS queens on a BOARD_SIZE size chessboard
* such that no queen attacks any other.
*
* Naive backtracking with tables of rows, columns and diagonals is used.
*/
int
main(int argc, char *argv[]) {
int *rows;
int *columns;
int *diagonals1;
int *diagonals2;
int board_size, i;
if (argc != 2) {
fprintf(stderr, "Usage: nqueens \n");
return 1;
}
board_size = atoi(argv[1]);
rows = (int *)malloc(board_size*sizeof (int));
columns = (int *)malloc(board_size*sizeof (int));
diagonals1 = (int *)malloc(2*board_size*sizeof (int));
diagonals2 = (int *)malloc(2*board_size*sizeof (int));
for (i = 0; i < board_size; i++) {
rows[i] = 0;
columns[i] = 0;
}
for (i = 0; i < 2*board_size; i++) {
diagonals1[i] = 0;
diagonals2[i] = 0;
}
if (rows == NULL||columns == NULL||diagonals1 == NULL||diagonals2 == NULL) {
fprintf(stderr, "Couldn't allocate memory\n");
return 1;
}
if (place_queens(rows, columns, diagonals1, diagonals2, 0, board_size))
print_board(rows, board_size);
else
printf("No solution found!\n");
return 0;
}
/*
* place n_queens in random positions
* on a chessboard.
*/
int
place_queens(int rows[], int columns[], int diagonals1[], int diagonals2[], int row, int board_size) {
int column, d1, d2;
if (row == board_size)
return 1;
for (column = 0; column < board_size; column++) {
d1 = column + row;
d2 = board_size + column - row;
if (columns[column] + diagonals1[d1] + diagonals2[d2])
continue;
rows[row] = column;
columns[column] = 1;
diagonals1[d1] = 1;
diagonals2[d2] = 1;
if (place_queens(rows, columns, diagonals1, diagonals2, row + 1, board_size))
return 1;
/*
* backtracking
*/
columns[column] = 0;
diagonals1[d1] = 0;
diagonals2[d2] = 0;
}
return 0;
}
/*
* print the chessboard
*/
void
print_board(int queens[], int board_size) {
int row;
printf("\n");
for (row = 0; row < board_size; row++) {
int column;
for (column = 0; column < queens[row]; column++)
printf("%c", EMPTY);
putchar(QUEEN);
for (column++;column < board_size; column++)
printf("%c", EMPTY);
printf("\n");
}
printf("\n");
}
Andrew Taylor (andrewt@cse.unsw.edu.au)
Higher Computing 1B,
Computer Science & Engineering,
UNSW