//=========================================================================== // NANA'S FLOCKING BULLYING SIMULATION SONIFIED // Nanae Kido // 28 November 2006 // agent[0] is bully // agents 2-23 are non-bullies // agent 24 is teacher //=========================================================================== //--------------------------------------------------------------------------- #include #include #pragma hdrstop #include "Unit1.h" // The following two lines are needed to enable the randomizer #include "stdlib.h" #include "time.h" #include //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { // Double buffering eliminates some screen flicker... DoubleBuffered = true; } //--------------------------------------------------------------------------- //=========================================================================== // GLOBAL VARIABLES //=========================================================================== // ------------------------------------------------- your program begins here int midiport = 0; HMIDIOUT device; union { public: unsigned long word; unsigned char data[4]; } message; int soundType = 0; int instrument; int note; TImage *image[25] = {0}; // sets up an array of images #define GIRL 0 #define BOY 1 class anAgent { public: float velocity; double direction; double newDirection; double newDistance; double lastDistance; bool gender; bool bullied; bool helped; float x; float y; int lastNN; int bullyHits; int teacherHits; int helperHits; int bI; } agent[25]; int probBI; int bullyInfluence = 0; int increment = 5; bool stop = true; bool wasStopped = false; int iterations; int i; int grade; int chosenAgent; int imageDownX, imageDownY; bool agentWasJustChosen = false; int probability = 0; int countBullied = 0; int countHelped = 0; //=========================================================================== // FUNCTIONS //=========================================================================== //---------------------------------------------------------------- color ramp int colorRamp(int range, int value) { int pixelDistanceAlongPath = (value * 1792) / range; int red, green, blue; // Which edge of the color cube are we on? if (pixelDistanceAlongPath < 256) { // Edge 1 from BLACK to BLUE red=0; green=0; blue=pixelDistanceAlongPath; } else if (pixelDistanceAlongPath < 512) { // Edge 2 from BLUE to CYAN red =0; green=pixelDistanceAlongPath-256; blue=255; } else if (pixelDistanceAlongPath < 768) { // Edge 3 from CYAN to GREEN red =0; green =255; blue= 255-(pixelDistanceAlongPath-512); } else if (pixelDistanceAlongPath < 1024) { // Edge 4 from GREEN to YELLOW red= (pixelDistanceAlongPath-768); green =255; blue =0; } else if (pixelDistanceAlongPath <1280) { // Edge 5 from YELLOW to RED red =255; green=255-(pixelDistanceAlongPath-1024); blue =0; } else if (pixelDistanceAlongPath < 1536) { // Edge 6 from RED to MAGENTA red =255; green=0; blue=pixelDistanceAlongPath -1280; } else { // Edge 7 from MAGENTA to WHITE red =255; green=pixelDistanceAlongPath-1536; blue =255; } return (RGB(red, green, blue)); } //----------------------------------------------------------------------- sit void sit (void) { int who = 0; for (int i = 0; i < 3; i++) { for (int j = 0; j < 8; j++) { agent[who].x = j * 57 + 50; agent[who].y = i * 85 + 190; image[who]->Left = agent[who].x - image[who]->Width / 2; image[who]->Top = agent[who].y - image[who]->Height / 2; who++; } } agent[24].x = 256; agent[24].y = 52; image[24]->Left = agent[24].x - image[24]->Width / 2; image[24]->Top = agent[24].y - image[24]->Height / 2; } //------------------------------------------------------------------- shuffle void shuffle (void) { for (int i = 0; i < 25; i++) { agent[i].x = random(410) + 30; image[i]->Left = agent[i].x - image[i]->Width / 2; agent[i].y = random(510) + 30; image[i]->Top = agent[i].y - image[i]->Height / 2; agent[i].direction = (float(random(1000)) / 500) * M_PI; agent[i].velocity = float(random(1000)) / 1500 + .1; agent[i].lastNN = 99; image[i]->Visible = true; if (i % 2 == 0) { agent[i].gender = BOY; } else agent[i].gender = GIRL; agent[i].bI = bullyInfluence; } sit(); } //--------------------------------------------------------------------- reset void reset (void) { for (int i = 0; i < 25; i++) { if (i % 2 == 0) { image[i]->Picture = Form1->boyNormal->Picture; } else image[i]->Picture = Form1->girlNormal->Picture; agent[i].bullyHits = 0; } image[0]->Picture = Form1->boyBully->Picture; image[24]->Picture = Form1->maleTeacher->Picture; iterations = 0; Form1->EditIterations->Text = iterations; countBullied = 0; Form1->EditCountBullied->Text = countBullied; countHelped = 0; Form1->EditCountHelped->Text = countHelped; bullyInfluence = 0; Form1->EditProbability->Text = probability; grade = 0; Form1->RadioGroupBullyInfluence->ItemIndex = bullyInfluence; bullyInfluence = 0; Form1->EditProbability->Text = bullyInfluence; Form1->TrackBarProbability->Position = probability; Form1->EditProbability->Text = probability; shuffle(); } //-------------------------------------------------------------------- circle void circle (void) { for (int i = 0; i < 25; i++) { agent[i].x = 200 + 180 * cos(i * (2 * M_PI / 25)) + 30; agent[i].y = 200 + 180 * sin(i * (2 * M_PI / 25)) + 30; image[i]->Left = agent[i].x - image[i]->Width / 2; image[i]->Top = agent[i].y - image[i]->Height / 2; } } //---------------------------------------------------------- nearest neighbor int nearestNeighbor (int me) { int myNeighbor; double x, y, z; int dist = 10000; for (int i = 0; i < 25; i++) { if (i == me) continue; x = agent[i].x - agent[me].x; y = agent[i].y - agent[me].y; z = sqrt(x * x + y * y); if (z < dist) { dist = z; myNeighbor = i; } } // detect collisions... if (dist < 50 && agent[me].lastNN != myNeighbor) { // new collision if (myNeighbor == 0) { //Form1->Color = clYellow; //image[me]->Transparent = false; agent[me].bullyHits++; if (agent[me].gender == GIRL && random(100) < bullyInfluence && (random(100) < probability)) { // Girl if (agent[me].bullyHits > 1) { image[me]->Picture = Form1->girlCrying->Picture; } else image[me]->Picture = Form1->girlReceiver->Picture; // image[me]->Picture = Form1->girlCrying->Picture; } else if (agent[me].gender == BOY && random(100) < bullyInfluence && (random(100) < probability)) { if (agent[me].bullyHits > 1) { // Boy image[me]->Picture = Form1->boyCrying->Picture; } else image[me]->Picture = Form1->boyReceiver->Picture; // image[me]->Picture = Form1->girlCrying->Picture; } image[24]->Picture = Form1->maleTeacher->Picture; Application->ProcessMessages(); } //Helping if (myNeighbor == 24) { if (agent[me].bullyHits > 0) { agent[me].bullyHits = 0; if (agent[me].gender == GIRL) { //Girl image[me]->Picture = Form1->girlNormal->Picture; } if (agent[me].gender == BOY) { // Boy image[me]->Picture = Form1->boyNormal->Picture; } } } image[0]->Picture = Form1->boyBully->Picture; image[24]->Picture = Form1->maleTeacher->Picture; Application->ProcessMessages(); agent[me].lastNN = myNeighbor; } return myNeighbor; reset(); } /*int NN (int teacher) { int myNeighbor; double x, y, z; int dist = 10000; for (int j = 0; j < 24; i++) { if (j == teacher) continue; x = agent[j].x - agent[teacher].x; y = agent[j].y - agent[teacher].y; z = sqrt(x * x + y * y); if (z < dist) { dist = z; myNeighbor = j; } } // something's wrong with this - the code never goes here... if (dist < 50 && agent[teacher].lastNN != myNeighbor) { // new collision if (myNeighbor == 0) { //Form1->Color = clYellow; image[teacher]->Transparent = false; image[teacher]->Visible = true; Application->ProcessMessages(); } agent[teacher].lastNN = myNeighbor; } return myNeighbor; reset(); } */ void countF (void) { countBullied = 0; for (int i = 0; i < 24; i++) { if (i != 0) { if (agent[i].bullyHits > 0) { countBullied++; /*countHelped = 0; for (int i = 0; i < 24; i++) { if (i != 0) { if (agent[i].bullyHits > 0) { agent[i].bullyHits = 0; countHelped++; } } } */ } } } } //---------------------------------------------------------------------- step void step (void) { iterations++; Form1->EditIterations->Text = iterations; increment = Form1->TrackBarIncrement->Position; for (i = 0; i < 25; i++) { // calculate agent's new position based on velocity and direction agent[i].x += agent[i].velocity * cos(agent[i].direction) * increment; agent[i].y += agent[i].velocity * sin(agent[i].direction) * increment; // move the visualization on the screen accordingly image[i]->Left = agent[i].x - image[i]->Width / 2; image[i]->Top = agent[i].y - image[i]->Height / 2; /////////////////////////////////////////////////////////////////////// ///////////////////// FLOCKING BEHAVIORS BELOW //////////////////////// /////////////////////////////////////////////////////////////////////// // adopt nearest neighbor's direction (problematic with BOUNCE) if (Form1->RadioGroupFlockingBehavior->ItemIndex == 0) { nearestNeighbor(i); } // adopt nearest neighbor's direction (problematic with BOUNCE) if (Form1->RadioGroupFlockingBehavior->ItemIndex == 1) { agent[i].direction = agent[nearestNeighbor(i)].direction; } // increment direction by 1/50 your nearest neighbor's if (Form1->RadioGroupFlockingBehavior->ItemIndex == 2) { agent[i].direction += agent[nearestNeighbor(i)].direction / 50; if (agent[i].direction > 2 * M_PI) { // modulo divide agent[i].direction = agent[i].direction - 2 * M_PI; } } // decrement direction by 1/100 your nearest neighbor's if (Form1->RadioGroupFlockingBehavior->ItemIndex == 3) { agent[i].direction -= agent[nearestNeighbor(i)].direction / 100; if (agent[i].direction > 2 * M_PI) { // modulo divide agent[i].direction = agent[i].direction - 2 * M_PI; } } // adopt nearest neighbor's velocity if (Form1->RadioGroupFlockingBehavior->ItemIndex == 4) { agent[i].velocity = agent[nearestNeighbor(i)].velocity; } // increment by half nearest neighbor's velocity if (Form1->RadioGroupFlockingBehavior->ItemIndex == 5) { agent[i].velocity += agent[nearestNeighbor(i)].velocity / 50; } // adopt nearest neighbor's direction and speed if (Form1->RadioGroupFlockingBehavior->ItemIndex == 6) { agent[i].velocity = agent[nearestNeighbor(i)].velocity; agent[i].direction = agent[nearestNeighbor(i)].direction; } /////////////////////////////////////////////////////////////////////// ///////////////////// FLOCKING BEHAVIORS ABOVE /////////////////////// /////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////// BOUNCE if (Form1->RadioGroupBoundary->ItemIndex == 0) { if (agent[i].x > 480) { agent[i].direction = M_PI - agent[i].direction; if (soundType == 1) Beep(196, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP Balloon.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND181.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 55; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } if (agent[i].y > 390) { agent[i].direction = 2 * M_PI - agent[i].direction; if (soundType == 1) Beep(261, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP pop-up blocked.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND243.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 60; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } if (agent[i].x < 30) { agent[i].direction = M_PI - agent[i].direction; if (soundType == 1) Beep(330, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP Balloon.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND713.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 64; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } if (agent[i].y < 30) { agent[i].direction = 2 * M_PI - agent[i].direction; if (soundType == 1) Beep(392, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP pop-up blocked.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND735.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 67; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } // modular divide direction by one rotation if (agent[i].direction > 2 * M_PI) { agent[i].direction = agent[i].direction - 2 * M_PI; } if (agent[i].direction < 0) { agent[i].direction = agent[i].direction + 2 * M_PI; } } ///////////////////////////////////////////////////////////////// WRAP else { if (agent[i].x > 480) { agent[i].x = 30; image[i]->Left = agent[i].x - image[i]->Width / 2; if (soundType == 1) Beep(196, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP Balloon.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND181.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 55; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } if (agent[i].x < 30) { agent[i].x = 480; image[i]->Left = agent[i].x - image[i]->Width / 2; if (soundType == 1) Beep(261, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP pop-up blocked.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND243.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 60; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } if (agent[i].y > 390) { agent[i].y = 30; image[i]->Top = agent[i].y - image[i]->Height / 2; if (soundType == 1) Beep(330, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP Balloon.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND713.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 64; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } if (agent[i].y < 30) { agent[i].y = 430; image[i]->Top = agent[i].y - image[i]->Height / 2; if (soundType == 1) Beep(392, 50); if (soundType == 2) { PlaySound ("C:\\WINDOWS\\Media\\Windows XP pop-up blocked.wav", "", SND_ASYNC); } if (soundType == 3) { PlaySound ("C:\\Program Files\\Windows NT\\Pinball\\SOUND735.wav", "", SND_ASYNC); } if (soundType == 4) { message.data[0] = 0x90; message.data[1] = 67; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); } } } } countF(); Form1->EditCountBullied->Text = countBullied; Form1->EditCountHelped->Text = countHelped; } //----------------------------------------------------------------- run void run (void) { countBullied = 0; Form1->EditCountBullied->Text = countBullied; { /*if (Form1->RadioGroupBullyInfluence->ItemIndex == grade) { if (grade == 1) probBI = 4; if (grade == 2) probBI = 5; if (grade == 3) probBI = 9; if (grade == 4) probBI = 15; if (grade == 5) probBI = 24; if (grade == 6) probBI = 27; if (grade == 7) probBI = 100; if (grade == 8) probBI = 80; if (grade == 9) probBI = 35; if (grade == 10) probBI = 23; if (grade == 11) probBI = 11; if (grade == 12) probBI = 3; } */ countHelped = 0; Form1->EditCountHelped->Text = countHelped; stop = false; message.data[0] = 0xC0; message.data[1] = 6; message.data[2] = 100; message.data[3] = 0; midiOutShortMsg(device, message.word); while (stop == false) { step(); Application->ProcessMessages(); } } } //=========================================================================== // EVENT HANDLERS //=========================================================================== //------------------------------------------------------------ On Form Create void __fastcall TForm1::FormCreate(TObject *Sender) { midiOutOpen(&device, midiport, 0, 0, CALLBACK_NULL); randomize(); // defines an array of images with properties and events for (int i = 0; i < 25; i++) { image[i] = new TImage(this); image[i]->Parent = Form1; image[i]->Visible = true; image[i]->OnMouseDown = ImageMouseDown; image[i]->OnMouseUp = ImageMouseUp; image[i]->OnMouseMove = ImageMouseMove; image[i]->AutoSize = true; //image[i]->Height = 50; //image[i]->Width = 50; image[i]->Left = 0; image[i]->Top = 0; image[i]->Visible = true; if (i % 2 == 0) { image[i]->Picture = Form1->boyNormal->Picture; } else image[i]->Picture = Form1->girlNormal->Picture; image[i]->Transparent = true; image[i]->Tag = i; image[i]->BringToFront(); //shape[i]->Pen->Width = 2; //shape[i]->Pen->Color = // static_cast(colorRamp(25, 24 - shape[i]->Tag)); //shape[i]->Brush->Color = // static_cast(colorRamp(25, shape[i]->Tag)); } //image[3]->Transparent=false; image[0]->Picture = Form1->boyBully->Picture; image[24]->Picture = Form1->maleTeacher->Picture; //image[23]->Picture = Form1->ImageTeacher->Picture; shuffle(); } //------------------------------------------------------- On image Mouse Down // An exception to the rule which says "Let Borland write event handlers." // This one you must type in yourself in addition to a reference to it // in Unit1.h (look at the source code in that unit). void __fastcall TForm1::ImageMouseDown(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TImage *image = dynamic_cast(Sender); // The following will be used for mouseMove and mouseUp events... // Captures the index number of the image that was clicked chosenAgent = image->Tag; // remembers is we were stopped or running wasStopped = stop; stop = true; if (Button == 0) { // Begin drag object // Remembers that an image was chosen for mouseMove and mouseUp agentWasJustChosen = true; // Remembers where on the image the mouse was downed imageDownX = X; imageDownY = Y; } else { // Show nearest neighbor Form1->Canvas->MoveTo(agent[chosenAgent].x, agent[chosenAgent].y); Form1->Canvas->LineTo(agent[nearestNeighbor(chosenAgent)].x, agent[nearestNeighbor(chosenAgent)].y); } } //------------------------------------------------------- On image Mouse Move // An exception to the rule which says "Let Borland write event handlers." // This one you must type in yourself in addition to a reference to it // in Unit1.h (look at the source code in that unit). void __fastcall TForm1::ImageMouseMove(TObject *Sender, TShiftState Shift, int X, int Y) { TImage *image = dynamic_cast(Sender); chosenAgent = image->Tag; if (agentWasJustChosen) { // this drags the image along... image->Left = image->Left + X - imageDownX; image->Top = image->Top + Y - imageDownY; agent[chosenAgent].x = image->Left + image->Width / 2;; agent[chosenAgent].y = image->Top + image->Height / 2;; } // When the mouse moves over an image its values are displayed EditAgent->Text = image->Tag; EditX->Text = int(agent[chosenAgent].x); EditY->Text = int(agent[chosenAgent].y); EditDirection->Text = agent[image->Tag].direction; EditVelocity->Text = agent[image->Tag].velocity; } //--------------------------------------------------------- On image Mouse Up // An exception to the rule which says "Let Borland write event handlers." // This one you must type in yourself in addition to a reference to it // in Unit1.h (look at the source code in that unit). void __fastcall TForm1::ImageMouseUp(TObject *Sender, TMouseButton Button, TShiftState Shift, int X, int Y) { TImage *image = dynamic_cast(Sender); // this is the end of the drag... agentWasJustChosen = false; EditAgent->Text = image->Tag; // When the mouse moves over an image its values are displayed EditX->Text = int(agent[chosenAgent].x); EditY->Text = int(agent[chosenAgent].y); EditDirection->Text = agent[image->Tag].direction; EditVelocity->Text = agent[image->Tag].velocity; // if we were running before the drag, then run... Form1->Refresh(); if (!wasStopped) { run(); } } //---------------------------------------------------------------- run button void __fastcall TForm1::ButtonRunClick(TObject *Sender) { run(); } //--------------------------------------------------------------- step button void __fastcall TForm1::ButtonStepClick(TObject *Sender) { stop = true; step(); } //--------------------------------------------------------------- stop button void __fastcall TForm1::ButtonStopClick(TObject *Sender) { stop = true; } //---------------------------------------------------------- randomize button void __fastcall TForm1::ButtonResetClick(TObject *Sender) { reset(); } //------------------------------------------------------------- circle button void __fastcall TForm1::ButtonCircleClick(TObject *Sender) { circle(); } //------------------------------------------------------ size change trackBar void __fastcall TForm1::TrackBarSizeChange(TObject *Sender) { int size = TrackBarSize->Position; for (int i = 0; i < 24; i++) { image[i]->Height = size; image[i]->Width = size; } } //----------------------------------------------------- sound type RadioGroup void __fastcall TForm1::RadioGroupBullyInfluenceClick(TObject *Sender) { // soundType = RadioGroupSonification->ItemIndex; bullyInfluence = 25*RadioGroupBullyInfluence->ItemIndex; //bullyInfluence = RadioGroupBullyInfluence->ItemIndex; //bullyInfluence = probBI;{ probBI = TrackBarProbability->Position; Form1->EditProbability->Text = probBI; if (RadioGroupBullyInfluence->ItemIndex == 0){ TrackBarProbability->Position = 0; Form1->EditProbability->Text = 0; } if (RadioGroupBullyInfluence->ItemIndex == 1){ TrackBarProbability->Position = 4; Form1->EditProbability->Text = 4; } if (RadioGroupBullyInfluence->ItemIndex == 2){ probBI = TrackBarProbability->Position; Form1->EditProbability->Text = 5; } if (RadioGroupBullyInfluence->ItemIndex == 3) { TrackBarProbability->Position = 9; Form1->EditProbability->Text = 9; } if (RadioGroupBullyInfluence->ItemIndex == 4) { TrackBarProbability->Position = 15; Form1->EditProbability->Text = 15; } if (RadioGroupBullyInfluence->ItemIndex == 5) { TrackBarProbability->Position = 24; Form1->EditProbability->Text = 24; } if (RadioGroupBullyInfluence->ItemIndex == 6) { TrackBarProbability->Position = 27; Form1->EditProbability->Text = 27; } if (RadioGroupBullyInfluence->ItemIndex == 7) { TrackBarProbability->Position = 100; Form1->EditProbability->Text = 100; } if (RadioGroupBullyInfluence->ItemIndex == 8) { TrackBarProbability->Position = 80; Form1->EditProbability->Text = 80; } if (RadioGroupBullyInfluence->ItemIndex == 9) { TrackBarProbability->Position = 35; Form1->EditProbability->Text = 35; } if (RadioGroupBullyInfluence->ItemIndex == 10) { TrackBarProbability->Position = 23; Form1->EditProbability->Text = 23; } if (RadioGroupBullyInfluence->ItemIndex == 11) { TrackBarProbability->Position = 11; Form1->EditProbability->Text = 11; } if (RadioGroupBullyInfluence->ItemIndex == 12) { TrackBarProbability->Position = 3; Form1->EditProbability->Text = 3; //reset(); } //} } //--------------------------------------------------------------------------- void __fastcall TForm1::ButtonSitClick(TObject *Sender) { sit(); } //--------------------------------------------------------------------------- void __fastcall TForm1::TrackBarProbabilityChange(TObject *Sender) { probability = TrackBarProbability->Position; Form1->EditProbability->Text = probability; } //---------------------------------------------------------------------------