I have been having difficulty solving the N Queen problem, I am able to implement most of my functions, but the function that places the Queen recursively with backtracking. The placeQueens function is using a provided pseudocode that is required for the project. I had to create the array on the heap that is pointing to boardPtr, which is also required. I have a while loop condition that I have but I am not sure if it's correct. I have tried looking online for similar code but none of them were able to help me.
Here is my code:
#include <iostream>
#include "ChessBoard.h"
int main()
{
// Create a board
ChessBoard myBoard;
/* Loop through board sizes from 3 to 13.
Since 3 and 13 are invalid you should see
board sizes 4 and 12 twice. */
for (int i = 3; i <= 13; i++)
{
myBoard.setSize(i);
/* Attempt to solve the N-Queens Problem. If the solve
code is working it should find solutions for all
sizes. */
if (!myBoard.solve())
std::cout << "Sorry, no solution was found for board size "
<< myBoard.getSize() << "." << std::endl << std::endl;
else
{
std::cout << "Size " << myBoard.getSize()
<< " solution:" << std::endl;
myBoard.displayBoard();
std::cout << std::endl << std::endl;
}
}
return 0;
}
#include "ChessBoard.h"
#include <iostream>
using namespace std;
bool ChessBoard::placeQueens( int column)
{
int row = 0;
if (column >= boardSize)
{
// The board is filled, problem is solved.
return true;
}
else
{
while (row < boardSize && column < boardSize) // unconsidered rows exist in column
{
if ((canPlace(boardPtr, row, column)) == true) //[row][column] is unattacked
{
//Place a queen in the un - attacked square.
boardPtr[row][column] = 'Q';
//Do a recursive call to try and place queens in subsequent columns :
if (!placeQueens(column + 1))
{
//If we’re here, placement of the last queen resulted in a dead end; no solution could be found.Remove the last queen placed.
boardPtr[row][column] = '*';
//Move to next row so search can continue in next iteration.
row++;
}
else
{
// If we’re here, recursive calls were able to place queens in all columns to the right of column, the problem is solved.
return true;
}
}
else
{
//Square is attacked, move to next row.
row++;
}
}
//All rows have been considered in column without a successful queen placement.Backtrack by returning false.
return false;
}
}
bool ChessBoard::canPlace(char** boardPtr, int row, int column)
{
int i, j;
// Check row
for (i = 0; i < column; i++)
if (boardPtr[row][i] )
return false;
// Check upper diagonal
for (i = row, j = column; i >= 0 && j >= 0; i--, j--)
if (boardPtr[i][j])
return false;
// Check lower diagonal
for (i = row, j = column; j >= 0 && i < boardSize; i++, j--)
if (boardPtr[i][j] )
return false;
return true;
}
ChessBoard::ChessBoard()
{
boardSize = 8;
boardPtr = nullptr;
}
ChessBoard::ChessBoard(int size)
{
if (size < 4)
{
boardSize = 4;
}
else if (size > 12)
{
boardSize = 12;
}
}
ChessBoard::~ChessBoard()
{
}
int ChessBoard::setSize(int size)
{
delete[] boardPtr;
//Initialize array at size 4
if (size < 4)
{
boardSize = 4;
char** chessBoard = new char* [4];
for (int i = 0; i < 4; i++)
{
chessBoard[i] = new char[4];
}
// Point initialized ChessBoard to boardPtr
boardPtr = chessBoard;
// Fill ChessBoard with *
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
boardPtr[i][j] = '*';
}
}
}
//Initialize array at size 12
else if (size > 12)
{
boardSize = 12;
char** chessBoard = new char* [12];
for (int i = 0; i < size; i++)
{
chessBoard[i] = new char[12];
}
// Point initialized ChessBoard to boardPtr
boardPtr = chessBoard;
// Fill ChessBoard with *
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
boardPtr[i][j] = '*';
}
}
}
//Initialize array at given size
else
{
boardSize = size;
char** chessBoard = new char* [size];
for (int i = 0; i < size; i++)
{
chessBoard[i] = new char[size];
}
// Point initialized ChessBoard to boardPtr
boardPtr = chessBoard;
// Fill ChessBoard with *
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
boardPtr[i][j] = '*';
}
}
}
return 1;
}
int ChessBoard::getSize()
{
return boardSize;
}
bool ChessBoard::solve()
{
int column = 0;
if (placeQueens(column) == false)
{
return false;
}
else
{
return true;
}
}
void ChessBoard::displayBoard()
{
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
cout << boardPtr[i][j] << " ";
}
cout << endl;
}
}
#ifndef CHESSBOARD_H
#define CHESSBOARD_H
class ChessBoard
{
private:
char** boardPtr;
int boardSize;
bool placeQueens( int column);
bool canPlace(char** boardPtr, int row, int col);
public:
ChessBoard();
ChessBoard(int size);
~ChessBoard();
int setSize(int size);
int getSize();
bool solve();
void displayBoard();
};
#endif
Interesting task you have! I decided to implement my own code from scratch for solving N Queen problem. Actually I implemented it for any board size N, not just equal to 8.
I didn't fix bugs in your code, but instead implemented my own solution. Although it may be not the answer you want, still it would be a good thing from educational point of view. Hoping that there would be other answers later that are fixing bugs in your code, as you wished.
I made code very optimized, so it is not very simple from first side, but solves task very fast, using BackTracking, with several extra techniques of speeding it up.
After program finishes it prints to console all solutions in a nice form. Please scroll down below the code to see example of console output.
First program has some extra descriptive comments to show what's happenning in program.
Notice that I provided two codes below, first is simplified version, that is more easy to understand, so it is better from educational point of view. Second code is advanced one, it is more difficult, but solves task fast. Please look at first code if you want just to learn basics, and look at second code if you want to learn advanced techniques.
Simplified:
Try it online!
#include <iostream>
#include <vector>
#include <string>
void Output(std::vector<std::vector<bool>> & board, std::vector<std::string> & lines, bool last);
void Solve(std::vector<std::vector<bool>> & board, std::vector<std::string> & lines,
int N, int & num_sol, int cnt = 0, int start_i = 0, int start_j = 0, int depth = 0) {
if (cnt >= N) {
Output(board, lines, false);
// Increase number of solutions.
++num_sol;
return;
}
// Traverse whole board starting from last queen
for (int i = start_i; i < board.size(); ++i)
for (int j = i == start_i ? start_j : 0; j < board[i].size(); ++j) {
bool attacked = false;
// k-loop checks if position [i][j] is being attacked
for (int k = 0; k < (board.size() > board[i].size() ?
board.size() : board[i].size()); ++k)
if (
// Is there horizontal attack
k < board[i].size() && k != j && board[i][k] ||
// Is there vertical attack
k < board.size() && k != i && board[k][j] ||
// Is there main diagonal attack
k < board.size() && k != i && 0 <= j - i + k &&
j - i + k < board[i].size() && board[k][j - i + k] ||
// Is there secondary diagonal attack
k < board.size() && k != i && 0 <= j + i - k &&
j + i - k < board[i].size() && board[k][j + i - k]
) {
attacked = true;
break;
}
if (attacked)
continue;
// Position [i][j] is not under attack, hence placing a queen
board[i][j] = true;
// Recursive descend to place another queen
Solve(board, lines, N, num_sol, cnt + 1, i, j + 1, depth + 1);
// Backtrack, to delete previous queen
board[i][j] = false;
}
if (depth == 0)
Output(board, lines, true);
}
// Function of outputting solutions to console
void Output(std::vector<std::vector<bool>> & board, std::vector<std::string> & lines, bool last) {
if (1) {
if (!last) {
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[i].size(); ++j)
lines[i].push_back(board[i][j] ? 'Q' : '.');
lines[i] += "|";
}
}
if (lines.at(0).size() >= 70 || last && !lines.at(0).empty()) {
for (int i = 0; i < lines.size(); ++i)
std::cout << lines[i] << std::endl;
for (int j = 0; j < lines.at(0).size(); ++j)
std::cout << (lines.at(0)[j] == '|' ? '+' : '-');
std::cout << std::endl;
lines.clear();
lines.resize(board.size());
}
}
}
int main() {
// rows - number of rows in a board, cols - number of columns in a board
// N - number of queens to be placed
int const rows = 8, cols = 8, N = 8;
// Filling with empty values board [rows][cols]
std::vector<std::vector<bool>> board(rows, std::vector<bool>(cols));
std::vector<std::string> lines(rows);
// Answer, number of solutions
int num_sol = 0;
// Starting a backtracking
Solve(board, lines, N, num_sol);
// Outputting answer
std::cout << "Number of solutions: " << num_sol << std::endl;
}
Advanced:
Try it online!
#include <iostream>
#include <string>
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
enum { max_rows = 32, max_cols = 32, max_max_rows_cols = MAX(max_rows, max_cols) };
void Output(bool (& board)[max_rows][max_cols], std::string (& lines)[max_rows],
int rows, int cols, bool last);
void Solve(bool (& board)[max_rows][max_cols], std::string (& lines)[max_rows],
bool (& busy_cols)[max_cols], bool (& busy_diagA)[2 * max_max_rows_cols],
bool (& busy_diagB)[2 * max_max_rows_cols],
int rows, int cols, int N, int & num_sol, int cnt = 0, int start_i = 0, int depth = 0) {
if (cnt >= N) {
Output(board, lines, rows, cols, false);
++num_sol;
return;
}
int const max_rows_cols = MAX(rows, cols);
if (rows - start_i < N - cnt)
return;
int avail_cols[max_cols];
int avail_cols_cnt = 0;
for (int j = 0; j < cols; ++j)
if (!busy_cols[j]) {
avail_cols[avail_cols_cnt] = j;
++avail_cols_cnt;
}
if (avail_cols_cnt < N - cnt)
return;
for (int i = start_i; i < rows; ++i)
for (int jj = 0; jj < avail_cols_cnt; ++jj) {
int const j = avail_cols[jj];
if (busy_diagA[max_rows_cols + j - i] || busy_diagB[j + i])
continue;
board[i][j] = true;
busy_cols[j] = true;
busy_diagA[max_rows_cols + j - i] = true;
busy_diagB[j + i] = true;
Solve(board, lines, busy_cols, busy_diagA, busy_diagB,
rows, cols, N, num_sol, cnt + 1, i + 1, depth + 1);
board[i][j] = false;
busy_cols[j] = false;
busy_diagA[max_rows_cols + j - i] = false;
busy_diagB[j + i] = false;
}
if (depth == 0)
Output(board, lines, rows, cols, true);
}
void Output(bool (& board)[max_rows][max_cols], std::string (& lines)[max_rows],
int rows, int cols, bool last) {
if (1) {
if (!last) {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j)
lines[i].push_back(board[i][j] ? 'Q' : '.');
lines[i] += "|";
}
}
if (lines[0].size() >= 70 || last && !lines[0].empty()) {
for (int i = 0; i < rows; ++i)
std::cout << lines[i] << std::endl;
for (int j = 0; j < lines[0].size(); ++j)
std::cout << (lines[0][j] == '|' ? '+' : '-');
std::cout << std::endl;
for (int i = 0; i < rows; ++i)
lines[i].clear();
}
}
}
int main() {
int const rows = 8, cols = 8, N = 8;
bool board[max_rows][max_cols] = {};
std::string lines[max_rows] = {};
bool busy_cols[max_cols] = {};
bool busy_diagA[2 * max_max_rows_cols] = {};
bool busy_diagB[2 * max_max_rows_cols] = {};
int num_sol = 0;
Solve(board, lines, busy_cols, busy_diagA, busy_diagB, rows, cols, N, num_sol);
std::cout << "Number of solutions: " << num_sol << std::endl;
}
Output:
Q.......|Q.......|Q.......|Q.......|.Q......|.Q......|.Q......|.Q......|
....Q...|.....Q..|......Q.|......Q.|...Q....|....Q...|....Q...|.....Q..|
.......Q|.......Q|...Q....|....Q...|.....Q..|......Q.|......Q.|Q.......|
.....Q..|..Q.....|.....Q..|.......Q|.......Q|Q.......|...Q....|......Q.|
..Q.....|......Q.|.......Q|.Q......|..Q.....|..Q.....|Q.......|...Q....|
......Q.|...Q....|.Q......|...Q....|Q.......|.......Q|.......Q|.......Q|
.Q......|.Q......|....Q...|.....Q..|......Q.|.....Q..|.....Q..|..Q.....|
...Q....|....Q...|..Q.....|..Q.....|....Q...|...Q....|..Q.....|....Q...|
--------+--------+--------+--------+--------+--------+--------+--------+
.Q......|.Q......|.Q......|.Q......|..Q.....|..Q.....|..Q.....|..Q.....|
.....Q..|......Q.|......Q.|.......Q|Q.......|....Q...|....Q...|....Q...|
.......Q|..Q.....|....Q...|.....Q..|......Q.|.Q......|.Q......|......Q.|
..Q.....|.....Q..|.......Q|Q.......|....Q...|.......Q|.......Q|Q.......|
Q.......|.......Q|Q.......|..Q.....|.......Q|Q.......|.....Q..|...Q....|
...Q....|....Q...|...Q....|....Q...|.Q......|......Q.|...Q....|.Q......|
......Q.|Q.......|.....Q..|......Q.|...Q....|...Q....|......Q.|.......Q|
....Q...|...Q....|..Q.....|...Q....|.....Q..|.....Q..|Q.......|.....Q..|
--------+--------+--------+--------+--------+--------+--------+--------+
..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|
....Q...|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|
.......Q|.Q......|.Q......|.Q......|...Q....|...Q....|.......Q|.......Q|
...Q....|....Q...|......Q.|......Q.|Q.......|.Q......|Q.......|Q.......|
Q.......|.......Q|Q.......|....Q...|.......Q|.......Q|...Q....|....Q...|
......Q.|Q.......|...Q....|Q.......|....Q...|....Q...|......Q.|......Q.|
.Q......|......Q.|.......Q|.......Q|......Q.|......Q.|....Q...|.Q......|
.....Q..|...Q....|....Q...|...Q....|.Q......|Q.......|.Q......|...Q....|
--------+--------+--------+--------+--------+--------+--------+--------+
..Q.....|..Q.....|..Q.....|..Q.....|...Q....|...Q....|...Q....|...Q....|
.....Q..|......Q.|......Q.|.......Q|Q.......|Q.......|.Q......|.Q......|
.......Q|.Q......|.Q......|...Q....|....Q...|....Q...|....Q...|......Q.|
.Q......|.......Q|.......Q|......Q.|.......Q|.......Q|.......Q|..Q.....|
...Q....|....Q...|.....Q..|Q.......|.Q......|.....Q..|.....Q..|.....Q..|
Q.......|Q.......|...Q....|.....Q..|......Q.|..Q.....|Q.......|.......Q|
......Q.|...Q....|Q.......|.Q......|..Q.....|......Q.|..Q.....|Q.......|
....Q...|.....Q..|....Q...|....Q...|.....Q..|.Q......|......Q.|....Q...|
--------+--------+--------+--------+--------+--------+--------+--------+
...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|
.Q......|.Q......|.Q......|.Q......|.....Q..|.....Q..|.....Q..|......Q.|
......Q.|......Q.|.......Q|.......Q|Q.......|.......Q|.......Q|Q.......|
..Q.....|....Q...|....Q...|.....Q..|....Q...|.Q......|..Q.....|.......Q|
.....Q..|Q.......|......Q.|Q.......|.Q......|......Q.|Q.......|....Q...|
.......Q|.......Q|Q.......|..Q.....|.......Q|Q.......|......Q.|.Q......|
....Q...|.....Q..|..Q.....|....Q...|..Q.....|..Q.....|....Q...|.....Q..|
Q.......|..Q.....|.....Q..|......Q.|......Q.|....Q...|.Q......|..Q.....|
--------+--------+--------+--------+--------+--------+--------+--------+
...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|....Q...|....Q...|
......Q.|......Q.|......Q.|.......Q|.......Q|.......Q|Q.......|Q.......|
..Q.....|....Q...|....Q...|Q.......|Q.......|....Q...|...Q....|.......Q|
.......Q|.Q......|..Q.....|..Q.....|....Q...|..Q.....|.....Q..|...Q....|
.Q......|.....Q..|Q.......|.....Q..|......Q.|Q.......|.......Q|.Q......|
....Q...|Q.......|.....Q..|.Q......|.Q......|......Q.|.Q......|......Q.|
Q.......|..Q.....|.......Q|......Q.|.....Q..|.Q......|......Q.|..Q.....|
.....Q..|.......Q|.Q......|....Q...|..Q.....|.....Q..|..Q.....|.....Q..|
--------+--------+--------+--------+--------+--------+--------+--------+
....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|
Q.......|.Q......|.Q......|.Q......|.Q......|..Q.....|..Q.....|..Q.....|
.......Q|...Q....|...Q....|.....Q..|.......Q|Q.......|Q.......|.......Q|
.....Q..|.....Q..|......Q.|Q.......|Q.......|.....Q..|......Q.|...Q....|
..Q.....|.......Q|..Q.....|......Q.|...Q....|.......Q|.Q......|......Q.|
......Q.|..Q.....|.......Q|...Q....|......Q.|.Q......|.......Q|Q.......|
.Q......|Q.......|.....Q..|.......Q|..Q.....|...Q....|.....Q..|.....Q..|
...Q....|......Q.|Q.......|..Q.....|.....Q..|......Q.|...Q....|.Q......|
--------+--------+--------+--------+--------+--------+--------+--------+
....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|
......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|.......Q|.......Q|
Q.......|Q.......|.Q......|.Q......|.Q......|...Q....|...Q....|...Q....|
..Q.....|...Q....|...Q....|.....Q..|.....Q..|Q.......|Q.......|Q.......|
.......Q|.Q......|.......Q|..Q.....|..Q.....|..Q.....|..Q.....|......Q.|
.....Q..|.......Q|Q.......|Q.......|Q.......|.......Q|.....Q..|.Q......|
...Q....|.....Q..|..Q.....|...Q....|.......Q|.....Q..|.Q......|.....Q..|
.Q......|..Q.....|.....Q..|.......Q|...Q....|.Q......|......Q.|..Q.....|
--------+--------+--------+--------+--------+--------+--------+--------+
.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|
Q.......|.Q......|.Q......|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|
....Q...|......Q.|......Q.|Q.......|Q.......|Q.......|....Q...|....Q...|
.Q......|Q.......|Q.......|......Q.|.......Q|.......Q|......Q.|.......Q|
.......Q|..Q.....|...Q....|....Q...|...Q....|....Q...|Q.......|Q.......|
..Q.....|....Q...|.......Q|.......Q|.Q......|.Q......|...Q....|...Q....|
......Q.|.......Q|....Q...|.Q......|......Q.|...Q....|.Q......|.Q......|
...Q....|...Q....|..Q.....|...Q....|....Q...|......Q.|.......Q|......Q.|
--------+--------+--------+--------+--------+--------+--------+--------+
.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|
..Q.....|..Q.....|..Q.....|...Q....|...Q....|...Q....|...Q....|.......Q|
......Q.|......Q.|......Q.|Q.......|.Q......|......Q.|......Q.|.Q......|
.Q......|.Q......|...Q....|....Q...|.......Q|Q.......|Q.......|...Q....|
...Q....|.......Q|Q.......|.......Q|....Q...|..Q.....|.......Q|Q.......|
.......Q|....Q...|.......Q|.Q......|......Q.|....Q...|.Q......|......Q.|
Q.......|Q.......|.Q......|......Q.|Q.......|.Q......|....Q...|....Q...|
....Q...|...Q....|....Q...|..Q.....|..Q.....|.......Q|..Q.....|..Q.....|
--------+--------+--------+--------+--------+--------+--------+--------+
......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|
Q.......|.Q......|.Q......|..Q.....|..Q.....|...Q....|...Q....|....Q...|
..Q.....|...Q....|.....Q..|Q.......|.......Q|.Q......|.Q......|..Q.....|
.......Q|Q.......|..Q.....|.....Q..|.Q......|....Q...|.......Q|Q.......|
.....Q..|.......Q|Q.......|.......Q|....Q...|.......Q|.....Q..|.....Q..|
...Q....|....Q...|...Q....|....Q...|Q.......|Q.......|Q.......|.......Q|
.Q......|..Q.....|.......Q|.Q......|.....Q..|..Q.....|..Q.....|.Q......|
....Q...|.....Q..|....Q...|...Q....|...Q....|.....Q..|....Q...|...Q....|
--------+--------+--------+--------+--------+--------+--------+--------+
.......Q|.......Q|.......Q|.......Q|
.Q......|.Q......|..Q.....|...Q....|
...Q....|....Q...|Q.......|Q.......|
Q.......|..Q.....|.....Q..|..Q.....|
......Q.|Q.......|.Q......|.....Q..|
....Q...|......Q.|....Q...|.Q......|
..Q.....|...Q....|......Q.|......Q.|
.....Q..|.....Q..|...Q....|....Q...|
--------+--------+--------+--------+
Number of solutions: 92
There are several issues, starting from the multiple memory leaks (see e.g. the empty destructor or the delete[] boardPtr; at the beginning of ChessBoard::setSize), but what prevents the program to solve the problem is this:
bool ChessBoard::canPlace(char** boardPtr, int row, int column)
{
int i, j;
// Check row
for (i = 0; i < column; i++)
if (boardPtr[row][i] )
// ^^^^^^^^^^^^^^^^
return false;
// ...
}
That condition and the following ones should be boardPtr[row][i] == 'Q', because, as written, it just check if the char is not 0, while an empty spot is indicated by a . in this program.
My screen isn't printing please help me with this.I'm a beginner and i'm trying to make snake game.
void myScreen()
{
char screen[30][50];
int x = 30, y = 50;
for (int i = 1; i <= x; i++)
{
if (i == 1 || i == x)
for (int j = 1; j <= y; j++)
screen[i][j] = '#';
else
for (int j = 1; j <= y; j++)
if (j == 1 || j == y)
screen[i][j] = '#';
else
screen[i][j] = ' ';
}
for (int i = 1; i <= x; i++)
{
for (int j = 1; j <= y; j++)
cout << screen[i][j];
cout << endl;
}
}
the screen isn't printing
C++ arrays are zero-based. That means that the "first" element has actually the index 0. So your code like that:
for(int i=1;i<=x;i++)
shall be reworked like that:
for (int i = 0; i < x; i++)
Now back to your question: why it isn't printing? The fact is that you are accessing the memory outside of the array, and that is an Undefined Behavior in C++. That may be observed as the program that never gets to the code that prints the array.
The reason it becose you don't call the funtion in main()
here how to do it:
int main(){
myScreen();
}
the int main() is when the program is starting.after you can call other functions
They have other reason like you don't import any libraries
#include <iostream>
using namespace std;
add this in the start of your code
You are missing a main function in your code. In C++ (and C), the main function gets called when you start the program. All other functions that you want to be executed you have to call from this function. Additionally, you start counting your array indexes from 1 - but the first element of an array has 0 as index in most programming languages (including C, C++, Python, JavaScript, bash, …, …). This code should work:
#inclue <iostream>
using namespace std;
void myScreen()
{
int x = 30, y = 50;
char screen[x][y];
for (int i = 0; i < x; i++)
{
if (i == 0 || i == x - 1)
{
for (int j = 0; j < y; j++)
{
screen[i][j] = '#';
}
} else
{
for (int j = 0; j < y; j++)
{
if (j == 1 || j == y)
{
screen[i][j] = '#';
} else
{
screen[i][j] = ' ';
}
}
}
}
for (int i = 0; i < x; i++)
{
for (int j = 0; j < y; j++)
{
cout << screen[i][j];
}
cout << endl;
}
}
int main(int argc, char* argv[]) {
myScreen();
}
Alright so I have created this code. However, when i run it, it stops when it displays 104 for the counter??? I am so frustrated because I don't know how this could happen. The purpose of the code is to do the typical magic number output where the rows all add up to the same thing, the columns all add up to the same thing, and the diaganols all add up to the same thing. I believe the functions to do these calculations are correct, but the counter keeps stopping short of the 10000 attempts I am trying to do.
#include <iostream>
#include<time.h>
#include<stdlib.h>
using namespace std;
void getrandom();
void insertnumber(int n);
bool magic();
void create();
const int rows = 3;
const int cols = 3;
int arr[rows][cols] = { {0,0,0}, {0,0,0} , {0,0,0} };
int main() {
int counter = 0;
do
{
counter++;
cout << counter << endl;
getrandom();
if (counter == 100000)
break;
} while (!magic());
create();
cout << "It took " << counter << " tries." << endl;
return 0;
}
void getrandom() {
int n = 0;
const int size = 9;
int oldnum[size];
for (int i = 0; i < rows * cols; i++) {
oldnum[i] = 0;
}
srand(time(NULL)); // had to import the new libraries to use this
bool used = true;
for (int i = 0; i < size; i++) {
do
{
used = true;
n = rand() % 9 + 1;
if (oldnum[n - 1] == 0)
{
oldnum[n - 1] = n;
used = false;
}
} while (used);
insertnumber(n);
}
}
void insertnumber(int n) {
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
if (arr[i][j] == 0) {
arr[i][j] = n;
return;
}
}
}
}
bool magic() {
int rowsum = arr[0][0] + arr[0][1] + arr[0][2];
for (int i = 1; i < cols; i++)
{
if (arr[i][0] + arr[i][1] + arr[i][2] != rowsum)
return false;
}
for (int j = 0; j < rows; j++)
{
if (arr[0][j] + arr[1][j] + arr[2][j] != rowsum)
return false;
}
if (arr[0][0] + arr[1][1] + arr[2][2] != rowsum)
return false;
if (arr[0][2] + arr[1][1] + arr[2][0] != rowsum)
return false;
return true;
}
void create() {
{
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
}
}
You can try using a debugger for such problems.
I think you code crashes because of this:
for (int i = 0; i < rows; i++) {
for (int j = 0; i < cols; j++) {
It looks like you mean j < cols here :)
Check line 76. When I compile and run the code, line 76 is where the exception is thrown.
This line specifically
arr[i][j] = n;
It seems your insertnumber() function is the culprit.
I'm trying to create a 3x3 sliding tile puzzle game and I made the puzzle in a 2d array and now im trying to get the puzzle to slide a tile.
I'm new to debugging and cannot find out why the program isn't receiving the users input for the slide.
#define SLIDE_UP 1
#define SLIDE_DOWN 2
#define SLIDE_LEFT 3
#define SLIDE_RIGHT 4
void InitializeBoard(int[NUM_ROWS][NUM_COLS]);
void PrintBoard(int[NUM_ROWS][NUM_COLS]);
bool slideTile(int[NUM_ROWS][NUM_COLS], int);
void scrambleBoard(int[NUM_ROWS][NUM_COLS]);
bool isBoardSolved(int[NUM_ROWS][NUM_COLS]);
void DeallocateMemory(int[NUM_ROWS][NUM_COLS]);
int** ppRootPointer = NULL;
int main() {
int slidingBoard[NUM_ROWS][NUM_COLS];
char keyStroke = ' ';
int directionCode = UNSET;
int slideDirection = 0;
InitializeBoard(slidingBoard);
PrintBoard(slidingBoard);
slideTile(slidingBoard,slideDirection);
PrintBoard(slidingBoard);
_getch();
DeallocateMemory(slidingBoard);
return 0;
}
void InitializeBoard(int theBoard[NUM_ROWS][NUM_COLS]) {
ppRootPointer = new(int*[NUM_COLS]);
for (int i = 0; i < NUM_COLS; i++) {
ppRootPointer[i] = new(int[NUM_ROWS]);
}
int counter = 1;
int i = 0, j = 0;
for (i = 0; i < NUM_COLS; i++) {
for (j = 0; j < NUM_ROWS; j++) {
ppRootPointer[i][j] = counter++;
}
}
ppRootPointer[i-1][j-1] = PIVOT;
}
void PrintBoard(int theBoard[NUM_ROWS][NUM_COLS]) {
cout << left;
for (int i = 0; i < NUM_COLS; i++) {
for (int j = 0; j < NUM_ROWS; j++) {
if (ppRootPointer[i][j] != PIVOT) {
cout << setw(3) << ppRootPointer[i][j];
}
else {
cout << setw(3) << (char)PIVOT;
}
}
cout << endl;
}
cout << endl << endl;
}
bool slideTile(int theBoard[NUM_ROWS][NUM_COLS], int slideDirection) {
int pivotRow=0;
int pivotCol=0;
bool slidebool;
//once I declare i and j before the loop they go up to 3 instead of 2
//which causes the loop to not work
int i = 0;
int j = 0;
for (i = 0; i < NUM_COLS; i++) {
for (j = 0; j < NUM_ROWS; j++) {
if (theBoard[i][j] == (char)PIVOT) {
pivotCol = i;
pivotRow = j;
break;
}
}
}
//These are to assign pivotRow and Col because they dont get assigned
//inside of the loop
pivotCol = i;
pivotRow = j;
cout << "please enter a number to slide the tile (1 = up, 2 = down, 3 =
left, 4 = right" << endl;
cin >> slideDirection;
if (slideDirection == SLIDE_UP) {
if (pivotRow + 1 > NUM_ROWS) {
slidebool = false;
}
else {
ppRootPointer[pivotRow + 1][pivotCol] = PIVOT;
ppRootPointer[pivotRow][pivotCol] = ppRootPointer[pivotRow + 1]
[pivotCol];
slidebool = true;
}
}
.I'm hoping for the user to be able to enter an integer 1-4 representing the slide for the tile. This would allow me to build the scramble board function and get closer to finishing the code. Thanks to anyone that reads this and tries to help!!
I have an array of 20 x 20 that outputs how hot a plate is. I need to reiterate through a loop until no cell in the array changes more than 0.1 degree(I refresh the values through every iteration. How would you monitor the largest change for any cell in an array in order to determine when to stop iterating? Right now I have tried, but the below doesn't output correctly.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
const int ARRAY_SIZE = 20;
const int NEIGHBORS = 4;
void initialize(double hot_plate[][ARRAY_SIZE]);
bool writeFile(const double HOT_PLATE[][ARRAY_SIZE],
const string FILE_NAME);
double sum_cell(const double HOT_PLATE[][ARRAY_SIZE],
const int CELL_X, const int CELL_Y);
int main()
{
double hot_plate[ARRAY_SIZE][ARRAY_SIZE];
double hot_plate_prev[ARRAY_SIZE][ARRAY_SIZE];
initialize(hot_plate);
string file_name = "hot_plate.csv";
//accuracy up to 4 decmials
int runs = 724;
double hot_plate[ARRAY_SIZE][ARRAY_SIZE];
double hot_plate_prev[ARRAY_SIZE][ARRAY_SIZE];
while (true)
{
// This is your code
for (int i = 0; i < ARRAY_SIZE; i++)
{
for (int j = 0; j < ARRAY_SIZE; j++)
{
if (i > 0 && i < ARRAY_SIZE - 1 && j > 0 && j < ARRAY_SIZE - 1)
{
hot_plate[i][j] = sum_cell(hot_plate, j, i);
}
}
}
bool theSame = true;
for (int i = 0; i < ARRAY_SIZE; i++)
{
for (int j = 0; j < ARRAY_SIZE; j++)
{
if (abs(hot_plate[i][j] - hot_plate_prev[i][j]) < 0.1)
{
theSame = false;
}
hot_plate_prev[i][j] = hot_plate[i][j];
}
}
if (!theSame) break;
}
}
if (writeFile(hot_plate, file_name))
{
cout << "File wrote correctly\n";
}
else
{
cout << "The file did not write!\n";
}
//system("pause");
return 0;
}
double sum_cell(const double HOT_PLATE[][ARRAY_SIZE],
const int CELL_X, const int CELL_Y)
{
/* This code should never go out of bounds as it's in an if statement
if (i > 0 && i < ARRAY_SIZE - 1 && j > 0 && j < ARRAY_SIZE - 1)
*/
double cell_num = HOT_PLATE[CELL_X - 1][CELL_Y]; // Top
cell_num += HOT_PLATE[CELL_X][CELL_Y - 1]; // Left
cell_num += HOT_PLATE[CELL_X][CELL_Y + 1]; // Right
cell_num += HOT_PLATE[CELL_X + 1][CELL_Y]; // Bottom
cell_num /= NEIGHBORS;
return cell_num;
}
// setup the Array so all values are defined when starting
void initialize(double hot_plate[][ARRAY_SIZE])
{
for (int i = 0; i < ARRAY_SIZE; i++)
{
for (int j = 0; j < ARRAY_SIZE; j++)
{
if (i == 0 || i == ARRAY_SIZE - 1)
{
if (j == 0 || j == ARRAY_SIZE - 1)
{
hot_plate[i][j] = 0.0;
}
else
{
hot_plate[i][j] = 100.0;
}
}
else
{
hot_plate[i][j] = 0.0;
}
}
}
}
// Write the data to the CSV file
bool writeFile(const double HOT_PLATE[][ARRAY_SIZE],
const string FILE_NAME)
{
// open the file
ofstream fout(FILE_NAME);
if (fout.fail())
return false;
for (int i = 0; i < ARRAY_SIZE; i++)
{
for (int j = 0; j < ARRAY_SIZE; j++)
{
fout << HOT_PLATE[i][j];
if ( j < ARRAY_SIZE - 1)
{
fout << ", ";
}
else if (i != ARRAY_SIZE - 1)
{
fout << endl;
}
}
}
// close the input stream from the file.
fout.close();
return true;
}
At the beginning of your while loop, you can set a boolean variable called something like allSmallChanges to true. In your inner if statement, you can check to see if the change to hot_plate[i][j] is "too big". If it is too big, then set allSmallChanges to false. Then, just before the end of the while loop, you can break if allSmallChanges is still true.
If you don't want to have that cap of 724 iterations, you can get rid of your runs variable, and change the loop to while(true).
Note: The code in the question got changed after I wrote this answer. I'm not sure this answer still applies. However, I'm also sure that will be the last change to the code in the question. So, I'll leave this answer as-is for now.