1
0
Files

178 lines
4.2 KiB
ObjectPascal

unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls,
States, Problems;
const
CELL_SIZE = 32;
type
{ TForm1 }
TForm1 = class(TForm)
BackBuffer: TImage;
ImageList: TImageList;
MoveList: TListBox;
Screen: TImage;
OpenLevel: TButton;
OpenDialog: TOpenDialog;
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure OpenLevelClick(Sender: TObject);
private
public
end;
var
Form1: TForm1;
Board: TBoard; { Игровое поле. }
implementation
{$R *.lfm}
{ Загрузить уровень из файла. }
procedure LoadLevel(FileName: String);
var
f: File of Char;
i, j, ColumnCount, CurrentColumn: Integer;
c: Char;
InitialState: TState;
begin
AssignFile(f, FileName); { Открыть файл. }
Reset(f);
FreeAndNil(Board);
InitialState := TState.Create;
{ Читаем первую строку, чтобы найти количество столбцов. }
ColumnCount := 0;
repeat
Read(f, c);
if c = 'x' then
InitialState.AddWall(ColumnCount, 0);
Inc(ColumnCount)
until c <> 'x';
Dec(ColumnCount);
Read(f, c); { Считываем и пропускаем перевод строки. }
j := 1;
repeat { Цикл по строкам. }
CurrentColumn := 0;
for i := 0 to ColumnCount - 1 do { Цикл по элементам строки. }
begin
Read(f, c); { Считаем текущий эелемент }
case c of
'x':
begin
InitialState.AddWall(i, j);
Inc(CurrentColumn)
end;
's':
InitialState.SetAgent(i, j);
'p': { Если это "место". }
InitialState.AddPlace(i, j);
'b': { Если это "камень". }
InitialState.AddBoulder(i, j)
end
end;
Inc(j);
Read(f, c); { считываем и пропускаем возврат каретки }
Read(f, c) { Считываем и пропускаем перевод строки. }
until CurrentColumn = ColumnCount;
Board := TBoard.Create(ColumnCount, j, InitialState);
CloseFile(f) { закрыть файл }
end;
procedure DrawCell(APosition: TPosition; Bitmap: TBitmap);
begin
Form1.BackBuffer.Canvas.Draw(APosition.X * CELL_SIZE,
APosition.Y * CELL_SIZE,
Bitmap)
end;
procedure RedrawField;
var
Bitmap: TBitmap;
ScreenRect: TRect;
CurrentPosition: TPosition;
begin
Bitmap := TBitmap.Create; { Объект для временного хранения рисунка. }
Form1.BackBuffer.Canvas.Brush.Color := clBlack;
Form1.BackBuffer.Canvas.Clear;
{ Рисуем стены. }
Form1.ImageList.GetBitmap(8, bitmap);
for CurrentPosition in Board.InitialState.Walls do
DrawCell(CurrentPosition, bitmap);
{ Рисуем агента. }
Form1.ImageList.GetBitmap(4, bitmap);
DrawCell(Board.InitialState.Agent, Bitmap);
{ Рисуем камни. }
Form1.ImageList.GetBitmap(2, bitmap);
for CurrentPosition in Board.InitialState.Boulders do
DrawCell(CurrentPosition, bitmap);
{ Рисуем объекты. }
Form1.ImageList.GetBitmap(1, bitmap);
For CurrentPosition in Board.InitialState.Places do
DrawCell(CurrentPosition, bitmap);
Bitmap.Free;
{ Копируем содержимое виртуального экрана на основной. }
ScreenRect := Rect(0, 0, Screen.Width, Screen.Height);
Form1.Screen.Canvas.CopyRect(ScreenRect, Form1.BackBuffer.Canvas, ScreenRect)
end;
{ TForm1 }
procedure TForm1.OpenLevelClick(Sender: TObject);
var
i: Integer;
Solution: TStates;
SolutionLine: String;
begin
if OpenDialog.Execute then
begin
LoadLevel(OpenDialog.FileName);
RedrawField;
Solution := Search(Board.InitialState);
for i := 0 to High(Solution) do
begin
SolutionLine := 'Agent: (' + IntToStr(Solution[i].Agent.X)
+ ', ' + IntToStr(Solution[i].Agent.Y) + ')';
FreeAndNil(Solution[i]);
MoveList.AddItem(SolutionLine, nil)
end
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Board := nil
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(Board)
end;
end.