Bad pointer error in class when passing array - c++

So I'm writing a simple battlesystem for a game and I'm getting an error passing an array of pointers to the battlesystem class.
//Create the player and 3 enemies
Battler player("Player", 100, 100, 50, 50, 50, 50, 90);
Battler foe1("Imp", 100, 100, 50, 50, 50, 50, 80);
Battler foe2("Ogre", 100, 100, 50, 50, 50, 50, 75);
Battler foe3("Giant", 100, 100, 50, 50, 50, 50, 60);
//Create an array of pointers that point to the enemies
Battler *foes[3];
foes[0] = &foe1;
foes[1] = &foe2;
foes[2] = &foe3;
//Initialize the battlesystem passing the player, the array of enemies
//and the number of enemies (3)
BattleSystem *btl = new BattleSystem(&player, *foes, 3);
So this was working fine, but when I pass the array to the class, the first member is passed fine, but the rest are passed and when I do a breakpoint, they are sent as "Badptr".
Here is the code for the battlesystem constructor:
BattleSystem::BattleSystem(Battler *plyr, Battler enemies[], int numEnemies)
{
player = plyr;
//foe is declared as Battler *foe; So it just points to the first member of the enemies
// array so I can access them. But only the first member gets a value the rest get
// "Bad ptr" with garbage values and when I look through the enemies array passed
// to the constructor, it has BAD PTRs in everything but the first element.
foe = enemies;
numFoes = numEnemies;
totalTurns = 0;
foeTurns = new int[numFoes];
turnList = new Battler*[numFoes + 1];
for(int i = 0; i <= numFoes; i++)
{
turnList[i] = &foe[i];
}
turnList[numFoes + 1] = player1;
}
I'm missing something obvious I think, but can anyone share some wisdom?
Thank you.

Leaving aside style issues about naked pointers and ownership, I believe you mean
// v-- array of pointers
BattleSystem::BattleSystem(Battler *plyr, Battler *enemies[], int numEnemies)
And
BattleSystem *btl = new BattleSystem(&player, foes, 3);

Related

How to assign value to dart enum like in c++

I'm trying to adapt a c++ to dart, and I ran into this situation with enum, assigning default values ​​I think. follow the code
enum skills_t : uint8_t {
SKILL_FIST = 0,
SKILL_CLUB = 1,
SKILL_SWORD = 2,
SKILL_AXE = 3,
SKILL_DISTANCE = 4,
SKILL_SHIELD = 5,
SKILL_FISHING = 6,
SKILL_CRITICAL_HIT_CHANCE = 7,
SKILL_CRITICAL_HIT_DAMAGE = 8,
SKILL_LIFE_LEECH_CHANCE = 9,
SKILL_LIFE_LEECH_AMOUNT = 10,
SKILL_MANA_LEECH_CHANCE = 11,
SKILL_MANA_LEECH_AMOUNT = 12,
SKILL_MAGLEVEL = 13,
SKILL_LEVEL = 14,
SKILL_FIRST = SKILL_FIST,
SKILL_LAST = SKILL_MANA_LEECH_AMOUNT
};
}
uint32_t skillBase[SKILL_LAST + 1] = {50, 50, 50, 50, 30, 100, 20};
Is it possible to adapt this code to dart/flutter?
I would like to replicate the same operation in dart, it seems that he assigned these values ​​to each enum in a range
Yes, it is possible to adapt this code to Dart/Flutter.
In Dart, you can use the enum keyword to define an enumeration. The syntax is similar to C++, but there is no need to specify a type like uint8_t.
Regarding the default values, you can initialize the enum members with a value like in C++.
Here is an example of how the C++ code could be adapted to Dart:
enum Skills {
FIST,
CLUB,
SWORD,
AXE,
DISTANCE,
SHIELD,
FISHING,
CRITICAL_HIT_CHANCE,
CRITICAL_HIT_DAMAGE,
LIFE_LEECH_CHANCE,
LIFE_LEECH_AMOUNT,
MANA_LEECH_CHANCE,
MANA_LEECH_AMOUNT,
MAGLEVEL,
LEVEL,
FIRST = FIST,
LAST = MANA_LEECH_AMOUNT,
}
final List<int> skillBase = [
50, 50, 50, 50, 30, 100, 20
];
You can also use a Map to assign the default values to each enum member.
enum Skills {
FIST,
CLUB,
SWORD,
AXE,
DISTANCE,
SHIELD,
FISHING,
CRITICAL_HIT_CHANCE,
CRITICAL_HIT_DAMAGE,
LIFE_LEECH_CHANCE,
LIFE_LEECH_AMOUNT,
MANA_LEECH_CHANCE,
MANA_LEECH_AMOUNT,
MAGLEVEL,
LEVEL,
FIRST = FIST,
LAST = MANA_LEECH_AMOUNT,
}
final Map<Skills, int> skillBase = {
Skills.FIST: 50,
Skills.CLUB: 50,
Skills.SWORD: 50,
Skills.AXE: 50,
Skills.DISTANCE: 30,
Skills.SHIELD: 100,
Skills.FISHING: 20,
// Add the rest of the skills
};
Both the above examples will work fine in dart/flutter.

Changing QGraphicsItem stack order with stackBefore

I have a QGraphicsItem "p" with 4 children a, b, c and d, inserted in that order.
#include <QtWidgets/QApplication>
#include <QtWidgets/QGraphicsScene>
#include <QtWidgets/QGraphicsItem>
#include <QtWidgets/QGraphicsView>
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QGraphicsScene scene(0, 0, 200, 200);
QGraphicsView view(&scene);
QGraphicsItem* p = new QGraphicsRectItem(nullptr);
scene.addItem(p);
QGraphicsRectItem* a = new QGraphicsRectItem( 0, 0, 40, 40, p);
QGraphicsRectItem* b = new QGraphicsRectItem(10, 10, 40, 40, p);
QGraphicsRectItem* c = new QGraphicsRectItem(20, 20, 40, 40, p);
QGraphicsRectItem* d = new QGraphicsRectItem(30, 30, 40, 40, p);
// cosmetic
p->moveBy(40, 40);
a->setBrush(Qt::blue);
b->setBrush(Qt::red);
c->setBrush(Qt::yellow);
d->setBrush(Qt::green);
view.show();
return app.exec();
}
I want to put item a between c and d like this:
So basically I use stackBefore and do:
a->stackBefore(d);
But it doesn't work. So I took a look at QGraphicsItem's code and it seems like if the item is already stacked before (immediately or not) it will not move:
// Only move items with the same Z value, and that need moving.
int siblingIndex = sibling->d_ptr->siblingIndex;
int myIndex = d_ptr->siblingIndex;
if (myIndex >= siblingIndex) {
I can either do:
b->stackBefore(a);
c->stackBefore(a);
which move all elements under a.
or:
a->setParentItem(nullptr);
a->setParentItem(p);
a->stackBefore(d);
which remove a, and re-insert it on top so I can use stackBefore.
Both solutions look no very efficient. The first one, does not scale and the second one lack semantics.
Is there an elegant way to achieve this ?
I would assign an explicit Z value for each graphics item:
int z = 0;
a->setBrush(Qt::blue);
a->setZValue(++z);
b->setBrush(Qt::red);
b->setZValue(++z);
c->setBrush(Qt::yellow);
c->setZValue(++z);
d->setBrush(Qt::green);
d->setZValue(++z);
And then, before using stackBefore(), change the Z value of the moving item:
a->setZValue(d->zValue());
a->stackBefore(d);

Checkers jump moves (in SFML)

I started coding a few weeks ago and trying out a checker-game right now. I made a class called "figure" and then an array (figure Figure[value]).
I created a 2D field-array in main.cpp and filled it with the numbers for each Figure[]. E.G.:
(main.cpp)
figure Figure[33]; //Figure-array
for (int i = 0; i < 33; i++)
{
Figure[i].id = i;
}
int field[7][7] = { // (I messed the ID's up a little, just ignore it
{0, 0, 1, 2, 3, 0, 0},
{0, 0, 4, 5, 6, 0, 0},
{7, 8, 9, 10, 11, 12, 13}
{14, 15, 16, 17, 18, 19, 20},
{21, 22, 23, 24, 25, 26, 27},
{0, 0, 28, 29, 30, 0, 0},
{0, 0, 31, 32, 33, 0, 0}
};
for (int y = 0; y < 7; y++) //Field gets filled with figure-values {
for (int x = 0; x < 7; x++)
{
if (field[y][x] != 0)
{
Figure[field[y][x] - 1].setPosition(Vector2i(x + 1, y + 1));
}
}
}
Now I want to make an update function to make them jump over each other etc. My problem here is that i dont know is how to do this properly, I dont know how to write this function completely.Here is what i have already:
(Updatefunction)
void figure::update(int (&field)[7][7], RenderWindow &window) {
Vector2i mouseCoords;
mouseCoords.x = int(Mouse::getPosition(window).x / 114);
mouseCoords.y = int(Mouse::getPosition(window).y / 85);
if ((field[mouseCoords.y][mouseCoords.x] != 0) && (Mouse::isButtonPressed(Mouse::Left)))
{
if ((field[mouseCoords.y][mouseCoords.x] != 0) && !(Mouse::isButtonPressed(Mouse::Left)))
{
selected = true; //selected defined in figure.h
}
}
Vector2i newMouseCoords;
newMouseCoords.x = int(Mouse::getPosition(window).x / 114);
newMouseCoords.y = int(Mouse::getPosition(window).y / 85);
if (selected = true)
{
if ((newMouseCoords.x == mouseCoords.x + 2) && (field[newMouseCoords.y][newMouseCoords.x + 2] != 0))
{
}
}
}
I dont know how to continue here, tips are greatly appreciated!
You haven't provided all your code, so I can't give you an exact solution (and your full listing would probably be too long, and make the question unreadable if you included it, so I wouldn't recommend that).
Here's how I would solve it, given what your existing code looks like:
Do something in this function to handle the appropriate turns. Don't let a player move a piece that isn't theirs.
In your first click check, don't just set a non-piece-specific boolean value to true. Store the "selected piece" in some other variable instead.
Before your second click check, see if the "selected piece" variable is set (maybe check if it is not null - depends on how you define that variable).
Inside the body of your second click check, see if the target position for the selected piece constitutes a valid move. If it doesn't, then display an error to the user.
If the second click check constitutes a valid move, then update the board:
Move the piece, capture any pieces it jumped over, king if necessary
If there is another double-jump move that is possible (there might be two double jumps they could choose from), then allow the player to choose another move. This means more "if" blocks...
If there is a double-jump, then allow the person to back out of the move, since they haven't completed it yet. Uncapture their first jump.
Depending on how strict you are being on the rules, don't allow a person to choose not to do a double-jump. Some checkers rules make capture mandatory if it is possible.
Once all moves are complete, then switch the variable that keeps track of whose turn it is, and unset the "selected piece" variable.
Handle the game end check, and the game over state. This probably should be done after a move.

Struct C++ array in function parameters not working at all

hello i have to do a program using an array of structures.. and i have to initialize it in a function. below i am trying, but my prototype keeps getting error "Expected primary expression".. i have followed tutorials but cant figure out what im doing wrong please help. i cant use pointers or vectors.. just basic stuff thank you for your time
struct gameCases{
bool flag = false;
int casenum;
double value;
};
int initialize(gameCases cases); //prototype
--- main()
gameCases cases[26];
initialize(cases); //call
int initialize(gameCases cases) //definition
{
double values[26] = {.01, 1, 5, 10, 25, 50,
75, 100, 200, 300, 400, 500, 750, 1000,
5000, 10000 , 25000, 50000, 75000, 100000,
200000 , 300000, 400000, 500000,
1000000, 2000000};
for (int i = 0; i < 26; i++)
{
array[i].value = values[i];
}
}
Declare the function like
int initialize( gameCases *array, size_t n );
and call it like
initialize( cases, 26 );
Or you could pass the array by reference. For example
int initialize( gameCases ( &cases )[26] );
Take into account that the function is declared as having return type int but it acrually returns nothing.
int initialize(gameCases cases[26]); //prototype
int initialize(gameCases cases[26]) //definition
{
double values[26] = {.01, 1, 5, 10, 25, 50,
75, 100, 200, 300, 400, 500, 750, 1000,
5000, 10000 , 25000, 50000, 75000, 100000,
200000 , 300000, 400000, 500000,
1000000, 2000000};
for (int i = 0; i < 26; i++)
{
cases[i].value = values[i];
}
}
and to call:
initialize(cases);

Initializing a private array c++

SOLVED! (See Edit)
I am trying to initialize an couple of arrays that are private members of a class. I am trying to use a public function to initialize these private arrays. My code looks like this:
void AP_PitchController::initGains(void){
_fvelArray[] = {20, 25, 30, 60, 90, 130, 160, 190, 220, 250, 280};
_kpgArray[] = {6.0, 6.0, 8.0, 4.0, 3.0, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5};
_kdgArray[] = {2000, 2000, 1900, 300, 300, 200, 200, 200, 200, 200, 200};
_kigArray[] = {0.1, 0.1, 0.2, 0.25, 0.3, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5};
}
These arrays are found in the header file AP_PitchController where they are declared private. When I try to compile the code, I get one of these messages for each initialization:
/../AP_PitchController.cpp:106: error: expected primary-expression before ']' token
/../AP_PitchController.cpp:106: error: expected primary-expression before '{' token
/../AP_PitchController.cpp:106: error: expected `;' before '{' token
And here are my private declarations:
Private:
uint8_t _fvelArray[];
float _kpgArray[];
float _kdgArray[];
float _kigArray[];
Does anyone know what I am doing wrong to initialize these arrays upon the call of initGains()?
EDIT:
I found the answer in one of the related questions.
All i need to do is provide an array size for the initialization:
static float _kpgArray[11];
And then initialize it outside of a function in the .cpp file:
uint8_t AP_PitchController::_fvelArray[11] = {20, 25, 30, 60, 90, 130, 160, 190, 220, 250, 280};
Thank you for your input!
You can only use initialization syntax at declaration:
float _array[2] = {0.1f, 0.2f};
After it is declared you will have to initialize the members individually:
_array[0] = 0.1f;
_array[1] = 0.2f;
Or you could do it in a loop:
float temp[2] = {0.1f, 0.2f};
for( int i = 0; i < 2; ++i )
_array[i] = temp[i];
First, you cannot use the the initialization-list syntax that you're using since you've already declared your arrays (e.g. uint8_t _fvelArray = { ... }; would be valid when you first declare it under private: but _fvelArray = { ... }; is not valid in your initGains method). You must also declare the size of each array in your private declarations:
private:
uint8_t _fvelArray[10]; // or whatever size you want
Once you've taken those steps, you can populate the arrays:
_fvelArray[0] = 20;
_fvelArray[1] = 25;
// ...
Is there a reason you don't initialize your arrays right away? Will the gain values change? Your method is called initGains after all. If not, use the initializer-list syntax at the point of declaration:
private:
uint8_t _fvelArray[] = {20, 25, 30, 60, 90, 130, 160, 190, 220, 250, 280};
You have several issues here:
uint8_t _fvelArray[]; does not declare an array, but a pointer, the same as uint8_t *_fvelArray;. If you want to declare fixed-size array, you need to write uint8_t _fvelArray[11]; or in c++11 std::array<uint8_t, 11> _fvelArray;. For variable-length array you should use std::vector<uint8_t> _fvelArray;.
{20, ...} expression is an initializer-list an cannot be used for array initialization outside of its definition. That means that you can write uint8_t _fvelArray_tmp[] = {20, ...}; and then copy it to your variable : memcpy (_fvelArray, _fvelArray_tmp, sizeof (_fvelArray_tmp)); but not to initialize some already existing variable. But if you use std::array or std::vector for _fvelArray type, you could simply write _fvelArray = {20, ...}; (but it only works for c++11).