diff options
| author | Eugen Wissner <belka@caraus.de> | 2025-12-13 16:35:46 +0100 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2025-12-13 16:35:46 +0100 |
| commit | c1147629f7aae2ee90ccd7c9f1ccbf106361d486 (patch) | |
| tree | 67a549c6796702fa3db9248d599424066345dab4 /Занимательное программирование/1/4_gas/unit1.pas | |
| parent | 98329e0a3dd4f78b5d815ac3896272ec70904901 (diff) | |
| download | book-exercises-c1147629f7aae2ee90ccd7c9f1ccbf106361d486.tar.gz | |
Add book "Занимательное программирование"
Diffstat (limited to 'Занимательное программирование/1/4_gas/unit1.pas')
| -rw-r--r-- | Занимательное программирование/1/4_gas/unit1.pas | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/Занимательное программирование/1/4_gas/unit1.pas b/Занимательное программирование/1/4_gas/unit1.pas new file mode 100644 index 0000000..22a8433 --- /dev/null +++ b/Занимательное программирование/1/4_gas/unit1.pas @@ -0,0 +1,181 @@ +unit Unit1; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, + Math; + +type + + Molecule = record + X, Y: Integer; + Vx, Vy: Integer; + end; + + { TForm1 } + + TForm1 = class(TForm) + Cold: TLabel; + Warm: TLabel; + StartStopBtn: TButton; + Screen: TPaintBox; + procedure ScreenPaint(Sender: TObject); + procedure StartStopBtnClick(Sender: TObject); + private + + public + + end; + +var + Form1: TForm1; + IsRunning: Boolean = false; + +implementation + +{$R *.lfm} + +procedure TForm1.ScreenPaint(Sender: TObject); +begin + +end; + +procedure TForm1.StartStopBtnClick(Sender: TObject); + const RMolecule: Integer = 10; { Радиус молекулы } + const RHole: Integer = 15; + const V: Integer = 7; { Скорость молекулы } + const N = 20; { Количество молекул } + + var angle: Real; { Угол, задающий начальное направление полета } + i: Integer; { Счетчик цикла } + Mol: array[1..N * 2] of Molecule; { Массив молекул } + CurV: Integer; { Выбранаая случайная скорость молекулы } + halfScreen: Integer; + T1, T2: Integer; { Температуры и количество, статистика } + +begin + if IsRunning then + begin + IsRunning := false; + StartStopBtn.Caption := 'Пуск'; + Exit; + end; + + StartStopBtn.Caption := 'Стоп'; + IsRunning := true; + + Randomize; + Screen.Refresh; + + halfScreen := Screen.Width div 2; + T1 := V * N; + T2 := V * N; + + for i := 1 to N * 2 do { Цикл по все молекулам } + begin + { Выбор начального положения молекулы } + if i <= N then + begin + Mol[i].X := RandomRange(RMolecule, halfScreen - RMolecule); + end + else + begin + Mol[i].X := RandomRange(halfScreen + RMolecule, + Screen.Width - RMolecule); + end; + Mol[i].Y := RandomRange(RMolecule, Screen.Height - RMolecule); + + { Выбор нправления и скорости молекулы (1 - V) } + angle := Random(360) * Pi / 180; + CurV := RandomRange(1, V); + Mol[i].Vx := Round(CurV * Sin(angle)); { Получение составляющих } + Mol[i].Vy := Round(CurV * Cos(angle)); { скорости молекулы } + end; + + while IsRunning do { Основной цикл } + begin + { Черчение перегородки } + Screen.Canvas.Line(halfScreen, 0, halfScreen, + Screen.Height div 2 - RHole - RMolecule); + Screen.Canvas.Line(halfScreen, Screen.Height div 2 + RHole + RMolecule, + halfScreen, Screen.Height); + + for i := 1 to N * 2 do { Цикл по всем молекулам } + begin + Screen.Canvas.Pen.Color := clBtnFace; + Screen.Canvas.Ellipse(Mol[i].X - RMolecule, Mol[i].Y - RMolecule, + Mol[i].X + RMolecule, Mol[i].Y + RMolecule); + + { Сдвигаем на новую позицию } + Mol[i].X := Mol[i].X + Mol[i].Vx; + Mol[i].Y := Mol[i].Y + Mol[i].Vy; + + if (Mol[i].X > halfScreen - RMolecule) and + (Mol[i].X - Mol[i].Vx <= halfScreen - RMolecule) then + begin + if (Mol[i].Y >= Screen.Height div 2 - RHole) and + (Mol[i].Y <= Screen.Height div 2 + RHole) then + begin + T1 := T1 - V; T2 := T2 + V; + end + else + begin + Mol[i].X := halfScreen - RMolecule; + Mol[i].Vx := -Mol[i].Vx; + end; + end + else if (Mol[i].X < halfScreen + RMolecule) and + (Mol[i].X - Mol[i].Vx >= halfScreen + RMolecule) then + begin + if (Mol[i].Y >= Screen.Height div 2 - RHole) and + (Mol[i].Y <= Screen.Height div 2 + RHole) then + begin + T2 := T2 - V; + T1 := T1 + V; + end + else + begin + Mol[i].X := halfScreen + RMolecule; + Mol[i].Vx := -Mol[i].Vx; + end; + end; + + { Определяем, не вышла ли молекула за границы аквариума } + if Mol[i].X > Screen.Width - RMolecule then + begin + Mol[i].X := Screen.Width - RMolecule; + Mol[i].Vx := -Mol[i].Vx; + end; + if Mol[i].X < RMolecule then + begin + Mol[i].X := RMolecule; + Mol[i].Vx := -Mol[i].Vx; + end; + if Mol[i].Y > Screen.Height - RMolecule then + begin + Mol[i].Y := Screen.Height - RMolecule; + Mol[i].Vy := -Mol[i].Vy; + end; + if Mol[i].Y < RMolecule then + begin + Mol[i].Y := RMolecule; + Mol[i].Vy := -Mol[i].Vy; + end; + + Cold.Caption := IntToStr(T1); + Warm.Caption := IntToStr(T2); + + Screen.Canvas.Pen.Color := clBlue; { Рисуем молекулу на новой } + Screen.Canvas.Ellipse(Mol[i].X - RMolecule, Mol[i].Y - RMolecule, { позиции } + Mol[i].X + RMolecule, Mol[i].Y + RMolecule); + end; + Sleep(10); { Пауза на 10 миллисекунд } + Application.ProcessMessages; + end; +end; + +end. + |
