So what im trying to do is use an array of pointers to keep track of spawning bots and let them do battle by colliding. This is done by using methods in an array of pointers but i keep getting a LNK2020 error when I build it
This is the VBot.h File
class VBot
{
public:
VBot( int startX, int startY, Panel ^ drawingPanel ) :
x(startX), y(startY), panel(drawingPanel), energy(100), image(NULL) { };
virtual ~VBot() { };
virtual void Move() = 0;
virtual int EnergyToFightWith() = 0;
bool IsDead() const { return energy <= 0; }
virtual void Show();
bool CollidedWith ( VBot * b ) const;
void DoBattleWith ( VBot * b );
protected:
int x, y; // Current position of the VBot
gcroot<Drawing::Bitmap ^> image; // Image displayed for the VBot
gcroot<Panel ^> panel; // Panel on which to show the VBot.
int energy;
VBot();
};
class CNNBot : public VBot
{
public:
CNNBot( int startX, int startY, Panel ^ drawingPanel ):
VBot(startX, startY, drawingPanel)
{
image = gcnew Drawing::Bitmap("HappyBot.bmp");
}
~CNNBot(){};
void Move();
int EnergyToFightWith();
bool IsDead() { return (VBot::IsDead()); }
virtual void Show() { VBot::Show();}
bool CollidedWith ( VBot * b ) { return VBot::CollidedWith(b);}
void DoBattleWith ( VBot * b ){ VBot::DoBattleWith(b);}
private:
static const int MOVE_VAL = 55;
static const int RIGHT_BOUND = 490;
static const int DOWN = 40;
static const int MAXY = 379;
bool switcher;
};
This is the VBot.cpp File
#include "stdafx.h"
#include "Vbot.h"
void VBot::Show()
{
Graphics ^ g = panel->CreateGraphics();
g->DrawImageUnscaled( image, x, y );
g->~Graphics();
}
bool VBot::CollidedWith ( VBot * b ) const
{
if ( b == NULL )
return false;
return ( x + image->Width ) >= b->x
&& ( b->x + b->image->Width ) >= x
&& ( y + image->Height ) >= b->y
&& ( b->y + b->image->Height ) >= y;
}
void VBot::DoBattleWith ( VBot * b )
{
int mine = EnergyToFightWith();
int yours = b->EnergyToFightWith();
if( mine == yours )
{
energy = energy - mine / 2;
b->energy = b->energy - yours / 2;
}
void CNNBot::Move()
{
if (this->switcher)
{
this->x += MOVE_VAL;
if( this->x >= RIGHT_BOUND)
{
this->x = 0;
this->y += DOWN;
if(this->y > MAXY)
{
this->switcher = false;
this->y = MAXY;
}
}
}
else
{
this->x += MOVE_VAL;
if( this->x >= RIGHT_BOUND)
{
this->x = 0;
this->y -= DOWN;
if(this->y < 0)
{
this->switcher = true;
this->y = 0;
}
}
}
panel->Invalidate();
}
This is the BotContainer.h
#include <vcclr.h>
#include "VBot.h"
#include "stdafx.h"
#ifndef BOTCONTAINER_H
#define BOTCONTAINER_H
using namespace std;
//------------------------------------------------------------------------------
// This class is an array class that will contain pointers to bots that are spawned
//
class BotContainer
{
private:
static const int MAXARRAY = 1000; //this is the max size of the array
VBot * list[MAXARRAY]; //This is the array of pointers
int count; // the variable that keeps track of the array
public:
//-------------------------------------------------------------------------------
//this the constructor that sets count to zero
//-------------------------------------------------------------------------------
BotContainer(){ count = 0;}
//--------------------------------------------------------------------------------
//This method will check for a collision between the all possible combinations of
//two bots it is const
//---------------------------------------------------------------------------------
void checkCollisions() const;
//---------------------------------------------------------------------------------
//This method will destroy all dead bots in the array
//---------------------------------------------------------------------------------
void destroy();
//----------------------------------------------------------------------------------
//This method will take given bot pointer and add it to the list.
//The Parameters are a pointer to a VBot called inBot.
//This inBot will be added to the end of the array which will then increment count
//Before adding it checks to make sure the array isn't full.
//----------------------------------------------------------------------------------
void add(VBot * inBot);
void Add(CNNBot * inBot);
//----------------------------------------------------------------------------------
//This method will move all the elements in the array.
//----------------------------------------------------------------------------------
void moveAll();
};
#endif
This the BotContainer.cpp file
#include "stdafx.h"
#include <vcclr.h>
#include "BotContainer.h"
//---------------------------------------------------------------------------------
//This method will delete all the deat bots in the array from the highest indexed
//dead bot. If a bot is deleted then the method will shift all higher indexed elements
// to one index less than its previous index
//-------------------------------------------------------------------------------------
void BotContainer::destroy()
{
for( int i = count - 1; i <= 0; i--)
{
if ( list[i]->IsDead() == true )
{
int current = i; //index of the dead array
delete list[i];
for( int j = i + 1; j < count; j++)
{
list[current] = list[j];
current = j; // index of the next element above the one just shifted
}
count--;
}
}
}
//------------------------------------------------------------------------------------
//This method will go throught the array calling move() for each bot in the array
//-----------------------------------------------------------------------------------
void BotContainer::moveAll()
{
for( int i = 0; i < count; i++)
{
list[i]->Move();
}
}
//-----------------------------------------------------------------------------------
//This method checks for collisions between any 2 bots in the array making sure to not
//test (ivsi) or (ivsj) and also testing (jvsi).
// This method is const therfore it doesn't change the array just tests it.
//-----------------------------------------------------------------------------------
void BotContainer::checkCollisions() const
{
for( int i = 0; i < count; i++)
{
if (list[i]->IsDead() != true)
{
for( int j = i + 1; j < count; j++)
{
if(list[j]->IsDead() != true)
{
if ( list[i]->CollidedWith(list[j]))
{
list[i]->DoBattleWith(list[j]);
}
}
}
}
}
}
//--------------------------------------------------------------------------------
//This method will add a pointer of a bot to the array checking first to make sure
//the array isn't full
//--------------------------------------------------------------------------------
void BotContainer::add(VBot * inBot)
{
if(this->count <= MAXARRAY)
{
list[count] = inBot;
count++;
}
}
void BotContainer::Add(CNNBot * inBot)
{
if(this->count <= MAXARRAY)
{
list[count] = inBot;
count++;
}
}
And this is the Form.h file
#pragma once
#include "stdafx.h"
#include <vcclr.h>
#include "BotContainer.h"
namespace Prog3
{
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
x = 0;
y = 0;
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Panel^ pnlGameZone;
private: System::Windows::Forms::ComboBox^ cmbSelect;
protected:
private: System::Windows::Forms::Button^ btnBotSpawn;
private: System::Windows::Forms::TrackBar^ trackBar1;
private: System::Windows::Forms::Label^ label1;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::Label^ label3;
private: System::Windows::Forms::Label^ label4;
private: System::ComponentModel::IContainer^ components;
private:
/// <summary>
/// Required designer variable.
/// </summary>
int x;
int y;
BotContainer VList();
private: System::Windows::Forms::Timer^ tmrspeed;
private: System::Windows::Forms::NumericUpDown^ updownX;
private: System::Windows::Forms::NumericUpDown^ updownY;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->components = (gcnew System::ComponentModel::Container());
this->pnlGameZone = (gcnew System::Windows::Forms::Panel());
this->cmbSelect = (gcnew System::Windows::Forms::ComboBox());
this->btnBotSpawn = (gcnew System::Windows::Forms::Button());
this->trackBar1 = (gcnew System::Windows::Forms::TrackBar());
this->label1 = (gcnew System::Windows::Forms::Label());
this->label2 = (gcnew System::Windows::Forms::Label());
this->label3 = (gcnew System::Windows::Forms::Label());
this->label4 = (gcnew System::Windows::Forms::Label());
this->updownX = (gcnew System::Windows::Forms::NumericUpDown());
this->updownY = (gcnew System::Windows::Forms::NumericUpDown());
this->tmrspeed = (gcnew System::Windows::Forms::Timer(this-
>components));
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >
(this->trackBar1))->BeginInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >
(this->updownY))->BeginInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >
(this->updownY))->BeginInit();
this->SuspendLayout();
//
// pnlGameZone
//
this->pnlGameZone->BackColor =
System::Drawing::SystemColors::Window;
this->pnlGameZone->Location = System::Drawing::Point(53, 102);
this->pnlGameZone->Name = L"pnlGameZone";
this->pnlGameZone->Size = System::Drawing::Size(495, 379);
this->pnlGameZone->TabIndex = 0;
//
// cmbSelect
//
this->cmbSelect->DropDownStyle =
System::Windows::Forms::ComboBoxStyle::DropDownList;
this->cmbSelect->FormattingEnabled = true;
this->cmbSelect->Items->AddRange(gcnew cli::array< System::Object^
>(3) {L"CNN Bot\t", L"MSNBC Bot", L"FOX NEWS Bot"});
this->cmbSelect->Location = System::Drawing::Point(53, 52);
this->cmbSelect->Name = L"cmbSelect";
this->cmbSelect->Size = System::Drawing::Size(121, 21);
this->cmbSelect->TabIndex = 1;
//
// btnBotSpawn
//
this->btnBotSpawn->Location = System::Drawing::Point(427, 48);
this->btnBotSpawn->Name = L"btnBotSpawn";
this->btnBotSpawn->Size = System::Drawing::Size(87, 23);
this->btnBotSpawn->TabIndex = 4;
this->btnBotSpawn->Text = L"Spawn a Bot";
this->btnBotSpawn->UseVisualStyleBackColor = true;
this->btnBotSpawn->Click += gcnew System::EventHandler(this,
&Form1::tmrspeed_Tick);
//
// trackBar1
//
this->trackBar1->Location = System::Drawing::Point(552, 48);
this->trackBar1->Maximum = 800;
this->trackBar1->Minimum = 50;
this->trackBar1->Name = L"trackBar1";
this->trackBar1->Size = System::Drawing::Size(134, 45);
this->trackBar1->TabIndex = 5;
this->trackBar1->TickFrequency = 100;
this->trackBar1->Value = 50;
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(50, 34);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(65, 13);
this->label1->TabIndex = 6;
this->label1->Text = L"Select a Bot";
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(200, 35);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(53, 13);
this->label2->TabIndex = 7;
this->label2->Text = L"Starting X";
//
// label3
//
this->label3->AutoSize = true;
this->label3->Location = System::Drawing::Point(306, 35);
this->label3->Name = L"label3";
this->label3->Size = System::Drawing::Size(53, 13);
this->label3->TabIndex = 8;
this->label3->Text = L"Starting Y";
//
// label4
//
this->label4->AutoSize = true;
this->label4->Location = System::Drawing::Point(549, 32);
this->label4->Name = L"label4";
this->label4->Size = System::Drawing::Size(103, 13);
this->label4->TabIndex = 9;
this->label4->Text = L"Speed of Movement";
//
// updownX
//
this->updownX->Location = System::Drawing::Point(203, 53);
this->updownX->Name = L"updownX";
this->updownX->Size = System::Drawing::Size(85, 20);
this->updownX->TabIndex = 12;
//
// updownY
//
this->updownY->Location = System::Drawing::Point(309, 52);
this->updownY->Name = L"updownY";
this->updownY->Size = System::Drawing::Size(80, 20);
this->updownY->TabIndex = 13;
//
// tmrspeed
//
this->tmrspeed->Tick += gcnew System::EventHandler(this,
&Form1::tmrspeed_Tick);
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(740, 493);
this->Controls->Add(this->updownY);
this->Controls->Add(this->updownX);
this->Controls->Add(this->label4);
this->Controls->Add(this->label3);
this->Controls->Add(this->label2);
this->Controls->Add(this->label1);
this->Controls->Add(this->trackBar1);
this->Controls->Add(this->btnBotSpawn);
this->Controls->Add(this->cmbSelect);
this->Controls->Add(this->pnlGameZone);
this->Name = L"Form1";
this->Text = L"Form1";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >
(this->trackBar1))->EndInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >
(this->updownX))->EndInit();
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >e) e)
(this->updownY))->EndInit();
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
private: System::Void btnBotSpawn_Click(System::Object^ sender, System::EventArgs^
e) {
if ( cmbSelect->SelectedIndex == 0)
{
x = Decimal::ToInt32(updownX->Value);
y = Decimal::ToInt32(updownY->Value);
CNNBot newBot(x,y,pnlGameZone);
CNNBot * temp = &newBot;
VList().Add(temp);
}
}
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
}
private: System::Void tmrspeed_Tick(System::Object^ sender, System::EventArgs^ e)
{
VList().moveAll();
VList().checkCollisions();
VList().destroy();
}
};
};
This is the error message i get.
Error 1 error LNK2020: unresolved token (06000003) Prog3.Form1::VList C:\Users\Duerst\Documents\Visual Studio 2010\Projects\Prog 3\Prog 3\Prog 3.obj Prog 3
I am a novice programmer so it is probably something pretty basic, but it would be great if you guys could find what I've done wrong.
The problem is that when you declare VList like this:
BotContainer VList();
The compiler thinks it is a function instead of an object because of the () operator.
To fix it, remove the parenthesis ()
BotContainer VList;
And also remove the parenthesis on very ocurrence of VList:
VList.Add(temp);
instead of:
VList().Add(temp);
And:
VList.moveAll();
VList.checkCollisions();
VList.destroy();
instead of:
VList().moveAll();
VList().checkCollisions();
VList().destroy();
Related
I was creating a custom operating system and I have a problem. I have an array of child components in an array of all opened windows. When I call a function CDraw (Component Draw) on the child array the system crashes with the message "General Protection Fault Detected".
Window array and code:
int openedWindows = 0;
Window* windows[128];
int OpenWindow(Window win) {
windows[0][openedWindows] = win;
openedWindows++;
return openedWindows-1;
};
void CloseWindow(int index) {
for(int i = index+1; i < 127; i++) {
if(i != 127)
windows[0][i] = windows[0][i-1];
else
windows[0][i] = Window();
}
openedWindows--;
};
void CloseAllWindows() {
for(int i = 0; i < 127; i++) {
windows[0][i] = Window();
}
openedWindows = 0;
};
/*Draw Windows*/
for(int i = 0; i < openedWindows; i++)
{
windows[0][i].Update();
}
Where I call the code:
Window wnd = Window("Window");
wnd.Update();
Button btn = Button(wnd, "Hello");
btn.CPosition = Point(10, 10);
btn.BackColor = Color(MediumTurquoise);
btn.parent = &wnd;
btn.parent->AddComponent(btn);
btn.Update();
Button btn2 = Button(wnd, "H2");
btn2.CPosition = Point(100, 100);
btn2.BackColor = Color(Red);
btn2.parent = &wnd;
btn2.parent->AddComponent(btn2);
btn2.Update();
OpenWindow(wnd);
Componet code:
int childIndex = 0;
BaseGuiComponent* children[128];
int BaseGuiComponent::AddComponent(BaseGuiComponent baseGuiComponent) {
children[0][childIndex] = baseGuiComponent;
childIndex++;
return childIndex-1;
};
void BaseGuiComponent::RemoveComponent(int index) {
for(int i = index+1; i < 127; i++) {
if(i != 127)
children[0][i] = children[0][i-1];
else
children[0][i] = BaseGuiComponent();
}
childIndex--;
};
void BaseGuiComponent::ClearComponents() {
for(int i = 0; i < 127; i++) {
children[0][i] = BaseGuiComponent();
}
childIndex = 0;
};
//List components and Update();
void BaseGuiComponent::DrawChildren() {
for(int i = 0; i < childIndex; i++) {
children[0][i].Update();
}
};
Drawing code:
void BaseGuiComponent::CDraw() {
if (strcmp(type,"Window",128)) {
Draw->DrawWindow(BackColor.GetHexColor(), CPosition.X, CPosition.Y, CSize.Width, CSize.Height, 2, CText, WindowStyle, Draw->GetScreenBounds());
DrawChildren();
} else if (strcmp(type,"Button",128)) {
Draw->FillRect(BackColor.GetHexColor(), CGlobalPosition.X*4, CGlobalPosition.Y, CSize.Width*4, CSize.Height, parent->bound/* Conflicting code */);
Draw->PRINTAT(ForeColor.GetHexColor(),CText, CGlobalPosition.X + nabs(CSize.Width - svlen(CText))/2,CGlobalPosition.Y + nabs(CSize.Height-16)/2, bound);
}
};
All help is welcomed. Thanks.
when i try to create an array of 'gameObject'-s i get a stack overflow exception, any idea what might be the reason?
Edit: for an array of 1 it DOES NOT throw an exception, i was mistaken
(creating just a 'gameObject' variable is fine)
I know my code is messy, and just all around bad, but i'm fairly new to c++ so please excuse my code :(
Here is my Main.cpp:
int main()
{
using namespace std::literals::chrono_literals;
HWND myconsole = GetConsoleWindow();
HDC mydc = GetDC(myconsole);
bool loop;
loop = false;
std::chrono::steady_clock::time_point start;
std::chrono::steady_clock::time_point end;
std::chrono::duration<float> duration;
gameObject test(mydc, "test.dat");
gameObject objList[100];
test.posX = 200;
test.posY = 10;
std::cout << getCurrentId();
while (true)
{
start = std::chrono::high_resolution_clock::now();
if (GetKeyState(VK_DOWN) & 0x8000)
{
test.move(0, -3);
}
if (GetKeyState(VK_UP) & 0x8000)
{
test.move(0, 3);
}
if (GetKeyState(VK_RIGHT) & 0x8000)
{
test.move(6, 0);
}
if (GetKeyState(VK_SPACE) & 0x8000)
{
gameObject shell(mydc, "shell.dat");
shell.type = 1;
shell.posX = test.posX + test.l;
shell.posY = test.posY + test.h;
objList[getCurrentId()] = shell;
}
if (loop == false)
{
for (int i = 0; i < 100; i++)
{
if (objList[i].type == 1)
{
objList[i].move(1, 0);
}
}
}
if (loop == false)
{
loop = true;
}
else
{
loop = false;
}
end = std::chrono::high_resolution_clock::now();
duration = end - start;
if (duration < 0.0333s)
{
std::this_thread::sleep_for(0.0333s - duration);
}
}
}
and here is the 'gameObject' class:
class gameObject
{
public:
gameObject(HDC currentDc, std::string dataFile);
gameObject();
~gameObject();
void clear();
void draw();
void move(int x, int y);
void loadSprite(std::string spriteName);
bool collide(gameObject);
unsigned short h = 1;
unsigned short l = 1;
int posX;
int posY;
unsigned short type;
COLORREF spriteData[256][256];
unsigned short id;
HDC dc;
};
You are creating all your objects on the stack gameObject objList[100];, and each of them has a big array in them COLORREF spriteData[256][256];. That's your stack overflow.
Use a std::vector to store your objects.
I know there has been tons of questions like that, but unfortunately after hours of googling and browsing through all of them, none of the answers I read helped. Therefore I am making my own version of my question. The error message I get is: "error: invalid use of incomplete type ‘std::iterator_traits::value_type {aka class Cell}’" My code:
cell.h
#ifndef CELL_H
#define CELL_H
#include <QPushButton>
#include <QMouseEvent>
#include <vector>
class Padding;
class Cell : public QPushButton
{
Q_OBJECT
public:
friend class Padding;
Cell(int x, int y, Padding* padding, QWidget* parent = 0) : QPushButton(parent), x(x), y(y),
padding(padding)
{
setFixedSize(20, 20);
}
Cell(const Cell& object) : QPushButton(), x(object.x), y(object.y), padding(object.padding)
{
setFixedSize(20, 20);
}
int getX() { return x; };
int getY() { return y; };
bool hasMine() { return mine; };
void setHasMine(bool mine) { this -> mine = mine; };
bool isFlagged() { return flagged; };
bool didExplode() { return exploded; };
bool getHasBeenClicked() { return hasBeenClicked; };
void clicked();
~Cell() {};
Cell operator=(const Cell& object)
{
if(&object == this)
{
return *this;
}
padding = object.padding;
x = object.x;
y = object.y;
mine = object.mine;
flagged = object.flagged;
exploded = object.exploded;
hasBeenClicked = object.hasBeenClicked;
setFixedSize(20, 20);
return *this;
}
private:
Padding* padding;
int x;
int y;
bool mine = false;
bool flagged = false;
bool exploded = false;
bool hasBeenClicked = false;
void mousePressEvent(QMouseEvent* e);
void rightClicked();
};
#endif // CELL_H
cell.cpp
#include "cell.h"
#include "padding.h"
void Cell::mousePressEvent(QMouseEvent* event)
{
if(event -> button() == Qt::LeftButton)
{
clicked();
}
else if(event -> button() == Qt::RightButton)
{
rightClicked();
}
}
void Cell::clicked()
{
hasBeenClicked = true;
// TODO: Set the button frame to flat. DONE.
setFlat(true);
// TODO: Make the button not click able. DONE.
setEnabled(false);
// TODO: Display appropriate number on the button, or mine and end the game. DONE.
if(mine)
{
// TODO: Send game over signal and end the game.
//setIcon(QIcon("mine_clicked.png"));
setText("/");
exploded = true;
padding -> gameOver();
}
else
{
setText(QString::number(padding -> countMinesAround(this)));
}
if(padding -> countMinesAround(this) == 0)
{
// Trigger chain reaction; uncover many neighboring cells, if they are not mines.
padding -> triggerChainReactionAround(this);
}
}
void Cell::rightClicked()
{
if(text() != "f")
{
setText("f");
(padding -> minesLeft)--;
}
else
{
setText("");
(padding -> minesLeft)++;
}
flagged = !flagged;
}
padding.h
#ifndef PADDING_H
#define PADDING_H
#include <QWidget>
#include <QGridLayout>
#include <vector>
class Cell;
class Padding : public QWidget
{
Q_OBJECT
public:
friend class Cell;
enum class Difficulty
{
Beginner,
Intermediate,
Advanced,
Custom
};
Padding(QWidget* parent = 0);
void newGame();
void gameOver();
void setLevel(Padding::Difficulty difficulty) { this -> difficulty = difficulty; };
void setPaddingHeight(int height) { paddingHeight = height; };
void setPaddingWidth(int width) { paddingWidth = width; };
void setMines(int mines) { this -> mines = mines; };
int getMinesLeft() { return minesLeft; };
~Padding() {};
private:
struct DifficultyLevelsProperties
{
struct BeginnerProperties
{
const int PADDING_HEIGHT = 9;
const int PADDING_WIDTH = 9;
const int MINES = 10;
} Beginner;
struct IntermediateProperties
{
const int PADDING_HEIGHT = 16;
const int PADDING_WIDTH = 16;
const int MINES = 40;
} Intermediate;
struct AdvancedProperties
{
const int PADDING_HEIGHT = 16;
const int PADDING_WIDTH = 40;
const int MINES = 99;
} Advanced;
} LevelProperties;
Difficulty difficulty = Difficulty::Beginner;
int paddingHeight;
int paddingWidth;
int mines;
// Mines that are not flagged.
int minesLeft;
// Time in seconds since the game was started.
int secondsSinceStart;
std::vector<Cell> cells;
QGridLayout* paddingLayout;
const int CELLS_HEIGHT = 20;
const int CELLS_WIDTH = 20;
int countMinesAround(Cell*);
void triggerChainReactionAround(Cell*);
void updateSecondsSinceStart();
};
#endif // PADDING_H
padding.cpp
#include "padding.h"
#include <QGridLayout>
#include <QTimer>
#include <QTime>
#include <QDebug>
#include "cell.h"
Padding::Padding(QWidget* parent) : QWidget(parent)
{
newGame();
paddingLayout = new QGridLayout(this);
paddingLayout -> setSpacing(0);
}
void Padding::newGame()
{
if(difficulty == Padding::Difficulty::Beginner)
{
paddingHeight = LevelProperties.Beginner.PADDING_HEIGHT;
paddingWidth = LevelProperties.Beginner.PADDING_WIDTH;
mines = LevelProperties.Beginner.MINES;
}
else if(difficulty == Padding::Difficulty::Intermediate)
{
paddingHeight = LevelProperties.Intermediate.PADDING_HEIGHT;
paddingWidth = LevelProperties.Intermediate.PADDING_WIDTH;
mines = LevelProperties.Intermediate.MINES;
}
else if(difficulty == Padding::Difficulty::Advanced)
{
paddingHeight = LevelProperties.Advanced.PADDING_HEIGHT;
paddingWidth = LevelProperties.Advanced.PADDING_WIDTH;
mines = LevelProperties.Advanced.MINES;
}
minesLeft = mines;
cells.clear();
for(int i = 0; i < paddingHeight; i++)
{
for(int j = 0; j < paddingWidth; j++)
{
// TODO: Use smart pointers instead of raw pointers.
Cell* cell = new Cell(j + 1, i + 1, this);
cells.push_back(*cell);
delete cell;
}
}
qsrand(QTime::currentTime().msec());
for(int i = 0; i < mines; i++)
{
// TODO: Fix the randomness of the numbers. DONE.
cells[qrand() % (paddingHeight * paddingWidth) + 1].setHasMine(true);
}
for(int i = 0; i < cells.size(); i++)
{
paddingLayout -> addWidget(&cells[i], cells[i].getY(), cells[i].getX());
}
}
void Padding::gameOver()
{
for(int i = 0; i < cells.size(); i++)
{
cells[i].setEnabled(false);
if((cells[i].hasMine()) && (!cells[i].getHasBeenClicked()))
{
cells[i].clicked();
}
}
}
int Padding::countMinesAround(Cell*)
{
int minesCounter = 0;
for(int i = 0; i < cells.size(); i++)
{
qDebug() << QString::number(cells[i].getX());
if(((x - cells[i].getX() == 0) || (x - cells[i].getX() == 1) || (x -
cells[i].getX() == -1)) && ((y - cells[i].getY() == 0) || (y -
cells[i].getY() == 1) || (y - cells[i].getY() == -1)) &&
(cells[i].hasMine()))
{
minesCounter++;
}
}
return minesCounter;
}
void Padding::triggerChainReactionAround(Cell*)
{
for(int i = 0; i < cells.size(); i++)
{
if(((x - cells[i].getX() == 0) || (x - cells[i].getX() == 1) || (x -
cells[i].getX() == -1)) && ((y - cells[i].getY() == 0) || (y -
cells[i].getY() == 1) || (y - cells[i].getY() == -1)) &&
(!cells[i].getHasBeenClicked()))
{
cells[i].clicked();
}
}
}
Sorry for how long the whole thing, but I could not shorten it as I can't locate what causes the error. Also please ignore any TODO's or any lines that are commented out and I forgot to delete them. Please help!
When you forward declare a type, you can only use pointers or references to that type objects, so this line in padding.h is pretty much not compiling:
std::vector<Cell> cells;
I suppose the compiler complaint comes from where it is trying to decide how to build/destroy a Cell object in a vector. To do that, it needs information about the type, generally from the type declaration (i.e. the header file).
I work in cocos2d-x help the problem. error in this line
string route = pathFind(xA, yA, xB, yB);
code HelloWorldScene.cpp
#include "HelloWorldScene.h"
#include "SimpleAudioEngine.h"
#include <iostream>
#include <iomanip>
#include <math.h>
#include <queue>
#include <string>
using namespace std;
using namespace cocos2d;
using namespace CocosDenshion;
const int n = 20; // horizontal size of the map
const int m = 20; // vertical size size of the map
static int MAPP[n][m];
static int putX[100];
static int putY[100];
static int closed_nodes_map[n][m]; // map of closed (tried-out) nodes
static int open_nodes_map[n][m]; // map of open (not-yet-tried) nodes
static int dir_map[n][m]; // map of directions
const int dir = 8; // number of possible directions to go at any position
static int dx[dir] = { 1, 1, 0, -1, -1, -1, 0, 1 };
static int dy[dir] = { 0, 1, 1, 1, 0, -1, -1, -1 };
class node
{
// current position
int xPos;
int yPos;
// total distance already travelled to reach the node
int level;
// priority=level+remaining distance estimate
int priority; // smaller: higher priority
public:
node(int xp, int yp, int d, int p)
{
xPos = xp; yPos = yp; level = d; priority = p;
}
int getxPos() const { return xPos; }
int getyPos() const { return yPos; }
int getLevel() const { return level; }
int getPriority() const { return priority; }
void updatePriority(const int & xDest, const int & yDest)
{
priority = level + estimate(xDest, yDest) * 10; //A*
}
// give better priority to going strait instead of diagonally
void nextLevel(const int & i) // i: direction
{
level += (dir == 8 ? (i % 2 == 0 ? 10 : 14) : 10);
}
// Estimation function for the remaining distance to the goal.
const int & estimate(const int & xDest, const int & yDest) const
{
static int xd, yd, d;
xd = xDest - xPos;
yd = yDest - yPos;
// Euclidian Distance
d = static_cast<int>(sqrt(xd*xd + yd*yd));
// Manhattan distance
//d=abs(xd)+abs(yd);
// Chebyshev distance
//d=max(abs(xd), abs(yd));
return(d);
}
};
CCScene* HelloWorld::scene()
{
// 'scene' is an autorelease object
CCScene *scene = CCScene::create();
// 'layer' is an autorelease object
HelloWorld *layer = HelloWorld::create();
// add layer as a child to scene
scene->addChild(layer);
// return the scene
return scene;
}
// on "init" you need to initialize your instance
bool HelloWorld::init()
{
//////////////////////////////
// 1. super init first
if ( !CCLayer::init() )
{
return false;
}
for (int y = 0; y < m; y++)
{
for (int x = 0; x < n; x++) MAPP[x][y] = 0;
}
int xA=0, yA=0, xB=7, yB=5;
// get the route
string route = pathFind(xA, yA, xB, yB);
// follow the route on the map and display it
if (route.length() > 0)
{
int j; char c;
int x = xA;
int y = yA;
MAPP[x][y] = 2;
for (int i = 0; i < route.length(); i++)
{
c = route.at(i);
j = atoi(&c);
x = x + dx[j];
y = y + dy[j];
MAPP[x][y] = 3;
}
MAPP[x][y] = 4;
}
int putS=0;
for (int y = 0; y < m; y++)
{
for (int x = 0; x < n; x++)
{
if (MAPP[x][y] == 3)
{
putY[putS] = y;
putX[putS] = x;
putS++;
}
}
}
return true;
}
bool operator < (const node & a, const node & b)
{
return a.getPriority() > b.getPriority();
}
// A-star algorithm.
// The route returned is a string of direction digits.
string pathFind(const int & xStart, const int & yStart,
const int & xFinish, const int & yFinish)
{
static priority_queue<node> pq[2]; // list of open (not-yet-tried) nodes
static int pqi; // pq index
static node* n0;
static node* m0;
static int i, j, x, y, xdx, ydy;
static char c;
pqi = 0;
// reset the node maps
for (y = 0; y < m; y++)
{
for (x = 0; x < n; x++)
{
closed_nodes_map[x][y] = 0;
open_nodes_map[x][y] = 0;
}
}
// create the start node and push into list of open nodes
n0 = new node(xStart, yStart, 0, 0);
n0->updatePriority(xFinish, yFinish);
pq[pqi].push(*n0);
open_nodes_map[x][y] = n0->getPriority(); // mark it on the open nodes map
// A* search
while (!pq[pqi].empty())
{
// get the current node w/ the highest priority
// from the list of open nodes
n0 = new node(pq[pqi].top().getxPos(), pq[pqi].top().getyPos(),
pq[pqi].top().getLevel(), pq[pqi].top().getPriority());
x = n0->getxPos(); y = n0->getyPos();
pq[pqi].pop(); // remove the node from the open list
open_nodes_map[x][y] = 0;
// mark it on the closed nodes map
closed_nodes_map[x][y] = 1;
// quit searching when the goal state is reached
//if((*n0).estimate(xFinish, yFinish) == 0)
if (x == xFinish && y == yFinish)
{
// generate the path from finish to start
// by following the directions
string path = "";
while (!(x == xStart && y == yStart))
{
j = dir_map[x][y];
c = '0' + (j + dir / 2)%dir;
path = c + path;
x += dx[j];
y += dy[j];
}
// garbage collection
delete n0;
// empty the leftover nodes
while (!pq[pqi].empty()) pq[pqi].pop();
return path;
}
// generate moves (child nodes) in all possible directions
for (i = 0; i < dir; i++)
{
xdx = x + dx[i]; ydy = y + dy[i];
if (!(xdx<0 || xdx>n - 1 || ydy<0 || ydy>m - 1 || MAPP[xdx][ydy] == 1
|| closed_nodes_map[xdx][ydy] == 1))
{
// generate a child node
m0 = new node(xdx, ydy, n0->getLevel(),
n0->getPriority());
m0->nextLevel(i);
m0->updatePriority(xFinish, yFinish);
// if it is not in the open list then add into that
if (open_nodes_map[xdx][ydy] == 0)
{
open_nodes_map[xdx][ydy] = m0->getPriority();
pq[pqi].push(*m0);
// mark its parent node direction
dir_map[xdx][ydy] = (i + dir / 2)%dir;
}
else if (open_nodes_map[xdx][ydy] > m0->getPriority())
{
// update the priority info
open_nodes_map[xdx][ydy] = m0->getPriority();
// update the parent direction info
dir_map[xdx][ydy] = (i + dir / 2)%dir;
// replace the node
// by emptying one pq to the other one
// except the node to be replaced will be ignored
// and the new node will be pushed in instead
while (!(pq[pqi].top().getxPos() == xdx &&
pq[pqi].top().getyPos() == ydy))
{
pq[1 - pqi].push(pq[pqi].top());
pq[pqi].pop();
}
pq[pqi].pop(); // remove the wanted node
// empty the larger size pq to the smaller one
if (pq[pqi].size() > pq[1 - pqi].size()) pqi = 1 - pqi;
while (!pq[pqi].empty())
{
pq[1 - pqi].push(pq[pqi].top());
pq[pqi].pop();
}
pqi = 1 - pqi;
pq[pqi].push(*m0); // add the better node instead
}
else delete m0; // garbage collection
}
}
delete n0; // garbage collection
}
return ""; // no route found
}
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
code HelloWorldScene.h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__
#include "cocos2d.h"
class HelloWorld : public cocos2d::CCLayer
{
public:
// Method 'init' in cocos2d-x returns bool, instead of 'id' in cocos2d-iphone (an object pointer)
virtual bool init();
// there's no 'id' in cpp, so we recommend to return the class instance pointer
static cocos2d::CCScene* scene();
// a selector callback
void menuCloseCallback(CCObject* pSender);
// preprocessor macro for "static create()" constructor ( node() deprecated )
CREATE_FUNC(HelloWorld);
};
#endif // __HELLOWORLD_SCENE_H__
pathFind is a function, you should prototype it. Add this somewhere the top of HelloWorldScene.cpp
string pathFind(const int & xStart, const int & yStart,
const int & xFinish, const int & yFinish);
Or if you are intending to call this function from another module then put the prototype in an appropriate header file.
I am at work on a gui based mergesort application. I am trying to print the steps as the recursive mergesort moves along. I am having trouble with accessing the "richTextBox1" component within my mergesort/print_arr() so I can print the current array out to the window. I am getting these errors which I understand a little bit. I think it has to do merge_sort being a static method trying to access a class component. I am stumped, any suggestions or workarounds for this without having to start completely over?
Here are the errors:
Form1.h(185): error C2227: left of '->Text' must point to class/struct/union/generic type
Form1.h(187): error C2227: left of '->Text' must point to class/struct/union/generic type
Form1.h(189): error C2227: left of '->Text' must point to class/struct/union/generic type
These errors are coming from the print_arr(arr[],size) method.
and the code......
#pragma once
#include <iostream>
#include <time.h>
#include <msclr\marshal.h>
#include <msclr\marshal_cppstd.h>
namespace prog1 {
using namespace std;
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
using namespace msclr::interop;
/// <summary>
/// Summary for Form1
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Add the constructor code here
//
}
static void randomize(int* a, int size){
srand ( time(NULL) );
for(unsigned i = 0; i < size; i++){
a[i] = rand()%45 + 1;
}
for(unsigned i = 0; i < size; i++){
cout << a[i] << " ";
}
}
protected:
/// <summary>
/// Clean up any resources being used.
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Label^ label1;
protected:
private: System::Windows::Forms::TextBox^ textBox1;
private: System::Windows::Forms::Button^ randButton;
private: System::Windows::Forms::Button^ increaseButton;
private: System::Windows::Forms::Button^ decreaseButton;
private: System::Windows::Forms::Label^ label2;
private: System::Windows::Forms::RichTextBox^ richTextBox1;
private: System::Windows::Forms::Button^ clearButton;
private:
/// <summary>
/// Required designer variable.
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
void InitializeComponent(void)
{
this->label1 = (gcnew System::Windows::Forms::Label());
this->textBox1 = (gcnew System::Windows::Forms::TextBox());
this->randButton = (gcnew System::Windows::Forms::Button());
this->increaseButton = (gcnew System::Windows::Forms::Button());
this->decreaseButton = (gcnew System::Windows::Forms::Button());
this->label2 = (gcnew System::Windows::Forms::Label());
this->richTextBox1 = (gcnew System::Windows::Forms::RichTextBox());
this->clearButton = (gcnew System::Windows::Forms::Button());
this->SuspendLayout();
//
// label1
//
this->label1->AutoSize = true;
this->label1->Location = System::Drawing::Point(13, 13);
this->label1->Name = L"label1";
this->label1->Size = System::Drawing::Size(65, 13);
this->label1->TabIndex = 0;
this->label1->Text = L"Enter a size:";
//
// textBox1
//
this->textBox1->Location = System::Drawing::Point(84, 13);
this->textBox1->Name = L"textBox1";
this->textBox1->Size = System::Drawing::Size(27, 20);
this->textBox1->TabIndex = 1;
//
// randButton
//
this->randButton->Location = System::Drawing::Point(118, 9);
this->randButton->Name = L"randButton";
this->randButton->Size = System::Drawing::Size(75, 23);
this->randButton->TabIndex = 2;
this->randButton->Text = L"Random";
this->randButton->UseVisualStyleBackColor = true;
this->randButton->Click += gcnew System::EventHandler(this, &Form1::randButton_Click);
//
// increaseButton
//
this->increaseButton->Location = System::Drawing::Point(200, 9);
this->increaseButton->Name = L"increaseButton";
this->increaseButton->Size = System::Drawing::Size(75, 23);
this->increaseButton->TabIndex = 3;
this->increaseButton->Text = L"Increasing";
this->increaseButton->UseVisualStyleBackColor = true;
//
// decreaseButton
//
this->decreaseButton->Location = System::Drawing::Point(282, 9);
this->decreaseButton->Name = L"decreaseButton";
this->decreaseButton->Size = System::Drawing::Size(75, 23);
this->decreaseButton->TabIndex = 4;
this->decreaseButton->Text = L"Decreasing";
this->decreaseButton->UseVisualStyleBackColor = true;
//
// label2
//
this->label2->AutoSize = true;
this->label2->Location = System::Drawing::Point(363, 14);
this->label2->Name = L"label2";
this->label2->Size = System::Drawing::Size(91, 13);
this->label2->TabIndex = 5;
this->label2->Text = L"# of comparisons:";
//
// richTextBox1
//
this->richTextBox1->Location = System::Drawing::Point(16, 44);
this->richTextBox1->Name = L"richTextBox1";
this->richTextBox1->Size = System::Drawing::Size(473, 238);
this->richTextBox1->TabIndex = 6;
this->richTextBox1->Text = L"";
//
// clearButton
//
this->clearButton->Location = System::Drawing::Point(411, 289);
this->clearButton->Name = L"clearButton";
this->clearButton->Size = System::Drawing::Size(75, 23);
this->clearButton->TabIndex = 7;
this->clearButton->Text = L"Clear";
this->clearButton->UseVisualStyleBackColor = true;
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(501, 319);
this->Controls->Add(this->clearButton);
this->Controls->Add(this->richTextBox1);
this->Controls->Add(this->label2);
this->Controls->Add(this->decreaseButton);
this->Controls->Add(this->increaseButton);
this->Controls->Add(this->randButton);
this->Controls->Add(this->textBox1);
this->Controls->Add(this->label1);
this->Name = L"Form1";
this->Text = L"CS4413 MergeSort";
this->ResumeLayout(false);
this->PerformLayout();
}
#pragma endregion
static void print_arr(int* arr, int size){
richTextBox1->Text = "[ ";
for(int i = 0; i < size; i++){
richTextBox1->Text = arr[i] + ", ";
}
richTextBox1->Text = " ]";
}
static void merge_arrays(int h, int m, int arr[], int arrA[], int arrB[]){
int i = 0,j=0,k=0;
while(i < h && j < m){
if(arrA[i] < arrB[j]){
arr[k] = arrA[i];
i++;
}else{
arr[k] = arrB[j];
j++;
}
k++;
}
if(i > h){
for(int x = j; x < m; x++){
arr[k] = arrB[x];
k++;
}
}else{
for(int x = i; x < h; x++){
arr[k] = arrA[x];
k++;
}
}
}
static int* merge_sort(int* arr, const int size){
if ( size == 1 )
return arr;
int h = size/2;
int m = size/2;
int arrayAHsize = h;
int arrayBMsize = size - m;
//cout << "h: " << h << "arr[h]: " << arr[h] << "m: " << m << " arraryBMsize" <<
//arrayBMsize<< endl;
int *arrA = (int*)malloc(h);
int *arrB = (int*)malloc(arrayBMsize);
int* pa;
int* pb;
for(int i = 0; i < h; i++){
arrA[i] = arr[i];
}
for(int i = 0; i < arrayBMsize; i++){
arrB[i] = arr[i + h];
}
cout << endl;
print_arr(arrA, size/2);
cout << "----";
print_arr(arrB, arrayBMsize);
cout << endl;
//l1 = mergesort( l1 )
pa = merge_sort(arrA,h);
//l2 = mergesort( l2 )
pb = merge_sort(arrB, arrayBMsize);
merge_arrays( h, arrayBMsize,arr, arrA, arrB);
}
private: System::Void randButton_Click(System::Object^ sender, System::EventArgs^ e) {
String^ s = textBox1->Text;
string Ssize = marshal_as<std::string>(s);
const int size = atoi(Ssize.c_str());
//int a[atoi(Ssize.c_str())];
int *a = (int*)malloc(size);
int* pa = a;
//int* pa;
randomize(a, size);
richTextBox1->Text += "Your set: \n";
for(int i = 0; i < size; i++){
richTextBox1->Text += a[i] + ", ";
}
pa = merge_sort(a,size);
}
};
}
static void print_arr(int* arr, int size){
richTextBox1->Text = "[ ";
for(int i = 0; i < size; i++){
richTextBox1->Text = arr[i] + ", ";
}
richTextBox1->Text = " ]";
}
Is wrong because richTextBox1 is a data member of the class, and a static function cannot access a class data member. Data members are for instances of the class, and thus a static function, not having an instance, would not know which instances data members to refer to.
Make this method non-static and you'll be fine.