/trunk/Choice.pas |
---|
4,7 → 4,8 |
uses |
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, |
Dialogs, StdCtrls, ImgList, ComCtrls, Menus, ExtCtrls, System.ImageList, LevelFunctions; |
Dialogs, StdCtrls, ImgList, ComCtrls, Menus, ExtCtrls, ImageList, |
LevelFunctions; |
type |
TLevelChoice = class(TForm) |
44,9 → 45,8 |
procedure TLevelChoice.DrawLevelPreview(Level: TLevel); |
var |
LevelArray: TLevelArray; |
PlaygroundMatrix: TPlayGroundMatrix; |
y, x: integer; |
t: TFieldType; |
indent: Integer; |
Image: TImage; |
BackgroundColor: TColor; |
57,21 → 57,17 |
Image := PreviewImage; |
BackgroundColor := Self.Color; |
LevelArray := nil; |
ClearImage(Image, BackgroundColor); |
LevelArray := Level.LevelStringToLevelArray(false); |
for y := Low(LevelArray) to High(LevelArray) do |
Level.FillPlaygroundMatrix(PlaygroundMatrix, false); |
try |
for x := Low(PlaygroundMatrix.Fields) to High(PlaygroundMatrix.Fields) do |
begin |
for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do |
for y := Low(PlaygroundMatrix.Fields[x]) to High(PlaygroundMatrix.Fields[x]) do |
begin |
t := LevelArray[y].Fields[x].Typ; |
indent := LevelArray[y].Indent; |
case t of |
ftFullSpace: Image.Canvas.Brush.Color := BackgroundColor; |
// Rectange filling |
case PlaygroundMatrix.Fields[x,y].FieldType of |
ftFullSpace: Image.Canvas.Brush.Color := BackgroundColor; // invisible |
ftEmpty: Image.Canvas.Brush.Color := clWhite; |
ftGreen: Image.Canvas.Brush.Color := clLime; |
ftYellow: Image.Canvas.Brush.Color := clYellow; |
78,11 → 74,19 |
ftRed: Image.Canvas.Brush.Color := clRed; |
end; |
if LevelArray[y].Fields[x].Goal then |
// Rectangle border |
if PlaygroundMatrix.Fields[x,y].Goal then |
Image.Canvas.Pen.Color := clBlack |
else |
Image.Canvas.Pen.Color := BackgroundColor; |
begin |
if PlaygroundMatrix.Fields[x,y].FieldType = ftFullSpace then |
Image.Canvas.Pen.Color := BackgroundColor // invisible |
else |
Image.Canvas.Pen.Color := clLtGray; |
end; |
// Draw the rectangle |
indent := PlaygroundMatrix.Fields[x,y].Indent; |
Image.Canvas.Rectangle(x*PREVIEW_BLOCK_SIZE + indent*PREVIEW_TAB_SIZE, |
y*PREVIEW_BLOCK_SIZE, |
x*PREVIEW_BLOCK_SIZE + indent*PREVIEW_TAB_SIZE + PREVIEW_BLOCK_SIZE, |
89,7 → 93,10 |
y*PREVIEW_BLOCK_SIZE + PREVIEW_BLOCK_SIZE); |
end; |
end; |
finally |
PlaygroundMatrix.ClearMatrix(true); |
end; |
end; |
function TLevelChoice.SelectedLevel: string; |
begin |
/trunk/LevelFunctions.pas |
---|
13,37 → 13,13 |
TFieldType = (ftUndefined, ftFullSpace, ftEmpty, ftRed, ftYellow, ftGreen); |
TFieldProperties = record |
Typ: TFieldType; |
Goal: Boolean; |
end; |
TGameMode = (gmUndefined, gmNormal, gmDiagonal); |
TRow = record |
Indent: integer; |
Fields: array of TFieldProperties; |
end; |
TLevelArray = array of TRow; |
TLevelError = (leUndefined, leNone, leInvalidElement, leEmptyBoard, leRowInvalidLength, |
leUnsupportedVersion, leUnsupportedMode); |
TLevel = class(TObject) |
private |
FStringList: TStringList; |
procedure Load(ABoardFile: string); |
function GetGameMode: TGameMode; |
public |
constructor Create(ABoardFile: string); |
destructor Destroy; override; |
function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
function CheckLevelIntegrity: TLevelError; overload; |
function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload; |
property GameMode: TGameMode read GetGameMode; |
end; |
TField = record |
Indent: integer; |
FieldType: TFieldType; |
Goal: Boolean; |
Panel: TPanel; |
52,7 → 28,7 |
TGoalStatus = (gsUndefined, gsNoGoal, gsMultipleStonesRemaining, gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen, gsLastStoneOutsideGoal); |
TFieldState = (fsUndefined, fsError, fsLocked, fsAvailable, fsStone); |
TFieldState = (fsUndefined, fsLocked, fsAvailable, fsOccupied); |
TPlayGroundMatrix = record |
Fields: array of array of TField; |
67,7 → 43,9 |
function FieldState(f: TField): TFieldState; overload; |
function FieldState(x, y: integer): TFieldState; overload; |
function CanJump(SourceX, SourceY, DestX, DestY: integer; DiagonalOK: boolean): boolean; overload; |
function CanJump(Source, Dest: TCoord; DiagonalOK: boolean): boolean; overload; |
function CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean; overload; |
function CanJump(Source: TCoord; DiagonalOK: boolean): boolean; overload; |
function CanJump(DiagonalOK: boolean): boolean; overload; |
function IndexToCoord(index: integer): TCoord; |
function CoordToIndex(coord: TCoord): integer; overload; |
76,6 → 54,20 |
function Height: integer; |
end; |
TLevel = class(TObject) |
private |
FStringList: TStringList; |
procedure Load(ABoardFile: string); |
function GetGameMode: TGameMode; |
public |
constructor Create(ABoardFile: string); |
destructor Destroy; override; |
procedure FillPlaygroundMatrix(var matrix: TPlayGroundMatrix; ShowErrors: boolean); |
function CheckLevelIntegrity: TLevelError; overload; |
function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload; |
property GameMode: TGameMode read GetGameMode; |
end; |
function FieldTypeWorth(t: TFieldType): integer; |
implementation |
141,7 → 133,7 |
begin |
for y := Low(Fields[x]) to High(Fields[x]) do |
begin |
Fields[x,y].FieldType := ftUndefined; |
Fields[x,y].FieldType := ftUndefined |
end; |
end; |
end; |
165,16 → 157,28 |
result := Length(Fields); |
end; |
function TPlayGroundMatrix.CanJump(Source: TCoord; |
DiagonalOK: boolean): boolean; |
begin |
result := CanJump(Source.X, Source.Y, DiagonalOK); |
end; |
function TPlayGroundMatrix.CanJump(Source, Dest: TCoord; |
DiagonalOK: boolean): boolean; |
begin |
result := CanJump(Source.X, Source.Y, Dest.X, Dest.Y, DiagonalOK); |
end; |
procedure TPlayGroundMatrix.ClearMatrix(FreeVCL: boolean); |
var |
x, y: integer; |
begin |
if FreeVCL then |
begin |
for x := Low(Fields) to High(Fields) do |
begin |
for y := Low(Fields[x]) to High(Fields[x]) do |
begin |
if FreeVCL then |
begin |
if Assigned(Fields[x,y].Stone) then Fields[x,y].Stone.Free; |
if Assigned(Fields[x,y].Panel) then Fields[x,y].Panel.Free; |
end; |
202,28 → 206,24 |
end; |
function TPlayGroundMatrix.CoordToIndex(x, y: integer): integer; |
var |
c: TCoord; |
begin |
c.X := x; |
c.Y := y; |
result := CoordToIndex(c); |
result := x + y * Width; |
end; |
function TPlayGroundMatrix.CoordToIndex(coord: TCoord): integer; |
begin |
result := coord.X + coord.Y * Width; |
result := CoordToIndex(coord.X, coord.Y); |
end; |
class function TPlayGroundMatrix.FieldState(t: TFieldType): TFieldState; |
begin |
result := fsError; |
result := fsUndefined; |
case t of |
ftFullSpace: result := fsLocked; |
ftEmpty: result := fsAvailable; |
ftGreen: result := fsStone; |
ftYellow: result := fsStone; |
ftRed: result := fsStone; |
ftGreen: result := fsOccupied; |
ftYellow: result := fsOccupied; |
ftRed: result := fsOccupied; |
end; |
end; |
234,7 → 234,7 |
function TPlayGroundMatrix.FieldState(x, y: integer): TFieldState; |
begin |
result := fsError; |
result := fsUndefined; |
if (x < Low(Fields)) or (x > High(Fields)) then exit; |
if (y < Low(Fields[x])) or (y > High(Fields[x])) then exit; |
251,21 → 251,21 |
// Check 2: Befindet sich ein Stein zwischen Source und Destination und ist der Abstand 2? |
if DiagonalOK then |
begin |
if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX-1, SourceY-1) = fsStone) then result := true; |
if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX-1, SourceY+1) = fsStone) then result := true; |
if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX+1, SourceY-1) = fsStone) then result := true; |
if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX+1, SourceY+1) = fsStone) then result := true; |
if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX-1, SourceY-1) = fsOccupied) then result := true; |
if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX-1, SourceY+1) = fsOccupied) then result := true; |
if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX+1, SourceY-1) = fsOccupied) then result := true; |
if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX+1, SourceY+1) = fsOccupied) then result := true; |
end; |
if (SourceX+2 = DestX) and (SourceY = DestY) and (FieldState(SourceX+1, SourceY ) = fsStone) then result := true; |
if (SourceX-2 = DestX) and (SourceY = DestY) and (FieldState(SourceX-1, SourceY ) = fsStone) then result := true; |
if (SourceX = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX , SourceY+1) = fsStone) then result := true; |
if (SourceX = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX , SourceY-1) = fsStone) then result := true; |
if (SourceX+2 = DestX) and (SourceY = DestY) and (FieldState(SourceX+1, SourceY ) = fsOccupied) then result := true; |
if (SourceX-2 = DestX) and (SourceY = DestY) and (FieldState(SourceX-1, SourceY ) = fsOccupied) then result := true; |
if (SourceX = DestX) and (SourceY+2 = DestY) and (FieldState(SourceX , SourceY+1) = fsOccupied) then result := true; |
if (SourceX = DestX) and (SourceY-2 = DestY) and (FieldState(SourceX , SourceY-1) = fsOccupied) then result := true; |
end; |
function TPlayGroundMatrix.CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean; |
begin |
if FieldState(SourceX, SourceY) <> fsStone then |
if FieldState(SourceX, SourceY) <> fsOccupied then |
begin |
result := false; |
exit; |
351,7 → 351,7 |
end; |
end; |
function TLevel.LevelStringToLevelArray(ShowErrors: boolean): TLevelArray; |
procedure TLevel.FillPlaygroundMatrix(var matrix: TPlayGroundMatrix; ShowErrors: boolean); |
var |
i: integer; |
t: TFieldType; |
361,23 → 361,36 |
Line: string; |
lch, uch: char; |
ch: char; |
width: Integer; |
height: Integer; |
lineIndent: Integer; |
begin |
// Zuerst nach Fehlern suchen |
err := CheckLevelIntegrity(ShowErrors); |
if err <> leNone then exit; |
// Breite feststellen |
if FStringList.Count > NUM_HEADERS then |
begin |
Line := FStringList.Strings[NUM_HEADERS]; |
Line := StringReplace(Line, '.', '', [rfReplaceAll]); |
width := Length(Line); |
end |
else width := 0; |
// Höhe feststellen |
height := FStringList.Count - NUM_HEADERS; |
// Nun Matrix aufbauen |
SetLength(result, 0); |
matrix.ClearMatrix(true); |
matrix.InitFieldArray(width, height); |
for i := NUM_HEADERS to FStringList.Count-1 do |
begin |
y := i - NUM_HEADERS; |
SetLength(result, Length(result)+1); // add line to matrix |
Line := FStringList.Strings[i]; |
result[y].Indent := DotsAtBeginning(Line) - DotsAtEnd(Line); |
lineIndent := DotsAtBeginning(Line) - DotsAtEnd(Line); |
Line := StringReplace(Line, '.', '', [rfReplaceAll]); |
SetLength(result[y].Fields, Length(Line)); |
for x := 0 to Length(Line)-1 do |
begin |
394,8 → 407,9 |
'g': t := ftGreen; |
end; |
result[y].Fields[x].Typ := t; |
result[y].Fields[x].Goal := (ch = uch) and (ch <> lch); |
matrix.Fields[x,y].Indent := lineIndent; |
matrix.Fields[x,y].FieldType := t; |
matrix.Fields[x,y].Goal := (ch = uch) and (ch <> lch); |
end; |
end; |
end; |
440,7 → 454,8 |
exit; |
end; |
if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and (LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then |
if ((LowerCase(FStringList.Strings[1]) <> 'mode: normal') and |
(LowerCase(FStringList.Strings[1]) <> 'mode: diagonal')) then |
begin |
result := leUnsupportedMode; |
exit; |
464,7 → 479,7 |
thisLine := StringReplace(FStringList.Strings[i], '.', '', [rfReplaceAll]); |
if Length(thisLine) <> Length(firstLine) then |
begin |
result := leRowInvalidLength; // at row y-NUM_HEADERS |
result := leRowInvalidLength; // at row y = i-NUM_HEADERS |
exit; |
end; |
end; |
484,7 → 499,7 |
if Length(Line) > 0 then |
begin |
result := leInvalidElement; // at row y-NUM_HEADERS |
result := leInvalidElement; // at row y = i-NUM_HEADERS |
Exit; |
end; |
end; |
/trunk/Main.pas |
---|
75,10 → 75,9 |
function MayJump(SourceTag, DestTag: integer): boolean; overload; |
procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); |
procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer); |
function DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField; |
procedure DrawField(x, y: integer; var f: TField); |
function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage; |
function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel; |
procedure BuildPlayground(LevelArray: TLevelArray); |
procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture); |
function GoalStatus: TGoalStatus; |
end; |
103,10 → 102,10 |
begin |
for y := Low(Matrix.Fields[x]) to High(Matrix.Fields[x]) do |
begin |
if Assigned(Matrix.Fields[x][y].Stone) then |
if Assigned(Matrix.Fields[x,y].Stone) then |
begin |
LoadPictureForType(Matrix.Fields[x][y].FieldType, Matrix.Fields[x][y].Stone.Picture); |
StoneDraggingAllow(Matrix.Fields[x][y].Stone, Matrix.FieldState(Matrix.Fields[x][y].FieldType) <> fsAvailable); |
LoadPictureForType(Matrix.Fields[x,y].FieldType, Matrix.Fields[x,y].Stone.Picture); |
StoneDraggingAllow(Matrix.Fields[x,y].Stone, Matrix.FieldState(Matrix.Fields[x,y].FieldType) <> fsAvailable); |
end; |
end; |
end; |
277,7 → 276,7 |
procedure TMainForm.DoJump(SourceTag, DestTag: integer); |
resourcestring |
LNG_JUMP_LOG = '%d [%d, %d] -> %d [%d, %d];'; |
LNG_JUMP_LOG = '[%d, %d] -> [%d, %d];'; |
var |
d, s: TCoord; |
old_fieldtype: TFieldType; |
288,21 → 287,21 |
s := PlaygroundMatrix.IndexToCoord(SourceTag); |
d := PlaygroundMatrix.IndexToCoord(DestTag); |
JumpHistory.Add(Format(LNG_JUMP_LOG, [SourceTag+1, s.x+1, s.y+1, DestTag+1, d.x+1, d.y+1])); |
JumpHistory.Add(Format(LNG_JUMP_LOG, [s.x+1, s.y+1, d.x+1, d.y+1])); |
{$REGION 'Stein entfernen und Punkte vergeben'} |
if Level.GameMode = gmDiagonal then |
begin |
if (s.X-2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y-1) = fsStone) then RemoveStone(s.X-1, s.Y-1, true); |
if (s.X-2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y+1) = fsStone) then RemoveStone(s.X-1, s.Y+1, true); |
if (s.X+2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y-1) = fsStone) then RemoveStone(s.X+1, s.Y-1, true); |
if (s.X+2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y+1) = fsStone) then RemoveStone(s.X+1, s.Y+1, true); |
if (s.X-2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y-1) = fsOccupied) then RemoveStone(s.X-1, s.Y-1, true); |
if (s.X-2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y+1) = fsOccupied) then RemoveStone(s.X-1, s.Y+1, true); |
if (s.X+2 = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y-1) = fsOccupied) then RemoveStone(s.X+1, s.Y-1, true); |
if (s.X+2 = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y+1) = fsOccupied) then RemoveStone(s.X+1, s.Y+1, true); |
end; |
if (s.X+2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y ) = fsStone) then RemoveStone(s.X+1, s.Y, true); |
if (s.X-2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y ) = fsStone) then RemoveStone(s.X-1, s.Y, true); |
if (s.X = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X , s.Y+1) = fsStone) then RemoveStone(s.X, s.Y+1, true); |
if (s.X = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X , s.Y-1) = fsStone) then RemoveStone(s.X, s.Y-1, true); |
if (s.X+2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X+1, s.Y ) = fsOccupied) then RemoveStone(s.X+1, s.Y, true); |
if (s.X-2 = d.X) and (s.Y = d.Y) and (PlayGroundMatrix.FieldState(s.X-1, s.Y ) = fsOccupied) then RemoveStone(s.X-1, s.Y, true); |
if (s.X = d.X) and (s.Y+2 = d.Y) and (PlayGroundMatrix.FieldState(s.X , s.Y+1) = fsOccupied) then RemoveStone(s.X, s.Y+1, true); |
if (s.X = d.X) and (s.Y-2 = d.Y) and (PlayGroundMatrix.FieldState(s.X , s.Y-1) = fsOccupied) then RemoveStone(s.X, s.Y-1, true); |
{$ENDREGION} |
// Den Timer erst nach dem ersten Zug starten |
358,7 → 357,7 |
s := PlayGroundMatrix.IndexToCoord(SourceTag); |
d := PlayGroundMatrix.IndexToCoord(DestTag); |
result := PlaygroundMatrix.CanJump(s.X, s.Y, d.X, d.Y, Level.GameMode = gmDiagonal); |
result := PlaygroundMatrix.CanJump(s, d, Level.GameMode = gmDiagonal); |
end; |
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer); |
372,48 → 371,63 |
Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag); |
end; |
function TMainForm.DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField; |
procedure TMainForm.DrawField(x, y: integer; var f: TField); |
var |
newField: TField; |
index: integer; |
begin |
ZeroMemory(@result, SizeOf(result)); |
if t.Typ = ftFullSpace then exit; |
if f.FieldType = ftFullSpace then exit; |
index := PlaygroundMatrix.CoordToIndex(x, y); |
newField.FieldType := t.Typ; |
newField.Goal := t.Goal; |
newField.Panel := DrawStoneBox(x, y, index, indent, t.Goal); |
newField.Stone := DrawStone(t.Typ, newField.Panel); |
f.Panel := DrawStoneBox(x, y, index, f.indent, f.Goal); |
f.Stone := DrawStone(f.FieldType, f.Panel); |
end; |
result := newField; |
procedure TMainForm.TimerTimer(Sender: TObject); |
begin |
if MPauseTime.Checked then exit; |
if mainform.Focused then Inc(CountedSeconds); |
RefreshTime; |
end; |
procedure TMainForm.BuildPlayground(LevelArray: TLevelArray); |
function TMainForm.LevelTime: String; |
begin |
result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay) |
end; |
procedure TMainForm.NewGame(Filename: string); |
resourcestring |
LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.'; |
var |
y, x: integer; |
max_x, max_y: integer; |
p: TPanel; |
newField: TField; |
begin |
DestroyLevel; |
MPauseTime.Checked := true; |
MPauseTime.Enabled := true; |
Timer.Enabled := true; |
MRestartGame.Enabled := true; |
LevelFile := Filename; |
Level := TLevel.Create(LevelFile); |
Level.FillPlaygroundMatrix(PlaygroundMatrix, true); |
if Length(PlaygroundMatrix.Fields) = 0 then Exit; |
PlayGround.Visible := false; |
// Attention: PlaygroundMatrix is indexed [x,y] while LevelArray is indexed [y,x] |
// TODO: PlaygroundMatrix and LevelArray are redundant. Can't we just replace one with the other? |
PlaygroundMatrix.InitFieldArray(Length(LevelArray[0].Fields), Length(LevelArray)); |
max_x := 0; |
max_y := 0; |
for y := Low(LevelArray) to High(LevelArray) do |
for x := Low(PlaygroundMatrix.Fields) to High(PlaygroundMatrix.Fields) do |
begin |
for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do |
for y := Low(PlaygroundMatrix.Fields[x]) to High(PlaygroundMatrix.Fields[x]) do |
begin |
if TPlayGroundMatrix.FieldState(LevelArray[y].Fields[x].Typ) = fsStone then |
if TPlayGroundMatrix.FieldState(PlaygroundMatrix.Fields[x,y].FieldType) = fsOccupied then |
Inc(LevelTotalStones); |
newField := DrawField(x, y, LevelArray[y].Fields[x], LevelArray[y].Indent); |
PlaygroundMatrix.Fields[x, y] := newField; |
p := newField.Panel; |
DrawField(x, y, PlaygroundMatrix.Fields[x,y]); |
p := PlaygroundMatrix.Fields[x,y].Panel; |
if Assigned(p) then |
begin |
max_x := Max(max_x, p.Left + p.Width); |
443,38 → 457,7 |
SetLength(PrevPlaygroundMatrixes,1); |
PrevPlaygroundMatrixes[0] := PlayGroundMatrix.CloneMatrix; |
MUndo.Enabled := false; |
end; |
procedure TMainForm.TimerTimer(Sender: TObject); |
begin |
if MPauseTime.Checked then exit; |
if mainform.Focused then Inc(CountedSeconds); |
RefreshTime; |
end; |
function TMainForm.LevelTime: String; |
begin |
result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay) |
end; |
procedure TMainForm.NewGame(Filename: string); |
resourcestring |
LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.'; |
var |
LevelArray: TLevelArray; |
begin |
DestroyLevel; |
MPauseTime.Checked := true; |
MPauseTime.Enabled := true; |
Timer.Enabled := true; |
MRestartGame.Enabled := true; |
LevelFile := Filename; |
Level := TLevel.Create(LevelFile); |
LevelArray := Level.LevelStringToLevelArray(true); |
if Length(LevelArray) = 0 then Exit; |
BuildPlayground(LevelArray); |
if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then |
begin |
MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0); |