I've been trying to solve the N queen problem using backtracking. Most of the approaches that I found online, involved vectors, making it difficult for me to visualize the solutions as some applets on the Internet do.
The solution I came up with, is giving me many problems(which i have a feeling are related to indexing of the dynamic 2D array used) and I'm not able to figure it out using Dev-C++ debugger.Any help and/or constructive criticism is highly appreciated. Many thanks in advance.
Here is the solution that i came up with:
#include<iostream>
#include<string.h>
#include<conio.h>
using namespace std;
void display(char** b, int len);
void initialize(char** &b, int k);
void consider1strow(char ** b, int len);
void markunsafe(char** board, int rowno, int colno);
void marksafe(char** board, int rowno, int colno);
void considerrow(char** board, int rowno);
void backtrack(char** board, int rowno);
bool checksafety(char** board, int rowno, int colno);
void place(char** board, int rowno, int colno);
void solve(char** board, int len);
int state[20] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
int len;
void display(char** board, int len)
{
int i, j;
cout << endl << "The current state of the board:" << endl;
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
cout << board[i][j];
}
cout << endl;
}
}
void initialize(char** &b, int k)
{
int i, j;
//create dynamic board
b = new char*[k];
for (i = 0; i < k; i++)
{
b[i] = new char[k];
}
//initialize array
for (i = 0; i < k; i++)
{
for (j = 0; j < k; j++)
{
b[i][j] = '-';
}
}
}
void consider1strow(char ** board, int len)
{
int col;
cout << "Enter the column to try for the first row!";
cin >> col;
board[0][col - 1] = 'Q';
state[0] = col - 1;
markunsafe(board, 0, col - 1);
display(board, len);
}
void markunsafe(char** board, int rowno, int colno)
{
int i, j;
//mark row as unsafe
for (i = 0; i < len; i++)
{
board[rowno][i] = 'x';
}
//mark column as unsafe
for (i = 0; i < len; i++)
{
board[i][colno] = 'x';
}
//mark unsafe diagonals
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
if ((rowno + colno) == (i + j))
{
board[i][j] = 'x'; //check if index gives a problem of +/- 1
}
if ((rowno - colno) == (i - j))
{
board[i][j] = 'x'; //check if index gives a problem of +/- 1
}
}
}
board[rowno][colno] = 'Q';
}
void marksafe(char** board, int rowno, int colno)
{
int i, j;
//mark row as safe
for (i = 0; i < len; i++)
{
board[rowno][i] = '-';
}
//mark column as unsafe
for (i = 0; i < len; i++)
{
board[i][colno] = '-';
}
//mark unsafe diagonals
for (i = 0; i < len; i++)
{
for (j = 0; j < len; j++)
{
if ((rowno + colno) == (i + j))
{
board[i][j] = '-'; //check if index gives a problem of +/- 1
}
if ((rowno - colno) == (i - j))
{
board[i][j] = '-'; //check if index gives a problem of +/- 1
}
}
}
}
void considerrow(char** board, int rowno)
{
bool safe = 0;
int i;
for (i = 0; i < len; i++)
{
safe = checksafety(board, rowno, i);
if (safe && (i >= state[rowno]))
{
break;
}
}
if (safe && (i >= state[rowno]))
{
place(board, rowno, i);
}
else if (!safe)
{
backtrack(board, rowno);
}
}
void backtrack(char** board, int rowno)
{
marksafe(board, rowno - 2, state[rowno - 2]);
considerrow(board, rowno);
}
bool checksafety(char** board, int rowno, int colno)
{
if (rowno == 0)
{
return 1;
}
else if (board[rowno][colno] == 'x')
{
return 0;
}
else if (board[rowno][colno] == '-')
{
return 1;
}
}
void place(char** board, int rowno, int colno)
{
board[rowno][colno] = 'Q';
state[rowno] = colno;
markunsafe(board, rowno, colno);
}
void solve(char** board, int len)
{
int i = 0;
if (i == len)
{
display(board, len);
}
else
{
consider1strow(board, len);
for (i = 1; i < len; i++)
{
considerrow(board, i);
}
}
}
int main()
{
char** board;
cout << "Enter the size of the board!";
cin >> len;
initialize(board, len);
solve(board, len);
getch();
}
It is running after the initial configuration, but you're not printing it. Change this (inside solve):
for(i=1;i<len;i++)
{considerrow(board,i);}
for this:
for(i=1; i<len; i++) {
considerrow(board,i);
display(board,len);
}
Besides that, there is a problem with the way you are doing backtracking. If no options are available, you are removing the queen from the previous row (that's ok) and then you are marking every cell it was attacking as safe (not ok). The problem is that some of these cells may be under attack by a different queen, so you cannot mark them as safe. Furthermore, you do not place a different queen on that row. I propose some solutions:
First, make it recursive: considerrow would call itself with the following row, and return true (1) if it succeeds or false (0) if it fails. If it fails with the next row, you can use the next queen in the current row and call considerrow again, until you succeed or run out of columns, in which case you return false.
To consider a different queen on a certain row, you can do two things: create a copy of the board which you would pass to considerrow for the next row (and thus keeping a 'before' copy to try a different queen), or mark every cell as safe, and then check all the existing queens to mark cells unsafe.
Edit:
To make it recursive, we are going to make considerrow call itself with the next value.
bool considerrow(char** board,int rowno) {
//Print the board
display(board,len);
bool safe=0;
int i;
for(i=0; i<len; i++) {
safe=checksafety(board,rowno,i);
if(safe) {
place(board,rowno,i);
//Is this the last row? If so, we suceeded
if (rowno==len-1) return 1;
//Call itself with next row, check if suceeded
if (considerrow(board,rowno+1))
return 1;
else //Failed, try a different row
backtrack(board,rowno);
}
}
return 0; //If we got here, then we ran out of colums. Return failure
}
The backtrack function can be modified to revert the current row like this:
void backtrack(char** board, int rowno) {
//Clear the current row
marksafe(board,rowno,state[rowno]);
//Check that every cell attacked by another queen is marked unsafe
for(int i=0; i<rowno; i++) markunsafe(board,i,state[i]);
}
Doing that, solve will only need to call the first row:
void solve(char** board,int len) {
considerrow(board,0);
display(board,len);
}
Related
I was having a go at the standard N-Queens problem for an upcoming interview.
I have tried to dry run my code and it seems to work fine. I can't spot the error in my code.
I am traversing it column by column, and using backtracking to recur back from an incorrect path.
Can anyone help me with why this doesn't give me the desired output (details below)?
Here's the problem statement
#include<bits/stdc++.h>
using namespace std;
void solve(vector<vector<int>> &ans, vector<int> &curr, int col, int n){
if(col==n){
ans.push_back(curr);
return;
}
bool flag=false;
for(int row=0; row<n; row++){
if(col==0){
curr.push_back(row);
solve(ans, curr, col+1, n);
curr.pop_back();
}
else{
for(int i=0; i<curr.size(); i++){
if((curr[i] == row) || (abs(row-curr[i]) == (col-i))){
flag=true;
break;
}
}
if(flag)
continue;
curr.push_back(row);
solve(ans, curr, col+1, n);
curr.pop_back();
}
}
}
int main()
{
int t;
cin>>t;
while(t--){
int n;
cin>>n;
vector<vector<int>> ans;
vector<int> curr;
solve(ans, curr, 0, n);
for (int i = 0; i < ans.size(); i++) {
cout << "[";
for (int j = 0; j < ans[i].size(); j++)
cout << ans[i][j]+1 << " ";
cout << "]";
}
cout << endl;
}
return 0;
}
A sample input would look like:
2
1
4
and the corresponding output would be:
[1 ]
[2 4 1 3 ] [3 1 4 2 ]
The compiler gives me an output (for my code):
[1 ]
The bool flag variable (used to check if placing a queen at (row, col) would intersect with any existing queens in curr) is currently being re-used across rows.
So, if you place the line bool flag=false; just above for(int i=0; i<curr.size(); i++){, it should produce the correct output for your test case.
Other notes:
It might be easier to create a separate function bool does_intersect(const vector<int>& cur, int row, int col) to check the queen intersection condition so that the bool flag variable isn't needed.
The if(col==0){ condition can be removed since it doesn't do anything that the else part cannot already handle.
This solution passes LeetCode's online judge for N Queens problem, and uses three flags to solve the problem:
#include <string>
#include <vector>
class Solution {
public:
std::vector<std::vector<std::string>> solveNQueens(int n) {
std::vector<std::vector<std::string>> possibilities;
std::vector<std::string> n_queens(n, std::string(n, '.'));
std::vector<int> flag_col(n, 1);
std::vector<int> flag_diag_a(2 * n - 1, 1);
std::vector<int> flag_diag_b(2 * n - 1, 1);
solveNQueens(possibilities, n_queens, flag_col, flag_diag_a, flag_diag_b, 0, n);
return possibilities;
}
private:
void solveNQueens(std::vector<std::vector<std::string>>& possibilities,
std::vector<std::string>& n_queens,
std::vector<int>& flag_col, std::vector<int>& flag_diag_a, std::vector<int>& flag_diag_b,
int row, int& n) {
if (row == n) {
possibilities.push_back(n_queens);
return;
}
for (int col = 0; col != n; col++) {
if (flag_col[col] && flag_diag_a[row + col] && flag_diag_b[n - 1 + col - row]) {
flag_col[col] = flag_diag_a[row + col] = flag_diag_b[n - 1 + col - row] = 0;
n_queens[row][col] = 'Q';
solveNQueens(possibilities, n_queens, flag_col, flag_diag_a, flag_diag_b, row + 1, n);
n_queens[row][col] = '.';
flag_col[col] = flag_diag_a[row + col] = flag_diag_b[n - 1 + col - row] = 1;
}
}
}
};
For interview, you should not probably use:
#include<bits/stdc++.h>
using namespace std;
and make sure to write clean codes.
N Queens is a low frequency interview question. There are much better questions to be asked in the interviews (such as Number of Islands), probably you would not get N Queens. But, it's good to practice.
This is a pretty simple way to solve the problem of the N-Queens using backtracking:
#include <bits/stdc++.h>
using namespace std;
int m[20][20];
bool ended = false;
void print(int n){
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cout<<(m[i][j] == -1? "O" : "-")<<" ";
}
cout<<endl;
}
}
void fill(int val, int row, int col, int n){
int d = 1;
for(int i = col + 1; i < n; i++, d++){
m[row][i] += val;
if(row - d >= 0) m[row - d][i] += val;
if(row + d < n) m[row + d][i] += val;
}
}
void solve(int n, int col = 0){
if(ended) return;
if(col == n){ print(n); ended = true; return; }
for(int i = 0; i < n; i++){
if(m[i][col] == 0){
m[i][col] = -1;
fill(1, i, col, n);
solve(n, col + 1);
m[i][col] = 0;
fill(-1, i, col, n);
}
}
}
int main(){
memset(m, 0, sizeof(m));
solve(8); //dimension of board
return 0;
}
The idea is to always look forward. Place a queen in a slot that is 0 in the matrix. After that, add 1 in all slots where she can move to. When you return from the backtracking, subtract 1 from the same slots you just added and continue trying.
Pointers are still a little confusing to me. I want the split function to copy negative elements of an array into a new array, and positive elements to be copied into another new array. A different function prints the variables. I've included that function but I don't think it is the problem. When the arrays are printed, all elements are 0:
Enter number of elements: 5
Enter list:1 -1 2 -2 3
Negative elements:
0 0
Non-Negative elements:
0 0 0
I assume that the problem is that in the split function below i need to pass the parameters differently. I've tried using '*' and '**' (no quotes) for passing the parameters but I get error messages, I may have done so incorrectly.
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
alpha[i] = bravo[a];
++a;
}
else {
alpha[i] = charlie[b];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
my main function (all arrays are required to be pointers):
int num_elements;
cin >> num_elements;
int * arr1 = new int[num_elements];
int x;
cout << "Enter list:";
for (int i = 0; i < num_elements; ++i) {
cin >> x;
arr1[i] = x;
}
int y = 0;
int z = 0;
count(arr1, num_elements, y, z);
int * negs = new int [y];
int * nonNegs = new int[z];
split(arr1, negs, nonNegs, num_elements, y, z);
cout << "Negative elements:" << endl;
print_array(negs, y);
cout << endl;
cout << "Non-Negative elements:" << endl;
print_array(nonNegs, z);
cout << endl;
All functions:
void count(int A[], int size, int & negatives, int & nonNegatives) {
for (int i = 0; i < size; ++i) {
if (A[i] < 0) {
++negatives;
}
if (A[i] >= 0) {
++nonNegatives;
}
}
}
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
alpha[i] = bravo[a];
++a;
}
else {
alpha[i] = charlie[b];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
void print_array(int A[], int size) {
for (int i = 0; i < size; ++i) {
cout << A[i] << " ";
}
}
All help is appreciated.
EDIT: I apologize for my unclear question, I was wondering how to get my arrays to behave as I want them to.
Array is behaving correctly as per instruction :), you are doing minor mistake (may be overlook) in split function. I have commented out the statement and given reason of problem, please correct those two line of code, rest is fine.
void split(int alpha[], int bravo[], int charlie[], int aSize, int bSize, int cSize) {
int a = 0;
int b = 0;
for (int i = 0; i < aSize; ++i) {
if (alpha[i] < 0) {
//alpha[i] = bravo[a];// here alpha is your source array, don't overwrite it
bravo[a] = alpha[i];
++a;
}
else {
//alpha[i] = charlie[b];// here alpha is your source array, don't overwrite it
charlie[b] = alpha[i];
++b;
}
}
if (a + b != aSize) {
cout << "SOMETHING HAS GONE HORRIBLY WRONG!";
exit(0);
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm am trying to dynamically make 2d arrays that are then supposed to be iterated through to check their contents. Whenever I try to use a function that indexes the array I get a segmentation fault. The two functions that are creating the problems are the printg() and get() functions. I'm not sure exactly what I'm doing wrong, but neither of them will work properly for me.
Any help would be great. Thank you.
#ifndef _GRID_H
#define _GRID_H
#include <iostream>
using namespace std;
class Grid
{
public:
Grid();
Grid(const Grid& g2);
Grid(int x, int y, double density);
Grid(string file);
~Grid();
bool check(int x, int y); //check if a cell is inhabited or not
bool isEmpty();//check if a grid is living
bool equals(const Grid& g2);//checks if two grids are equal
void kill(int x, int y);//kill a cell
void grow(int x, int y);//grow a cell
int getSize();
int getNumRows();
int getNumCol();
int getNumLiving();
void printg(int r, int c);
char get(int x, int y) const;
private:
int size; //number of cells in grid
int row; //row length (number of columns)
int column; //column length (number of rows)
int num_living; //number of X's in the grid
char** myGrid;
};
#endif
#include "Grid.h"
#ifndef _GRID_C
#define _GRID_C
#include <iostream>
#include <cmath>
#include <fstream>
#include <cstdlib>
//compile with g++ -I /home/cpsc350/GameOfLife Grid.cpp
using namespace std;
Grid::Grid() //do i need a default constructor????
{
char myGrid[10][10] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};
row = 10;
column = 10;
size = 100;
}
Grid::Grid(const Grid& g2)//copy constructor/////////////help
{
size = g2.size;
row = g2.row;
column = g2.column;
num_living = g2.num_living;
char** myGrid = new char*[row];
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int i1 = 0; i1 < row; i1++)
{
for(int i2 = 0; i2 < column; i2++)
{
//copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
myGrid[i1][i2] = g2.get(i1,i2);
}
}
}
Grid::Grid(int x, int y, double density)
{
char** myGrid = new char*[x];
for(int i = 0; i < x; i++)
myGrid[i] = new char[y];
row = x;
column = y;
size = x*y;
num_living = size * density;
string str = "";
for(int a = 0; a < num_living; a++)//adds the density of X's to a string
{
str += 'X';
}
for(int a = 0; a < size - num_living; a++)//adds the rest to the string
{
str += '-';
}
int randnum;
//randomly generates indicies in the string str and puts them into the array
for(int i1 = 0; i1 < column; i1++)
{
for(int i2 = 0; i2 < row; i2++)
{
//generate random numbers from index 0 to length of string - 1
if(str.length()>1)
{
randnum = (rand()%(str.length()-1))+1;
}
else
{
randnum = 0;
}
myGrid[i1][i2] = str[randnum];
str.erase(randnum);
}
}
}
Grid::Grid(string file)
{
num_living = 0;
//code to create a 2d array from a filepath
ifstream openfile(file);
//error handling
if(! openfile)
{
cout << "Error, file could not be opened" << endl;
exit(0);
}
openfile >> column;//gets number of rows
openfile >> row;//gets number of columns
size = row*column;
char** myGrid = new char*[row];
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int x = 0; x<column; x++)
{
for(int y = 0; y<row; y++)
{
openfile >> myGrid[x][y];
if(! openfile)//error handling
{
cout << "Error reading file at " << row << "," << column << endl;
}
if(myGrid[x][y] == 'X')
{
num_living++;
}
}
}
openfile.close();
}
Grid::~Grid()
{
if(myGrid)
{
for(int i = 0; i < row; i++)
{
delete []myGrid[i];
}
delete []myGrid;
}
}
void Grid::kill(int x, int y)
{
if(myGrid[x][y] == 'X')
{
num_living--;
}
myGrid[x][y] = '-';
}
void Grid::grow(int x, int y)
{
if(myGrid[x][y] == '-')
{
num_living++;
}
myGrid[x][y] = 'X';
}
bool Grid::check(int x, int y)
{
if(y<0 || x<0)
{
return(false);
}
return (myGrid[x][y] == 'X');
}
bool Grid::isEmpty()
{
return (num_living == 0);
}
bool Grid::equals(const Grid& g2)
{
if(size != g2.size) //checks if sizes are equal
{
return false;
}
if(row != g2.row)//checks if numRows are equal
{
return false;
}
if(column != g2.column)//checks if numCol are equal
{
return false;
}
if(num_living != g2.num_living)//checks if numliving are equal
{
return false;
}
for(int x = 0; x < row; x++)//checks each element
{
for(int y = 0; y < column; y++)
{
if(myGrid[x][y] != g2.get(x,y))
{
return false;
}
}
}
return true;
}
int Grid::getSize()
{
return(size);
}
int Grid::getNumRows()
{
return(column);
}
int Grid::getNumCol()
{
return(row);
}
int Grid::getNumLiving()
{
return(num_living);
}
void Grid::printg(int r, int c)
{
for(int x = 0; x < r; x++)
{
for(int y = 0; y < c; y++)
{
cout << myGrid[x][y];
}
cout << endl;
}
}
char Grid::get(int x, int y) const
{
return myGrid[x][y];
}
#endif
The problem that I see at first is that both your default and copy constructor do not initialize myGrid. what you are doing in them will create an additional array with the same name which 'shadows' myGrid. instead you have to do:
Grid::Grid(const Grid& g2)
{
size = g2.size;
row = g2.row;
column = g2.column;
num_living = g2.num_living;
myGrid = new char*[row]; // removed "char**" at the start of this line
for(int i = 0; i < row; i++)
myGrid[i] = new char[column];
for(int i1 = 0; i1 < row; i1++)
{
for(int i2 = 0; i2 < column; i2++)
{
//copy(&g2[i1][i2], &g2[i1][i2]+row*column,&myGrid[i1][i2]);
myGrid[i1][i2] = g2.get(i1,i2);
}
}
}
your default constructor has the same problem. but note that you can't initialize it with braces. but you don't have to have a default constructor if you are not using it.
I'm working on a coding assignment for a C++ class. When I run my program I seem to be dealing with a memory leakage issue, which is weird since I am NOT explicitly allocating any memory in my code. I ran the program under gdb, and it seems as though the program crashes when running the destructor for a Deck object. I tried stepping through the code, but I when I do so I end up in a host of .h files related to vectors. Then suddenly, it stops. I tried going to a TA for some help, but they seem to be as perplexed as I am on the issue.
# include <stdlib.h>
# include <time.h>
# include <iostream>
# include <vector>
# include <stdio.h>
using namespace std;
//function signatures
float bustProbability (const int);
class Deck
{
public:
//data members
vector <int> cardArray;
vector <int> wasteCards;
//constructor
Deck();
//methods
void shuffleDeck();
void populateDeckWithCards();
void removeCopyCards();
int dealCard();
int remainingCards();
void showCards();
};
void Deck::removeCopyCards() {
for (unsigned int i = 0; i < wasteCards.size(); i++) {
bool removedCopy = false;
for (unsigned int j = 0; j < cardArray.size() && removedCopy == false; j++) {
if (cardArray[j] == wasteCards[i]) {
cardArray.erase (cardArray.begin() + j - 1);
removedCopy = true;
}
}
}
}
int Deck::dealCard() {
if (remainingCards() > 0) {
int tmp = cardArray.back();
wasteCards.push_back(tmp);
cardArray.pop_back();
return tmp;
}
else {
populateDeckWithCards();
removeCopyCards();
shuffleDeck();
//shuffle method
int tmp = cardArray.back();
cardArray.pop_back();
return tmp;
}
}
void Deck::populateDeckWithCards() {
//populate regular cards into array
for (int i = 2; i <= 10; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(i);
}
}
//populate J, Q, K into array
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cardArray.push_back(10);
}
}
//populating array with Aces... treating them as special case '100'
for (int i = 0; i < 4; i++) {
cardArray.push_back(100);
}
return;
}
void Deck::showCards() {
for (unsigned int i = 0; i < cardArray.size(); i++) {
cout << cardArray[i] << endl;
}
}
Deck::Deck() {
wasteCards.clear();
cardArray.clear();
populateDeckWithCards();
shuffleDeck();
}
void Deck::shuffleDeck() {
int n = cardArray.size();
for(int a = n-1; a > 0; a--) {
int min = 0;
int max = a;
int j = min + rand() / (RAND_MAX / (max-min + 1) + 1);
int tmp = cardArray[a];
cardArray[a] = cardArray[j];
cardArray[j] = tmp;
}
return;
}
int Deck::remainingCards() {
return cardArray.size();
}
class Player {
public:
//data members
vector <int> playerHand;
//constructor
Player();
//methods
bool isBust();
int count();
void hit(Deck&);
void stand();
bool muckHand();
void showHand();
};
Player::Player() {
playerHand.clear();
}
void Player::showHand() {
for (unsigned int i = 0; i < playerHand.size(); i++) {
cout << playerHand[i] << endl;
}
return;
}
int Player::count() {
int handCount = 0;
for (unsigned int i = 0; i < playerHand.size(); i++) {
if (playerHand[i] != 100)
handCount += playerHand[i];
else {
if (playerHand[i] == 100) {
if ((handCount) > 11) {
handCount += 1;
}
else
handCount += 10;
}
}
}
return handCount;
}
bool Player::isBust() {
if (count() > 21)
return true;
else
return false;
}
void Player::hit(Deck& d) {
playerHand.push_back(d.dealCard());
}
void Player::stand() {
return;
}
bool Player::muckHand() {
playerHand.clear();
return true;
}
float bustProbability (const int threshHold) {
int threshHoldReached = 0;
Deck myDeck;
Player myPlayer;
Player dealer;
for (int i = 0; i < 10000; i++) {
myPlayer.hit(myDeck);
dealer.hit(myDeck);
myPlayer.hit(myDeck);
dealer.hit(myDeck);
while (myPlayer.count() < threshHold) {
myPlayer.hit(myDeck);
}
if (!(myPlayer.isBust())) {
++threshHoldReached;
}
myDeck.wasteCards.clear();
myPlayer.muckHand();
dealer.muckHand();
}
float bustFraction = float(threshHoldReached)/float(10000);
return bustFraction;
}
int main () {
cout << "blackjack simulation" << endl;
srand((unsigned int)time(NULL));
cout << bustProbability(19);
return 0;
}
I'm incredibly sorry for just posting my code, but I've spend 4 days on this issue, and I can't even begin to figure out what the problem is.
There is at least the line
cardArray.erase (cardArray.begin() + j - 1);
which seems to be dubious in case of j = 0
Here is my code:
#include<iostream>
private int chessBoard[8][8];
void printBoard(int board[][])
{
for(int i=0; i<8; i++)
{
for(int j=0; j<8; j++)
{
if(board[i][j])
{
cout<<"Q ";
}
else
{
cout<<"* ";
}
}
cout<<endl;
}
}
//This method will check if any queens are in attacking position to the left of the test queen placement
bool checkSpot(int board[][],int row, int col)
{
bool safe = true;
//checks the current row for queens
for(int i=0; i<col, i++)
{
if(board[row][i])
safe=false;
{
//checks the upper diag
for( int i=row, int j=col; i>0 && j>0; i--, j--)
{
if(board[i][j])
safe=false;
}
//checks lower diag
for(int i = row, int j=col; i<8 && j>0; i--, j++)
{
if(board[i][j])
safe=false;
}
if(safe)
{
return true;
}
else
return false;
}
bool solve(int board[][], int testCol)
{
bool solved = false;
bool safe;
if(testCol==8)
{
solved = true;
return solved;
}
for(int i =0; i>8; i++)
{
// test if the tested column(testCol) and the row(i) are both safe for the queen to be placed at then we can move into placing said queen and more onto the next column for
// more solutions in this same method recursivly
safe = checkSpot(board, i, testCol);
if(safe)
{
//place the queen
board[i][col]=1;
//recursion to go back through this method in the next column
if(solve(board[][], testCol+1)
{
solved = true;
printBoard(board)
return solved;
}
else
{
//if the queen cannot be placed, we have to remove the previous queens and move them until a solution is found.
board[i][testCol]=0;
}
}
}
int main()
{
solve(chessBoard, 0);
}
There errors i continue to get are as follows:
8queens.cpp:3:17: error: variable or field ‘printBoard’ declared void
void printBoard(board[][])
^
8queens.cpp:3:17: error: ‘board’ was not declared in this scope
8queens.cpp:3:23: error: expected primary-expression before ‘]’ token
void printBoard(board[][])
^
8queens.cpp:3:25: error: expected primary-expression before ‘]’ token
void printBoard(board[][])
The logic of this was pretty simple(at least i hope it works well) but i cant even get past the compiler. Can I get a little guidance on this problem?
You were all a huge help, but sadly i found out that I can only use 1d arrays for this problem so I had to start from scratch. Again thank you all for the help, your advice will definitely help me in the future.
Well, there are many errors in your code. Lets look at them.
First of all, remove that private from
private int chessBoard[8][8];
you need to use private only on the members of classes . So change it to
int chessBoard[8][8];
Next, in all your functions, you have something like
void printBoard(int board[][])
^
here, it's wrong
You need to provide the size, you can only skip the first size, all the rest must be provided so better to change it to
void printBoard(int board[][8])
^
it's okay to leave this one
make that change to all of your functions.
You are also missing a few } in some places of your code.
Nearly forgot, you need to either add a
using namespace std;
right after the headers, or use
std::cin
std::cout
and
std::endl
instead of cin , cout and endl .
You also have
for(int i=0; i<col, i++)
^
you need a semicolon here
And also
for( int i=row, int j=col; i>0 && j>0; i--, j--)
^
no need for another int here
just change that to
for( int i=row, j=col; i>0 && j>0; i--, j--)
This compiles. As to what I did, there was a lot and it would take awhile to write each thing down. One major thing to pay attention to is the for loops.
You have:
for( int i=row, int j=col; i>0 && j>0; i--, j--)
{
if(board[i][j])
safe=false;
}
When you want to do a nested for loop, do this:
for (int i = row; i > 0; i--)
{
for (int j = col; j > 0; j--)
{
if (board[i][j])
safe = false;
}
}
Also, pay attention to your brackets {} () as they were inconsistent and some were missing.
For arrays, you must specify at least one dimension when using a 2d array.
You had: int board[][] in various places. You must have: int board[][8] instead.
Also, if you want to use cout, endl, cin, etc... You must have include namespace std; otherwise you will have to use: std::cout, std::endl, std::cin.
But anyway, this should compile now.
#include<iostream>
using namespace std;
int chessBoard[8][8];
void printBoard(int board[][8])
{
for (int i = 0; i<8; i++)
{
for (int j = 0; j<8; j++)
{
if (board[i][j])
{
cout << "Q ";
}
else
{
cout << "* ";
}
}
cout << endl;
}
}
//This method will check if any queens are in attacking position to the left of the test queen placement
bool checkSpot(int board[][8], int row, int col)
{
bool safe = true;
//checks the current row for queens
for (int i = 0; i < col; i++)
{
if (board[row][i])
safe = false;
{
//checks the upper diag
for (int i = row; i > 0; i--)
{
for (int j = col; j > 0; j--)
{
if (board[i][j])
safe = false;
}
}
//checks lower diag
for (int i = row; i < 8; i--)
{
for (int j = col; j > 0; j++)
{
if (board[i][j])
safe = false;
}
}
if (safe)
{
return true;
}
else
return false;
}
}
}
bool solve(int board[][8], int testCol)
{
bool solved = false;
bool safe;
if (testCol == 8)
{
solved = true;
return solved;
}
for (int i = 0; i > 8; i++)
{
// test if the tested column(testCol) and the row(i) are both safe for the queen to be placed at then we can move into placing said queen and more onto the next column for
// more solutions in this same method recursivly
safe = checkSpot(board, i, testCol);
if (safe)
{
//place the queen
board[i][testCol] = 1;
//recursion to go back through this method in the next column
if (solve(board, testCol + 1))
{
solved = true;
printBoard(board);
return solved;
}
else
{
//if the queen cannot be placed, we have to remove the previous queens and move them until a solution is found.
board[i][testCol] = 0;
}
}
}
}
int main()
{
solve(chessBoard, 0);
}