LINUX.ORG.RU

Он это смог сделать, потому что в его обучающем материале было много примеров таких простых игр. Такие игры пишут все кто обучается программированию, и на основе этого обучащего материала он и сгенерировал код.

vbcnthfkmnth123 ★★★★★
()

Я как-то спросил у perplexity про один проприетарный продукт, и он мне посоветовал обратиться в саппорт. Засим прошу считать, что ИИ может полностью заменить лорчик)

goingUp ★★★★★
()
Ответ на: комментарий от goingUp

Gemini защищает несовершеннолетнего пользователя от повреждения мозга сиплюсплюсом

А ведь скольких спасти не удалось? Страдают многие организации, и даже гос. конторы!

sanyo1234
()

Ты у него попроси решить DevOps задачки, к которым никогда ещё не было готового решения. Хотя бы поменяй немного условия.

Terraform, Ansible, etc.

Cloude v2 - образцовопоказательный галлюционирующий тупень на таких задачах.

sanyo1234
()
Ответ на: комментарий от vbcnthfkmnth123

Ну мне GPT-4-Turbo написала как-то программу с использованием незадокументированного NT API. Чет я сомневаюсь, что такое много кто писал…

Nxx ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Вот игра, которую он написал. Я не то что ни строчки не добавил, диже никаких исправлений не вносил. Только просил добавить фичи, звёзды, уровни, жизни…

https://filetransfer.io/data-package/aYgbExCj#link

Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 1)
Ответ на: комментарий от Nxx

с использованием незадокументированного NT API

Ну давайте названия функций, иначе 4.2

anc ★★★★★
()
Ответ на: комментарий от Nxx

GPT бесплатный с сайта openai мне написал скрипт для микротика, конфиг бэкапить с некоторыми особенностями. Ну, работает, прям искаропки без правок. Притом, что по этому их языку (недо-Lua) даже документации нет по сути, только примеры, а дальше сам как хочешь.

Вот copilot барахло, даже в скрипты не может нормально. Уровень алисы или первых версий GPT. Генерит код с выдуманными командами и библиотеками, упорно пытается решать не ту задачу которую ему дали, игнорирует половину условий сколько его не пинай и т.д..

yu-boot ★★★★
()
Брожу один меж голых серых скал,
Вдали от шума праздной суеты.
Здесь Музы голос ясно прозвучал,
Средь вечной, первозданной красоты.

(с) Claude-3-Opus

Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 1)
Ответ на: комментарий от knovich

Чему там вылетать? Там всего два файла:

EGAVGA.BGI
starwe.exe

Или ты пытаешься запустить в Linux через Wine виндовый Dosbox через start.bat?

Я имел в виду что запускать надо в Dosbox. В Linux есть нативный Dosbox, в нем и надо запускать, само собой.

Xintrea ★★★★★
()
Ответ на: комментарий от Nxx

Результат интересный, как сам факт такой генерации игры.

Но вопрос в том, можно ли сделать любую игру на придуманной тобой механике, или можно делать только то что уже известно - «вертикальный скролл-шутер», «битемап с горизонтальным продвижением вправо» и т. д.

И да, игра какая-то тормозная. Почему?

Xintrea ★★★★★
()
Ответ на: комментарий от Gary
uses GraphABC;

const
  WindowWidth = 800;
  WindowHeight = 600;
  PlayerSize = 50;
  EnemySize = 30;
  InitialEnemyCount = 5;
  BulletSize = 10;
  MaxLives = 5;
  EnemiesPerLevel = 10;
  StarCount = 100;

var
  playerX, playerY: integer;
  enemyX, enemyY: array[1..100] of integer;
  enemyCount, bulletCount, lives, score, level: integer;
  bulletX, bulletY: array[1..100] of integer;
  starX, starY: array[1..StarCount] of integer;
  leftKeyDown, rightKeyDown, upKeyDown, downKeyDown, gameOver: boolean;

procedure PlaySound(freq1, freq2, duration: integer);
begin
  System.Console.Beep(freq1, duration);
  System.Console.Beep(freq2, duration);
end;

procedure KeyDown(key: integer);
begin
  case key of
    VK_Left: leftKeyDown := true;
    VK_Right: rightKeyDown := true;
    VK_Up: upKeyDown := true;
    VK_Down: downKeyDown := true;
    VK_Space:
      if bulletCount < 100 then
      begin
        Inc(bulletCount);
        bulletX[bulletCount] := playerX + PlayerSize div 2 - BulletSize div 2;
        bulletY[bulletCount] := playerY - BulletSize;
      end;
    VK_Escape: gameOver := true;
  end;
end;

procedure KeyUp(key: integer);
begin
  case key of
    VK_Left: leftKeyDown := false;
    VK_Right: rightKeyDown := false;
    VK_Up: upKeyDown := false;
    VK_Down: downKeyDown := false;
  end;
end;

procedure Init;
var
  i: integer;
begin
  SetWindowSize(WindowWidth, WindowHeight);
  CenterWindow;
  Window.Title := 'Spaceship Game';
  OnKeyDown := KeyDown;
  OnKeyUp := KeyUp;
  playerX := WindowWidth div 2 - PlayerSize div 2;
  playerY := WindowHeight - PlayerSize - 20;
  enemyCount := InitialEnemyCount;
  for i := 1 to enemyCount do
  begin
    enemyX[i] := Random(WindowWidth - EnemySize);
    enemyY[i] := -EnemySize;
  end;
  for i := 1 to StarCount do
  begin
    starX[i] := Random(WindowWidth);
    starY[i] := Random(WindowHeight);
  end;
  bulletCount := 0;
  gameOver := false;
  lives := MaxLives;
  score := 0;
  level := 1;
end;

procedure MovePlayer;
begin
  if leftKeyDown and (playerX > 0) then playerX := playerX - 5;
  if rightKeyDown and (playerX < WindowWidth - PlayerSize) then playerX := playerX + 5;
  if upKeyDown and (playerY > 30) then playerY := playerY - 5;
  if downKeyDown and (playerY < WindowHeight - PlayerSize) then playerY := playerY + 5;
end;

procedure MoveEnemies;
var
  i: integer;
begin
  for i := 1 to enemyCount do
  begin
    case i of
      1: enemyY[i] := enemyY[i] + 2;
      2: begin
           enemyX[i] := enemyX[i] + Round(3 * Sin(enemyY[i] / 50));
           enemyY[i] := enemyY[i] + 2;
         end;
      3: enemyY[i] := enemyY[i] + Round(abs(enemyY[i] - WindowHeight div 2) / 50) + 1;
      4: begin
           enemyX[i] := enemyX[i] + Round(2 * Cos(enemyY[i] / 30));
           enemyY[i] := enemyY[i] + 2;
         end;
      5: enemyY[i] := enemyY[i] + Round(Sqrt(abs(enemyY[i] - WindowHeight div 2))) + 1;
      else
        enemyY[i] := enemyY[i] + 2;
    end;
    if enemyY[i] > WindowHeight then
    begin
      enemyX[i] := Random(WindowWidth - EnemySize);
      enemyY[i] := -EnemySize;
    end;
  end;
end;

procedure MoveBullets;
var
  i: integer;
begin
  for i := 1 to bulletCount do
  begin
    bulletY[i] := bulletY[i] - 10;
    if bulletY[i] < -BulletSize then
    begin
      bulletX[i] := bulletX[bulletCount];
      bulletY[i] := bulletY[bulletCount];
      Dec(bulletCount);
    end;
  end;
end;

procedure CheckCollision;
var
  i, j: integer;
begin
  for i := 1 to enemyCount do
  begin
    if (playerX < enemyX[i] + EnemySize) and (playerX + PlayerSize > enemyX[i]) and
       (playerY < enemyY[i] + EnemySize) and (playerY + PlayerSize > enemyY[i]) then
    begin
      lives := lives - 1;
      if lives = 0 then gameOver := true;
      enemyX[i] := Random(WindowWidth - EnemySize);
      enemyY[i] := -EnemySize;
      PlaySound(500, 400, 100);
    end;
    for j := 1 to bulletCount do
    begin
      if (bulletX[j] < enemyX[i] + EnemySize) and (bulletX[j] + BulletSize > enemyX[i]) and
         (bulletY[j] < enemyY[i] + EnemySize) and (bulletY[j] + BulletSize > enemyY[i]) then
      begin
        enemyX[i] := Random(WindowWidth - EnemySize);
        enemyY[i] := -EnemySize;
        bulletX[j] := bulletX[bulletCount];
        bulletY[j] := bulletY[bulletCount];
        Dec(bulletCount);
        Inc(score);
        PlaySound(800, 1000, 50);
        if score mod EnemiesPerLevel = 0 then
        begin
          Inc(level);
          Inc(enemyCount);
          enemyX[enemyCount] := Random(WindowWidth - EnemySize);
          enemyY[enemyCount] := -EnemySize;
        end;
        Break;
      end;
    end;
  end;
end;

procedure ShowGameOver;
begin
  SetBrushColor(clWhite);
  FillRectangle(0, 0, WindowWidth, WindowHeight);
  SetFontSize(48);
  SetFontColor(clRed);
  var text := 'Game Over';
  var x := (WindowWidth - TextWidth(text)) div 2;
  var y := (WindowHeight - TextHeight(text)) div 2;
  TextOut(x, y, text);
  Redraw();
  PlaySound(200, 100, 200);
end;

procedure DrawSpaceship;
begin
  Pen.Color := clBlue;
  Pen.Width := 2;
  Line(playerX + PlayerSize div 2, playerY, playerX, playerY + PlayerSize);
  Line(playerX, playerY + PlayerSize, playerX + PlayerSize div 4, playerY + PlayerSize div 2);
  Line(playerX + PlayerSize div 4, playerY + PlayerSize div 2, playerX + PlayerSize div 2, playerY + PlayerSize div 3);
  Line(playerX + PlayerSize div 2, playerY + PlayerSize div 3, playerX + PlayerSize * 3 div 4, playerY + PlayerSize div 2);
  Line(playerX + PlayerSize * 3 div 4, playerY + PlayerSize div 2, playerX + PlayerSize, playerY + PlayerSize);
  Line(playerX + PlayerSize, playerY + PlayerSize, playerX + PlayerSize div 2, playerY);
end;

begin
  Init;
  while not gameOver do
  begin
    LockDrawing;
    ClearWindow(clBlack);
    for var i := 1 to StarCount do
    begin
      Brush.Color := clWhite;
      FillEllipse(starX[i], starY[i], starX[i] + 2, starY[i] + 2);
    end;
    MovePlayer;
    MoveEnemies;
    MoveBullets;
    CheckCollision;
    DrawSpaceship;
    for var i := 1 to enemyCount do
    begin
      Brush.Color := clRed;
      Ellipse(enemyX[i], enemyY[i], enemyX[i] + EnemySize, enemyY[i] + EnemySize);
    end;
    for var i := 1 to bulletCount do
    begin
      Brush.Color := clYellow;
      Ellipse(bulletX[i], bulletY[i], bulletX[i] + BulletSize, bulletY[i] + BulletSize);
    end;
    SetBrushColor(clBlack);
    FillRectangle(0, 0, WindowWidth, 30);
    SetFontSize(20);
    SetFontColor(clWhite);
    TextOut(10, 10, 'Lives: ' + IntToStr(lives));
    TextOut(WindowWidth - 150, 10, 'Score: ' + IntToStr(score));
    TextOut(WindowWidth div 2 - 50, 10, 'Level: ' + IntToStr(level));
    Redraw;
    Sleep(10);
  end;
  ShowGameOver;
  Sleep(2000);
  CloseWindow;
end.
Nxx ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Но вопрос в том, можно ли сделать любую игру на придуманной тобой механике, или можно делать только то что уже известно - «вертикальный скролл-шутер», «битемап с горизонтальным продвижением вправо» и т. д.

Всё что он поймёт по-русски можно сделать. Я, например, говорю, «добавь жизни», «добавь уровни», «добавь очки», «добавь звук». Можно добавить разные виды оружия, раные виды врагов, бонусы и т.д. На что фантазии хватит.

Можно сказать сделать из вертикального горизонтальный шутер - думаю, в один запрос переделает.

Тормозное, видимо, из-за библиотек PascalABC.

Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 2)
Ответ на: комментарий от yu-boot

Без понятия, чего он в плане кода, но на простых задачках из курса математики 10-11 классов он тупит невероятно, причем косячит в элементарных вещах вроде вынесения общего множителя за скобки и сокращения числителя и знаменателя на этот множитель. Вольфрам на запуске в 2009 году лучше справлялся.

leave ★★★★★
()
Ответ на: комментарий от Nxx

Тормозное, видимо, из-за библиотек PascalABC.

Ну так попроси переписать без тормозов.
А потом переписать на C++.

Bad_ptr ★★★★★
()
Ответ на: комментарий от Xintrea

Я в windows 10 запускаю в режиме совместимости с xp. Потом попробую по-другому.

У меня стартует, я что-то нажимаю, появляется корабль на резинке, и через секунду всё пропадает.

knovich
()
Ответ на: комментарий от Xintrea

Загрузил в Клод-3-Сонет скриншот твоей игры и объяснил динамику.

Он мне сделал такое: https://filetransfer.io/data-package/cAnS3odB#link

Судя по коду там ещё звёздное небо должно рисоваться, но я его не вижу.

Корабль (красный треугольник) летит к желтой точке, которая управляется мышкой. Стреляет красными пулями (по щелчку мышки) по зеленым врагам. Число врагов уменьшается.

Код:

program SpaceshipGame;

uses
  GraphABC;

const
  WindowWidth = 800;
  WindowHeight = 600;
  PlayerSpeed = 5;
  BulletSpeed = 10;
  NumStars = 100;
  NumEnemies = 10;

type
  TVector2 = record
    X, Y: Integer;
  end;

  TEnemy = record
    Position: TVector2;
    Velocity: TVector2;
    Active: Boolean;
  end;

  TBullet = record
    Position: TVector2;
    Velocity: TVector2;
  end;

var
  PlayerPosition: TVector2;
  TargetPosition, TargetVelocity: TVector2;
  Enemies: array [0..NumEnemies - 1] of TEnemy;
  Bullets: array of TBullet;
  Stars: array [0..NumStars - 1] of TVector2;
  IsMouseDown: Boolean;

procedure DrawShip(Position: TVector2);
begin
  SetPenColor(clRed);
  Line(Position.X, Position.Y - 10, Position.X - 10, Position.Y + 10);
  Line(Position.X - 10, Position.Y + 10, Position.X + 10, Position.Y + 10);
  Line(Position.X + 10, Position.Y + 10, Position.X, Position.Y - 10);
end;

procedure DrawTarget(Position: TVector2);
begin
  SetPenColor(clYellow);
  Circle(Position.X, Position.Y, 5);
end;

procedure DrawEnemies;
var
  i: Integer;
begin
  SetPenColor(clGreen);
  for i := 0 to High(Enemies) do
    if Enemies[i].Active then
      Rectangle(Enemies[i].Position.X - 5, Enemies[i].Position.Y - 5, Enemies[i].Position.X + 5, Enemies[i].Position.Y + 5);
end;

procedure DrawBullets;
var
  i: Integer;
begin
  SetPenColor(clRed);
  for i := 0 to High(Bullets) do
    Line(Bullets[i].Position.X, Bullets[i].Position.Y, Bullets[i].Position.X + Bullets[i].Velocity.X * 5, Bullets[i].Position.Y + Bullets[i].Velocity.Y * 5);
end;

procedure DrawStars;
var
  i: Integer;
begin
  SetPenColor(clWhite);
  for i := 0 to High(Stars) do
    Rectangle(Stars[i].X, Stars[i].Y, Stars[i].X + 1, Stars[i].Y + 1);
end;

procedure UpdatePlayer;
var
  Direction: TVector2;
  Distance: Integer;
begin
  Direction.X := TargetPosition.X - PlayerPosition.X;
  Direction.Y := TargetPosition.Y - PlayerPosition.Y;
  Distance := Round(Sqrt(Direction.X * Direction.X + Direction.Y * Direction.Y));
  if Distance > 0 then
  begin
    Direction.X := Round(Direction.X / Distance * PlayerSpeed);
    Direction.Y := Round(Direction.Y / Distance * PlayerSpeed);
    PlayerPosition.X := PlayerPosition.X + Direction.X;
    PlayerPosition.Y := PlayerPosition.Y + Direction.Y;
  end;
end;

procedure UpdateTarget;
begin
  TargetPosition.X := TargetPosition.X + TargetVelocity.X;
  TargetPosition.Y := TargetPosition.Y + TargetVelocity.Y;
end;

procedure UpdateEnemies;
var
  i: Integer;
begin
  for i := 0 to High(Enemies) do
  begin
    if Enemies[i].Active then
    begin
      Enemies[i].Position.X := Enemies[i].Position.X + Enemies[i].Velocity.X;
      Enemies[i].Position.Y := Enemies[i].Position.Y + Enemies[i].Velocity.Y;

      // Keep enemies within the field of view
      if (Enemies[i].Position.X < -10) then
        Enemies[i].Position.X := WindowWidth + 10;
      if (Enemies[i].Position.X > WindowWidth + 10) then
        Enemies[i].Position.X := -10;
      if (Enemies[i].Position.Y < -10) then
        Enemies[i].Position.Y := WindowHeight + 10;
      if (Enemies[i].Position.Y > WindowHeight + 10) then
        Enemies[i].Position.Y := -10;
    end;
  end;
end;

procedure UpdateBullets;
var
  i, j: Integer;
begin
  for i := 0 to High(Bullets) do
  begin
    Bullets[i].Position.X := Bullets[i].Position.X + Bullets[i].Velocity.X;
    Bullets[i].Position.Y := Bullets[i].Position.Y + Bullets[i].Velocity.Y;

    // Check for collisions with enemies
    for j := 0 to High(Enemies) do
    begin
      if Enemies[j].Active and
         (Abs(Bullets[i].Position.X - Enemies[j].Position.X) < 10) and
         (Abs(Bullets[i].Position.Y - Enemies[j].Position.Y) < 10) then
      begin
        Enemies[j].Active := False;
        Bullets[i].Position.X := -100; // Move the bullet off-screen
        Break;
      end;
    end;
  end;
end;

procedure MouseDown(x, y, mb: Integer);
begin
  TargetPosition.X := x;
  TargetPosition.Y := y;
  TargetVelocity.X := Random(11) - 5;
  TargetVelocity.Y := Random(11) - 5;
  IsMouseDown := True;
end;

procedure MouseMove(x, y, mb: Integer);
begin
  if IsMouseDown then
  begin
    TargetPosition.X := x;
    TargetPosition.Y := y;
  end;
end;

procedure MouseUp(x, y, mb: Integer);
begin
  IsMouseDown := False;
  if mb = 1 then
  begin
    SetLength(Bullets, Length(Bullets) + 1);
    Bullets[High(Bullets)].Position := PlayerPosition;
    Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) div BulletSpeed;
    Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) div BulletSpeed;
  end;
end;

begin
  SetWindowSize(WindowWidth, WindowHeight);
  SetWindowCaption('Spaceship Game');
  SetBrushColor(clBlack);
  ClearWindow(clBlack);
  PlayerPosition.X := WindowWidth div 2;
  PlayerPosition.Y := WindowHeight div 2;
  TargetPosition := PlayerPosition;
  TargetVelocity.X := Random(11) - 5;
  TargetVelocity.Y := Random(11) - 5;

  for var i := 0 to High(Stars) do
  begin
    Stars[i].X := Random(WindowWidth);
    Stars[i].Y := Random(WindowHeight);
  end;

  for var i := 0 to High(Enemies) do
  begin
    Enemies[i].Position.X := Random(WindowWidth);
    Enemies[i].Position.Y := Random(WindowHeight);
    Enemies[i].Velocity.X := Random(11) - 5;
    Enemies[i].Velocity.Y := Random(11) - 5;
    Enemies[i].Active := True;
  end;

  OnMouseDown := MouseDown;
  OnMouseMove := MouseMove;
  OnMouseUp := MouseUp;

  while True do
  begin
    UpdatePlayer;
    UpdateTarget;
    UpdateEnemies;
    UpdateBullets;

    ClearWindow(clBlack);
    DrawStars;
    DrawShip(PlayerPosition);
    DrawTarget(TargetPosition);
    DrawEnemies;
    DrawBullets;

    Sleep(10);
  end;
end.
Nxx ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Вот, исправилось. Но исправления вручную скопировал из той игры, которую сделал Opus. Всё-таки, Opus мощнее Sonet. Но все проблемы касаются деталей работы PascalABC а не логики игры.

https://filetransfer.io/data-package/SNtUUCsz#link

Тут стрельба по пробелу и корабль следует за мышкой.

program SpaceshipGame;

uses
  GraphABC;

const
  WindowWidth = 800;
  WindowHeight = 600;
  PlayerSpeed = 5;
  BulletSpeed = 10;
  NumStars = 100;
  NumEnemies = 10;

type
  TVector2 = record
    X, Y: Integer;
  end;

  TEnemy = record
    Position: TVector2;
    Velocity: TVector2;
    Active: Boolean;
  end;

  TBullet = record
    Position: TVector2;
    Velocity: TVector2;
  end;

var
  PlayerPosition: TVector2;
  TargetPosition: TVector2;
  Enemies: array [0..NumEnemies - 1] of TEnemy;
  Bullets: array of TBullet;
  Stars: array [0..NumStars - 1] of TVector2;
  IsSpacePressed: Boolean;

procedure DrawShip(Position: TVector2);
begin
  SetPenColor(clRed);
  Line(Position.X, Position.Y - 10, Position.X - 10, Position.Y + 10);
  Line(Position.X - 10, Position.Y + 10, Position.X + 10, Position.Y + 10);
  Line(Position.X + 10, Position.Y + 10, Position.X, Position.Y - 10);
end;

procedure DrawTarget(Position: TVector2);
begin
  SetPenColor(clYellow);
  Circle(Position.X, Position.Y, 5);
end;

procedure DrawEnemies;
var
  i: Integer;
begin
  SetPenColor(clGreen);
  for i := 0 to High(Enemies) do
    if Enemies[i].Active then
      Rectangle(Enemies[i].Position.X - 5, Enemies[i].Position.Y - 5, Enemies[i].Position.X + 5, Enemies[i].Position.Y + 5);
end;

procedure DrawBullets;
var
  i: Integer;
begin
  SetPenColor(clRed);
  for i := 0 to High(Bullets) do
    Line(Bullets[i].Position.X, Bullets[i].Position.Y, Bullets[i].Position.X + Bullets[i].Velocity.X * 5, Bullets[i].Position.Y + Bullets[i].Velocity.Y * 5);
end;

procedure DrawStars;
var
  i: Integer;
begin
  SetPenColor(clWhite);
  for i := 0 to High(Stars) do
    Ellipse(Stars[i].X, Stars[i].Y, Stars[i].X + 2, Stars[i].Y + 2);
end;

procedure UpdatePlayer;
var
  Direction: TVector2;
  Distance: Integer;
begin
  if PlayerPosition <> TargetPosition then
  begin
    Direction.X := TargetPosition.X - PlayerPosition.X;
    Direction.Y := TargetPosition.Y - PlayerPosition.Y;
    Distance := Round(Sqrt(Direction.X * Direction.X + Direction.Y * Direction.Y));
    if Distance > 0 then
    begin
      Direction.X := Round(Direction.X / Distance * PlayerSpeed);
      Direction.Y := Round(Direction.Y / Distance * PlayerSpeed);
      PlayerPosition.X := PlayerPosition.X + Direction.X;
      PlayerPosition.Y := PlayerPosition.Y + Direction.Y;
    end;
  end;
end;

procedure UpdateEnemies;
var
  i: Integer;
begin
  for i := 0 to High(Enemies) do
  begin
    if Enemies[i].Active then
    begin
      Enemies[i].Position.X := Enemies[i].Position.X + Enemies[i].Velocity.X;
      Enemies[i].Position.Y := Enemies[i].Position.Y + Enemies[i].Velocity.Y;

      // Keep enemies within the field of view
      if (Enemies[i].Position.X < -10) then
        Enemies[i].Position.X := WindowWidth + 10;
      if (Enemies[i].Position.X > WindowWidth + 10) then
        Enemies[i].Position.X := -10;
      if (Enemies[i].Position.Y < -10) then
        Enemies[i].Position.Y := WindowHeight + 10;
      if (Enemies[i].Position.Y > WindowHeight + 10) then
        Enemies[i].Position.Y := -10;
    end;
  end;
end;

procedure UpdateBullets;
var
  i, j: Integer;
begin
  for i := 0 to High(Bullets) do
  begin
    Bullets[i].Position.X := Bullets[i].Position.X + Bullets[i].Velocity.X;
    Bullets[i].Position.Y := Bullets[i].Position.Y + Bullets[i].Velocity.Y;

    // Check for collisions with enemies
    for j := 0 to High(Enemies) do
    begin
      if Enemies[j].Active and
         (Abs(Bullets[i].Position.X - Enemies[j].Position.X) < 10) and
         (Abs(Bullets[i].Position.Y - Enemies[j].Position.Y) < 10) then
      begin
        Enemies[j].Active := False;
        Bullets[i].Position.X := -100; // Move the bullet off-screen
        Break;
      end;
    end;
  end;
end;

procedure MouseMove(x, y, mb: Integer);
begin
  TargetPosition.X := x;
  TargetPosition.Y := y;
end;

procedure KeyDown(Key: Integer);
begin
  if Key = vk_Space then
  begin
    IsSpacePressed := True;
    SetLength(Bullets, Length(Bullets) + 1);
    Bullets[High(Bullets)].Position := PlayerPosition;
    Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) div BulletSpeed;
    Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) div BulletSpeed;
  end;
end;

procedure KeyUp(Key: Integer);
begin
  if Key = vk_Space then
    IsSpacePressed := False;
end;

begin
  SetWindowSize(WindowWidth, WindowHeight);
  SetWindowCaption('Spaceship Game');
  SetBrushColor(clBlack);
  ClearWindow(clBlack);
  PlayerPosition.X := WindowWidth div 2;
  PlayerPosition.Y := WindowHeight div 2;
  TargetPosition := PlayerPosition;

  for var i := 0 to High(Stars) do
  begin
    Stars[i].X := Random(WindowWidth);
    Stars[i].Y := Random(WindowHeight);
  end;

  for var i := 0 to High(Enemies) do
  begin
    Enemies[i].Position.X := Random(WindowWidth);
    Enemies[i].Position.Y := Random(WindowHeight);
    Enemies[i].Velocity.X := Random(11) - 5;
    Enemies[i].Velocity.Y := Random(11) - 5;
    Enemies[i].Active := True;
  end;

  OnMouseMove := MouseMove;
  OnKeyDown := KeyDown;
  OnKeyUp := KeyUp;

  while True do
  begin
    UpdatePlayer;
    UpdateEnemies;
    UpdateBullets;
    LockDrawing;
    ClearWindow(clBlack);
    DrawStars;
    DrawShip(PlayerPosition);
    DrawTarget(TargetPosition);
    DrawEnemies;
    DrawBullets;

    if IsSpacePressed then
    begin
      SetLength(Bullets, Length(Bullets) + 1);
      Bullets[High(Bullets)].Position := PlayerPosition;
      Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) div BulletSpeed;
      Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) div BulletSpeed;
    end;
    Redraw;

    Sleep(10);
  end;
end.
Nxx ★★★★★
() автор топика
Ответ на: комментарий от Nxx

с использованием незадокументированного NT API

Возможно, он не только не задокументирован, но даже и не существует.

Leupold_cat ★★★★★
()
Ответ на: комментарий от Nxx

Вначале посмотрел код, понял что идея игры не воспроизвелась, затем запустил и подтвердил это.

Фишка оригинала в том, что корабль прикреплен к резинке (поэтому и называется Star Wars Elastic). Грубо говоря, чем дальше корабль от указателя, тем сильнее натягивается резинка, тем быстрее корабль двигается в сторону указателя. Плюс у корабля есть вес, а значит и инерция, то есть он не может мгновенно начать движение в указанную сторону.

А реализация сетки никуда не ушла от одноэкранного шутера (даже без приставки «скролл»). То есть, я спрашивал - можно ли сделать любую игру на придуманной тобой механике, или можно делать только то что уже известно - «вертикальный скролл-шутер», «битемап с горизонтальным продвижением вправо» и т. д.

То, что получилось - это очередное линейное перемещение главного героя по стрелкам или в сторону указателя, не более того. Таким образом, оригинальная механика не была сделана.

Но есть и плюс: сетка смогла сделать правильные выстрелы во все стороны, а не только горизонталь-вертикаль. Это, я считаю, достижение. Хотя, на 99% код основан на том, что куча игр с такими выстрелами уже была написана и сетка на них натренирована.

Еще плюс - хороший императивный код, все разбито на короткие функции с понятным неймингом как функций, так и переменных. Код гораздо лучше чем может написать средний джун, которых я видел.

Вывод: эти нейросетки могут привести к очередному взрыву однотипных говноигр, похожих друг на друга, и различающихся в деталях. Как это было с Atari. Пора писать следующие нейросетки для магазинов приложений, которые будут ранжировать игрули и отметать нейросетевые поделия.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Фишка оригинала в том, что корабль прикреплен к резинке (поэтому и называется Star Wars Elastic). Грубо говоря, чем дальше корабль от указателя, тем сильнее натягивается резинка, тем быстрее корабль двигается в сторону указателя. Плюс у корабля есть вес, а значит и инерция, то есть он не может мгновенно начать движение в указанную сторону.

Как это объяснить по-русски-то? Я просто сказал, что корабль притягивается к точке.

Сначало надо понять, как объяснить понятно.

Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 1)
Ответ на: комментарий от Xintrea

Но есть и плюс: сетка смогла сделать правильные выстрелы во все стороны, а не только горизонталь-вертикаль. Это, я считаю, достижение. Хотя, на 99% код основан на том, что куча игр с такими выстрелами уже была написана и сетка на них натренирована.

Довольно удивлен был, что снаряды летят со скоростью, тем большей, чем больше скорость корабля во время выстрела. И длина штриха указывает скорость снаряда.

Nxx ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Короче, вот.

https://filetransfer.io/data-package/6Ln8xiXb#link

Просто сказал, что корабль привязан к точке резинкой и имеет массу.

program SpaceshipGame;

uses
  GraphABC;

const
  WindowWidth = 800;
  WindowHeight = 600;
  PlayerSpeed = 5;
  BulletSpeed = 10;
  NumStars = 100;
  NumEnemies = 10;
  SpringConstant = 0.05;
  DampingFactor = 0.9;

type
  TVector2 = record
    X, Y: Double;
  end;

  TEnemy = record
    Position: TVector2;
    Velocity: TVector2;
    Active: Boolean;
  end;

  TBullet = record
    Position: TVector2;
    Velocity: TVector2;
  end;

var
  PlayerPosition: TVector2;
  PlayerVelocity: TVector2;
  TargetPosition: TVector2;
  Enemies: array [0..NumEnemies - 1] of TEnemy;
  Bullets: array of TBullet;
  Stars: array [0..NumStars - 1] of TVector2;
  IsSpacePressed: Boolean;

procedure DrawShip(Position: TVector2);
begin
  SetPenColor(clRed);
  Line(Round(Position.X), Round(Position.Y - 10), Round(Position.X - 10), Round(Position.Y + 10));
  Line(Round(Position.X - 10), Round(Position.Y + 10), Round(Position.X + 10), Round(Position.Y + 10));
  Line(Round(Position.X + 10), Round(Position.Y + 10), Round(Position.X), Round(Position.Y - 10));
end;

procedure DrawTarget(Position: TVector2);
begin
  SetPenColor(clYellow);
  Circle(Round(Position.X), Round(Position.Y), 5);
end;

procedure DrawEnemies;
var
  i: Integer;
begin
  SetPenColor(clGreen);
  for i := 0 to High(Enemies) do
    if Enemies[i].Active then
      Rectangle(Round(Enemies[i].Position.X - 5), Round(Enemies[i].Position.Y - 5),
                Round(Enemies[i].Position.X + 5), Round(Enemies[i].Position.Y + 5));
end;

procedure DrawBullets;
var
  i: Integer;
begin
  SetPenColor(clRed);
  for i := 0 to High(Bullets) do
    Line(Round(Bullets[i].Position.X), Round(Bullets[i].Position.Y),
         Round(Bullets[i].Position.X + Bullets[i].Velocity.X * 5),
         Round(Bullets[i].Position.Y + Bullets[i].Velocity.Y * 5));
end;

procedure DrawStars;
var
  i: Integer;
begin
  SetPenColor(clWhite);
  for i := 0 to High(Stars) do
    Ellipse(Round(Stars[i].X), Round(Stars[i].Y), Round(Stars[i].X + 2), Round(Stars[i].Y + 2));
end;

procedure UpdatePlayer;
var
  SpringForce, Acceleration: TVector2;
begin
  SpringForce.X := (TargetPosition.X - PlayerPosition.X) * SpringConstant;
  SpringForce.Y := (TargetPosition.Y - PlayerPosition.Y) * SpringConstant;

  Acceleration.X := SpringForce.X;
  Acceleration.Y := SpringForce.Y;

  PlayerVelocity.X := PlayerVelocity.X * DampingFactor + Acceleration.X;
  PlayerVelocity.Y := PlayerVelocity.Y * DampingFactor + Acceleration.Y;

  PlayerPosition.X := PlayerPosition.X + PlayerVelocity.X;
  PlayerPosition.Y := PlayerPosition.Y + PlayerVelocity.Y;
end;

procedure UpdateEnemies;
var
  i: Integer;
begin
  for i := 0 to High(Enemies) do
  begin
    if Enemies[i].Active then
    begin
      Enemies[i].Position.X := Enemies[i].Position.X + Enemies[i].Velocity.X;
      Enemies[i].Position.Y := Enemies[i].Position.Y + Enemies[i].Velocity.Y;

      // Keep enemies within the field of view
      if (Enemies[i].Position.X < -10) then
        Enemies[i].Position.X := WindowWidth + 10;
      if (Enemies[i].Position.X > WindowWidth + 10) then
        Enemies[i].Position.X := -10;
      if (Enemies[i].Position.Y < -10) then
        Enemies[i].Position.Y := WindowHeight + 10;
      if (Enemies[i].Position.Y > WindowHeight + 10) then
        Enemies[i].Position.Y := -10;
    end;
  end;
end;

procedure UpdateBullets;
var
  i, j: Integer;
begin
  for i := 0 to High(Bullets) do
  begin
    Bullets[i].Position.X := Bullets[i].Position.X + Bullets[i].Velocity.X;
    Bullets[i].Position.Y := Bullets[i].Position.Y + Bullets[i].Velocity.Y;

    // Check for collisions with enemies
    for j := 0 to High(Enemies) do
    begin
      if Enemies[j].Active and
         (Abs(Bullets[i].Position.X - Enemies[j].Position.X) < 10) and
         (Abs(Bullets[i].Position.Y - Enemies[j].Position.Y) < 10) then
      begin
        Enemies[j].Active := False;
        Bullets[i].Position.X := -100; // Move the bullet off-screen
        Break;
      end;
    end;
  end;
end;

procedure MouseMove(x, y, mb: Integer);
begin
  TargetPosition.X := x;
  TargetPosition.Y := y;
end;

procedure KeyDown(Key: Integer);
begin
  if Key = vk_Space then
  begin
    IsSpacePressed := True;
    SetLength(Bullets, Length(Bullets) + 1);
    Bullets[High(Bullets)].Position := PlayerPosition;
    Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) / BulletSpeed;
    Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) / BulletSpeed;
  end;
end;

procedure KeyUp(Key: Integer);
begin
  if Key = vk_Space then
    IsSpacePressed := False;
end;

begin
  SetWindowSize(WindowWidth, WindowHeight);
  SetWindowCaption('Spaceship Game');
  SetBrushColor(clBlack);
  ClearWindow(clBlack);
  PlayerPosition.X := WindowWidth / 2;
  PlayerPosition.Y := WindowHeight / 2;
  TargetPosition := PlayerPosition;

  for var i := 0 to High(Stars) do
  begin
    Stars[i].X := Random(WindowWidth);
    Stars[i].Y := Random(WindowHeight);
  end;

  for var i := 0 to High(Enemies) do
  begin
    Enemies[i].Position.X := Random(WindowWidth);
    Enemies[i].Position.Y := Random(WindowHeight);
    Enemies[i].Velocity.X := Random(11) - 5;
    Enemies[i].Velocity.Y := Random(11) - 5;
    Enemies[i].Active := True;
  end;
  
  OnMouseMove := MouseMove;
  OnKeyDown := KeyDown;
  OnKeyUp := KeyUp;

  while True do
  begin
    UpdatePlayer;
    UpdateEnemies;
    UpdateBullets;
    LockDrawing;
    ClearWindow(clBlack);
    DrawStars;
    DrawShip(PlayerPosition);
    DrawTarget(TargetPosition);
    DrawEnemies;
    DrawBullets;

    if IsSpacePressed then
    begin
      SetLength(Bullets, Length(Bullets) + 1);
      Bullets[High(Bullets)].Position := PlayerPosition;
      Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) / BulletSpeed;
      Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) / BulletSpeed;
    end;
    Redraw;

    Sleep(10);

  end;
end.
Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 1)
Ответ на: комментарий от Nxx

Просто сказал, что корабль привязан к точке резинкой и имеет массу.

Но ты же сам видишь по коду, что никакой массы у кораблика нет. Появилась Acceleration, которая тупо равна SpringForce, а SpringForce просто линейно возрастает чем кораблик дальше от указателя.

Да, и кстати, сетка смогет повернуть нос корабля в сторону указателя?

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Но ты же сам видишь по коду, что никакой массы у кораблика нет. Появилась Acceleration, которая тупо равна SpringForce, а SpringForce просто линейно возрастает чем кораблик дальше от указателя.

DampingFactor же.

Да, и кстати, сетка смогет повернуть нос корабля в сторону указателя?

Оно пытается использовать функции, которых нет в PascalABC (Polygon). Ему надо сказать, что нужно Line использовать.

Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 1)
Ответ на: комментарий от Nxx

DampingFactor же.

Это не учет массы, это линейное торможение, причем в сторону, куда направлен вектор «кораблик-мышка». Перемещаешь указатель в сторону, противоположную движению, и кораблик тупо в эту сторону тоже начинает тормозить. То есть, инертности нет, нет учета массы.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Вот. Сказал трение заменить гравитацией: https://filetransfer.io/data-package/56onuGZJ#link

program SpaceshipGame;

uses
  GraphABC;

const
  WindowWidth = 800;
  WindowHeight = 600;
  PlayerSpeed = 5;
  BulletSpeed = 10;
  NumStars = 100;
  NumEnemies = 10;
  SpringConstant = 0.05;
  GravityConstant = 0.1;

type
  TVector2 = record
    X, Y: Double;
  end;

  TEnemy = record
    Position: TVector2;
    Velocity: TVector2;
    Active: Boolean;
  end;

  TBullet = record
    Position: TVector2;
    Velocity: TVector2;
  end;

var
  PlayerPosition: TVector2;
  PlayerVelocity: TVector2;
  TargetPosition: TVector2;
  Enemies: array [0..NumEnemies - 1] of TEnemy;
  Bullets: array of TBullet;
  Stars: array [0..NumStars - 1] of TVector2;
  IsSpacePressed: Boolean;

procedure DrawShip(Position: TVector2);
begin
  SetPenColor(clRed);
  Line(Round(Position.X), Round(Position.Y - 10), Round(Position.X - 10), Round(Position.Y + 10));
  Line(Round(Position.X - 10), Round(Position.Y + 10), Round(Position.X + 10), Round(Position.Y + 10));
  Line(Round(Position.X + 10), Round(Position.Y + 10), Round(Position.X), Round(Position.Y - 10));
end;

procedure DrawTarget(Position: TVector2);
begin
  SetPenColor(clYellow);
  Circle(Round(Position.X), Round(Position.Y), 5);
end;

procedure DrawEnemies;
var
  i: Integer;
begin
  SetPenColor(clGreen);
  for i := 0 to High(Enemies) do
    if Enemies[i].Active then
      Rectangle(Round(Enemies[i].Position.X - 5), Round(Enemies[i].Position.Y - 5),
                Round(Enemies[i].Position.X + 5), Round(Enemies[i].Position.Y + 5));
end;

procedure DrawBullets;
var
  i: Integer;
begin
  SetPenColor(clRed);
  for i := 0 to High(Bullets) do
    Line(Round(Bullets[i].Position.X), Round(Bullets[i].Position.Y),
         Round(Bullets[i].Position.X + Bullets[i].Velocity.X * 5),
         Round(Bullets[i].Position.Y + Bullets[i].Velocity.Y * 5));
end;

procedure DrawStars;
var
  i: Integer;
begin
  SetPenColor(clWhite);
  for i := 0 to High(Stars) do
    Ellipse(Round(Stars[i].X), Round(Stars[i].Y), Round(Stars[i].X + 2), Round(Stars[i].Y + 2));
end;

procedure UpdatePlayer;
var
  SpringForce, GravityForce, Acceleration: TVector2;
begin
  SpringForce.X := (TargetPosition.X - PlayerPosition.X) * SpringConstant;
  SpringForce.Y := (TargetPosition.Y - PlayerPosition.Y) * SpringConstant;

  GravityForce.X := -PlayerVelocity.X * GravityConstant;
  GravityForce.Y := -PlayerVelocity.Y * GravityConstant;

  Acceleration.X := SpringForce.X + GravityForce.X;
  Acceleration.Y := SpringForce.Y + GravityForce.Y;

  PlayerVelocity.X := PlayerVelocity.X + Acceleration.X;
  PlayerVelocity.Y := PlayerVelocity.Y + Acceleration.Y;

  PlayerPosition.X := PlayerPosition.X + PlayerVelocity.X;
  PlayerPosition.Y := PlayerPosition.Y + PlayerVelocity.Y;
end;

procedure UpdateEnemies;
var
  i: Integer;
begin
  for i := 0 to High(Enemies) do
  begin
    if Enemies[i].Active then
    begin
      Enemies[i].Position.X := Enemies[i].Position.X + Enemies[i].Velocity.X;
      Enemies[i].Position.Y := Enemies[i].Position.Y + Enemies[i].Velocity.Y;

      // Keep enemies within the field of view
      if (Enemies[i].Position.X < -10) then
        Enemies[i].Position.X := WindowWidth + 10;
      if (Enemies[i].Position.X > WindowWidth + 10) then
        Enemies[i].Position.X := -10;
      if (Enemies[i].Position.Y < -10) then
        Enemies[i].Position.Y := WindowHeight + 10;
      if (Enemies[i].Position.Y > WindowHeight + 10) then
        Enemies[i].Position.Y := -10;
    end;
  end;
end;

procedure UpdateBullets;
var
  i, j: Integer;
begin
  for i := 0 to High(Bullets) do
  begin
    Bullets[i].Position.X := Bullets[i].Position.X + Bullets[i].Velocity.X;
    Bullets[i].Position.Y := Bullets[i].Position.Y + Bullets[i].Velocity.Y;

    // Check for collisions with enemies
    for j := 0 to High(Enemies) do
    begin
      if Enemies[j].Active and
         (Abs(Bullets[i].Position.X - Enemies[j].Position.X) < 10) and
         (Abs(Bullets[i].Position.Y - Enemies[j].Position.Y) < 10) then
      begin
        Enemies[j].Active := False;
        Bullets[i].Position.X := -100; // Move the bullet off-screen
        Break;
      end;
    end;
  end;
end;

procedure MouseMove(x, y, mb: Integer);
begin
  TargetPosition.X := x;
  TargetPosition.Y := y;
end;

procedure KeyDown(Key: Integer);
begin
  if Key = vk_Space then
  begin
    IsSpacePressed := True;
    SetLength(Bullets, Length(Bullets) + 1);
    Bullets[High(Bullets)].Position := PlayerPosition;
    Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) / BulletSpeed;
    Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) / BulletSpeed;
  end;
end;

procedure KeyUp(Key: Integer);
begin
  if Key = vk_Space then
    IsSpacePressed := False;
end;

begin
  SetWindowSize(WindowWidth, WindowHeight);
  SetWindowCaption('Spaceship Game');
  SetBrushColor(clBlack);
  ClearWindow(clBlack);
  PlayerPosition.X := WindowWidth / 2;
  PlayerPosition.Y := WindowHeight / 2;
  TargetPosition := PlayerPosition;

  for var i := 0 to High(Stars) do
  begin
    Stars[i].X := Random(WindowWidth);
    Stars[i].Y := Random(WindowHeight);
  end;

  for var i := 0 to High(Enemies) do
  begin
    Enemies[i].Position.X := Random(WindowWidth);
    Enemies[i].Position.Y := Random(WindowHeight);
Enemies[i].Velocity.X := Random(11) - 5;
    Enemies[i].Velocity.Y := Random(11) - 5;
    Enemies[i].Active := True;
  end;
  
  OnMouseMove := MouseMove;
  OnKeyDown := KeyDown;
  OnKeyUp := KeyUp;

  while True do
  begin
    UpdatePlayer;
    UpdateEnemies;
    UpdateBullets;
    LockDrawing;
    ClearWindow(clBlack);
    DrawStars;
    DrawShip(PlayerPosition);
    DrawTarget(TargetPosition);
    DrawEnemies;
    DrawBullets;

    if IsSpacePressed then
    begin
      SetLength(Bullets, Length(Bullets) + 1);
      Bullets[High(Bullets)].Position := PlayerPosition;
      Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) / BulletSpeed;
      Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) / BulletSpeed;
    end;
    Redraw;

    Sleep(10);

  end;
end.```
Nxx ★★★★★
() автор топика
Ответ на: комментарий от Xintrea

Попросил ещё чтобы нос корабля смотрел на точку.

https://filetransfer.io/data-package/f0lMp0LJ#link


  PlayerSpeed = 5;
  BulletSpeed = 10;
  NumStars = 100;
  NumEnemies = 10;
  SpringConstant = 0.02;
  GravityConstant = 0.08;

type
  TVector2 = record
    X, Y: Double;
  end;

  TEnemy = record
    Position: TVector2;
    Velocity: TVector2;
    Active: Boolean;
  end;

  TBullet = record
    Position: TVector2;
    Velocity: TVector2;
  end;

var
  PlayerPosition: TVector2;
  PlayerVelocity: TVector2;
  TargetPosition: TVector2;
  Enemies: array [0..NumEnemies - 1] of TEnemy;
  Bullets: array of TBullet;
  Stars: array [0..NumStars - 1] of TVector2;
  IsSpacePressed: Boolean;

procedure DrawShip(Position: TVector2);
var
  Angle: Double;
  NoseX, NoseY: Integer;
  DeltaX, DeltaY: Double;
begin
  DeltaX := TargetPosition.X - Position.X;
  DeltaY := TargetPosition.Y - Position.Y;

  if DeltaX = 0 then
  begin
    if DeltaY > 0 then
      Angle := Pi / 2
    else if DeltaY < 0 then
      Angle := -Pi / 2
    else
      Angle := 0;
  end
  else
  begin
    Angle := ArcTan(DeltaY / DeltaX);
    if DeltaX < 0 then
      Angle := Angle + Pi;
  end;

  NoseX := Round(Position.X + 20 * Cos(Angle));
  NoseY := Round(Position.Y + 20 * Sin(Angle));

  SetPenColor(clBlue);
  Line(Round(Position.X), Round(Position.Y), NoseX, NoseY);
  Line(Round(Position.X), Round(Position.Y), Round(Position.X + 10 * Cos(Angle + 2.5)), Round(Position.Y + 10 * Sin(Angle + 2.5)));
  Line(Round(Position.X), Round(Position.Y), Round(Position.X + 10 * Cos(Angle - 2.5)), Round(Position.Y + 10 * Sin(Angle - 2.5)));
end;

procedure DrawTarget(Position: TVector2);
begin
  SetPenColor(clYellow);
  Circle(Round(Position.X), Round(Position.Y), 5);
end;

procedure DrawEnemies;
var
  i: Integer;
begin
  SetPenColor(clGreen);
  for i := 0 to High(Enemies) do
    if Enemies[i].Active then
      Rectangle(Round(Enemies[i].Position.X - 5), Round(Enemies[i].Position.Y - 5),
                Round(Enemies[i].Position.X + 5), Round(Enemies[i].Position.Y + 5));
end;

procedure DrawBullets;
var
  i: Integer;
begin
  SetPenColor(clRed);
  for i := 0 to High(Bullets) do
    Line(Round(Bullets[i].Position.X), Round(Bullets[i].Position.Y),
         Round(Bullets[i].Position.X + Bullets[i].Velocity.X * 5),
         Round(Bullets[i].Position.Y + Bullets[i].Velocity.Y * 5));
end;

procedure DrawStars;
var
  i: Integer;
begin
  SetPenColor(clWhite);
  for i := 0 to High(Stars) do
    Ellipse(Round(Stars[i].X), Round(Stars[i].Y), Round(Stars[i].X + 2), Round(Stars[i].Y + 2));
end;

procedure UpdatePlayer;
var
  SpringForce, GravityForce, Acceleration: TVector2;
begin
  SpringForce.X := (TargetPosition.X - PlayerPosition.X) * SpringConstant;
  SpringForce.Y := (TargetPosition.Y - PlayerPosition.Y) * SpringConstant;

  GravityForce.X := -PlayerVelocity.X * GravityConstant;
  GravityForce.Y := -PlayerVelocity.Y * GravityConstant;

  Acceleration.X := SpringForce.X + GravityForce.X;
  Acceleration.Y := SpringForce.Y + GravityForce.Y;

  PlayerVelocity.X := PlayerVelocity.X + Acceleration.X;
  PlayerVelocity.Y := PlayerVelocity.Y + Acceleration.Y;

  PlayerPosition.X := PlayerPosition.X + PlayerVelocity.X;
  PlayerPosition.Y := PlayerPosition.Y + PlayerVelocity.Y;
end;

procedure UpdateEnemies;
var
  i: Integer;
begin
  for i := 0 to High(Enemies) do
  begin
    if Enemies[i].Active then
    begin
      Enemies[i].Position.X := Enemies[i].Position.X + Enemies[i].Velocity.X;
      Enemies[i].Position.Y := Enemies[i].Position.Y + Enemies[i].Velocity.Y;

      // Keep enemies within the field of view
      if (Enemies[i].Position.X < -10) then
        Enemies[i].Position.X := WindowWidth + 10;
      if (Enemies[i].Position.X > WindowWidth + 10) then
        Enemies[i].Position.X := -10;
      if (Enemies[i].Position.Y < -10) then
        Enemies[i].Position.Y := WindowHeight + 10;
      if (Enemies[i].Position.Y > WindowHeight + 10) then
        Enemies[i].Position.Y := -10;
    end;
  end;
end;

procedure UpdateBullets;
var
  i, j: Integer;
begin
  for i := 0 to High(Bullets) do
  begin
    Bullets[i].Position.X := Bullets[i].Position.X + Bullets[i].Velocity.X;
    Bullets[i].Position.Y := Bullets[i].Position.Y + Bullets[i].Velocity.Y;

    // Check for collisions with enemies
    for j := 0 to High(Enemies) do
    begin
      if Enemies[j].Active and
         (Abs(Bullets[i].Position.X - Enemies[j].Position.X) < 10) and
         (Abs(Bullets[i].Position.Y - Enemies[j].Position.Y) < 10) then
      begin
        Enemies[j].Active := False;
        Bullets[i].Position.X := -100; // Move the bullet off-screen
        Break;
      end;
    end;
  end;
end;

procedure MouseMove(x, y, mb: Integer);
begin
  TargetPosition.X := x;
  TargetPosition.Y := y;
end;

procedure KeyDown(Key: Integer);
begin
  if Key = vk_Space then
  begin
    IsSpacePressed := True;
    SetLength(Bullets, Length(Bullets) + 1);
    Bullets[High(Bullets)].Position := PlayerPosition;
    Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) / BulletSpeed;
    Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) / BulletSpeed;
  end;
end;

procedure KeyUp(Key: Integer);
begin
  if Key = vk_Space then
    IsSpacePressed := False;
end;

begin
  SetWindowSize(WindowWidth, WindowHeight);
  SetWindowCaption('Spaceship Game');
  SetBrushColor(clBlack);
  ClearWindow(clBlack);
  PlayerPosition.X := WindowWidth / 2;
  PlayerPosition.Y := WindowHeight / 2;
  TargetPosition := PlayerPosition;

  for var i := 0 to High(Stars) do
  begin
    Stars[i].X := Random(WindowWidth);
    Stars[i].Y := Random(WindowHeight);
  end;

  for var i := 0 to High(Enemies) do
  begin
    Enemies[i].Position.X := Random(WindowWidth);
    Enemies[i].Position.Y := Random(WindowHeight);
Enemies[i].Velocity.X := Random(11) - 5;
    Enemies[i].Velocity.Y := Random(11) - 5;
    Enemies[i].Active := True;
  end;
  
  OnMouseMove := MouseMove;
  OnKeyDown := KeyDown;
  OnKeyUp := KeyUp;

  while True do
  begin
    UpdatePlayer;
    UpdateEnemies;
    UpdateBullets;
    LockDrawing;
    ClearWindow(clBlack);
    DrawStars;
    DrawShip(PlayerPosition);
    DrawTarget(TargetPosition);
    DrawEnemies;
    DrawBullets;

    if IsSpacePressed then
    begin
      SetLength(Bullets, Length(Bullets) + 1);
      Bullets[High(Bullets)].Position := PlayerPosition;
      Bullets[High(Bullets)].Velocity.X := (TargetPosition.X - PlayerPosition.X) / BulletSpeed;
      Bullets[High(Bullets)].Velocity.Y := (TargetPosition.Y - PlayerPosition.Y) / BulletSpeed;
    end;
    Redraw;

    Sleep(10);

  end;
end.
Nxx ★★★★★
() автор топика
Ответ на: комментарий от sanyo1234

попроси решить … задачки, к которым никогда ещё не было готового решения

Пусть напишет сортировку пузырьком, вряд ли ее где-то предлагают решить.

Irma ★★
()
Ответ на: комментарий от Irma

Сортировка пузырьком - это вообще самая элементарная вещь, которую любая модель знает.

Nxx ★★★★★
() автор топика
Ответ на: комментарий от Nxx

Может, она реагирует на слово «пузырек»? Надо попросить «попарную перестановку с минимальной сложностью».

Irma ★★
()

Если он такой умный, то надо заставить его писать Claude 4 Opus Magnum.

Irma ★★
()
Ответ на: комментарий от Nxx

Да, убедил, теперь механика как в оригинале.

Тридцать лет назад я не мог и представить, что воссоздать механику этой игры можно будет через нейросетку, которая сможет написать адекватный исходный код, который можно закомпилить и он будет работать как задумано. Это круто.

Xintrea ★★★★★
()
Ответ на: комментарий от Xintrea

Два сегодняшних запроса (поменять механику и поворот корабля) - это на Opus. А механику с замедлением сделал Sonnet. Вот и видна разница в силе между моделями.

Nxx ★★★★★
() автор топика
Последнее исправление: Nxx (всего исправлений: 1)
Ответ на: комментарий от Irma

Да любую сортировку она тебе зделает. Это вообше элементарно для всех моделей, даже слабых. Даже GPT-3.5 тебе это сделает легко.

Nxx ★★★★★
() автор топика
Ответ на: комментарий от Nxx

Я специально задала противоречие: «минимальная сложность» и «попарная перестановка». Можно прямо спросить «сортировка пузырьком минимальной сложности», интересно, как выкрутится.

Irma ★★
()
Ответ на: комментарий от Irma

Сделает сортировку пузырьком в базовом варианте и постарается упростить код.

Nxx ★★★★★
() автор топика
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)