Overwhelmed by assignment based on Conway's Game of Life [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am given files gameOfLife.cpp, life.cpp, and life.h. I am only allowed to edit life.cpp in order to make the program work. I don't know where to with editing life.cpp because there is so much going on that I am unfamiliar with. I am given a file checkoutLife.cpp to check my work.
I've spent the last two days looking at other people's Game of Life files trying to see how to proceed but am at a loss. I don't want someone to do my work for me but I need some direction.
gameOfLife.cpp
#include <iostream>
#include "life.cpp"
#include "life.h"
const int GENERATIONS=100;
using namespace std;
//make a random array of initial living cells
void gen(bool a[ROWS][COLS]){
for(int i=0;i<ROWS;++i){
for(int j=0;j<COLS;++j){
if(rand()%100<10)a[i][j]=true;
else a[i][j]=false;
}
}
a[5][5]=true;
a[5][6]=true;
a[5][7]=true;
return;
}
// check to see if two arrays are equal
bool equal(const bool a[ROWS][COLS], const bool b[ROWS][COLS]){
int i,j;
for(i=0;i<ROWS;++i)for(j=0;j<COLS;++j)if(a[i][j]!=b[i][j])return false;
return true;
}
//copy the b array into the a array
void copy(bool a[ROWS][COLS], const bool b[ROWS][COLS]){
for(int i=0;i<ROWS;++i){
for(int j=0;j<COLS;++j){
a[i][j]=b[i][j];
}
}
return;
}
//print out the array
void print(const bool a[ROWS][COLS]){
for(int i=0;i<ROWS;++i){
for(int j=0;j<COLS;++j){
if(a[i][j])cout << 'X';
else cout << ' ';
}
cout << endl;
}
return;
}
int main(){
bool current[ROWS][COLS];
bool next[ROWS][COLS];
int i=0;
//initialze the cell array and print it out
gen(current);
print(current);
while(i<GENERATIONS){
//get a carriage return before the next generation
cin.get();
//give the current generation to life()
//it puts the next generation into next
life(current,next);
//copy the next generation into the current
copy(current,next);
//print it out
print(current);
i++;
}
return 0;
}
life.cpp
/*1. You need to write a file life.cpp that implements the function prototyped in life.h. You can and should write other functions
and tuck them into the same file; whatever you need to get your function working in an elegant manner.
2. Compile your file with checkoutLife.cpp and run the resulting executable to see if it passes all the tests.
3. Compile yourfile with gameOfLife.cpp and run the resulting executable to see if it makes pretty pictures.
4. If you are convinced steps 2 and 3 are working, submit your life.cpp via canvas.
*/
#include <iostream>
#include <cstdlib>
#include "life.h"
using namespace std;
void life(const bool current[ROWS][COLS], bool next[ROWS][COLS]){
}
life.h
#ifndef LIFE_H
#define LIFE_H
const int ROWS=25;
const int COLS=25;
// Simulate one generation of Conways Game of Life
//
// Given:
// a constant 2D bool array called "current" where each true element
// indicates a live cell and each false element indicates a dead cell.
//
// an empty 2D bool array called "next"
void life(const bool current[ROWS][COLS], bool next[ROWS][COLS]);
#endif

life() is called with two parameters: an array of your board's current state (which presumably you will not touch) and an array of the board's next state (which you will populate).
Here is an algorithm you could use:
For each row in ROW:
For each col in COL:
Add up all surrounding neighbours in current[][], store in "neighbours"
If current[row][col] is alive and neighbours < 2, next[row][col] = dead
Else if current[row][col] is alive and neighbours == 2 or 3, next[row][col] = alive
Else if current[row][col] is alive and neighbours > 4, next[row][col] = dead
Else if current[row][col] is dead and neighbours == 3, next[row][col] = alive
You can clean up the logic a bit, but I printed it out just like the rules on Wikipedia's Game of Life entry. The complicated part (IMO) is "Add up all surrounding neighbours" - there's a lot of bounds checking here. I suggest calling a different method that you write, for clarity's sake.

Related

How to handle this odd and even bubble sorting error? [closed]

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 last month.
Improve this question
I wanna ask why the even side of the odd&even bubble sort will raise a zsh:abort error in VScode? Is it because it is out of range? If so, does that mean that I have to precisely modify the range? Thank you!
#include <iostream>
using namespace std;
int main()
{
int a[10];
for (int i=0;i<10;i++)
{
cin>>a[i];
}
//First, sort odd and even numbers
int l=0,r=9;//point to the two ends of the array
while (l<=r)
{
bool leftIsOdd=a[l]%2==1;
bool rightIsEven=a[r]%2==0;
//move the two pointers from ends to middle
if (leftIsOdd)
{
l++;
}
else if (rightIsEven)
{
r--;
}
//since it's a symmetric array, with 5 odd and 5 even, we can swap when both sides get stuck
//Q:If we have 4 odd numbers and 6 even numbers, is the approach OK?
else if (!leftIsOdd && !rightIsEven)
{
int temp=a[l];
a[l]=a[r];
a[r]=temp;
}
}
//perform bubble sort for left odd part
int start=0,end=l;
for (int i=start; i<end-1;i++)
{
for (int j=start+1;j<end-i;j++)
{
if (a[j-1]>a[j])
{
int temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}
}
//now bubble the right even side
start=l,end=10;
for (int i=start; i<end-1;i++)
{
for (int j=start+1;j<start+end-i;j++)
# # # //Why j<start+end-1 would produce error?
{
if (a[j-1]>a[j])
{
int temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}
}
for (int i=0;i<10;i++)
{
cout<<a[i]<<' ';
}
return 0;
}
I tried putting index j out of the expected range, and received zsh:abort error.
If you initialize the input array a with 10,9,8,7,6,5,4,3,2,1 as you mentioned then when you reach the "// now bubble the right even side" loop you will initialize start to 5 and end to 10. If you write j<start+end-1 then this will allow j to be as large as 13. (i.e. j must be less than 14). You will then try to access a[13], but a has only 10 elements. Therefore, if you are lucky, you will get some kind of memory access error when you run the program and it will crash.
I don't know why you want to replace the expression j<start+end-i (which seems to work, with the expression j<start+end-1 which causes a crash.
You could probably make the crash happen a lot easier just by including the line a[13]=0; after you declare and initialize a.
When you are using arrays it is your responsibility to ensure that all array accesses are valid. When you ask "does that mean that I have to precisely modify the range" the answer is "yes, definitely!"

C++ - seg fault from inserting elements into array in ascending order

As part of a BookGroup class that manages an array of Book objects, I'm asked to create a void add(Book* b) member function that adds the given Book b to an array of books in its correct place (from oldest to most recent year of publication). I'm required to shift the elements in the array towards the back of the array to make room for the new element in its correct place. I am not allowed to simply add to the end of the array and then sort or use any sorting function/sorting algorithm on the array.
I tried testing my add function and I get a seg fault. My approach was to add any new book at the end of the array and if that specific book's publication year was older (number is less) than the last book in the array, I would make the two books swap places. If not, the book would stay in the same spot at the very end of the array. I then continue this process.
I don't know what's causing the seg fault. As a side note, I was wondering if I'm supposed to use the delete function at any point in add()? I did a valgrind check on my compiler and it says there are a bunch of bytes lost somewhere in my program. My guess is that a good chunk of the bytes are probably coming from the add function, but I'm not sure and just wanted to double check.
bookCollection is supposed to be a statically allocated array of Book object pointers. There are two classes - Book.cc and BookGroup.cc.
I decided to show all of my code so people can compile it, but please post only what is necessary and refrain from posting all of it in the answers below.
BookGroup.cc:
#include <iostream>
#include <iomanip>
using namespace std;
#include "BookGroup.h"
BookGroup::BookGroup(int n){
numOfBooks = n;
}
void BookGroup::add(Book* b){
if(numOfBooks != MAX_BOOKS){
if(numOfBooks == 0){
bookCollection[0] = b; //add first element
++numOfBooks; //increase numOfBooks by 1 and go to next statement
}else{
for(int i = numOfBooks-1; i >= 0; --i){ //start at end of array and work towards front where lowest years are
if(b->getPubYear() < bookCollection[i]->getPubYear()){
bookCollection[i + 1] = bookCollection[i]; //swap positions if b is lower than last element
bookCollection[i] = b;
}else{
b = bookCollection[i + 1]; //otherwise stay in the same spot (keep b at the end)
//break;
}
}
++numOfBooks;
}
}
cout<<"Book could not be added to collection. No more space "<<endl;
}
BookGroup.h:
#ifndef BOOKGROUP_H
#define BOOKGROUP_H
#define MAX_BOOKS 15
#include <string>
using namespace std;
class BookGroup
{
public:
BookGroup(int);
BookGroup(BookGroup&);
~BookGroup();
void print();
void add(Book*);
Book* bookCollection[MAX_BOOKS];
private:
int numOfBooks;
};
#endif
Book.cc: https://pastebin.com/9swrwYgx
Book.h: https://pastebin.com/mqDn2C30
makefile: https://pastebin.com/xHKDsVL1
main: https://pastebin.com/TBzyduMC
When I try to run it:
Declaring two book groups...
Initializing two book groups...
-- default Book ctor: Peter pan year: 1982
Segmentation fault
This
BookGroup::BookGroup(int n){
numOfBooks = n;
}
together with this
BookGroup suzy(2);
creates book groups which do not contain any pointers to valid books but DO pretend to contain 2.
Then here
for(int i = numOfBooks-1; i >= 0; --i)
{ //start at end of array and work towards front where lowest years are
if(b->getPubYear() < bookCollection[i]->getPubYear()){
you start accessing index 1 (because of numBooks==2), which is not a valid pointer.
You should
correctly initialise your array, e.g. with NULL, to make sure that checks work cleanly later
double check that you only use valid pointer, everywhere, if necessary twice
not initialise an empty group with a non-zero number of pretended books

Function keeps overwriting previous structure data [closed]

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 6 years ago.
Improve this question
when I enter data using my add function, I am able to print them no problem. Adding a vaule for start(x,y), end(x,y) works and I am able to print the values. But when I specify that I want two numGraphicElements when the function leaves after entering the first set of start and end values. It overwrites my previous values when going through the loop a second time.
When I print the values it for some reason overwrites my first values with random numbers and then only shows the second set of start(x,y) end(x,y) values.
example of first set: start(1,2) end (3,4)....this print properly
example of second set added: start(9,8) end (6,7)...this prints as well
example pf print out with 2 sets together, x(23424), y(653243), end = x(2334) y(33434).....x(9) y(8) end x(3) y(4).
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
enum
{
RUNNING = 1
};
struct Point
{
int x, y;
};
struct Line
{
Point start;
Point end;
};
struct GraphicElement
{
enum
{
SIZE = 256
};
unsigned int numLines; //number of lines
Line* pLines; //plines points to start and end
char name[SIZE];
};
typedef struct
{
unsigned int numGraphicElements;
GraphicElement* pElements; //the head points to pLines
} VectorGraphic;
void InitVectorGraphic(VectorGraphic*);
void AddGraphicElement(VectorGraphic*);
void ReportVectorGraphic(VectorGraphic*);
VectorGraphic Image;
int main()
{
char response;
InitVectorGraphic(&Image);
//for debugging purposes
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//main menu for the program
while (RUNNING)
{
printf("\nPlease select an option:\n");
printf("1. Add a Graphic Element\n");
printf("2. List the Graphic Elements\n");
printf("q. Quit\n");
printf("CHOICE: ");
fflush(stdin);
scanf("%c", &response);
switch (response)
{
case '1':
AddGraphicElement(&Image);
break;
case '2':
ReportVectorGraphic(&Image);
break;
case 'q':
CleanUpVectorGraphic(&Image);
return 0;
default:
printf("Please enter a valid option\n");
}
printf("\n");
}
}
/*initialize the vectors, allocate memory*/
void InitVectorGraphic(VectorGraphic * pImage)
{ //addres of pImage is passed in
struct GraphicElement *pElements;
pImage->pElements = (GraphicElement*) malloc(sizeof(GraphicElement)); //pImage is now the addess of image
pElements = (GraphicElement*) malloc(sizeof(GraphicElement));
pImage->numGraphicElements = 8;
pImage->pElements = NULL;
}
Here
line = (struct Line *) malloc(sizeof(Line));
the code allocates exactly one line-object.
Here its seems to address more then just line[0]:
line[pImage->numGraphicElements]....
Doing so the code invokes undefined behaviour, anything can happen from this moment on. This includes overwriting other memory belonging to the same process.

Some questions regarding 2d Vectors, C++

This 2d vector is being used to hold a game-board for minesweeper. I want to create a 2d vector of struct cell, which has several "state" variables all holding information needed to construct the game board (I am creating a basic minesweeper game to run on the command line, very rudimentary, just want to get a better grasp of classes). First of all, what am I doing wrong when trying to pass the vector to the void function? And then how would I be able to access the separate variables to read and write to them? I know this may be unusual (could solve using arrays) but I'd like to do it a little differently. I have looked through various forums but people don't seem to use this approach. Thanks guys.
EDIT:
What I'm trying to accomplish with the vector of cell's is basically 3 vectors in 1 so that I can simultaneously use the information in the different states to check whether various conditions have been met when a player makes a move (i.e. check whether there is a mine there, or whether that spot has already been opened/marked/unmarked etc.) Please let me know if the code below doesn't allow for what I want to accomplish.
code:
#include <iostream>
#include <vector>
using namespace std;
void gameboard(vector<vector<int>> &stateboard)
struct cell
{
int state; //( 0 hidden, 1 revealed, 2 marked)
int value; //(-1 mine, 0 no surrounding, # > 0
bool isMine;
};
void gameboard(vector<vector<int>> &stateboard)
{
}
int main()
{
int columns = 10;
int rows = 10;
vector <vector<cell> > gameboard(rows, vector<cell>(columns));
gameboard(&gameboard);
return 0;
}
sorry guys, this piece of code doesn't even begin to resemble the outline I have in Xcode, I was just trying to present the question in an easier to follow manner and threw this together.
new code:
#include <iostream>
#include <vector>
using namespace std;
struct cell
{
int state; //( 0 hidden, 1 revealed, 2 marked)
int value; //(-1 mine, 0 no surrounding, # > 0
bool isMine;
};
void game_state(vector<vector<cell>> &stateboard)
{
}
int main()
{
int columns = 10;
int rows = 10;
vector <vector<cell> > gameboard(rows, vector<cell>(columns));
game_state(gameboard);
return 0;
}
I guess having the same name for a function and vector was throwing Xcode off, which is why I made game board a reference originally but now I see why that was stupid. Now that this works, how can i specifically read and write to just the bool isMine variable? I'm not asking for you to do it completely but a basic line of code showing me how to access that specific part would be a greatly help me. Am I conceptualizing this incorrectly?
hope it helps you:
#include <iostream>
#include <vector>
// your columns and rows are equal,
//and they should no change, so i think better to do them const
const int BOARD_SIZE = 10;
struct cell {
int state;
int value;
bool isMine;
};
void game_state(std::vector < std::vector <cell > > &stateboard) {
}
int main (){
std::vector < std::vector <cell > > gameboard;
//I give more preference to initialize matrix like this
gameboard.resize(BOARD_SIZE);
for (int x = 0; x < BOARD_SIZE; x++) {
gameboard[x].resize(BOARD_SIZE);
for (int y = 0; y < BOARD_SIZE; y++) {
// and this is an example how to use bool is mine
// here all cells of 10x10 matrix is false
// if you want place mine in a first cell just change it
// to gameboard[0][0].isMine = true;
gameboard[x][y].isMine = false;
}
}
game_state(gameboard);
return 0;
}

C++ total beginner needs guidance [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
yesterday,we had to solve problems at the codeforces contest
I couldn't solve this problem since I am a total beginner.
http://codeforces.com/contest/353/problem/A
I used this algorithm, but something is wrong with it. I think it should print s or f, however it prints nothing. it just auto closes. Even when I added an input to stop instant close
#include <cstdlib>
#include <iostream>
using namespace std;
int main(){
int y=0;
int x=0;
int f;
int a;
cin >> a;
int s;
s = 0;
int number [a][a];
for(int i = 0;i<a;i++){
cin >> number[i][0] >> number[i][1];
x += number[i][0];
y += number[i][1];
}
for(int i = 0;i<a;i++){
if(x%2==0 && y%2==0){
return s;
}else if(y%2!=0 && x%2==0){
f = -1;
return f;
}else if(y%2==0 && x%2!=0){
f = -1;
return f;
}else{
y+= number[i][0];
x+= number[i][1];
s++;
}
}
int g;
if(f!=-1){
cout << s;
}else{
cout << f;
}
}
As Angew said, the return statements are incorrect and causing you to exit your main. You want to replace this by a break; to exit the loop but not the function.
I have not spent effort in trying to understand your algorithm, but at first glance it looks more complicated than it should be.
From my understanding of the problem, there are 3 possibilities:
the totals of the upper halves and the lower halves are already even (so nothing needs to be done)
the totals of the upper halves and the lower halves cannot be made even (so no solution exists)
just one Domino needs to be rotated to get the totals of the upper halves and the lower halves to be even (so the time needed is 1 second)
I base this on the fact that adding only even numbers always gives an even result, and adding an even number of odd numbers also always gives an even result.
Based on this, instead of having a 2-dimensional array like in your code, I would maintain 2 distinct arrays - one for the upper half numbers and the other for the lower half numbers. In addition, I would write the following two helper functions:
oddNumCount - takes an array as input; simply returns the number of odd numbers in the array.
oddAndEvenTileExists - takes 2 arrays as input; returns the index of the first tile with an odd+even number combination, -1 if no such tile exists.
Then the meat of my algorithm would be:
if (((oddNumCount(upper_half_array) % 2) == 0) && ((oddNumCount(lower_half_array) % 2) == 0))
{
// nothing needs to be done
result = 0;
}
else if (((oddNumCount(upper_half_array) - oddNumCount(lower_half_array)) % 2) == 0)
{
// The difference between the number of odd numbers in the two halves is even, which means a solution may exist.
// A solution really exists only if there exists a tile in which one number is even and the other is odd.
result = (oddAndEvenTileExists(upper_half_array, lower_half_array) >= 0) ? 1 : -1;
}
else
{
// no solution exists.
result = -1;
}
If you wanted to point out exactly which tile needs to be rotated, then you can save the index that "oddAndEvenTileExists" function returns.
You can write the actual code yourself to test if this works. Even if it doesn't, you would have written some code that hopefully takes you a little above "total beginner".