OnClick event for dynamic TImage - onclick

I am trying to build a memory game with 16 pairs of cards.
I do not know exactly how to implement an OnClick event. I am new at using C++Builder, so please help.
The images are in an array, I allocate them dynamically like this:
for(int i=0;i<4;i++)
{
for(int j = 0; j < 8 ; j++)
{
VectorOfImages[i*8+j]=new Card(9+i*112,9+j*112,pan, 0);
VectorOfImages[i*8+j]->image->Picture>LoadFromFile("...OOP\\c\\images\\0.bmp");
VectorOfImages[i*8+j]->image->Tag=i*8+j;
VectorOfImages[i*8+j]->image->Enabled=false;
}
}

OnClick is a property of TImage, you can assign it like you would any other property, eg:
for(int i = 0; i < 4; ++i)
{
for(int j = 0; j < 8; ++j)
{
int idx = (i*8) + j;
VectorOfImages[idx] = new Card(9+i*112, 9+j*112, pan, 0);
VectorOfImages[idx]->image->Picture->LoadFromFile("...OOP\\c\\images\\0.bmp");
VectorOfImages[idx]->image->Tag = idx;
VectorOfImages[idx]->image->Enabled = false;
VectorOfImages[idx]->OnClick = &ImageClicked; // <-- here
}
}
Then, add ImageClicked() to your Form:
private:
void __fastcall ImageClicked(TObject *Sender);
...
void __fastcall TMyForm::ImageClicked(TObject *Sender)
{
// Sender points at the TImage that was clicked...
TImage *Image = static_cast<TImage*>(Sender);
// use Image as needed...
}

Related

Segmentation fault inside range

#include <iostream>
#include <vector>
#include <algorithm>
#include <queue> // std::priority_queue
using std::vector;
using std::cin;
using std::cout;
struct fj{
int indexI=0;
int freeT=0;
};
struct DereferenceCompareNode : public std::binary_function<fj, fj, bool>
{
bool operator()(const fj lhs, const fj rhs) const
{
return lhs.freeT > rhs.freeT;
}
};
class JobQueue {
private:
int num_workers_;
vector<int> jobs_;
vector<int> assigned_workers_;
vector<long long> start_times_;
void WriteResponse() const {
for (int i = 0; i < jobs_.size(); ++i) {
cout << assigned_workers_[i] << " " << start_times_[i] << "\n";
}
}
void ReadData() {
int m;
cin >> num_workers_ >> m;
jobs_.resize(m);
std::cout<<"Read fault"<<"\n";
for(int i = 0; i < m; i++)
cin >> jobs_[i];
std::cout<<"Read fault ends"<<"\n";
}
void AssignJobs() {
// TODO: replace this code with a faster algorithm.
std::cout<<"Fault point 1"<<"\n";
assigned_workers_.resize(jobs_.size());
start_times_.resize(jobs_.size());
vector<long long> next_free_time(num_workers_, 0);
std::priority_queue<int, vector<int>, std::greater<int> > thread;
std::priority_queue<fj, vector<fj>, DereferenceCompareNode > freeJob;
/*
for (int i = 0; i < jobs_.size(); ++i) {
int duration = jobs_[i];
int next_worker = 0;
for (int j = 0; j < num_workers_; ++j) {
if (next_free_time[j] < next_free_time[next_worker])
next_worker = j;
}
assigned_workers_[i] = next_worker;
start_times_[i] = next_free_time[next_worker];
next_free_time[next_worker] += duration;
}
*/
std::cout<<"dump point 2"<<"\n";
for(int i=0;i<num_workers_;i++){
thread.push(i);
}
std::cout<<"dump point 1"<<"\n";
int counter = 0;
while(jobs_.size()!=0){
std::cout<<"jobs_.size:"<<jobs_.size()<<"\n";
std::cout<<"freeJob.size:"<<freeJob.size()<<"\n";
//check logic
do{
if(freeJob.top().freeT == counter){
std::cout<<"freeJob.top().freeT:"<<freeJob.top().freeT<<"\n";
std::cout<<"counter:"<<counter<<"\n";
thread.push(freeJob.top().indexI);
freeJob.pop();
}else{
break;
}
}
while(freeJob.size()!=0);
std::cout<<"Thread:"<<thread.size()<<"\n";
while(thread.size()!=0){
if(jobs_.size()!=0){
fj currA;
currA.indexI = thread.top();
currA.freeT = jobs_.at(0)+counter;
std::cout<<"currA.indexI:"<<currA.indexI<<"\n";
std::cout<<"currA.freeT:"<<currA.freeT<<"\n";
thread.pop();
jobs_.erase(jobs_.begin());
assigned_workers_.push_back(currA.indexI);
start_times_.push_back(currA.freeT);
}else{
break;
}
}
counter++;
}
}
public:
void Solve() {
ReadData();
AssignJobs();
WriteResponse();
}
};
int main() {
std::ios_base::sync_with_stdio(false);
JobQueue job_queue;
job_queue.Solve();
return 0;
}
I am getting segmentation fault in function ReadData while taking inputs for vector jobs.
I am getting fault even when I am inside bounds of defined size.
Everything was fine when have not written AssignJob function.
Am I doing something wrong with some bounds or taking illegal inputs format or messing with some other stuff?
Am I doing something wrong
Yes, you are: freeJob starts out empty, so this is undefined behavior:
if(freeJob.top().freeT == counter){
In fact, you never push anything into freeJob, you only pop() things from it.

StoreProhibitedCause Exception with linked list on ESP8266

I have implemented a linked list class as follows for storage of sensor data readings.
(Note the total code is ~4000 lines so I can't provide it all, hopefully this gives an idea of what's done).
struct DataItem {
String _dataType;
float _dataArray[dataArraySize_const];
float _calibratedData = -1.0;
float _rawData = -1.0;
DataItem *_next;
uint8_t _dataArraySize = dataArraySize_const;
float *_calibrationParameters;
uint8_t _numCalibrationParameters;
};
class DataContainer {
public:
DataContainer() {
_head = NULL;
_tail = NULL;
};
DataItem* addDataItem(String dataTypeIn, float calibrationParameters[10], uint8_t numberOfCalibrationParameters) {
DataItem *temp = new DataItem;
temp->_dataType = dataTypeIn;
temp->_calibratedData = -1.0;
temp->_rawData = -1.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) { temp->_dataArray[i] = 0; } //Setting all the data array to 0
temp->_calibrationParameters = calibrationParameters;
temp->_numCalibrationParameters = numberOfCalibrationParameters;
temp->_next = NULL;
if(_head == NULL) {
_head = temp;
_tail = temp;
temp = NULL;
}
else {
_tail->_next = temp;
_tail = temp;
}
return temp;
};
uint8_t setDataValue(String dataType, float value, uint8_t arrayIndex) {
DataItem *temp = new DataItem;
temp = _head;
Serial.println("Addresses: ");
while(temp != NULL) {
Serial.print("temp address: 0x");
Serial.println((unsigned long)temp, HEX);
Serial.print("head address: 0x");
Serial.println((unsigned long)_head, HEX);
Serial.print("temp add address: 0x");
Serial.println((unsigned long)&temp, HEX);
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_dataArray[arrayIndex] = value;
float sum = 0.0;
for (uint8_t i = 0; i < dataArraySize_const; i++) {
sum += temp->_dataArray[i];
}
temp->_rawData = sum/dataArraySize_const;
Serial.println("Pre calibration");
this->calibrate(temp);
Serial.println("Finished calibration");
return 0;
};
void calibrate(DataItem *temp) {
temp->_calibratedData = temp->_calibrationParameters[0];
for (uint8_t i = 1; i <= temp->_numCalibrationParameters; i++) {
temp->_calibratedData += temp->_calibrationParameters[i] * pow(temp->_rawData, i);
}
}
uint8_t setCalibrationParameters(String dataType, float calibrationParameters[10]) {
DataItem *temp = new DataItem;
temp = _head;
while(temp != NULL) {
if (temp->_dataType == dataType) { break; }
else if (temp == NULL) { return 1; }
temp = temp->_next;
}
temp->_calibrationParameters = calibrationParameters;
return 0;
};
private:
DataItem *_head, *_tail;
};
uint8_t numUsedCalibrationParameters = 10;
float calibrationParam[numUsedCalibrationParameters] = {0,1,0,0,0,0,0,0,0,0};
uint8_t dataArrayPosition = 0;
uint8_t dataArraySize = 10;
void setup(void) {
Serial.begin(115200);
Serial.setDebugOutput(false);
delay(20);
Serial.println("\n\nbegin");
pinMode(A0, INPUT);
dataContainer.addDataItem("ADC",calibrationParam,numUsedCalibrationParameters);
void loop(void) {
dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);
if (dataArrayPosition < dataArraySize) { ++dataArrayPosition; }
else { dataArrayPosition = 0; }
delay(100);
}
After around 31000 loops (just under 2^15 which is suspicious to me), I get a StoreProhibitedCause Exception. If I comment out dataContainer.setDataValue("ADC", analogRead(A0), dataArrayPosition);, I no longer get the exception. I suspect it's some way that I have implemented the linked list and it has a memory issue but I have tried printing out the addresses of everything and it doesn't look like anything is running away.
Exception:
Exception (29):
epc1=0x4000df64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
>>>stack>>>
ctx: sys
sp: 3fffec10 end: 3fffffb0 offset: 01a0
3fffedb0: 4024576b 3fff0b08 00000002 40245700
.....
===================== SOLVED =====================
DataItem *temp = new DataItem; should be DataItem *temp; for setDataValue() and setCalibrationParameters().
Otherwise it keeps on creating new structs for every addition.
DataItem *temp = new DataItem; should be DataItem *temp; for setDataValue() and setCalibrationParameters().
Otherwise it keeps on creating new structs for every addition.
(I can't mark it solved without having an answer).

How to check if Image in ImageView Array is set to 'null'?

I am trying to create a counter that increases if an Image contained in an ImageView array is set to null. I have a Bullet class that calls the method below
Whenever I kill an enemy it sets the image to 'null'
public void Collision(ImageView ene[], Rectangle b){
for (int i = 0; i < 10 * wave; i++) {
if (ene[i].getBoundsInParent().intersects(b.getBoundsInParent())){
ene[i].setVisible(false);
ene[i].setImage(null);
score();
bulletGone();
}
}
}
My problem is that it prints out the first "Null count: " in the checkWave method, but never reaches the for loop. Am I comparing to null incorrectly?
Look at this checkWave(ImageView e[])
now check your Collision method pal, who do you set to null? go back to your checkWave(ImageView e[]) method, who you check for null?
hope you find your solution.
one tip: int counter = 10 * wave;//its final
for (int i = 0; i < 10 * wave; i++) {//save yourself some keys
or (int i = 0; i < counter; i++) {
EDIT
for (int i = 0; i < counter; i++) {
if (e[i].getImage() == null){ //now your loop will do
nullCount++;
System.out.println("Null count: " + nullCount);
}
}

ArrayIndexOutOfBoundsException - why am I still having this problem?

I'm trying to print a chessboard to the console using a 2D array. For testing purposes, I'm trying to simply populate the board as 'x' chars. However, I keep getting an ArrayIndexOutOfBounds exception when I try to populate the array with the following:
public void setupBoard(){
for (int i=0; i < height; i++){
for (int j=0; j < width; j++){
boardArray[i][j] = 'x';
}
}
}
The error apparently occurs at boardArray[i][j] = 'x';
Everything seems to be in order, I dont see why this isnt working.
EDIT: I got the array to populate, but now I cannot format the printing correctly. The contents all print on one line, instead of as an 8x8 square of 'x' chars. Here's what I have now:
public void displayBoard(){
for (int k=0; k < boardArray.length; k++)
for (int l=0; l < boardArray[k].length; l++){
System.out.print(boardArray[k][l]);
}
System.out.println();
}
Well, presumably it's because you haven't created the board properly. Unfortunately you haven't shown us the array creation statement. It should be something like:
char[][] boardArray = new char[height][width];
EDIT: Okay, now for the printing part. Your current code is:
public void displayBoard(){
for (int k=0; k < boardArray.length; k++)
for (int l=0; l < boardArray[k].length; l++){
System.out.print(boardArray[k][l]);
}
System.out.println();
}
This is equivalent to:
public void displayBoard() {
for (int k = 0; k < boardArray.length; k++) {
for (int l = 0; l < boardArray[k].length; l++) {
System.out.print(boardArray[k][l]);
}
}
System.out.println();
}
... so you're only calling println after the outer loop has finished. If you just move the call to println to after the inner loop, it'll be fine:
public void displayBoard() {
for (int k = 0; k < boardArray.length; k++) {
for (int l = 0; l < boardArray[k].length; l++) {
System.out.print(boardArray[k][l]);
}
System.out.println();
}
}
Note that this sort of thing is clearer if you always include braces for loops, if statements etc.

Why does the x value change in this program?

I have created this code, and when I run it, don't get any errors until the arrow leaves the screen (ie: (*I)->x>maxx), after which the O will randomly teleport (Well, I'm guessing its not random, but I'm trying to find a pattern to it).
EDIT: the random teleportation don't seem to occur if I move up, and if I move down, the O is teleported directly to the bottom. Also, a glitch has occured where the O becomes a '>'. (I am trying to figure out how that happens)
EDIT: the transform-into-'>' glitch occurs if the O is at the bottom right of the screen (player.x=9;player.y=9) and the sequence "wqs" is entered.
EDIT: I've removed the class declarations because I am fairly sure that the error is within the _move()s and check().
EDIT: The transform glitch appears to occur when 'wq' is typed, then any other character is entered (ie "skiping" the next move)
EDIT: The tranform glitch occurs when player.x=9; player.y=8; and then 'q' is pressed, the next move the player tranforms into a '>'
This is the code:
#include<vector>
#include<iostream>
#include<string>
using namespace std;
const int maxx = 10, maxy = 10; //two constants that show the size of the sector
char sector[maxx][maxy]; //array of characters used to display the sector
prgm player(0, 0, 'O'); //player definition at x0,y0,and displayed with 'O'
const int vsize = 1; //size of the enemy array (ie: how many enemies there will be
X1 a(9, 5, 'X', 10); //enemy "a", has a move function that moves it back and forth
virus * viral_data[vsize] = {&a}; //array of enemies used to set the sector
vector<antivirus*> antiviral_data; //vector of pointers to "antivirus" the weapon used
vector<antivirus*>::iterator I; //iterator for previous vector
void display() //function to display the sector
{
for(int i = 0; i < maxy; i++)
{
for(int j = 0; j < maxx; j++)
{
cout<<sector[j][i];
}
cout<<endl;
}
return;
}
void p_move() //function to get players input, then move the player or create "antivirus"
{
char dir;
cin>>dir;
switch(dir)
{
case 'w':
player.y--;
break;
case 'a':
player.x--;
break;
case 's':
player.y++;
break;
case 'd':
player.x++;
break;
case 'q':
antiviral_data.push_back(new aX1(player.x, player.y, '>')); //creates a new aX1 at the players position
break;
}
return;
}
void v_move() //uses the enemies move
{
for(int i = 0; i < vsize; i++)
{
viral_data[i]->move();
}
return;
}
void a_move() //uses the weapon (ie: moves the weapon forward)
{
for(I = antiviral_data.begin(); I < antiviral_data.end(); I++)
{
(*I)->move();
}
return;
}
void set() //sets the sector array (char)
{
for(int i = 0; i < maxy; i++)
{
for(int j = 0; j < maxx; j++)
{
sector[j][i] = ' '; makes the entire sector blank
}
}
sector[player.x][player.y]=player.sym; //sets the sector at the player's position to 'O'
for(int i = 0; i < vsize; i++)
{
sector[viral_data[i]->x][viral_data[i]->y] = viral_data[i]->sym; //sets the sector at each enemy's position to be 'X'
}
for(I = antiviral_data.begin(); I < antiviral_data.end(); I++)
{
sector[(*I)->x][(*I)->y] = (*I)->sym; //sets the sector at each weapon's position to be '>'
}
return;
}
void check() //prevents the player from moving off the screen, erases bullet if it moves of the screen (to prevent access to non-allocated memory)
{
if(player.x < 0)
{
player.x = 0;
}
if(player.y < 0)
{
player.y = 0;
}
if(player.x > (maxx-1))
{
player.x = (maxx-1);
}
if(player.y > (maxy-1))
{
player.y = (maxy-1);
}
//PROBLEM APPEARS TO OCCUR HERE
for(I = antiviral_data.begin(); I! = antiviral_data.end();)
{
if((*I)->x > maxx)
{
I = antiviral_data.erase(I);
}
else
{
I++;
}
}
//*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
return;
}
int main()
{
while(true)
{
set(); //set sector
display(); //display sector
p_move(); //player's move
v_move(); //enemy's move
a_move(); //bullet's move
check();//check moves
}
return 0;
}
In check(), the test
((*I)->x > maxx)
should be
((*I)->x >= maxx)
. This is an off-by-one error that lets the > get one square off the screen. When the display routine tries to display it, it clobbers the display symbol for the X.

Resources