Rev 18 | Rev 21 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 18 | Rev 19 | ||
---|---|---|---|
Line 12... | Line 12... | ||
12 | Goal: Boolean; |
12 | Goal: Boolean; |
13 | Panel: TPanel; |
13 | Panel: TPanel; |
14 | Stone: TImage; |
14 | Stone: TImage; |
15 | end; |
15 | end; |
16 | 16 | ||
17 | TGoalStatus = (gsNoGoal, gsMultipleStonesRemaining, gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen, gsLastStoneOutsideGoal); |
17 | TGoalStatus = (gsUndefined, gsNoGoal, gsMultipleStonesRemaining, gsLastStoneInGoalRed, gsLastStoneInGoalYellow, gsLastStoneInGoalGreen, gsLastStoneOutsideGoal); |
18 | 18 | ||
19 | TFieldState = (fsError, fsLocked, fsAvailable, fsStone); |
19 | TFieldState = (fsUndefined, fsError, fsLocked, fsAvailable, fsStone); |
20 | 20 | ||
21 | TPlayGroundMatrix = array of array of TField; |
21 | TPlayGroundMatrix = array of array of TField; |
22 | 22 | ||
23 | TMainForm = class(TForm) |
23 | TMainForm = class(TForm) |
24 | Playground: TPanel; |
24 | Playground: TPanel; |
Line 91... | Line 91... | ||
91 | procedure RemoveStone(x, y: integer; count_points: boolean); |
91 | procedure RemoveStone(x, y: integer; count_points: boolean); |
92 | procedure DoJump(SourceTag, DestTag: integer); |
92 | procedure DoJump(SourceTag, DestTag: integer); |
93 | function CanJump(x, y: integer): boolean; |
93 | function CanJump(x, y: integer): boolean; |
94 | function MayJump(SourceX, SourceY, DestX, DestY: integer): boolean; overload; |
94 | function MayJump(SourceX, SourceY, DestX, DestY: integer): boolean; overload; |
95 | function MayJump(SourceTag, DestTag: integer): boolean; overload; |
95 | function MayJump(SourceTag, DestTag: integer): boolean; overload; |
96 | procedure StoneDragOver(Sender, Source: TObject; X, |
- | |
97 | Y: Integer; State: TDragState; var Accept: Boolean); |
96 | procedure StoneDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); |
98 | procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer); |
97 | procedure StoneDragDrop(Sender, Source: TObject; X, Y: Integer); |
99 | procedure DrawField(x, y: integer; t: TFieldProperties; halftabs: integer); |
98 | function DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField; |
100 | function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage; |
99 | function DrawStone(fieldtype: TFieldType; panel: TPanel): TImage; |
101 | function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel; |
100 | function DrawStoneBox(x, y, tag, halftabs: integer; isGoal: boolean): TPanel; |
102 | procedure BuildPlayground(LevelArray: TLevelArray); |
101 | procedure BuildPlayground(LevelArray: TLevelArray); |
103 | function FieldState(t: TFieldType): TFieldState; overload; |
102 | function FieldState(t: TFieldType): TFieldState; overload; |
104 | function FieldState(f: TField): TFieldState; overload; |
103 | function FieldState(f: TField): TFieldState; overload; |
Line 116... | Line 115... | ||
116 | MainForm: TMainForm; |
115 | MainForm: TMainForm; |
117 | 116 | ||
118 | implementation |
117 | implementation |
119 | 118 | ||
120 | uses |
119 | uses |
121 | About, Finish, Choice, Functions, History, HighScore, Help, Constants; |
120 | About, Finish, Choice, Functions, History, HighScore, Help, Constants, Math; |
122 | 121 | ||
123 | {$R *.dfm} |
122 | {$R *.dfm} |
124 | 123 | ||
125 | function TMainForm.MatrixHasGoal(Matrix: TPlayGroundMatrix): boolean; |
124 | function TMainForm.MatrixHasGoal(Matrix: TPlayGroundMatrix): boolean; |
126 | var |
125 | var |
Line 138... | Line 137... | ||
138 | 137 | ||
139 | function TMainForm.GoalFieldType(Matrix: TPlayGroundMatrix): TFieldType; |
138 | function TMainForm.GoalFieldType(Matrix: TPlayGroundMatrix): TFieldType; |
140 | var |
139 | var |
141 | i, j: integer; |
140 | i, j: integer; |
142 | begin |
141 | begin |
- | 142 | result := ftEmpty; // Damit der Compiler nicht meckert |
|
143 | for i := Low(Matrix) to High(Matrix) do |
143 | for i := Low(Matrix) to High(Matrix) do |
144 | begin |
144 | begin |
145 | for j := Low(Matrix[i]) to High(Matrix[i]) do |
145 | for j := Low(Matrix[i]) to High(Matrix[i]) do |
146 | begin |
146 | begin |
147 | if Matrix[i][j].Goal then result := Matrix[i][j].FieldType |
147 | if Matrix[i][j].Goal then result := Matrix[i][j].FieldType |
Line 286... | Line 286... | ||
286 | end; |
286 | end; |
287 | result.Color := Playground.Color; |
287 | result.Color := Playground.Color; |
288 | result.BevelOuter := bvLowered; |
288 | result.BevelOuter := bvLowered; |
289 | result.Width := MET_FIELD_SIZE; |
289 | result.Width := MET_FIELD_SIZE; |
290 | result.Height := MET_FIELD_SIZE; |
290 | result.Height := MET_FIELD_SIZE; |
291 | result.Left := x * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE - (halftabs*MET_HALFTAB_SIZE); |
291 | result.Left := x * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE + (halftabs*MET_HALFTAB_SIZE); |
292 | result.Top := y * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE; |
292 | result.Top := y * (MET_FIELD_SIZE+MET_FIELD_SPACE) + MET_FIELD_SPACE; |
293 | 293 | ||
294 | result.Tag := tag; |
294 | result.Tag := tag; |
295 | result.OnDragOver := StoneDragOver; |
295 | result.OnDragOver := StoneDragOver; |
296 | result.OnDragDrop := StoneDragDrop; |
296 | result.OnDragDrop := StoneDragDrop; |
Line 304... | Line 304... | ||
304 | function TMainForm.FieldState(t: TFieldType): TFieldState; |
304 | function TMainForm.FieldState(t: TFieldType): TFieldState; |
305 | begin |
305 | begin |
306 | result := fsError; |
306 | result := fsError; |
307 | case t of |
307 | case t of |
308 | ftFullSpace: result := fsLocked; |
308 | ftFullSpace: result := fsLocked; |
309 | ftHalfSpace: result := fsLocked; |
- | |
310 | ftEmpty: result := fsAvailable; |
309 | ftEmpty: result := fsAvailable; |
311 | ftGreen: result := fsStone; |
310 | ftGreen: result := fsStone; |
312 | ftYellow: result := fsStone; |
311 | ftYellow: result := fsStone; |
313 | ftRed: result := fsStone; |
312 | ftRed: result := fsStone; |
314 | end; |
313 | end; |
Line 555... | Line 554... | ||
555 | Y: Integer; State: TDragState; var Accept: Boolean); |
554 | Y: Integer; State: TDragState; var Accept: Boolean); |
556 | begin |
555 | begin |
557 | Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag); |
556 | Accept := MayJump(TComponent(Source).Tag, TComponent(Sender).Tag); |
558 | end; |
557 | end; |
559 | 558 | ||
560 | procedure TMainForm.DrawField(x, y: integer; t: TFieldProperties; halftabs: integer); |
559 | function TMainForm.DrawField(x, y: integer; t: TFieldProperties; indent: integer): TField; |
561 | var |
560 | var |
562 | newField: TField; |
561 | newField: TField; |
563 | index: integer; |
562 | index: integer; |
564 | begin |
563 | begin |
- | 564 | ZeroMemory(@result, SizeOf(result)); |
|
565 | if (t.Typ = ftFullSpace) or (t.Typ = ftHalfSpace) then exit; |
565 | if t.Typ = ftFullSpace then exit; |
566 | 566 | ||
567 | index := Length(LookupFieldCoordinateArray); |
567 | index := Length(LookupFieldCoordinateArray); |
568 | 568 | ||
569 | newField.FieldType := t.Typ; |
569 | newField.FieldType := t.Typ; |
570 | newField.Goal := t.Goal; |
570 | newField.Goal := t.Goal; |
571 | newField.Panel := DrawStoneBox(x, y, index, halftabs, t.Goal); |
571 | newField.Panel := DrawStoneBox(x, y, index, indent, t.Goal); |
572 | newField.Stone := DrawStone(t.Typ, newField.Panel); |
572 | newField.Stone := DrawStone(t.Typ, newField.Panel); |
573 | if FieldState(t.Typ) = fsStone then Inc(LevelTotalStones); |
573 | if FieldState(t.Typ) = fsStone then Inc(LevelTotalStones); |
574 | 574 | ||
575 | SetLength(LookupFieldCoordinateArray, index + 1); |
575 | SetLength(LookupFieldCoordinateArray, index + 1); |
576 | LookupFieldCoordinateArray[index].X := x; |
576 | LookupFieldCoordinateArray[index].X := x; |
577 | LookupFieldCoordinateArray[index].Y := y; |
577 | LookupFieldCoordinateArray[index].Y := y; |
578 | 578 | ||
579 | if Length(PlayGroundMatrix) < x+1 then SetLength(PlayGroundMatrix, x+1); |
579 | if Length(PlayGroundMatrix) < x+1 then SetLength(PlayGroundMatrix, x+1); |
580 | if Length(PlayGroundMatrix[x]) < y+1 then SetLength(PlayGroundMatrix[x], y+1); |
580 | if Length(PlayGroundMatrix[x]) < y+1 then SetLength(PlayGroundMatrix[x], y+1); |
581 | PlaygroundMatrix[x, y] := newField; |
581 | PlaygroundMatrix[x, y] := newField; |
- | 582 | ||
- | 583 | result := newField; |
|
582 | end; |
584 | end; |
583 | 585 | ||
584 | function TMainForm.CloneMatrix(Source: TPlayGroundMatrix): TPlayGroundMatrix; |
586 | function TMainForm.CloneMatrix(Source: TPlayGroundMatrix): TPlayGroundMatrix; |
585 | var |
587 | var |
586 | i, j: integer; |
588 | i, j: integer; |
Line 599... | Line 601... | ||
599 | end; |
601 | end; |
600 | end; |
602 | end; |
601 | 603 | ||
602 | procedure TMainForm.BuildPlayground(LevelArray: TLevelArray); |
604 | procedure TMainForm.BuildPlayground(LevelArray: TLevelArray); |
603 | var |
605 | var |
604 | i, j, halftabs, cur_x: integer; |
606 | y, x: integer; |
605 | max_x, max_y, old_cw, old_ch: integer; |
607 | max_x, max_y: integer; |
- | 608 | p: TPanel; |
|
606 | begin |
609 | begin |
607 | PlayGround.Visible := false; |
610 | PlayGround.Visible := false; |
608 | 611 | ||
609 | // Die Dimensionen ermitteln |
612 | // Die Dimensionen ermitteln |
610 | max_x := 0; |
613 | max_x := 0; |
- | 614 | max_y := 0; |
|
611 | for i := Low(LevelArray) to High(LevelArray) do |
615 | for y := Low(LevelArray) to High(LevelArray) do |
- | 616 | begin |
|
- | 617 | for x := Low(LevelArray[y].Fields) to High(LevelArray[y].Fields) do |
|
612 | begin |
618 | begin |
613 | halftabs := 0; |
- | |
614 | for j := Low(LevelArray[i]) to High(LevelArray[i]) do |
619 | p := DrawField(x, y, LevelArray[y].Fields[x], LevelArray[y].Indent).Panel; |
- | 620 | if Assigned(p) then |
|
615 | begin |
621 | begin |
616 | if LevelArray[i][j].Typ = ftHalfSpace then inc(halftabs); |
622 | max_x := Max(max_x, p.Left + p.Width); |
617 | DrawField(j, i, LevelArray[i][j], halftabs); |
623 | max_y := Max(max_y, p.Top + p.Height); |
- | 624 | end; |
|
618 | end; |
625 | end; |
619 | cur_x := High(LevelArray[i]) + 1; |
- | |
620 | if cur_x > max_x then max_x := cur_x; |
- | |
621 | end; |
626 | end; |
622 | max_y := High(LevelArray) + 1; |
- | |
623 | 627 | ||
624 | PlayGround.Visible := true; |
628 | PlayGround.Visible := true; |
625 | 629 | ||
626 | // Die aktuellen Dimensionen merken |
- | |
627 | old_cw := ClientWidth; |
- | |
628 | old_ch := ClientHeight; |
- | |
629 | - | ||
630 | // Das Form an das Level anpassen |
630 | // Das Form an das Level anpassen |
631 | PlayGround.Width := MET_FIELD_SPACE + max_x * (MET_FIELD_SPACE + MET_FIELD_SIZE); |
631 | PlayGround.Top := MET_OUTER_MARGIN; |
632 | PlayGround.Height := MET_FIELD_SPACE + max_y * (MET_FIELD_SPACE + MET_FIELD_SIZE); |
632 | PlayGround.Left := MET_OUTER_MARGIN; |
- | 633 | PlayGround.Width := max_x; |
|
- | 634 | PlayGround.Height := max_y; |
|
633 | ClientWidth := 2 * MET_OUTER_MARGIN + PlayGround.Width; |
635 | ClientWidth := 2 * MET_OUTER_MARGIN + PlayGround.Width; |
634 | ClientHeight := 2 * MET_OUTER_MARGIN + PlayGround.Height + Statistics.Height; |
636 | ClientHeight := 2 * MET_OUTER_MARGIN + PlayGround.Height + Statistics.Height; |
635 | 637 | ||
- | 638 | // If the board is too small, ClientWidth/ClientHeight will stop at a minimum value |
|
- | 639 | // in this case, we make sure that the Playground is centered |
|
- | 640 | PlayGround.Left := ClientWidth div 2 - Playground.Width div 2; |
|
- | 641 | PlayGround.Top := (ClientHeight - Statistics.Height) div 2 - Playground.Height div 2; |
|
- | 642 | ||
636 | Statistics.Panels.Items[0].Width := Round(ClientWidth*MET_PERCENT_PNL_TIME); |
643 | Statistics.Panels.Items[0].Width := Round(ClientWidth*MET_PERCENT_PNL_TIME); |
637 | Statistics.Panels.Items[1].Width := Round(ClientWidth*MET_PERCENT_PNL_STONES); |
644 | Statistics.Panels.Items[1].Width := Round(ClientWidth*MET_PERCENT_PNL_STONES); |
638 | 645 | ||
639 | // Wenn sich das Form vergrößert oder verkleinert hat, neu justieren |
- | |
640 | if (old_cw <> ClientWidth) or (old_ch <> ClientHeight) then |
- | |
641 | begin |
- | |
642 | Left := Screen.Width div 2 - Width div 2; |
- | |
643 | Top := Screen.Height div 2 - Height div 2; |
- | |
644 | - | ||
645 | // Playground mittig setzen, falls die Mindestgröße für die |
- | |
646 | // Punkteanzeige unterschritten wurde, |
- | |
647 | PlayGround.Left := ClientWidth div 2 - PlayGround.Width div 2; |
- | |
648 | PlayGround.Top := ClientHeight div 2 - PlayGround.Height div 2; |
- | |
649 | end; |
- | |
650 | - | ||
651 | SetLength(PrevPlaygroundMatrixes,1); |
646 | SetLength(PrevPlaygroundMatrixes,1); |
652 | PrevPlaygroundMatrixes[0] := CloneMatrix(PlayGroundMatrix); |
647 | PrevPlaygroundMatrixes[0] := CloneMatrix(PlayGroundMatrix); |
653 | MUndo.Enabled := false; |
648 | MUndo.Enabled := false; |
654 | end; |
649 | end; |
655 | 650 | ||
Line 738... | Line 733... | ||
738 | if ft = ftRed then |
733 | if ft = ftRed then |
739 | result := gsLastStoneInGoalRed |
734 | result := gsLastStoneInGoalRed |
740 | else if ft = ftYellow then |
735 | else if ft = ftYellow then |
741 | result := gsLastStoneInGoalYellow |
736 | result := gsLastStoneInGoalYellow |
742 | else if ft = ftGreen then |
737 | else if ft = ftGreen then |
743 | result := gsLastStoneInGoalGreen; |
738 | result := gsLastStoneInGoalGreen |
- | 739 | else |
|
- | 740 | result := gsUndefined; |
|
744 | end; |
741 | end; |
745 | end; |
742 | end; |
746 | 743 | ||
747 | procedure TMainForm.FormCreate(Sender: TObject); |
744 | procedure TMainForm.FormCreate(Sender: TObject); |
748 | begin |
745 | begin |