Subversion Repositories jumper

Compare Revisions

Regard whitespace Rev 21 → Rev 22

/trunk/Choice.pas
181,7 → 181,7
 
if Level.CheckLevelIntegrity <> leNone then
ImageIndex := 2{Error}
else case Level.GetGameMode of
else case Level.GameMode of
gmNormal: ImageIndex := 0{Normal};
gmDiagonal: ImageIndex := 1{Diagonal};
gmUndefined: ImageIndex := 2{Error};
/trunk/LevelFunctions.pas
28,6 → 28,7
private
FStringList: TStringList;
procedure Load(ABoardFile: string);
function GetGameMode: TGameMode;
public
constructor Create(ABoardFile: string);
destructor Destroy; override;
34,7 → 35,7
function LevelStringToLevelArray(ShowErrors: boolean): TLevelArray;
function CheckLevelIntegrity: TLevelError; overload;
function CheckLevelIntegrity(ShowErrors: boolean): TLevelError; overload;
function GetGameMode: TGameMode;
property GameMode: TGameMode read GetGameMode;
end;
 
TField = record
59,6 → 60,9
function FieldState(t: TFieldType): TFieldState; overload;
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(SourceX, SourceY: integer; DiagonalOK: boolean): boolean; overload;
function CanJump(DiagonalOK: boolean): boolean; overload;
end;
 
function FieldTypeWorth(t: TFieldType): integer;
77,14 → 81,14
 
function TPlayGroundMatrix.MatrixHasGoal: boolean;
var
i, j: integer;
x, y: integer;
begin
result := false;
for i := Low(Fields) to High(Fields) do
for x := Low(Fields) to High(Fields) do
begin
for j := Low(Fields[i]) to High(Fields[i]) do
for y := Low(Fields[x]) to High(Fields[x]) do
begin
result := result or Fields[i][j].Goal;
result := result or Fields[x][y].Goal;
end;
end;
end;
91,14 → 95,14
 
function TPlayGroundMatrix.GoalFieldType: TFieldType;
var
i, j: integer;
x, y: integer;
begin
result := ftEmpty; // Damit der Compiler nicht meckert
for i := Low(Fields) to High(Fields) do
for x := Low(Fields) to High(Fields) do
begin
for j := Low(Fields[i]) to High(Fields[i]) do
for y := Low(Fields[x]) to High(Fields[x]) do
begin
if Fields[i][j].Goal then result := Fields[i][j].FieldType
if Fields[x][y].Goal then result := Fields[x][y].FieldType
end;
end;
end;
105,14 → 109,14
 
function TPlayGroundMatrix.MatrixWorth: integer;
var
i, j: integer;
x, y: integer;
begin
result := 0;
for i := Low(Fields) to High(Fields) do
for x := Low(Fields) to High(Fields) do
begin
for j := Low(Fields[i]) to High(Fields[i]) do
for y := Low(Fields[x]) to High(Fields[x]) do
begin
Inc(result, FieldTypeWorth(Fields[i][j].FieldType));
Inc(result, FieldTypeWorth(Fields[x][y].FieldType));
end;
end;
end;
119,19 → 123,19
 
procedure TPlayGroundMatrix.ClearMatrix(FreeVCL: boolean);
var
i, j: integer;
x, y: integer;
begin
for i := Low(Fields) to High(Fields) do
for x := Low(Fields) to High(Fields) do
begin
for j := Low(Fields[i]) to High(Fields[i]) do
for y := Low(Fields[x]) to High(Fields[x]) do
begin
if FreeVCL then
begin
if Assigned(Fields[i][j].Stone) then Fields[i][j].Stone.Free;
if Assigned(Fields[i][j].Panel) then Fields[i][j].Panel.Free;
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;
end;
SetLength(Fields[i], 0);
SetLength(Fields[x], 0);
end;
SetLength(Fields, 0);
end;
138,18 → 142,18
 
function TPlayGroundMatrix.CloneMatrix: TPlayGroundMatrix;
var
i, j: integer;
x, y: integer;
begin
SetLength(result.Fields, Length(Fields));
for i := Low(Fields) to High(Fields) do
for x := Low(Fields) to High(Fields) do
begin
SetLength(result.Fields[i], Length(Fields[i]));
for j := Low(Fields[i]) to High(Fields[i]) do
SetLength(result.Fields[x], Length(Fields[x]));
for y := Low(Fields[x]) to High(Fields[x]) do
begin
result.Fields[i][j].FieldType := Fields[i][j].FieldType;
result.Fields[i][j].Goal := Fields[i][j].Goal;
result.Fields[i][j].Panel := Fields[i][j].Panel;
result.Fields[i][j].Stone := Fields[i][j].Stone;
result.Fields[x][y].FieldType := Fields[x][y].FieldType;
result.Fields[x][y].Goal := Fields[x][y].Goal;
result.Fields[x][y].Panel := Fields[x][y].Panel;
result.Fields[x][y].Stone := Fields[x][y].Stone;
end;
end;
end;
180,6 → 184,73
result := FieldState(Fields[x][y]);
end;
 
function TPlayGroundMatrix.CanJump(SourceX, SourceY, DestX, DestY: integer; DiagonalOK: boolean): boolean;
begin
result := false;
 
// Check 1: Ist das Zielfeld überhaupt leer?
if FieldState(DestX, DestY) <> fsAvailable then exit;
 
// 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;
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;
end;
 
function TPlayGroundMatrix.CanJump(SourceX, SourceY: integer; DiagonalOK: boolean): boolean;
begin
if FieldState(SourceX, SourceY) <> fsStone then
begin
result := false;
exit;
end;
 
result := true;
 
if CanJump(SourceX, SourceY, SourceX+2, SourceY, DiagonalOK) then exit;
if CanJump(SourceX, SourceY, SourceX-2, SourceY, DiagonalOK) then exit;
if CanJump(SourceX, SourceY, SourceX, SourceY+2, DiagonalOK) then exit;
if CanJump(SourceX, SourceY, SourceX, SourceY-2, DiagonalOK) then exit;
 
if DiagonalOK then
begin
if CanJump(SourceX, SourceY, SourceX-2, SourceY-2, DiagonalOK) then exit;
if CanJump(SourceX, SourceY, SourceX+2, SourceY-2, DiagonalOK) then exit;
if CanJump(SourceX, SourceY, SourceX-2, SourceY+2, DiagonalOK) then exit;
if CanJump(SourceX, SourceY, SourceX+2, SourceY+2, DiagonalOK) then exit;
end;
 
result := false;
end;
 
function TPlayGroundMatrix.CanJump(DiagonalOK: boolean): boolean;
var
x, y: integer;
begin
result := false;
for x := Low(Fields) to High(Fields) do
begin
for y := Low(Fields[x]) to High(Fields[x]) do
begin
if CanJump(x, y, DiagonalOK) then
begin
result := true;
break;
end;
if result then break;
end;
end;
end;
 
{ TLevel }
 
const NUM_HEADERS = 2;
361,7 → 432,7
end;
end;
 
// Check 5: Kann im Level gesprungen werden
// Check 5: Kann im Level gesprungen werden?
 
{ Wird hier nicht abgeprüft, da dafür zuerst der PlayGround gebaut sein muss.
Es ist außerdem eher ein logischer Fehler, kein Fehler in der Levelstruktur! }
/trunk/Main.pas
64,7 → 64,6
procedure SetNewPlayGroundMatrix(Matrix: TPlayGroundMatrix);
procedure RedrawStonesFromMatrix(Matrix: TPlayGroundMatrix);
function AskForLevel: String;
function AreJumpsPossible: boolean;
procedure StoneDraggingAllow(Stone: TImage; Allow: boolean);
procedure NewGame(Filename: string);
function LevelTime: String;
72,11 → 71,8
procedure RefreshTime;
procedure RefreshPoints;
procedure RefreshStonesRemoved;
procedure CountPoints(t: TFieldType);
procedure RemoveStone(x, y: integer; count_points: boolean);
procedure DoJump(SourceTag, DestTag: integer);
function CanJump(x, y: integer): boolean;
function MayJump(SourceX, SourceY, DestX, DestY: integer): boolean; overload;
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);
237,17 → 233,13
Statistics.Panels.Items[2].Text := Format(LNG_POINTS, [Points]);
end;
 
procedure TMainForm.CountPoints(t: TFieldType);
begin
inc(Points, FieldTypeWorth(t));
RefreshPoints;
end;
 
procedure TMainForm.RemoveStone(x, y: integer; count_points: boolean);
begin
if count_points then
begin
CountPoints(PlayGroundMatrix.Fields[x, y].FieldType);
Inc(Points, FieldTypeWorth(PlayGroundMatrix.Fields[x, y].FieldType));
RefreshPoints;
 
Inc(LevelRemovedStones);
RefreshStonesRemoved;
end;
256,32 → 248,6
StoneDraggingAllow(PlayGroundMatrix.Fields[x, y].Stone, false);
end;
 
function TMainForm.CanJump(x, y: integer): boolean;
begin
if PlayGroundMatrix.FieldState(x, y) <> fsStone then
begin
result := false;
exit;
end;
 
result := true;
 
if MayJump(x, y, x+2, y) then exit;
if MayJump(x, y, x-2, y) then exit;
if MayJump(x, y, x, y+2) then exit;
if MayJump(x, y, x, y-2) then exit;
 
if Level.GetGameMode = gmDiagonal then
begin
if MayJump(x, y, x-2, y-2) then exit;
if MayJump(x, y, x+2, y-2) then exit;
if MayJump(x, y, x-2, y+2) then exit;
if MayJump(x, y, x+2, y+2) then exit;
end;
 
result := false;
end;
 
procedure TMainForm.Aboutthislevel1Click(Sender: TObject);
var
mode: string;
293,12 → 259,11
LNG_GOAL_AVAILABLE = 'Target field defined';
LNG_NO_GOAL = 'No target field';
begin
if Level.GetGameMode = gmDiagonal then
mode := 'Diagonal'
else if Level.GetGameMode = gmNormal then
mode := 'Normal'
else
mode := '?';
case Level.GameMode of
gmNormal: mode := 'Diagonal';
gmDiagonal: mode := 'Normal';
gmUndefined: mode := '?';
end;
 
if GoalStatus = gsNoGoal then
goalYeSNo := LNG_NO_GOAL
312,25 → 277,6
goalYesNo);
end;
 
function TMainForm.AreJumpsPossible: boolean;
var
i, j: integer;
begin
result := false;
for i := Low(PlayGroundMatrix.Fields) to High(PlayGroundMatrix.Fields) do
begin
for j := Low(PlayGroundMatrix.Fields[i]) to High(PlayGroundMatrix.Fields[i]) do
begin
if CanJump(i, j) then
begin
result := true;
break;
end;
if result then break;
end;
end;
end;
 
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
resourcestring
LNG_JUMP_LOG = '%d [%d, %d] -> %d [%d, %d];';
347,7 → 293,7
JumpHistory.Add(Format(LNG_JUMP_LOG, [SourceTag+1, s.x+1, s.y+1, DestTag+1, d.x+1, d.y+1]));
 
{$REGION 'Stein entfernen und Punkte vergeben'}
if Level.GetGameMode = gmDiagonal then
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);
379,7 → 325,7
{$ENDREGION}
 
{$REGION 'Sind weitere Sprünge möglich oder ist das Spiel vorbei?'}
if not AreJumpsPossible then
if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
begin
MPauseTime.Checked := false;
MPauseTime.Enabled := false;
407,28 → 353,6
MUndo.Enabled := true;
end;
 
function TMainForm.MayJump(SourceX, SourceY, DestX, DestY: integer): boolean;
begin
result := false;
 
// Check 1: Ist das Zielfeld überhaupt leer?
if PlayGroundMatrix.FieldState(DestX, DestY) <> fsAvailable then exit;
 
// Check 2: Befindet sich ein Stein zwischen Source und Destination und ist der Abstand 2?
if Level.GetGameMode = gmDiagonal then
begin
if (SourceX-2 = DestX) and (SourceY-2 = DestY) and (PlayGroundMatrix.FieldState(SourceX-1, SourceY-1) = fsStone) then result := true;
if (SourceX-2 = DestX) and (SourceY+2 = DestY) and (PlayGroundMatrix.FieldState(SourceX-1, SourceY+1) = fsStone) then result := true;
if (SourceX+2 = DestX) and (SourceY-2 = DestY) and (PlayGroundMatrix.FieldState(SourceX+1, SourceY-1) = fsStone) then result := true;
if (SourceX+2 = DestX) and (SourceY+2 = DestY) and (PlayGroundMatrix.FieldState(SourceX+1, SourceY+1) = fsStone) then result := true;
end;
 
if (SourceX+2 = DestX) and (SourceY = DestY) and (PlayGroundMatrix.FieldState(SourceX+1, SourceY ) = fsStone) then result := true;
if (SourceX-2 = DestX) and (SourceY = DestY) and (PlayGroundMatrix.FieldState(SourceX-1, SourceY ) = fsStone) then result := true;
if (SourceX = DestX) and (SourceY+2 = DestY) and (PlayGroundMatrix.FieldState(SourceX , SourceY+1) = fsStone) then result := true;
if (SourceX = DestX) and (SourceY-2 = DestY) and (PlayGroundMatrix.FieldState(SourceX , SourceY-1) = fsStone) then result := true;
end;
 
function TMainForm.MayJump(SourceTag, DestTag: integer): boolean;
var
s, d: TPoint;
436,7 → 360,7
d := LookupFieldCoordinateArray[DestTag];
s := LookupFieldCoordinateArray[SourceTag];
 
result := MayJump(s.X, s.Y, d.X, d.Y);
result := PlaygroundMatrix.CanJump(s.X, s.Y, d.X, d.Y, Level.GameMode = gmDiagonal);
end;
 
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
554,7 → 478,7
LevelArray := Level.LevelStringToLevelArray(true);
if Length(LevelArray) = 0 then Exit;
BuildPlayground(LevelArray);
if not AreJumpsPossible then
if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
begin
MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
end;