C++ creating a forest - c++

am new to c++ and am trying to create a burning forest simulator. I have been trying to call a function from the forest class but i dont know how to give it an argument, if anyone could help that would be great here is the code that i have at the moment.
using namespace std;
class ForestSetup
{
private:
const char Tree = '^';
const char Fire = '*';
const char emptySpace = '.';
const char forestBorder = '#';
const int fireX = 10;
const int fireY = 10;
char forest[21][21];
public:
void CreateForest()
{
// this function is to create the forest
for (int i = 0; i < 21; i++) // this sets the value of the rows from 0 to 20
{
for (int j = 0; j < 21; j++) // this sets the value of the columns from 0 to 20
{
if (i == 0 || i == 20)
{
forest[i][j] = forestBorder; // this creates the north and south of the forest border
}
else if (j == 0 || j == 20)
{
forest[i][j] = forestBorder; // this creates the east and the west forest border
}
else
{
forest[i][j] = Tree; // this filles the rest of the arrays with trees
}
}
}
forest[fireX][fireY] = Fire; // this sets the fire in the middle of the grid
}
void ShowForest(char grid[21][21])
{
for (int i = 0; i < 21; i++)
{
for (int j = 0; j < 21; j++)
{
cout << grid[i][j];
}
cout << endl;
}
}
};
int main(void)
{
ForestSetup myForest;
myForest.ShowForest();
system("Pause");
return 0;
}

Let's say you have a setOnFire function with the x and y co-ordinates of where you want to start the fire.
public:
setOnFire(int x, int y)
{
// Code to flag that part of the forest on fire
}
In your main, you would call it with
myForest.setOnFire(5,5);
Within the ForestSetup class you just need setOnFire(5,5);
This tutorials point article might help.

Related

Gomoku winning condition c++ using pointers and arrays

I am currently working on a Gomoku game in c++. But I'm stuck with the winning conditions. I'm new to c++. I need to add the winning conditions using pointers for this game. Please I need help. I don't know how to start with it. So far I can only insert the player moves into the arrays. I need the pointers to determine the 8 directions for the winning condition.
Winning conditions are:
5 in a row horizontally, vertically, diagonally (but this must also be changed to 3 in a row, 4 in a row etc)
the header file
// file goboard.h
class boardBox{
public:
char PlayerColor; //z or W // 7 0 1
boardBox* neighbours[8]; // 6 2
boardBox( ); // 5 4 3
};//boardBox
class goboard {
private:
boardBox* entrance;
int height, width;
static const int gridX = 6;
static const int gridY = 7;
char grid[gridX][gridY];
// TODO
public:
void ask_turn(char symb);
goboard ( );
goboard (int height, int width);
~goboard ( );
void showBoard( );
void generate();
// TODO
};//goboard
this file linked with the header file
// file goboard.cc
#include <iostream>
#include "goboard.h"
using namespace std;
goboard::goboard ( ) {
// TODO
}//goboard::goboard
goboard::~goboard ( ) {
// TODO
}//goboard::~goboard
void goboard::generate()
{
cout << "Board shows like this." << endl;
int number = 1;
for(int x = 0; x < gridX; x++)
{
for(int y = 0; y < gridY; y++)
{
grid[x][y] = '.';
}
}
}
void goboard::showBoard( ) {
printf("\n................\n");
for(int x = 0; x < gridX; x++)
{
for(int y = 0; y < gridY; y++)
{
printf("%c |", grid[x][y]);
}
printf("\n");
}
cout<<endl;
// TODO
}//goboard::showBoard
void goboard::ask_turn(char symb) //symb is symbol Z or W
{
int input;
int input2;
while( true )
{
cout<<"Where would you like to play?"<<endl;
cin>>input;
cin>>input2;
int index = input;
int index2 = input2;
int row = index;
int col = index2;
char grid_position = grid[row][col];
if(grid_position == 'Z' || grid_position == 'W')
{
puts("That grid position is already take!");
}else{
grid[row][col] = symb;
break;
}
}
}
// TODO
The main file
// file hoofd.cc
#include <iostream>
#include <string>
#include "gobord.h"
#define GRID_SIZE 3
using namespace std;
int main (int argc, char *argv[] ) {
goboard Goboard;
Goboard.generate();
char symb = 'Z';
char symb1 = 'W';
while(true){
Goboard.showBoard( );
Goboard.ask_turn(symb);
Goboard.showBoard();
Goboard.ask_turn(symb1);
}
return 0;
}//main
EDIT: You need to change your datastructure from a char[][] to a boardBox[][].
In your constructor, you need to fix up each boardBox' neighbours array as follows:
goboard::goboard() {
for (int r = 0; r < gridX; r++) {
for (int c = 0; c < gridY; c++) {
boardBox& box = grid[r][c];
box.neighbours[0] = get_box(r-1, c);
box.neighbours[1] = get_box(r-1, c+1);
// and so on
}
}
}
boardBox* goboard::get_grid(int row, int col) {
return in_board(row, col) ? &grid[row][col] : nullptr;
}
where get_grid returns a pointer to the boardBox or a null pointer if that cell is out of bounds.
A win condition happens right after a move, so logically the just-placed piece must be part of the five-in-a-row in either direction.
Let's first implement a function that follows a certain direction and counts the number of pieces of a given symbol in that direction:
int count_direction(boardBox *box, int direction, char symb) {
int count = 0;
while (box) {
if (box->playerColor != symb)
break;
box = box->neighbours[direction];
}
return count;
}
This follows the pointers in the neighbours array until we hit the end of the board, denoted by a null pointer.
We can use this as follows to count the number of pieces along a diagonal:
boardBox *box = get_grid(row, col);
int count_diagonal1 = count_direction(box, 3, symb) // down and to the right
+ count_direction(box, 7, symb) // up and to the left
- 1; // count_direction visits (row,col) twice!
Implementing the other directions and determining the win condition from the counts is left to you :)

Dynamic ASCII Box with Numbers Inside

Having a problem in making a dynamic box using these set of ASCII codes. I'm really lost on what to do. This dynamic box also has numbers inside them.
I already tried making loops inside loops to adjust the box's size.
int main(){
char asciis[] = {'\xDA','\xB3','\xC3','\xC0','\x20','\xC4','\xC5','\xC1','\xBF','\xB4','\xD9', '\xC2'};
int box size = (n*2)+1;
char box[box size][box size]; //set the size of the box
//set a in all coordinates
/*for (int r = 0; r < n; r++){
for (int c = 0; c < n; c++){
box[r][c] = 'a';
}
}*/
for (int r = 0; r < n; r++){
for (int c = 0; c < n; c++){
for (int boxrow = 0; boxrow < box size; boxrow++){
for (int boxcol = 0; boxcol < box size; boxcol++){
//conditions
}
}
}
cout << endl;
}
}
This is the output I'm trying to create:
https://i.imgur.com/YRgMlaJ.png
Don't mind those numbers, I was just mapping the array.
I'm sure there's a simpler solution, but off the top of my head:
#include <iostream>
using namespace std;
enum BoxParts {
kLeftUpper = '\xDA',
kVertical = '\xB3',
kLeftBreak = '\xC3',
kLeftLower = '\xC0',
kEmpty = '\x20',
kHorizontal = '\xC4',
kIntersection = '\xC5',
kBottomBreak = '\xC1',
kRightUpper = '\xBF',
kRightBreak = '\xB4',
kRightLower = '\xD9',
kTopBreak = '\xC2',
kCount = 12
};
void drawLine(const int cellCount, const int cellWidth, const char left, const char divider, const char contents, const char right)
{
cout << left;
for (int i = 1; i < cellCount * cellWidth; ++i)
{
if (0 == i % cellWidth)
cout << divider;
else
cout << contents;
}
cout << right << endl;
}
void drawBox(const int cellCount, const int cellWidth, const int cellHeight)
{
// top
drawLine(cellCount, cellWidth, kLeftUpper, kTopBreak, kHorizontal, kRightUpper);
for (int i = 1; i < cellCount * cellHeight; ++i)
{
if (0 == i % cellHeight)
drawLine(cellCount, cellWidth, kLeftBreak, kIntersection, kHorizontal, kRightBreak);
else
drawLine(cellCount, cellWidth, kVertical, kVertical, ' ', kVertical);
}
// bottom
drawLine(cellCount, cellWidth, kLeftLower, kBottomBreak, kHorizontal, kRightLower);
}
int main(int argc, char** argv) {
const int n = 4;
drawBox(n, 10, 5);
getchar();
return 0;
}
Produces:

How do i make my function in my player class for game of hearts work without being a pointer?

I was assigned to make a game of hearts where there is an array of 4 people and each people has a hand of 13 cards. Currently, when dealing trying to deal cards to each person deck, I am only able to accomplish this using pointers. However, this has posed problems in getting other functions like sort and such to work. I know that it's possible to do it without pointers I'm just not sure how and was wondering if anybody could assist.
In the psudocode, my teacher gave us, the hand[13] array which holds the cards is not a pointer, but I made it a pointer in order to points the cards to it.
#include <iostream>
#include <iomanip>
#include "Card.h"
#include "Player.h"
#include <cstdlib>
#include <random>
using namespace std;
//Prototype
void shuffleDeck(Card deck1[])
{
int ranNum;
Card temp;
int count = 0;
for(int i = 0; i < 52; i++)
{
count++;
ranNum = (rand() % 52);
temp = deck1[ranNum];
deck1[ranNum] = deck1[i];
deck1[i] = temp;
}
}
int main()
{
//Declarations
int nextPlayer;
int firstPlayer;
Card deck2[4][13];
Suit temp;
Card deck1[52];
int count = 0;
int check = 0;
int round = 0;
int points = 0;
int numCards = 0;
//Part 1: The set-up
//Create player array of [4] players
Player player[4] = {Player("Me"),
Player("Elton John"),
Player("Snoop Dog"),
Player("Lady Gaga")
};
//create and initialize deck;
for (int r = 0; r < 4; r++)
{
for (int c = 0; c < 13; c++)
{
deck2[r][c].setNumber(c + 1);
temp = ((Suit)r);
deck2[r][c].setSuit(temp);
deck2[r][c].setDescription();
}
}
//Convert to one dimensional array
for(int i = 0; i < 4; i++)
{
for(int j = 0; j < 13; j++)
{
deck1[count] = deck2[i][j];
count++;
}
}
shuffleDeck(deck1); //call shuffle deck function
//Deal deck to players // have add card in player class that sticks a card in players deck
/*
for(int i = 0; i < 52; i++)
{
int playerIndex = i % 4;
player[playerIndex].addCard(&deck1[i]); //HERE IS WHERE I CALL IT IN THE MAIN
}
//Sort each players hand
for (int i = 0; i < 4; i++)
{
player[i].sort();
}
//Find player who goes first (the person holding the 2 of clubs) //firstPlayer
for(int j = 0; j < 4; j ++)
{
for(int i = 0; i < 13; i++)
{
if(player[j].getCard(i) == 20)
{
firstPlayer = j;
}
}
}
*/
Card openCard[4]; //keeps track of all played cards
// //Part 2: The play
for(int i = 0 ; i < 13; i++) //gonna play 13 rounds, same thing 13 times
{ numCards = 0;
round++;
// Print points of players
cout << "\nPlayer Round " << round << " Total\n";
cout << "------- -------- -----\n";
cout << "\nMe ";
cout << "\nSnoop Dogg ";
cout << "\nLady Gaga ";
cout << "\nElton John ";
// Print hand
cout << "\n\nMy Hand: \n" << "-------------\n\n";
for(int i = 0; i < 13; i++)
{
// cout << player[0].getCard(i) << "\n";
numCards++;
check++;
cout << numCards << ".) " << deck1[i].getDescription() << "\n";
}
for (int j = 0; j < 3; j++)
{
nextPlayer = (firstPlayer + j) % 4;
//Play a card
//Compare card to other card
// openCard[nextPlayer] = player[nextPlayer].playCard(deck1[i], firstPlayer);
//inside playCard() remove card from hand after it's played
// hand[cardPlayed] = null //null means played already// (I think this is another method of doing it)
}
//end for j
//count points per player
//firstPlayer = winner of round //implement this in
// if(firstPlayer) //something like this
// {
// points++;
// }
//add points to first player
}
//end for i
return 0;
}
//PLAYER CLASS
#ifndef PLAYER_H
#define PLAYER_H
#include "Card.h"
#include <iostream>
#include <iomanip>
using namespace std;
class Player
{
//Member variables
private:
string name;
public:
static int count;
Card *hand[13]; //TRYING TO MAKE THIS NOT A POINTER
int number;
bool played;
//Constructors
Player()
{
name = "";
}
Player(string n)
{
name = n;
}
string getName()
{
return name;
}
int getCard(int index)
{
return hand[index]->getNumber();
}
void setName(string n)
{
name = n;
}
// void addCard(Card *card) //THIS IS WHERE CARDS ARE DELT (HOW DO I
MAKE IT NOT A POINTER?)
// {
// if (number < 13)
// {
// hand[number] = card;
// number++;
// }
// }
// void sort()
// {
// for (int i = 1; i < 13; i++)
// {
// Card *temp;
// bool swap = false;
// int size = 52;
// do
// {
// swap = false;
// for (int count = 0; count < (size - 1); count++)
// {
// if (hand[count + 1] < hand[count])
// {
// temp = hand[count];
// hand[count] = hand[count + 1];
// hand[count + 1] = temp;
// swap = true;
// }
// }
// }
// while (swap == true);
// }
// }
// Card playCard(Suit lead, bool leader)
// {
// int cardPlayed;
// hand[cardPlayed] = -1; //null means played already// (I think this
is another method of doing it)
// }
};
#endif

Segmentation Fault when dealing with 2D Arrays [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 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.

Memory leak without allocating any memory?

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