i am having problem getting the correct object out from the lines
Cell cF = fList[rand() % fList.size()];//choose random frontier cell
Cell cl = inList[rand() % inList.size()];//choose random in cell
whenever i debug using visual studio, i can see a Cell will have it's members added due to the method pushToPrimsFrontierList(Cell& c), however when i try to get the object from the inList or fList, it seems like im not getting that same object reference, because its neighbour list is 0 again.what is happening here?
You can see from the image that during the first iteration a startCell is added to the inList, so when im accessing it it will return me only that one object, however that is not the case, it seems like my object is not even push_backed to the inList vector.
#ifndef __CELL_H_
#define __CELL_H_
#include <vector>
using namespace std;
class Cell{
private:
int x, y, val; // cell co-ordinate
bool visited;
void setX(int);
void setY(int);
vector<Cell> neighbourList;
public:
Cell();
Cell(int,int);
int getX();
int getY();
int getVal();
vector<Cell>& getNeighbourList();
void pushToNeighbourList(Cell&);
void setVal(int);
void setVisited(bool);
bool IsVisited();
bool equals(Cell&);
};
#endif
#ifndef GENMAZE_H
#define GENMAZE_H
#include <vector>
#include <iostream>
#include "cell.h"
using namespace std;
class GenMaze{
private:
int rows;
int cols;
int gridSize;
vector<vector<Cell>> mazeGrid;
vector<Cell> inList;
vector<Cell> fList;
public:
GenMaze(int,int);
void setRows(int);
void setCols(int);
void setGridSize(int);
int getGridSize();
int getRows();
int getCols();
vector<vector<Cell>>& getMazeGrid();
void setMazeGrid(vector<vector<Cell>>);
void setValAt(int,int, Cell);
void printMazeCoords();
void printMazeValue();
bool isOddBlock(int,int);
void Prims();
void pushToPrimsFrontierList(Cell&);
void printCell(Cell&);
void makePath(Cell&, Cell&);
void removeFromfList(Cell&);
};
#endif
void GenMaze::Prims(){
Cell startCell = mazeGrid[1][1];//startCell
inList.push_back(startCell);
pushToPrimsFrontierList(startCell);
int randomFrontier= 0;
int randomIn = 0;
while (!fList.empty()){
cout<< "e";
Cell cF = fList[rand() % fList.size()];//choose random frontier cell
Cell cl = inList[rand() % inList.size()];//choose random in cell
for (vector<Cell>::size_type i = 0; i != cl.getNeighbourList().size(); i++) {
if (cl.getNeighbourList()[i].equals(cF)){
inList.push_back(cF);
pushToPrimsFrontierList(cF);
makePath(cl, cF);
removeFromfList(cF);
}
}
}
}
void GenMaze::removeFromfList(Cell& c){
for (vector<Cell>::size_type i = 0; i != fList.size(); i++) {
if (fList[i].equals(c)){
fList.erase(fList.begin() + i);
}
}
}
void GenMaze::makePath(Cell& from, Cell& to){
cout << "making path";
//on top
if ((from.getX() - 2 == to.getX()) & (from.getY() == to.getY())){
mazeGrid[from.getX() - 1][from.getY()].setVal(0);
}
//on right
if ((from.getX() == to.getX()) & (from.getY() + 2 == to.getY())){
mazeGrid[to.getX()][from.getY() - 1].setVal(0);
}
//on bottom
if ((from.getX() + 2 == to.getX()) & (from.getY() == to.getY())){
mazeGrid[from.getX() + 1][from.getY()].setVal(0);
}
//on left
if ((from.getX() == to.getX()) & (from.getY() - 2 == to.getY())){
mazeGrid[from.getX()][from.getY() - 1].setVal(0);
}
}
void GenMaze::printCell(Cell& c){
cout << "(" << c.getX() << "," << c.getY() << ")";
}
void GenMaze::pushToPrimsFrontierList(Cell& c){
//push all Cells around the given Cell c, into the frontier list.
if (!(c.getX() - 2 < 0)){
Cell topCell = mazeGrid[c.getX() - 2][c.getY()];
fList.push_back(topCell);
c.pushToNeighbourList(topCell);
}
if (!(c.getY() - 2 < 0)){
Cell leftCell = mazeGrid[c.getX()][c.getY() - 2];
fList.push_back(leftCell);
c.pushToNeighbourList(leftCell);
}
if (!(c.getY() + 2 > getCols() - 1)){
Cell rightCell = mazeGrid[c.getX()][c.getY() + 2];
fList.push_back(rightCell);
c.pushToNeighbourList(rightCell);
}
if (!(c.getX() + 2 > getRows() - 1)){
Cell bottomCell = mazeGrid[c.getX() + 2][c.getY()];
fList.push_back(bottomCell);
c.pushToNeighbourList(bottomCell);
}
}
To the std::vector as pretty much to every STL collection you cannot put the reference to the object. If you do:
Cell c;
std::vector<Cell> myvector1;
std::vector<Cell> myvector2;
myvector1.push_back(c);
myvector2.push_back(c);
When you try to modify c in myvector1 the value won't be propagated to myvector2. This is because push_back adds the element by value not by reference. If you need the real reference to some object you should create collection of pointers to elements and the code should rather look like this:
Cell *c = new Cell;
std::vector<Cell*> myvector1;
std::vector<Cell*> myvector2;
myvector1.push_back(c);
myvector2.push_back(c);
Now when you want to modify element beneith c you just do:
myvector1[indexofc]->somecellfield = othervalue
Related
The title pretty much says it all. I'm required to write a program for a Software course I'm taking that puts two basic algorithms against each other in a game of checkers. For this, I have a Square class that stores whether the square is occupied (bool), which player by (enum Pl, either NA, P1, or P2), and the label of that square (Index, int). I then created a Board class, which is effectively a 2D array of Squares that will have dimensions specified by the user. However, in the implementation file of my Board class, I'm having an error using the board[][] array in one of my functions. I get the error "board was not declared in this scope", which shouldn't be too tricky to figure out, except that the exact same syntax (at least from what I can see, and I've been working on fixing this for a while now) that's causing the error works perfectly in the constructor for the Board class in the same file. Below is the code for my Board.h file, and the relevant parts of my Board.cpp file:
Board.h:
#ifndef BOARD_H
#define BOARD_H
#include "Square.h"
#include <string>
class Board
{
public:
Board(int);
int getBsize();
int getWinner();
std::string getCmove();
Square getSquare(int, int);
void setWinner(int);
void setCmove(std::string);
bool canMoveL(int, int);
bool canMoveR(int, int);
bool canTakeL(int, int);
bool canTakeR(int, int);
void P1Move(int, int);
void P2Move(int, int);
void printCmove(std::string);
void printWin(std::string);
private:
Square board[12][12];
int bSize;
int winner;
std::string cMove;
};
#endif // BOARD_H
Board.cpp constructor as well as top of the file (in case the error is with the libraries and files I've included in Board.cpp):
#include "Square.h"
#include "Board.h"
#include <string>
Board::Board(int bSize)
{
Board::bSize = bSize;
Board::winner = 0;
Board::cMove = "";
Board::board[12][12];
int x = bSize-1;
int index = 1;
for(int j = 0; j < bSize; j++)
{
for(int i = 0; i < bSize; i++)
{
if(((i%2!=0)&&(j%2==0))||((i%2==0)&&(j%2!=0)))
{
if((j==x/2)||(j==x/2+1))
{
board[i][j] = Square(false, NA, index);
index++;
}
else if(j < x/2)
{
board[i][j] = Square(true, P1, index);
index++;
}
else if(j > x/2+1)
{
board[i][j] = Square(true, P2, index);
index++;
}
}
else
{
board[i][j] = Square(false, NA, 0);
}
}
}
}
Function in Board.cpp causing the error:
bool canMoveL(int i, int j)
{
bool temp = false;
Square sq = board[i][j];
if((i-1 < 0)||((sq.getPl() == P1)&&(j-1 >= bSize))||((sq.getPl() == P2)&&(j-1 < 0)))
{
return temp;
}
if(sq.getOcc() == 0)
{
return temp;
}
else
{
if(sq.getPl() == P1)
{
temp = true;
}
else if(sq.getPl() == P2)
{
temp = true;
}
}
return temp;
}
Note: Since I haven't been able to test the canMovL function, I realise there may be errors in that as well, but I'm specifically just looking for help fixing the error I get with the board array in canMovL(). Thanks.
bool canMoveL(int i, int j)
should be
bool Board::canMoveL(int i, int j).
else you define free function unrelated to Board.
This is my code:
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#define ENTITY(A) entity##A
#define ALM(A) alm##A
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity ENTITY(i)(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable ALM(i)(&ENTITY(i));
list->Push(&ALM(i));
size++;
}
//do things like printing their value...
delete list;
return 0;
}
I need to create a new variable everytime it run the "TEntity ENTITY(i)" line,
the problem is that it creates the same variable always, I think it is because it creates the variable entityi and therefore it is overwriting on the same variable, besides it seems that the random it generates is always the same number since all entities have the same values in all its parameters. The c variable create a const char * random variable between a-z, A-Z , I don't put the print code because it is unnecessary, so what can I do? Is there any way to dynamically create variables of entities whose values are random?
EDIT
Here is the new code fixed (the macros have been eliminated since they were not necessary and the necessary code has been included to be able to execute it) but there is still the same problem that they are generated with the same parameters (since they are still the same variable):
#include <cstdlib>
#include <ctime>
#include <stdio.h>
#include <vector>
#include <conio.h>
#include <windows.h>
struct TEntity{
private:
int sumx;
int sumy;
const char * rep;
int m_ix;
int m_iy;
public:
TEntity(int x, int y, int sum_x, int sum_y, const char * txt);
void movimiento();
void pinta();
};
TEntity::TEntity(int x, int y, int sum_x, int sum_y, const char * txt) {
m_ix = x;
m_iy = y;
sumx = sum_x;
sumy = sum_y;
rep = txt;
}
void TEntity::movimiento() {
m_ix += sumx;
m_iy += sumy;
}
void TEntity::pinta() {
gotoxy(static_cast<short int>(m_ix), static_cast<short int>(m_iy));
printf("%s", rep);
}
void gotoxy(short int x, short int y)
{
COORD pos = {x, y};
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}
void clear()
{
system("cls");
}
class IAlmacenable {
private:
void * element;
public:
IAlmacenable(void * e);
IAlmacenable();
void * getValue();
};
IAlmacenable::IAlmacenable(void *e) {
element = e;
}
IAlmacenable::IAlmacenable() {
element = nullptr;
}
void * IAlmacenable::getValue() {
return element;
}
class TList {
private:
std::vector<IAlmacenable*> elementos;
int position;
public:
TList();
int Size();
int Push(IAlmacenable* psz);
IAlmacenable* First();
IAlmacenable* Next();
};
TList::TList() {
elementos = std::vector<IAlmacenable*>();
position = 0;
}
int TList::Size() {
return elementos.size();
}
int TList::Push(IAlmacenable* psz) {
int res = 0;
if (elementos.size() >= elementos.max_size()) {
res = -1;
}
else {
elementos.push_back(psz);
}
return res;
}
IAlmacenable* TList::First() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
res = elementos.front();
position = 1;
}
return res;
}
IAlmacenable* TList::Next() {
IAlmacenable* res;
if (elementos.empty()) {
res = nullptr;
}
else {
int pos = position;
int size = elementos.size();
if (pos < size) {
res = elementos.at(position);
position++;
}
else {
res = this->First();
}
}
return res;
}
int main(){
srand(time(NULL));
TList *list = new TList();
//we can put entities in the list and the rest will be filled up to 5
int size = list->Size();
for(int i = size; i<5;i++){
const char c[] = {(rand() % 2 ? 65 + rand() % 25 : 97 + rand() % 25), '\0'};
TEntity *entity = new TEntity(rand() % 10, rand() % 10, rand() % 5, rand() % 5, c);
IAlmacenable *alm = new IAlmacenable(entity);
list->Push(alm);
size++;
}
while(true){
clear();
for (int i = 0; i < size; i++) {
reinterpret_cast<TEntity *>(list->Next()->getValue())->pinta();
reinterpret_cast<TEntity *>(list->Next()->getValue())->movimiento();
}
Sleep(2000);
}
delete list;
return 0;
}
There is some confusion here.
Some points:
The macro is not fit-for-purpose, as you already know; you're just creating a variable name entityi each time;
That doesn't matter! The object only exists for the duration of the loop iteration anyway; C++ doesn't let you create multiple objects with the same name at the same time. In fact you can get rid of the entire macro stuff and just call the object entity;
Now that that's out of the way, you're getting repeated results because you're storing a pointer to each iteration of that local variable — on each occasion, that's a dangling pointer to an object that's been destroyed. Don't store dangling pointers!
You can either:
Dynamically allocate the objects that you're adding to the list, or
Store actual objects rather than pointers-to-objects.
Either way, the local-scope name is irrelevant and certainly need not change repeatedly for each loop iteration.
So I'm trying to create a program that mimics the Minesweeper game. I have double-checked the header files, the class names, and made sure the headers are #included in the other cpp files, but when I try to build the program, I get a LNK2019 error in the "Main" class I have.
Error in full:
Error 1 error LNK2019: unresolved external symbol "public: __thiscall
Board::Board(int,int,int)" (??0Board##QAE#HHH#Z) referenced in
function _main \fpsb\g\gathmr26\visual studio
2013\Projects\Minesweeper\Minesweeper\Main.obj Minesweeper
I've spent probably around 2 hours looking at answers here on StackOverflow and elsewhere and got nowhere. I've run down through every bullet point in this MSDN page, and every "common cause" in this popular answer, and none of them seemed to apply to my situation. I've also tried all the "Diagnosis tools" options on the MSDN page and all they've done is just confuse me more.
The closest I have to my situation (as far as I can tell) is this question except that all of my code is just in one project, not multiple. One of the people who answered that question has said "I typed this code into my Visual Studio and it worked fine", having assumed that the files were in one project. I don't understand why that answer got it working there when I have pretty much the same situation here.
So, anyway, here is the code:
Main.cpp
#include <iostream>
#include <string>
#include "Cell.h"
#include "Board.h"
int main() {
Board *bee;
bee = new Board(50, 50, 50);
std::cout << "board created";
return 0;
}
Board.cpp
#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;
#include "Cell.h"
#include "Board.h"
#ifndef BOARD_H
#define BOARD_H
// Board class. Used to create an array of cell objects to function as data model for Minsweeper game.
class Board
{
private:
int width; // number of columns in board
int height; // number of rows in board
int mines; // number of mines stored in board
Cell*** cells; // array storing cell objects
public:
// Constructor for board. Takes number of columns, rows, and mines as parameters
Board::Board(int cols, int rows, int numMines) {
width = cols;
height = rows;
mines = numMines;
cells = new Cell**[height];
for (int i = 0; i < height; i++) {
cells[i] = new Cell*[width];
}
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
setCell(c, r, CellValue::COVERED_CELL);
c++;
}
c = 0;
r++;
}
int m = 0;
while (m < numMines)
{
std::srand(std::time(nullptr));
int x = generateRandomNumberInRange(0, width - 1);
int y = generateRandomNumberInRange(0, height - 1);
if (!(getCellVal(x, y) == MINE))
{
setCell(x, y, CellValue::MINE);
m++;
}
}
}
// Accessor for width field
int Board::getWidth()
{
return width;
}
// Accessor for height field
int Board::getHeight()
{
return height;
}
// Accessor for mines field
int Board::getMines()
{
return mines;
}
// Function to access value of cell located in array where x is column parameter and y is row parameter
CellValue Board::getCellVal(int x, int y)
{
CellValue value = CellValue::INVALID_CELL;
if (!(x < 0 || x >(width - 1) || y < 0 || y >(height - 1)))
{
Cell temp = *cells[x][y];
value = temp.getValue();
}
return value;
}
// Function to set value of cell located in array where x is column parameter and y is row parameter
void Board::setCell(int x, int y, CellValue value)
{
if (!(x < 0 || x >(width - 1) || y < 0 || y >(height - 1)))
{
Cell temp = *cells[x][y];
temp.setValue(value);
}
}
// Function to determine if game is lost
// Loops through array to see if there are any UNCOVERED_MINES
// If so, returns true, game ends, as you've lost :(
// If not, returns false and game can continue
// Should run after every click action in game
bool Board::isGameLost()
{
bool isLost = false;
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
if (getCellVal(c, r) == UNCOVERED_MINE)
{
isLost = true;
}
c++;
}
c = 0;
r++;
}
return isLost;
}
// Function to determine if game is won
// Loops through array to determine if there are any falsely flagged mines, unflagged mines, covered cells, or uncovered mines
// If there are, returns false and game continues
// If not, returns true, games ends, you've won :)
bool Board::isGameWon()
{
bool isWon = true;
int c = 0;
int r = 0;
while (r < height)
{
while (c < width)
{
CellValue value = getCellVal(c, r);
if ((value == FLAG) ||
(value == MINE) ||
(value == COVERED_CELL) ||
(value == UNCOVERED_MINE))
{
isWon = false;
}
c++;
}
c = 0;
r++;
}
return isWon;
}
};
#endif
Board.h
#include <iostream>
#include <string>
#include "Cell.h"
#ifndef BOARD_H
#define BOARD_H
class Cell;
enum CellValue;
class Board
{
private:
int width;
int height;
int mines;
Cell*** cells;
public:
Board(int cols, int rows, int numMines);
int getWidth();
int getHeight();
int getMines();
CellValue* getCellVal(int x, int y);
void setCell(int x, int y, CellValue value);
void uncoverCell(int x, int y);
void flagCell(int x, int y);
bool isGameLost();
bool isGameWon();
};
#endif
I know this is a common error that people have and that there's more than a handful of questions about this on StackOverflow, but at this point, I've not found any that seem to match what I have here. What is the issue here?
Seems like you're mixing header and source files. Your cpp file contains a class declaration with all the functions defined inside. This is not what a cpp file looks like. It should only contain function declarations:
Board::Board(...)
{
...
}
bool Board::IsGameWon...
etc...
Since I cannot answer my own question in 8 hours after asking, I'm posting my solution here.
Made some mistakes in the incoming channel number and number of the vector element. Setting the value of channel-1 instead of channel fixed to problem.
My new function is as follows:
void input(long inlet, t_symbol *s, long ac, t_atom *av){
// GET VARIABLES
long channel = atom_getlong(av);
double value = atom_getfloat(av + 1);
long v_size = v_chan.size();
if(channel && v_size < channel){
for(int i = v_size; i < channel; i++){
v_chan.push_back(n_chan);
}
v_chan[channel - 1].value = value;
}
else if(channel){
v_chan[channel - 1].value = value;
}
}
I've got a vector containing structs, which I like to push_back with a new, empty struct.
Example code:
struct channels{
double value;
// eventually more variables
};
vector<channels> v_chan;
channels n_chan;
void push(){
v_chan.push_back(n_chan);
}
The problem is, if my vector contains elements, push_back add an element, but also overwrites the last element.
For example, if my vector size is 1 and element 0 has a value of 0.2, after push_back my vector size is 2, but element 0 and 1 have a value of 0.
What am I doing wrong here?
Real Code: (MAX/MSP external, function input is called in Max)
#include <maxcpp6.h>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
struct bind{
string param;
double* value;
int track;
double base;
double multiplier;
};
struct channels{
double value;
vector<int> bind;
};
vector<channels> v_chan;
vector<bind> v_bind(19);
channels n_chan;
class rec : public MaxCpp6<rec> {
public:
rec(t_symbol * sym, long ac, t_atom * av) {
setupIO(1, 1); // inlets / outlets
}
~rec() {}
// methods:
//SET BIND FUNCTION
void setBind(long inlet, t_symbol *s, long ac, t_atom *av){
}
void output(long track, long type){
}
void input(long inlet, t_symbol *s, long ac, t_atom *av){
// GET VARIABLES
long channel = atom_getlong(av);
double value = atom_getfloat(av + 1);
long v_size = v_chan.size();
if(v_size <= channel){
v_chan.push_back(n_chan);
}
else{
v_chan[channel].value = value;
}
}
void dump(long inlet){
for(int i = 1; i <= v_chan.size(); i++){
post("%d %.2f", i, v_chan[i].value);
}
}
void clearTrackBinds(long inlet){
}
void reset(long inlet){
clearTrackBinds(0);
}
};
C74_EXPORT int main(void) {
// create a class with the given name:
rec::makeMaxClass("solar_receiver");
REGISTER_METHOD_GIMME(rec, input);
REGISTER_METHOD_GIMME(rec, setBind);
REGISTER_METHOD(rec, dump);
REGISTER_METHOD(rec, clearTrackBinds);
REGISTER_METHOD(rec, reset);
}
This is for a poker game and I have class PokerTable defined in PokerTable.h
#include <iostream>
using namespace std;
class PokerTable
{
private:
int numPlayers;
int numPlaying;
int dealerPos;
int bigBlind;
int potSize;
int betSize;
bool flop;
bool turn;
bool river;
public:
//constructors
PokerTable();
PokerTable(int,int,int,int,int,bool,bool,bool);
//getters
int getNumPlayers(){return numPlayers;};
int getDealerPos(){return dealerPos;};
int getBigBlind(){return bigBlind;};
int getNumPlaying(){return numPlaying;};
int getPotSize(){return potSize;};
int getBetSize(){return betSize;};
bool getFlop(){return flop;};
bool getTurn(){return turn;};
bool getRiver(){return river;};
//void buttonShow(int);
//setters
void setBetSize(int inBetSize){betSize = inBetSize;};
void setBigBlind(int inBigBlind){bigBlind = inBigBlind;};
void setNumPlaying(int inNumPlaying){numPlaying = inNumPlaying;};
void setPotSize(int inPotSize){potSize = inPotSize;};
void setFlop(bool inFlop){flop = inFlop;};
void setTurn(bool inTurn){turn = inTurn;};
void setRiver(bool inRiver){river = inRiver;};
void setNumPlayers(int inPlayers){numPlayers = inPlayers;};
void setDealerPos(int inDealerPos){dealerPos = inDealerPos;};
};
PokerTable::PokerTable()
{
numPlayers = 9;
numPlaying = 9;
dealerPos = 1;
bigBlind = 20;
flop = false;
turn = false;
river = false;
}
PokerTable::PokerTable(int playerNum, int playingCount, int posDealer, int blindBig,int inPotSize, bool inFlop,bool inTurn,bool inRiver)
{
numPlayers = playerNum;
numPlaying = playingCount;
dealerPos = posDealer;
potSize = inPotSize;
bigBlind = blindBig;
flop = inFlop;
turn = inTurn;
river = inRiver;
}
In my watch list pokerTable.numPlayers has a random value up to 4 million before I even execute this next line of code.
PokerTable aPokerTable(9,9,1,20,30,false,false,false);
and afterwards here is pokerTable in my watch list:
- aPokerTable { numPlayers=2990892 numPlaying=9 dealerPos=9 ...} PokerTable
betSize 30 int
bigBlind 1 int
dealerPos 9 int
flop false bool
numPlayers 2990892 int
numPlaying 9 int
potSize 20 int
river false bool
turn false bool
Can anyone tell me why all the values are not what I declared them to be??!?!!
And how I can fix this?
This is Form1.h
#pragma once
#include "PokerTable.h"
#include "Card.h"
#include <time.h>
#include "PokerPlayer.h"
#include <fstream>
#include <string>
#include <sstream>
//global variables
//TODO make players start from 0
int firstPlayer;
int deck[52];
int nextCard=0;
PokerTable aPokerTable(9,9,1,20,30,false,false,false);
PokerPlayer players[9]; //however many players
ofstream gameLog;
/*
void setTable()
{
aPokerTable.setNumPlayers(9);
aPokerTable.setNumPlaying(9);
aPokerTable.setDealerPos(1);
aPokerTable.setBigBlind(20);
aPokerTable.setPotSize(30);
aPokerTable.setBetSize(20);
aPokerTable.setFlop(false);
aPokerTable.setTurn(false);
aPokerTable.setRiver(false);
}
*/
string convertInt(int number) //convert to string
{
stringstream ss;//create a stringstream
ss << number;//add number to the stream
return ss.str();//return a string with the contents of the stream
}
void createPlayers()
{
// aPokerTable.setNumPlayers(9);
for(int x=0;x<=(aPokerTable.getNumPlayers()-1);x++)
{
players[x] = *(new PokerPlayer(1000,(aPokerTable.getDealerPos())+1,false,0,1));//1000 chips, position i+1, not folded
}
}
void playRound()
{
int action;
for(int playerTurn = firstPlayer; playerTurn <= aPokerTable.getNumPlayers()+firstPlayer; playerTurn++)
{
if(players[playerTurn].getFold() == false)
{
if(aPokerTable.getNumPlaying() == 1)
{
players[playerTurn].setChipStack(players[playerTurn].getChipStack() + aPokerTable.getPotSize()); //player wins pot
}
else //there is more than one person playing
{
action = players[playerTurn].action(); //0 is check/fold, value is call/bet/raise,
if(action > aPokerTable.getBetSize())
{
aPokerTable.setBetSize(action);
aPokerTable.setPotSize(aPokerTable.getPotSize() + action);
playerTurn = playerTurn - aPokerTable.getNumPlayers();
}
else if (action == aPokerTable.getBetSize()) //call
{
aPokerTable.setPotSize(aPokerTable.getPotSize() + action);
}
else //action < aPokerTable.betSize
{
players[playerTurn].setFold(true);
aPokerTable.setNumPlaying(aPokerTable.getNumPlaying()-1); //removes player from playing tally
}
}
}
}
}
void randomDeck()
{
int random_integer;
int tempCard;
//srand((unsigned)time(0));
for(int j=0;j<=51;j++)
{
deck[j] = j;
}
for(int i=51; i>=1; i--)
{
random_integer = rand()%(i); //a random number between 0 and i
tempCard = deck[i];
deck[i] = deck[random_integer]; //put the random card from unshuffled deck into slot i of the deck
deck[random_integer] = tempCard; //put whatever was at slot i into the random slot
}
}
void dealCards()
{
for(int j=1;j<=aPokerTable.getNumPlayers();j++)
{
players[j].setCard1(deck[nextCard]);
nextCard++;
players[j].setCard2(deck[nextCard]);
nextCard++;
}
}
void playPreFlop()
{
aPokerTable.setBetSize(aPokerTable.getBigBlind());
aPokerTable.setFlop(false); //it is before the flop
aPokerTable.setTurn(false);
aPokerTable.setRiver(false);
randomDeck(); //shuffle cards
dealCards();
firstPlayer = (aPokerTable.getDealerPos() + 3)%(aPokerTable.getNumPlayers()); // first player is left of blinds between 0 and numplayers
playRound();
}
void playFlop()
{
aPokerTable.setFlop(true);
firstPlayer = (aPokerTable.getDealerPos())%aPokerTable.getNumPlayers(); // first player is left of dealer between 0 and numplayers
aPokerTable.setBetSize(0);
playRound();
}
void playTurn()
{
aPokerTable.setTurn(true);
firstPlayer = (aPokerTable.getDealerPos())%aPokerTable.getNumPlayers(); // first player is left of dealer between 0 and numplayers
aPokerTable.setBetSize(0);
playRound();
}
void playRiver()
{
aPokerTable.setRiver(true);
firstPlayer = (aPokerTable.getDealerPos())%(aPokerTable.getNumPlayers()); // first player is left of dealer between 0 and numplayers
aPokerTable.setBetSize(0);
playRound();
if(aPokerTable.getNumPlaying() >=2)
{
//showDown();
}
}
/*
void showDown()
{
}
*/
This is pokerPlayer.h
using namespace std;
class PokerPlayer
{
private:
int chipStack,position;
bool fold;
int card1,card2;
public:
//constructors
PokerPlayer();
PokerPlayer(int,int,bool,int,int);
//getters
int getChipStack() {return chipStack;}
int getPosition() {return position;}
int getCard1(){return card1;}
int getCard2(){return card2;}
bool getFold(){return fold;}
//setters
void setChipStack(int inChips){chipStack = inChips;}
void setPosition(int inPos){position = inPos;}
void setCard1(int inCard1){card1 = inCard1;}
void setCard2(int inCard2){card2 = inCard2;}
void setFold(bool inFold){fold = inFold;}
int action();
};
PokerPlayer::PokerPlayer()
{
chipStack = 1000;
position = 0;
fold=false;
card1 = 0;
card2 = 1;
}
PokerPlayer::PokerPlayer(int inChipStack,int inPos, bool inFold, int inCard1, int inCard2)
{
chipStack = inChipStack;
position = inPos;
fold = inFold;
card1 = inCard1;
card2 = inCard2;
}
int PokerPlayer::action()
{
return 0;
}
aPokerTable { numPlayers=2990892 numPlaying=9 dealerPos=9 ...}
Note that dealerPos got assigned the value 9, that's wrong as well. If you look closely, you'll see that everything is shifted by 4 bytes.
Two possible reasons. The debugger could have picked the wrong address for aPokerTable, the actual address minus 4. That's unlikely. Or there's a mismatch between the definition of the PokerTable class as seen by pokertable.cpp and the other .cpp files that #include the pokertable.h include file. Where pokertable.cpp saw an extra member before the numPlayers member. Maybe you edited the header and deleted that member but ended up not recompiling pokertable.cpp for some mysterious reason. Build + Rebuild to fix. Do panic a bit if this actually works.
It's because in C++ before the constructor is called, variable uses the value that it already contains in its memory location that is a "random" value
I cannot reconstruct it because i dont have the full code. However, a random value near 4 million sounds like a pointer. When you store or retrieve a member variable maybe you did not de-reference the pointer. Please post the rest of the code so we can check if that's the case.
players[x] = *(new PokerPlayer(...));
That is a memory leak. What you probably want is:
players[x] = PokerPlayer(1000,(aPokerTable.getDealerPos())+1,false,0,1);