Trouble with Beginner's C++ Game of Life Program - c++

Background: I am quite a beginner at programming. This is what I have so far in my rough draft for the Game of Life:
#include <iostream>
using namespace std;
int main()
{
//INTRODUCTION
int arraySize;
cout << "What is the length of your square-shaped grid? Enter an integer value greater than 0. Too big will cause problems.";
cin >> arraySize;
int original[arraySize][arraySize];
//REQUESTS INPUT FOR ARRAY
for (int n = 0; n < arraySize; n++)
{
for (int x = 0; x < arraySize; x++)
{
bool ValInput;
cout << "\n" << n << "," << x << "...";
cin >> ValInput;
original[n][x] = ValInput;
}
}
cout << "\n\n\n";
//DISPLAYS ARRAY
for (int row = 0; row < arraySize; row++)
{
for (int column = 0; column < arraySize; column++)
{
cout << original[row][column] << " ";
if (column == arraySize - 1)
{
cout << "\n";
}
}
}
cout << "Next frame.\n\n";
//FORMS NEXT FRAME WITH VALUES OF # OF LIVE NEIGHBORS
int liveNeighbors = 0;
for (int z = 0; z < arraySize; z++)
{
for (int h = 0; h < arraySize; h++)
{
liveNeighbors = 0;
if (z - 1 > -1)
liveNeighbors += original[z - 1][h];
if (z + 1 < arraySize)
liveNeighbors += original[z + 1][h];
if (h - 1 > -1)
liveNeighbors += original[z][h - 1];
if (h + 1 < arraySize)
liveNeighbors += original[z][h + 1];
if (z - 1 > -1, h - 1 > -1)
liveNeighbors += original[z - 1][h -1];
if (z - 1 > -1, h + 1 < arraySize)
liveNeighbors += original[z - 1][h + 1];
if (z + 1 < arraySize, h - 1 > -1)
liveNeighbors += original[z + 1][h - 1];
if (z + 1 < arraySize, h + 1 < arraySize)
{
liveNeighbors += original[z + 1][h + 1];
}
cout << liveNeighbors << " ";
}
}
}
The problem appears in the last step I have made so far (which is showing how many live neighbors each cell has.
Example: If the sample input is first "4" for a 4x4 grid and then you enter in a variety of 1s and 0s, the liveNeighbors value is not realistic. It may be in the hundreds, when the maximum should be only 8.
If you could help me find a solution to my problem, that would be nice. However, please keep in mind that I am a novice.
Thank you :)

Some of your conditions are wrong :
if (z - 1 > -1, h - 1 > -1) /* ... */
if (z - 1 > -1, h + 1 < arraySize) /* ... */
if (z + 1 < arraySize, h - 1 > -1) /* ... */
if (z + 1 < arraySize, h + 1 < arraySize) /* ... */
The comma does not do what you expect, what you need is probably a logical 'and' which in C++ is the operator && :
if ((z - 1 > -1) && (h - 1 > -1)) /* ... */
if ((z - 1 > -1) && (h + 1 < arraySize)) /* ... */
if ((z + 1 < arraySize) && (h - 1 > -1)) /* ... */
if ((z + 1 < arraySize) && (h + 1 < arraySize)) /* ... */
Extra parenthesis added for readability only, they are not required.
Just so you know, this is the standard definition of the comma operator :
A pair of expressions separated by a comma is evaluated left-to-right and the value of the left expression is
discarded.
In your case, the comparisons on the left side of the commas were basically not playing any role in the if condition.

I think that your problem is in this code:
if (z - 1 > -1, h - 1 > -1)
Your intuition is completely correct here, but the way that you've written this in code doesn't mean what you want. In C++, the comma operator is an esoteric operator that means "do both things, but discard the result of the first operation.". In this case, that means "check if z - 1 > -1, then completely discard that result, then see whether h - 1 > -1," which isn't at all what you want. To check and see if both of these conditions hold true, use the && operator:
if (z - 1 > -1 && h - 1 > -1)
That should help fix your bug.
Hope this helps!

Related

How do I make it go in diagonal directions?

I have code that I already have four basic directions (Up, Down, Left, Right). However, I want to have them go in diagonal directions as well, so it will add up to eight directions. How would I do that? What I see from it, I basically have to have two directions change at the same time, but I don't know how to do that.
Code:
// problem with backtracking using stack
#include <cstring>
#include <iostream>
#include <stack>
using namespace std;
#define N 4
#define M 5
class node {
public:
int x, y;
int dir;
node(int i, int j)
{
x = i;
y = j;
// Initially direction
// set to 0
dir = 0;
}
};
// maze of n*m matrix
int n = N, m = M;
// Coordinates of food
int fx, fy;
bool visited[N][M];
bool isReachable(int maze[N][M])
{
// Initially starting at (0, 0).
int i = 0, j = 0;
cout << '[' << i << ':' << j << ']';
stack<node> s;
node temp(i, j);
s.push(temp);
while (!s.empty()) {
// Pop the top node and move to the
// left, right, top, down or retract
// back according the value of node's
// dir variable.
temp = s.top();
int d = temp.dir;
i = temp.x, j = temp.y;
// Increment the direction and
// push the node in the stack again.
temp.dir++;
s.pop();
s.push(temp);
// If we reach the Food coordinates
// return true
if (i == fx and j == fy) {
return true;
}
// Checking the Up direction.
if (d == 0) {
if (i - 1 >= 0 and maze[i - 1][j] == 1 and
!visited[i - 1][j]) {
cout <<'['<< i - 1 << ':'<<j << ']' ;
node temp1(i - 1, j);
visited[i - 1][j] = true;
s.push(temp1);
}
}
// Checking the left direction
else if (d == 1) {
if (j - 1 >= 0 and maze[i][j - 1] == 1 and
!visited[i][j - 1]) {
cout << '[' << i << ':' << j-1 << ']' ;
node temp1(i, j - 1);
visited[i][j - 1] = true;
s.push(temp1);
}
}
// Checking the down direction
else if (d == 2) {
if (i + 1 < n and maze[i + 1][j] == 1 and
!visited[i + 1][j]) {
cout << '[' << i + 1 << ':' << j << ']' ;
node temp1(i + 1, j);
visited[i + 1][j] = true;
s.push(temp1);
}
}
// Checking the right direction
else if (d == 3) {
if (j + 1 < m and maze[i][j + 1] == 1 and
!visited[i][j + 1]) {
cout << '[' << i << ':' << j + 1<< ']' ;
node temp1(i, j + 1);
visited[i][j + 1] = true;
s.push(temp1);
}
}
// If none of the direction can take
// the rat to the Food, retract back
// to the path where the rat came from.
else {
visited[temp.x][temp.y] = false;
s.pop();
}
//system("pause");
}
// If the stack is empty and
// no path is found return false.
return false;
}
// Driver code
int main()
{
// Initially setting the visited
// array to true (unvisited)
memset(visited, false, sizeof(visited));
// Maze matrix
int maze[N][M] = {
{ 1, 0, 1, 1, 0 },
{ 1, 1, 1, 0, 1 },
{ 0, 1, 0, 1, 1 },
{ 1, 1, 1, 1, 1 }
};
// Food coordinates
fx = 2;
fy = 3;
if (isReachable(maze)) {
cout << "Path Found!" << '\n';
}
else
cout << "No Path Found!" << '\n';
return 0;
}```
By combining the conditions you already have... You have the following for checking the second dimension:
if (j + 1 < m and maze[i][j + 1] == 1 and !visited[i][j + 1])
If you want to increment both at once you would do something like:
if (i + 1 < n and j + 1 < m and maze[i + 1][j + 1] == 1 and !visited[i + 1][j + 1])
Since you have 4 diagonals, you would do similar checkings for the other 3 diagonals. Be careful with copy and paste not to forget to increment/decrement both i and j.
Let's assume a board, with row 0 and column 0 in the upper left corner.
Also, assume the present position is at <row, column>.
There are 8 locations relative to the present position (unless you are near the edge of the board).
+---------------------+---------------------+--------------------+
| row - 1, column - 1 | row - 1, column + 0 | row - 1, column + 1|
+---------------------+---------------------+--------------------+
| row + 0, column - 1 | row, column | row + 0, column + 1|
+---------------------+---------------------+--------------------+
| row + 1, column - 1 | row + 1, column + 0 | row + 1, column + 1|
+---------------------+---------------------+--------------------+
Before making a move, check the validity of the next move.
The next move would be based on the above table.

Coursera DSA Algorithmic toolbox week 4 2nd question- Partitioning Souvenirs

Problem Statement-
You and two of your friends have just returned back home after visiting various countries. Now you would
like to evenly split all the souvenirs that all three of you bought.
Problem Description
Input Format- The first line contains an integer ... The second line contains integers v1, v2, . . . ,vn separated by spaces.
Constraints- 1 . .. . 20, 1 . .... . 30 for all ...
Output Format- Output 1, if it possible to partition 𝑣1, 𝑣2, . . . , 𝑣𝑛 into three subsets with equal sums, and
0 otherwise.
What's Wrong with this solution? I am getting wrong answer when I submit(#12/75) I am solving it using Knapsack without repetition taking SUm/3 as my Weight. I back track my solution to replace them with 0. Test cases run correctly on my PC.
Although I did it using OR logic, taking a boolean array but IDK whats wrong with this one??
Example- 11
17 59 34 57 17 23 67 1 18 2 59
(67 34 17)are replaced with 0s. So that they dont interfare in the next sum of elements (18 1 23 17 59). Coz both of them equal to 118(sum/3) Print 1.
#include <iostream>
#include <vector>
using namespace std;
int partition3(vector<int> &w, int W)
{
int N = w.size();
//using DP to find out the sum/3 that acts as the Weight for a Knapsack problem
vector<vector<int>> arr(N + 1, vector<int>(W + 1));
for (int k = 0; k <= 1; k++)
{
//This loop runs twice coz if 2x I get sum/3 then that ensures that left elements will make up sum/3 too
for (int i = 0; i < N + 1; i++)
{
for (int j = 0; j < W + 1; j++)
{
if (i == 0 || j == 0)
arr[i][j] = 0;
else if (w[i - 1] <= j)
{
arr[i][j] = ((arr[i - 1][j] > (arr[i - 1][j - w[i - 1]] + w[i - 1])) ? arr[i - 1][j] : (arr[i - 1][j - w[i - 1]] + w[i - 1]));
}
else
{
arr[i][j] = arr[i - 1][j];
}
}
}
if (arr[N][W] != W)
return 0;
else
{
//backtrack the elements that make the sum/3 and = them to 0 so that they don't contribute to the next //elements that make sum/3
int res = arr[N][W];
int wt = W;
for (int i = N; i > 0 && res > 0; i--)
{
if (res == arr[i - 1][wt])
continue;
else
{
std::cout << w[i - 1] << " ";
res = res - w[i - 1];
wt = wt - w[i - 1];
w[i - 1] = 0;
}
}
}
}
if (arr[N][W] == W)
{
return 1;
}
else
{
return 0;
}
}
int main()
{
int n;
std::cin >> n;
vector<int> A(n);
int sum = 0;
for (size_t i = 0; i < A.size(); ++i)
{
int k;
std::cin >> k;
A[i] = k;
sum += k;
}
if (sum % 3 == 0)
std::cout << partition3(A, sum / 3) << '\n';
else
std::cout << 0;
}
Sum/3 can be achieved by multiple ways!!!! So backtracking might remove a subset that has an element that should have been a part of some other subset
8 1 6 is 15 as well as 8 2 5 makes 15 so better is u check this
if(partition3(A, sum / 3) == sum / 3 && partition3(A, 2 * (sum / 3)) == 2 * sum / 3 && sum == partition3(A, sum))

C++ Game of Life infinite looping function

This function in the Game of Life assignment is supposed to loop through the 2nd array and check to see how many neighbors each cell has. When I call this in the main, not even in any sort of loop, the terminal freezes as if in an infinite while loop. Can anyone tell me what's wrong with my code? Thanks.
void Grids::simulate(int** myGrid, int rows, int columns)
{
int neighbors = 0; //variable to store how many neighbors a cell has
for (int r = 0; r < rows; ++r) // iterates through rows
{
for(int c = 0; c < columns; ++c)//iterates through columns
{
for(int x = -1; x < 2; x + 2) //iterates through -1 and 1, the spaces next to the cell
{
for(int y = -1; y < 2; y + 2)
{
if ((r + x >= 0) && (r + x < rows) && (c + y >= 0) && (c + y < columns)) //prevents indexing the 2d array outside of its bounds
{
if (myGrid[r + x][c + y] == 1) //checks if the surrounding cells are alive
{
++neighbors;
}
}
}
}
if (neighbors < 2) //underpopulation
{
myGrid[r][c] = 0; //dead
}
else if (neighbors == 3) //reproduction
{
myGrid[r][c] = 1; //alive
}
else if (neighbors >= 4) //overpopulation
{
myGrid[r][c] = 0; //dead
}
}
}
}
You should change this x + 2 to x += 2 and y + 2 to y += 2, to make the loop increase by 2 each cycle. I also advise you to remove extra parentheses in this line if (r + x >= 0 && r + x < rows && c + y >= 0 && c + y < columns).

How to count moves in BFS algorithm? (Shortest path in a maze)

So I try implementing a BFS algorithm and really understand how it works (creating some kind of "my version", out of scratch, just looking at graphs and some pseudocodes) and here is what I ended up with:
#include<iostream>
#include<string>
#include<fstream>
#include<queue>
using namespace std;
void main(int argc, char *argv[])
{
// Deklaracja uchwytu do pliku (tylko do odczytu pliku)
ifstream plik(argv[1]);
// Tablica stringow - przechowujaca wartosci pol 12x12
string labirynt[12];
pair <int, int> start;
pair <int, int> koniec;
// Wektor par - działa jak tablica, przechowuje pary współrzędnych pól
queue <pair<int, int>> kolejka;
// Tablica odwiedzin - sprawdza czy pole zostalo odwiedzone, 0 jesli nie, 1 jesli tak
bool odwiedzone[12][12] = { 0 };
// Zmienna pomocnicza - bo getline sluzy do umieszczania danych w stringu, nie w tablicy znakow
int i = 0;
// Pętla wczytująca tekst z pliku do tablicy labirynt
while (getline(plik, labirynt[i]))
{
i++;
}
// Wyszukanie początku i końca w labiryncie (A i B)
for (int i = 0; i < 12; i++)
{
for (int j = 0; j < 12; j++)
{
if (labirynt[i][j] == 'A')
{
start.first = i;
start.second = j;
}
if (labirynt[i][j] == 'B')
{
koniec.first = i;
koniec.second = j;
}
}
}
// Ustawiamy pole startowe jako odwiedzone - żadne pole nie może być odwiedzone więcej niż 1 raz
odwiedzone[start.first][start.second] = true;
// Wiersz i kolumna bieżącego wierzchołka
int w, k;
kolejka.push(start);
// Dopóki kolejka nie jest pusta
while (!kolejka.empty())
{
// Pobieramy z kolejki wiersz i kolumnę bieżącego wierzchołka
w = kolejka.front().first;
k = kolejka.front().second;
// Usuwamy parę z kolejki
kolejka.pop();
// Sprawdzamy czy dotarliśmy do wyjścia
if (w == koniec.first && k == koniec.second)
break;
// Przeglądamy sąsiadów bieżącego wierzchołka
for (i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
{
if ((i != j) && (!i || !j))
if (labirynt[w + i][k + j] == ' ' && !odwiedzone[w + i][k + j])
{
odwiedzone[w + i][k + j] = true;
pair <int, int> para;
para.first = w + i;
para.second = k + j;
kolejka.push(para);
cout << kolejka.front().first << endl;
cout << kolejka.front().second << endl;
}
}
}
system("PAUSE");
}
Here is the example maze I use (program reads from file that is dropped on .exe)
xxxxxxxxxxxx
xxA xxxxxxx
xx x xxxxxx
x x xxxxxx
xx x xxxx
xx xxx xxxxx
x xxxxxxxx
x x xxxxxxx
x xxx xxxxxx
x xxxxxxx
xxx Bxxx
xxxxxxxxxxxx
It works (shows coordinates of every field in a maze it goes through and finds B), but I don't know how to count moves needed to go through shortest path.
instead of using odwiedzone[w + i][k + j] = true; for checking the coordinate have been stepped before, use something like odwiedzone[w + i][k + j] = now + 1 to count the number of step from start to that position:
// first, declare all odwiedzone[][]=-1
...
odwiedzone[start.first][start.second] = 0;
// first position needs 0 step
...
for (i = -1; i <= 1; i++)
for (int j = -1; j <= 1; j++)
{
if ((i != j) && (!i || !j))
if (labirynt[w + i][k + j] == ' ' && odwiedzone[w + i][k + j]==-1)
{
odwiedzone[w + i][k + j] = odwiedzone[w][k]+1;
//next position = now position + 1
pair <int, int> para;
para.first = w + i;
para.second = k + j;
kolejka.push(para);
cout << kolejka.front().first << endl;
cout << kolejka.front().second << endl;
}
}
I see 2 ways of achieving what you want:
Use a separate queue for storing the associated distance with each cell, e.g. start will have 0, each neighbour of start will have 1 and so on. Each time you add a new neighbor, his value will be distance to current cell + 1. The value for destination in the second queue will give you the path length.
When adding a neighbor in the queue, record his parent. So when you find the source you can reconstruct the path and count the number of steps.

Unexpected Harris Detector results

I load the vertical and horizontal gradients into the function posted here and it calculates the sums which than make up the corner response. Why do only boarder pixels get to be found, my threshold is 0 otherwise there is 0 corners on the image. For gradients I used sobel operator.
Look at the output image below.
for (int i = 0; i < width; i++)
{
for (int j = 0; j < height; j++)
{
if ((i - search_size / 2 < 0 || i + search_size / 2 > image1.rows - 1) || (j - search_size / 2 < 0 || j + search_size / 2 > image1.cols - 1)) {
continue;
}
double Ix2 = 0, Iy2 = 0, Ixy = 0;
double detM=0;
double traceM=0;
double R = 0;
for (int m = i-search_size /2; m < i + search_size /2 ; m++){
for (int n = j-search_size /2; n < j + search_size/2 ; n++){
gauss = exp(-(((i - m) * (i - m)) + ((j - n) * (j - n))) / gaus_del);
//Compute Ix^2 , Iy^2 and Ixy
Ix2 += gauss*(image1.at<float>(m, n)*image1.at<float>(m, n));
Iy2 += gauss*(image2.at<float>(m, n)*image2.at<float>(m, n));
Ixy += gauss*(image1.at<float>(m, n)*image2.at<float>(m, n));
}
}
detM = (Ix2*Iy2 - Ixy*Ixy);
traceM = Ix2*Ix2 + Iy2*Iy2;
R = detM / traceM;
//cout <<i+j<< endl;
// std::cout << "R :" << Iy2 << endl;
if (R > threshold)
{
circle(image, cv::Point2f(i, j), 3.5, cv::Scalar(255, 255, 0), 1, 5);
cout << "corner found" << endl;
}
}
}
EDIT : i am using uchars now and the result looks alot better
2