178 lines
4.2 KiB
ObjectPascal
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.
|
|
|