Subversion Repositories jumper

Rev

Rev 23 | Rev 25 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 23 Rev 24
Line 73... Line 73...
73
    procedure RemoveStone(x, y: integer; count_points: boolean);
73
    procedure RemoveStone(x, y: integer; count_points: boolean);
74
    procedure DoJump(SourceTag, DestTag: integer);
74
    procedure DoJump(SourceTag, DestTag: integer);
75
    function MayJump(SourceTag, DestTag: integer): boolean; overload;
75
    function MayJump(SourceTag, DestTag: integer): boolean; overload;
76
    procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
76
    procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean);
77
    procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
77
    procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
78
    function DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField;
78
    procedure DrawField(x, y: integer; var f: TField);
79
    function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage;
79
    function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage;
80
    function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel;
80
    function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel;
81
    procedure BuildPlayground(LevelArray: TLevelArray);
-
 
82
    procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
81
    procedure LoadPictureForType(FieldType: TFieldType; Picture: TPicture);
83
    function GoalStatus: TGoalStatus;
82
    function GoalStatus: TGoalStatus;
84
  end;
83
  end;
85
 
84
 
86
var
85
var
Line 101... Line 100...
101
begin
100
begin
102
  for x := Low(Matrix.Fields) to High(Matrix.Fields) do
101
  for x := Low(Matrix.Fields) to High(Matrix.Fields) do
103
  begin
102
  begin
104
    for y := Low(Matrix.Fields[x]) to High(Matrix.Fields[x]) do
103
    for y := Low(Matrix.Fields[x]) to High(Matrix.Fields[x]) do
105
    begin
104
    begin
106
      if Assigned(Matrix.Fields[x][y].Stone) then
105
      if Assigned(Matrix.Fields[x,y].Stone) then
107
      begin
106
      begin
108
        LoadPictureForType(Matrix.Fields[x][y].FieldType, Matrix.Fields[x][y].Stone.Picture);
107
        LoadPictureForType(Matrix.Fields[x,y].FieldType, Matrix.Fields[x,y].Stone.Picture);
109
        StoneDraggingAllow(Matrix.Fields[x][y].Stone, Matrix.FieldState(Matrix.Fields[x][y].FieldType) <> fsAvailable);
108
        StoneDraggingAllow(Matrix.Fields[x,y].Stone, Matrix.FieldState(Matrix.Fields[x,y].FieldType) <> fsAvailable);
110
      end;
109
      end;
111
    end;
110
    end;
112
  end;
111
  end;
113
end;
112
end;
114
 
113
 
Line 275... Line 274...
275
              goalYesNo);
274
              goalYesNo);
276
end;
275
end;
277
 
276
 
278
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
277
procedure TMainForm.DoJump(SourceTag, DestTag: integer);
279
resourcestring
278
resourcestring
280
  LNG_JUMP_LOG = '%d [%d, %d] -> %d [%d, %d];';
279
  LNG_JUMP_LOG = '[%d, %d] -> [%d, %d];';
281
var
280
var
282
  d, s: TCoord;
281
  d, s: TCoord;
283
  old_fieldtype: TFieldType;
282
  old_fieldtype: TFieldType;
284
  res: Integer;
283
  res: Integer;
285
begin
284
begin
286
  if not MayJump(SourceTag, DestTag) then exit;
285
  if not MayJump(SourceTag, DestTag) then exit;
287
 
286
 
288
  s := PlaygroundMatrix.IndexToCoord(SourceTag);
287
  s := PlaygroundMatrix.IndexToCoord(SourceTag);
289
  d := PlaygroundMatrix.IndexToCoord(DestTag);
288
  d := PlaygroundMatrix.IndexToCoord(DestTag);
290
 
289
 
291
  JumpHistory.Add(Format(LNG_JUMP_LOG, [SourceTag+1, s.x+1, s.y+1, DestTag+1, d.x+1, d.y+1]));
290
  JumpHistory.Add(Format(LNG_JUMP_LOG, [s.x+1, s.y+1, d.x+1, d.y+1]));
292
 
291
 
293
  {$REGION 'Stein entfernen und Punkte vergeben'}
292
  {$REGION 'Stein entfernen und Punkte vergeben'}
294
  if Level.GameMode = gmDiagonal then
293
  if Level.GameMode = gmDiagonal then
295
  begin
294
  begin
296
    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);
295
    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);
297
    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);
296
    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);
298
    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);
297
    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);
299
    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);
298
    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);
300
  end;
299
  end;
301
 
300
 
302
  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);
301
  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);
303
  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);
302
  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);
304
  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);
303
  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);
305
  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);
304
  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);
306
  {$ENDREGION}
305
  {$ENDREGION}
307
 
306
 
308
  // Den Timer erst nach dem ersten Zug starten
307
  // Den Timer erst nach dem ersten Zug starten
309
  // oder nach einer Pause neustarten
308
  // oder nach einer Pause neustarten
310
  MPauseTime.Checked := false;
309
  MPauseTime.Checked := false;
Line 356... Line 355...
356
  s, d: TCoord;
355
  s, d: TCoord;
357
begin
356
begin
358
  s := PlayGroundMatrix.IndexToCoord(SourceTag);
357
  s := PlayGroundMatrix.IndexToCoord(SourceTag);
359
  d := PlayGroundMatrix.IndexToCoord(DestTag);
358
  d := PlayGroundMatrix.IndexToCoord(DestTag);
360
 
359
 
361
  result := PlaygroundMatrix.CanJump(s.X, s.Y, d.X, d.Y, Level.GameMode = gmDiagonal);
360
  result := PlaygroundMatrix.CanJump(s, d, Level.GameMode = gmDiagonal);
362
end;
361
end;
363
 
362
 
364
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
363
procedure TMainForm.StoneDragDrop(Sender, Source: TObject; X, Y: Integer);
365
begin
364
begin
366
  DoJump(TComponent(Source).Tag, TComponent(Sender).Tag);
365
  DoJump(TComponent(Source).Tag, TComponent(Sender).Tag);
Line 370... Line 369...
370
  Y: Integer; State: TDragState; var Accept: Boolean);
369
  Y: Integer; State: TDragState; var Accept: Boolean);
371
begin
370
begin
372
  Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag);
371
  Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag);
373
end;
372
end;
374
 
373
 
375
function TMainForm.DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField;
374
procedure TMainForm.DrawField(x, y: integer; var f: TField);
376
var
375
var
377
  newField: TField;
-
 
378
  index: integer;
376
  index: integer;
379
begin
377
begin
380
  ZeroMemory(@result, SizeOf(result));
-
 
381
  if t.Typ = ftFullSpace then exit;
378
  if f.FieldType = ftFullSpace then exit;
382
 
379
 
383
  index := PlaygroundMatrix.CoordToIndex(x, y);
380
  index := PlaygroundMatrix.CoordToIndex(x, y);
384
 
381
 
-
 
382
  f.Panel := DrawStoneBox(x, y, index, f.indent, f.Goal);
385
  newField.FieldType := t.Typ;
383
  f.Stone := DrawStone(f.FieldType, f.Panel);
-
 
384
end;
-
 
385
 
386
  newField.Goal := t.Goal;
386
procedure TMainForm.TimerTimer(Sender: TObject);
-
 
387
begin
387
  newField.Panel := DrawStoneBox(x, y, index, indent, t.Goal);
388
  if MPauseTime.Checked then exit;
388
  newField.Stone := DrawStone(t.Typ, newField.Panel);
389
  if mainform.Focused then Inc(CountedSeconds);
-
 
390
  RefreshTime;
-
 
391
end;
389
 
392
 
390
  result := newField;
393
function TMainForm.LevelTime: String;
-
 
394
begin
-
 
395
  result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay)
391
end;
396
end;
392
 
397
 
393
procedure TMainForm.BuildPlayground(LevelArray: TLevelArray);
398
procedure TMainForm.NewGame(Filename: string);
-
 
399
resourcestring
-
 
400
  LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.';
394
var
401
var
395
  y, x: integer;
402
  y, x: integer;
396
  max_x, max_y: integer;
403
  max_x, max_y: integer;
397
  p: TPanel;
404
  p: TPanel;
398
  newField: TField;
-
 
399
begin
405
begin
400
  PlayGround.Visible := false;
406
  DestroyLevel;
401
 
407
 
-
 
408
  MPauseTime.Checked := true;
-
 
409
  MPauseTime.Enabled := true;
-
 
410
  Timer.Enabled := true;
-
 
411
  MRestartGame.Enabled := true;
-
 
412
 
-
 
413
  LevelFile := Filename;
-
 
414
  Level := TLevel.Create(LevelFile);
-
 
415
 
402
  // Attention: PlaygroundMatrix is indexed [x,y] while LevelArray is indexed [y,x]
416
  Level.FillPlaygroundMatrix(PlaygroundMatrix, true);
403
  // TODO: PlaygroundMatrix and LevelArray are redundant. Can't we just replace one with the other?
417
  if Length(PlaygroundMatrix.Fields) = 0 then Exit;
-
 
418
 
404
  PlaygroundMatrix.InitFieldArray(Length(LevelArray[0].Fields), Length(LevelArray));
419
  PlayGround.Visible := false;
405
 
420
 
406
  max_x := 0;
421
  max_x := 0;
407
  max_y := 0;
422
  max_y := 0;
408
  for y := Low(LevelArray) to High(LevelArray) do
423
  for x := Low(PlaygroundMatrix.Fields) to High(PlaygroundMatrix.Fields) do
409
  begin
424
  begin
410
    for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do
425
    for y := Low(PlaygroundMatrix.Fields[x]) to High(PlaygroundMatrix.Fields[x]) do
411
    begin
426
    begin
412
      if TPlayGroundMatrix.FieldState(LevelArray[y].Fields[x].Typ) = fsStone then
427
      if TPlayGroundMatrix.FieldState(PlaygroundMatrix.Fields[x,y].FieldType) = fsOccupied then
413
        Inc(LevelTotalStones);
428
        Inc(LevelTotalStones);
414
      newField := DrawField(x, y, LevelArray[y].Fields[x], LevelArray[y].Indent);
429
      DrawField(x, y, PlaygroundMatrix.Fields[x,y]);
415
      PlaygroundMatrix.Fields[x, y] := newField;
430
      p := PlaygroundMatrix.Fields[x,y].Panel;
416
      p := newField.Panel;
-
 
417
      if Assigned(p) then
431
      if Assigned(p) then
418
      begin
432
      begin
419
        max_x := Max(max_x, p.Left + p.Width);
433
        max_x := Max(max_x, p.Left + p.Width);
420
        max_y := Max(max_y, p.Top  + p.Height);
434
        max_y := Max(max_y, p.Top  + p.Height);
421
      end;
435
      end;
Line 441... Line 455...
441
  Statistics.Panels.Items[1].Width := Round(ClientWidth*MET_PERCENT_PNL_STONES);
455
  Statistics.Panels.Items[1].Width := Round(ClientWidth * MET_PERCENT_PNL_STONES);
442
 
456
 
443
  SetLength(PrevPlaygroundMatrixes,1);
457
  SetLength(PrevPlaygroundMatrixes,1);
444
  PrevPlaygroundMatrixes[0] := PlayGroundMatrix.CloneMatrix;
458
  PrevPlaygroundMatrixes[0] := PlayGroundMatrix.CloneMatrix;
445
  MUndo.Enabled := false;
459
  MUndo.Enabled := false;
446
end;
-
 
447
 
460
 
448
procedure TMainForm.TimerTimer(Sender: TObject);
-
 
449
begin
-
 
450
  if MPauseTime.Checked then exit;
-
 
451
  if mainform.Focused then Inc(CountedSeconds);
-
 
452
  RefreshTime;
-
 
453
end;
-
 
454
 
-
 
455
function TMainForm.LevelTime: String;
-
 
456
begin
-
 
457
  result := FormatDateTime('hh:nn:ss', CountedSeconds / SecsPerDay)
-
 
458
end;
-
 
459
 
-
 
460
procedure TMainForm.NewGame(Filename: string);
-
 
461
resourcestring
-
 
462
  LNG_LVL_INVALID_NO_JUMP = 'Warning! The level is not playable. There are no jumps possible.';
-
 
463
var
-
 
464
  LevelArray: TLevelArray;
-
 
465
begin
-
 
466
  DestroyLevel;
-
 
467
 
-
 
468
  MPauseTime.Checked := true;
-
 
469
  MPauseTime.Enabled := true;
-
 
470
  Timer.Enabled := true;
-
 
471
  MRestartGame.Enabled := true;
-
 
472
 
-
 
473
  LevelFile := Filename;
-
 
474
  Level := TLevel.Create(LevelFile);
-
 
475
  LevelArray := Level.LevelStringToLevelArray(true);
-
 
476
  if Length(LevelArray) = 0 then Exit;
-
 
477
  BuildPlayground(LevelArray);
-
 
478
  if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
461
  if not PlayGroundMatrix.CanJump(Level.GameMode = gmDiagonal) then
479
  begin
462
  begin
480
    MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
463
    MessageDlg(LNG_LVL_INVALID_NO_JUMP, mtError, [mbOk], 0);
481
  end;
464
  end;
482
  RefreshTime;
465
  RefreshTime;