I am trying to find the number of ways possible to set 5 queens on a chess board without them being able to attack each other. I have succeeded to find the first set. The problem is how would I be able to find the next set of positions for 5 queens. The procedure in my program is like this:
Generate a vector of disallowed positions based on the current queens on the board
Loop through all the positions on the board
Check if the current position is one of the disallowed positions on the board
If it is not, return the position, add it to the vector of queens on the board and begin the process again
Continue until there is no more position available i.e. all the remaining positions are disallowed
#include <iostream>
#include <vector>
using namespace std;
const int BSIZE = 8;
char chessBoard[BSIZE][BSIZE];
struct qPos
{
qPos() : h(0), v(0), found(true) {}
int h; //horizontal pos
int v; //vertical pos
bool found; //if position is available
};
qPos findNextQPos(vector<qPos> Qs);
void fillBoard(vector<qPos> Qs);
void print();
vector<qPos> generateDisallowed(vector<qPos> Qs);
bool isDisallowed(qPos nextPos, vector<qPos> disallowedPos);
int main(int argc, char **argv){
vector<qPos> QsOnBoard; //Position of all the queens on board
qPos nextQ; //next possible position
while (nextQ.found)
{
nextQ = findNextQPos(QsOnBoard);
if (nextQ.found)
{
QsOnBoard.push_back(nextQ); //If the nextQ is available i.e. not disallowed, add it to the queens vector
}
}
fillBoard(QsOnBoard); //Fill the board with queens positions
print(); // print the board
return 0;
}
qPos findNextQPos(vector<qPos> Qs) {
// Generate disallowed positions based on all the queens on board
vector <qPos> disallowedPos = generateDisallowed(Qs);
qPos nextQ;
for (size_t i = 0; i < BSIZE; i++)
{
for (size_t j = 0; j < BSIZE; j++)
{
nextQ.h = i;
nextQ.v = j;
if (!isDisallowed(nextQ, disallowedPos)) { //Check if next possible position is a disallowed position
//cout << "Next available:\n" << nextQ.h << ", " << nextQ.v << endl;
return nextQ; // if it is avaible return the position, break the loop
}
}
}
nextQ.found = false; // No available position is found to return, found is set to false, return the position
return nextQ;
}
Rest of the source code where I have the other functions such as generate disallowed and isDisallowed and etc is on this pastebin. I thought it would not be really related to the question and the code here should not be too long.
The result of the first set looks like this:
So how should I continue in order to be able to find all solution sets? This is where I get stuck.
First, combine these two loops into one:
for (size_t i = 0; i < BSIZE; i++)
{
for (size_t j = 0; j < BSIZE; j++)
{
Instead:
for (size_t n = 0; n < (BSIZE * BSIZE); ++n)
{
size_t i = n % BSIZE;
size_t j = n / BSIZE;
Now your function can easily take a starting n. To find the "next" solution, simply remove the last queen (noting its position) and call FindNextQPos, telling it to start at the position one past that queen. If that queen is already at the last position, go back and remove another queen.
If you find no solution, do the same thing as if you do find a solution. Remove the last queen and call FindNextQPos, again starting one past the position of the queen you removed.
When you have no queens to remove, you are done.
You can do this with a single "continue" function. You can call this function whether you found a solution or found no solution. Its logic is:
Find the last queen. If there's no last queen, stop. We are done.
Note its position. Remove it.
Call FindNextQPos starting at the position one past the position we noted. If we placed a queen, keep trying to place more queens starting at position zero until we find a solution or can't place a queen.
If we found a solution, output it.
Go to step 1.
Related
I am trying to make a c++ console application that tries to show you how merge sort looks like. I understand merge sort, and I created a program that organizes a vector of strings called sort_visualize, and each string in it is filled with many #. This is completely randomized for every string. The merge sort will organize them depending on length, instead of the traditional number organizing people do with it. Every time I make a change to the vector, I also clear the screen and print out the entire vector through a draw function, to give the effect of it actively visualizing the sort every frame. The problem is that when I use the draw function to print out the entire sort_visualize string, it does not print out any changes that I have made to it, and prints out the same thing over and over again until the end, when it finally prints the sorted order. What is going on? I Don't understand. I even tried changing the draw(sort_visualize) to draw(sort_visualize_), and that shows small areas of the vector it is working on. Makes no sense. Please try this code and tell me any solutions. Thank you.
Here's the code:
#include <vector>
#include <iostream>
#include <ctime>
#include "stdlib.h"
#include "windows.h"
using namespace std;
void merge_sort(vector<string> &sort_visual_);
void merge_halves(vector<string>&left, vector<string>& right, vector<string>& sort_visual_);
void draw(vector <string> &sort_visual_);
vector <string> sort_visual;
int main()
{
srand(time(NULL));
//vector
vector<int> num_list;
//fill vector with random integers
for (int i = 0; i < 40; i++)
num_list.push_back(rand() % 40);
//Fill the visualizer strings which will be bars with #'s
for (int i = 0; i < num_list.size(); i++)
{
sort_visual.push_back("");
string temp;
for (int j = 0; j < num_list.at(i); j++)
{
temp.push_back('#');
}
sort_visual.at(i) = temp;
}
draw(sort_visual);
system("pause");
//sort function
merge_sort(sort_visual);
}
void merge_sort(vector<string> &sort_visual_)
{
//dont do anything if the size of vector is 0 or 1.
if (sort_visual_.size() <= 1) return;
//middle of vector is size/2
int mid = sort_visual_.size() / 2;
//2 vectors created for left half and right half
vector<string> left;
vector<string> right;
//divided vectors
for (int j = 0; j < mid; j++)
{
left.push_back(sort_visual_[j]); //add all the elements from left side of original vector into the left vector
}
for (int j = 0; j < (sort_visual_.size()) - mid; j++)
{
right.push_back(sort_visual_[mid + j]);//add all the elements from right side of original vector into the right vector
}
//recursive function for dividing the left and right vectors until they are length of 1
merge_sort(left);
merge_sort(right);
//do the actual merging function
merge_halves(left, right, sort_visual_);
}
void merge_halves(vector<string>&left, vector<string>&right, vector<string>& sort_visual_) //pass in 3 vectors
{
// sizes of each vector (left and right)
int nL = left.size();
int nR = right.size();
//declaring variables pointint to elements for each vector. i will represent finished produce vector
int i = 0, j = 0, k = 0;
//as long as j and k are less than the left and right sizes
while (j < nL && k < nR)
{
if (left[j].length() < right[k].length()) //if the string in the left vector is smaller than string in right vector
{
sort_visual_[i] = left[j];//ad the string from left vector in the sort_visuals vector(which is the final product)
j++;//increment j to move on
}
else
{
sort_visual_[i] = right[k];//otherwise add the string from right vector in the sort_visual vector
k++; //increment k to move on
}
i++; //i is the final vector, and we have to increment it to set it up to take in the next number
system("CLS");
draw(sort_visual);
Sleep(15);
}
while (j < nL)
{
sort_visual_[i] = left[j];
j++; i++;
system("CLS");
draw(sort_visual);
Sleep(15);
}
while (k < nR)
{
sort_visual_[i] = right[k];
k++; i++;
system("CLS");
draw(sort_visual);
Sleep(15);
}
}
void draw(vector <string> &sort_visual)
{
for (int i = 0; i < sort_visual.size(); i++)
{
cout << sort_visual.at(i) << endl;
}
}
In merge_halves you work on sort_visual_ but draw sort_visual which is a global that does not seem to be changed. Make sure there are no globals and it will be harder to make mistakes.
So I'm doing a puzzle game and I came to a problem. My Board will get scrambled later on in the program. I want to make a copy of it before it gets scrambled, to use it in the win-condition for my game. My Idea is to compare the copied board to the scrambled board every time the user moves a tile to see if they succeded (won) or not. But I'm a bit unsure how to do the copy constructor for the board. Here is what I have done(doesn't work as it's supposed to do).
Board::Board(int userInput)
{
this->gameSize = userInput;
int zeroPos[2] = { 0, 0 };
SetTileNumbers();
}
void Board::SetTileNumbers()
{
const int sizeOfGame = gameSize; //Size given from user when the board was created.
int tileNumber = 0; //The value given to each Tile.Number.
int row, column;
boardOfTiles = new Tile* [sizeOfGame];
for (int i = 0; i < sizeOfGame; i++)
{
boardOfTiles[i] = new Tile [sizeOfGame]; //The doublepointer is given an additional dimension
}
for (row = 0; row < sizeOfGame; row++)
{
for (column = 0; column < sizeOfGame; column++)
{
boardOfTiles[row][column].number = tileNumber; //Loops that goes through the entirety to instantiate the board of tiles.
tileNumber++;
}
}
}
void Board::SetTileNumbers(const Board& copy)
{
const int sizeOfGame = copy.gameSize;
int row , column;
boardOfTiles = new Tile*[sizeOfGame];
for (int i = 0; i < sizeOfGame; i++)
{
boardOfTiles[i] = new Tile[sizeOfGame];
}
for (row = 0; row < sizeOfGame; row++)
{
for (column = 0; column < sizeOfGame; column++)
{
boardOfTiles[row][column].number = copy.boardOfTiles[row][column].number;
}
}
}
I hope this does not sound off-topic, but copy-constructor aside, I think you might have a different problem: the way you decide on a solution is very inefficient. You waste cpu time and you waste memory.
For every step to compare two NxN boards is about as ineffciciet as it gets. You can try a different approach: assign a number to each position on the board and you know that the solution is to have the numbers sorted in a particular order.
For a 3x3 board, 'THE' solution would look like:
1 2 3
4 5 6
7 8 9
Furthermore, a 2d array is stored in memory as a continuous array, you you can treat the solution as an array:
1 2 3 4 5 6 7 8 9
Any other arrangement will not represent an solution.
Checking weather an array is sorted is a much easier problem to solve. Worst case scenario you are still looking at O(n^2) to check if the array is sorted but without the memory overhead. Plus I'm sure you can figure out a more efficient algorithm to check if the array is sorted.
I hope this helps...
I've got a task to find which circle intersects with the most other circles.
I have the x-coordinates, y-coordinates, and the radii of many different circles. I've put x-coordinates into array X[], y-coordinates into Y[] and radius into R[]. I've also found the way to check if one circle intersects with another, shown below.
I know that two FOR loops should be used,but I can't seem to find the way,so that the loop compares one element to all other elements in the array,then compares another element to all other elements and etc. Maybe someone knows the way?
for (int i = 0; i < n; i++) // n is the number of circles
{
for (int j = 0; j < n - 1; j++)
{
// More code here...
}
}
To check if the circle i intersects with circle i+1, my if evaluates:
if (Distance (n, X, Y,i ) < (Radius[i] + Radius[i+1])) // i is the index of the element
From my perspective, there are two questions being asked simultaneously. First question is how to compare each element of one array to all elements of second array. Second question is how to find the maximum amount of times a condition has been met. Furthermore, the condition depends on the comparison of an element in the first array with the elements of the second array.
int max = 0;
int n = 9; // n will probably be the size of your arrays
for (int i = 0; i <= n; i++)
{
int times_condition_met = 0;
for (int j = 0; j <= n; j++)
{
if ( condition == true ) // Checking a condition/making a comparison.
{
times_condition_met++; // Increment the number of times the condition is met.
}
}
if (times_condition_met > max)
{
// Update the max and other information you're interested in.
// I.e. this is where you want to save the information regarding
// the index of your circles.
}
}
Essentially, I believe your task is requiring you two keep track of some sort of statistic while doing the comparisons between your two arrays. In order to do so, you have to add some extra code into the nested-for loops that does this tracking.
I was trying to make a knights tour problem solution and i have just made it. Now i want to improve it.It takes the starting value and then outputs the step by step instructions to move (in command line output).
Now the technique which i have used is that firstly i have divided the board into 4 blocks according to the solution given in a video
(here www.youtube.com%2Fwatch%3Fv%3DdWM5pKYZCHw&b=28) and also divided the whole board into 4 systems of boxes.
In the solution i have to do do lots of backtracking to decide between two different possibilities which greatly reduces the speed.Is there any way to do less or no backtracking to decide between two possibilities. And any other suggestion to improve the technique.
Here is a part of the code (a function which moves the knight across the board)
void move(int l[8][8][2],int g, int e) // g and e are the required systems and blocks respectively
{
backtracking(backtrackarray, l); // calling function to backtrack the array
backtracking(secondbacktrackarray,l); againcalling function to backtrack array in different array
int system = currentsystem(l, currentposition[0], currentposition[1]); //storing the current system
for (int i = 0; i < 3; i++)
{
nextmove(l, currentposition[0], currentposition[1]); //moving knight
}
if (blockshiftpossible(l, system, currentposition[0], currentposition[1])!= 1) // checks if next block shift possible
{
backimage(l, backtrackarray); getting back the stored image
for (int i = 0; i < 3; i++)
{
reversenextmove(l, currentposition[0], currentposition[1]); // moving in the opposite way
}
}
if ((systemshiftpossible(l, currentposition[0], currentposition[1])!= 1) && (g==4) && (e==4)) // checking if system shift is possible
{
backimage(l,secondbacktrackarray); // getting again image from second backtrack array
for (int i = 0; i < 3; i++)
{
reversenextmove(l, currentposition[0], currentposition[1]); // moving in opposite direction
}
if (systemshiftpossible(l, currentposition[0], currentposition[1])!= 1)
{
for (int i = 0; i < 3; i++)
{
nextmove(l, currentposition[0], currentposition[1]);
}
}
}
if ((blockshiftpossible(l, system, currentposition[0], currentposition[1])
== 1) && (g!=4))
{
blockshift(l, currentposition[0], currentposition[1]);
}
else
{
cout << "logical error"<<endl;
}
}
To see the details of this technique check my previous question
Solving knight tour with c++
Also how i can change it to get solutions for n*n puzzles if possible.
I have a "raffle" C++ program that I use to "draw out of a hat". I receive an EXC_BAD_ACCESS signal when I try to use it, though. Here is the function:
vector<int> speedRaffle(vector<Player>players,int pNum){
vector<int> spdtics,order;
int ticnum,randy;
vector<int>::iterator iter = spdtics.begin();
for (int k=0;k<pNum;k++){
for (int i=0; i<pNum; i++) {
for (int j=0; j<pow(players[i].speed,2); j++){
for (int io=0; io<order.size(); io++) {
if(order[io]!=i){
spdtics.push_back(i);
ticnum++;
}
}
}
}
randy=random() % ticnum;
for(int i=0;i<randy;i++){
iter++;
}
order[k]=*iter; //Thread 1: Program received signal: "EXC_BAD_ACCESS".
iter=spdtics.begin();
}
return order;
}
This function should take all of the players' speeds and square them. Then, it puts that many (the squares of speeds) "raffle tickets" into spdtics. It then randomly draws one "ticket" from spdtics, and puts the number of the player who owned the ticket into order. Then, it repeats again until all players have been drawn, not drawing the same player twice. It returns the order in which the players won.
The class Player contains an int speed. I call this function like this:
order=speedRaffle(players,pNum);
where players is vector and pNum is int. What am I doing wrong?
1. You are trying to access element at index k in empty vector order
It crashes because vector order is empty when you call order[k] = *iter;, you should use push_back function instead: order.push_back(*iter);.
2. You use loop for "moving" iterator instead of simple advance call
advance(iter, randy - 1); has same effect as this loop: for(int i=0;i<randy;i++){ iter++; }.
3. You call pow in every single iteration
for (int j=0; j<pow(players[i].speed,2); j++)
Note, that this would be much faster:
int maxspeed = pow(players[i].speed,2);
for (int j = 0; j < maxspeed; j++)
4. Elements in vector can be accessed directly by using index
You don't need any iterator at all in this case.
5. Passing vector by value instead of passing it by reference
vector<int> speedRaffle(vector<Player>players,int pNum)
Note, that copy of vector players is created every time you call this function. You don't want to do that. You also don't want to change this vector inside of function, so declaring this argument as const would be much better:
vector<int> speedRaffle(const vector<Player>& players, int pNum)
6. Your code does not do what you need it to do
"It should take all of the players' speeds and square them. Then, it puts that many (the squares of speeds) "raffle tickets" into spdtics. It then randomly draws one "ticket" from spdtics, and puts the number of the player who owned the ticket into order. Then, it repeats again until all players have been drawn, not drawing the same player twice. It returns the order in which the players won."
According to this, your function should look like this:
vector<int> speedRaffle(vector<Player>& players)
{
// create vector of tickets:
set<int> ticketOwners;
vector<int> spdtics;
for (int i = 0; i < players.size(); i++)
{
ticketOwners.insert(i);
int maxspeed = pow(players[i].speed,2);
for (int j = 0; j < maxspeed; j++)
{
spdtics.push_back(i);
}
}
// draw ticket for every player:
vector<int> order;
while (!ticketOwners.empty())
{
set<int>::const_iterator to;
int randy;
do
{
randy = random() % spdtics.size();
to = ticketOwners.find(spdtics[randy]);
}
while (to == ticketOwners.end());
spdtics.erase(spdtics.begin() + randy);
order.push_back(*to);
ticketOwners.erase(to);
}
return order;
}
Also note that you don't need pNum argument if it's equal to players.size().
Hope this will help you.