Sign in Join
Wiki copytemporary

15-puzzle/fi: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: 15-puzzle/fi

OldNewLine
1+## 15-peli
2+
3+<figure>
4+<img src="puzzle15.png" title="puzzle15.png" />
5+<figcaption>puzzle15.png</figcaption>
6+</figure>
7+
8+15-peli on liukupalapeli joka koostuu kehyksestä jossa on numeroituja neliömäisiä laattoja satunnaisessa järjestyksessä missä yksi laatta puuttuu. Pelissä tavoitteena on sijoittaa laatat järjestykseen liu'uttamalla siirrettävä pala tyhjään tilaan.
9+
10+## Luodaan ohjelmakoodi
11+
12+- Luo uusi tyhjä graafinen sovellus lomakkeella [[TForm/fi|Form1]]
13+- Muuta lomakkeen Form1 ominaisuus caption arvoon *15Puzzle*'.
14+- Lisää uusi käännösyksikkö [[15-puzzle/fi|unitGameBoard.pas]]
15+- Luodaan OnCreate tapahtumakäsittelijä lomakkeelle, käyttämällä komponenttimuokkaimen tapahtumat-välilehteä, valitsemalla OnCreate tapahtuma, klikkaamalla sen \[...\] painiketta tai kaksoisklikkaamalla painiketta lomakkeella.
16+- Lisää siihen seuraava koodi:
17+
18+``` pascal
19+procedure TForm1.FormCreate(Sender: TObject);
20+var
21+ i : Integer;
22+ aButton: TButton;
23+ point:TPoint;
24+begin
25+ Randomize;
26+ Puzzle15:= TGameBoard.Create;
27+ i := 1;
28+ while i < 16 do
29+ begin //luodaan 15 painiketta
30+ aButton:=TButton.Create(Self); //luodaan Button, Owner on Form1, kun painike myöhemmin julkaistaan
31+ aButton.Parent:=Self; //määrittää, missä se on näytettävä
32+ aButton.Caption:=IntToStr(i); //Painikkeessa näkyvä teksti
33+ aButton.Width:=aButton.Height; //Painike on neliö
34+ point := Puzzle15.ButtonPlace(aButton.Caption);
35+ aButton.Left:= point.x* aButton.Width; //painikkeen vasemman reunan etäisyys
36+ aButton.Top := point.y* aButton.Height;
37+
38+ aButton.OnClick:=@aButtonClick; //painikkeen tapahtumakäsittelijä
39+ inc(i);
40+ end;
41+ Self.Height:=aButton.Height*6; //lomakkeen korkeuden määritys
42+ Self.Width:=aButton.Width*6; //lomakkeen leveyden määritys
43+end;
44+```
45+
46+- Luodaan komponenttimuokkaimella tapahtumakäsittelijä tapahtumalle FormDestroy, klikkaamalla sen painiketta \[...\].
47+- Täydennetään tapahtuman koodi seuraavaksi:
48+
49+``` pascal
50+procedure TForm1.FormDestroy(Sender: TObject);
51+begin
52+ FreeAndNil(Puzzle15);
53+end;
54+```
55+
56+- Seuraavaksi luodaan tapahtumankäsittelijä painikkeiden klikkaukselle.
57+- Lähdekoodieditorissa siirrytään luokan TForm1 esittelyn private osaan.
58+- Lisää [[Procedure/fi|aliohjelma]] `procedure aButtonClick (Sender: TObject);` ja paina näppäimiä <span class="kbd">Ctrl</span>+<span class="kbd">Shift</span>+<span class="kbd">c</span> (Koodin täydennys aktivoituu ja luo aliohjelman rungon `procedure TForm1.aButtonClick (Sender: TObject) ;`.
59+- Täydennetään se tälläiseksi:
60+
61+``` pascal
62+procedure TForm1.aButtonClick(Sender: TObject); //Painikkeen tapahtumankäsittelijä
63+var
64+ i:integer;
65+ point : TPoint;
66+begin
67+ if (Sender is TButton) and //Tarkistetaan että tapahtuman tultiin näppäimen painalluksella
68+ TryStrToInt(TButton(Sender).Caption, i) // ja onko sen teksti kokonaisluku
69+ then
70+ begin
71+ if Puzzle15.CanMove(TButton(Sender).Caption) then
72+ begin
73+ point := Puzzle15.Change(TButton(Sender).Caption);
74+ TButton(Sender).Left:= point.x* TButton(Sender).Width;
75+ TButton(Sender).Top := point.y* TButton(Sender).Height;
76+ end;
77+ end;
78+end;
79+```
80+
81+## Lähdekoodi
82+
83+### unit1.pas
84+
85+``` pascal
86+unit Unit1;
87+
88+{$mode objfpc}{$H+}
89+
90+interface
91+
92+uses
93+ Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
94+ unitGameBoard;
95+
96+type
97+
98+ { TForm1 }
99+
100+ TForm1 = class(TForm)
101+ procedure FormCreate(Sender: TObject);
102+ procedure FormDestroy(Sender: TObject);
103+ private
104+ { private declarations }
105+ Puzzle15:TGameBoard;
106+ procedure aButtonClick(Sender: TObject);
107+
108+ public
109+ { public declarations }
110+ end;
111+
112+var
113+ Form1: TForm1;
114+
115+implementation
116+
117+{$R *.lfm}
118+
119+{ TForm1 }
120+
121+procedure TForm1.FormCreate(Sender: TObject);
122+var
123+ i : Integer;
124+ aButton: TButton;
125+ point:TPoint;
126+begin
127+ Randomize;
128+ Puzzle15:= TGameBoard.Create;
129+ i := 1;
130+ while i < 16 do
131+ begin //luodaan 15 painiketta
132+ aButton:=TButton.Create(Self); //luodaan Button, Owner on Form1, kun painike myöhemmin julkaistaan
133+ aButton.Parent:=Self; //määrittää, missä se on näytettävä
134+ aButton.Caption:=IntToStr(i); //Painikkeessa näkyvä teksti
135+ aButton.Width:=aButton.Height; //Painike on neliö
136+ point := Puzzle15.ButtonPlace(aButton.Caption);
137+ aButton.Left:= point.x* aButton.Width; //painikkeen vasemman reunan etäisyys
138+ aButton.Top := point.y* aButton.Height;
139+
140+ aButton.OnClick:=@aButtonClick; //painikkeen tapahtumakäsittelijä
141+ inc(i);
142+ end;
143+ Self.Height:=aButton.Height*6; //lomakkeen korkeuden määritys
144+ Self.Width:=aButton.Width*6; //lomakkeen leveyden määritys
145+end;
146+
147+procedure TForm1.FormDestroy(Sender: TObject);
148+begin
149+ FreeAndNil(Puzzle15);
150+end;
151+
152+procedure TForm1.aButtonClick(Sender: TObject); //Painikkeen tapahtumankäsittelijä
153+var
154+ i:integer;
155+ point : TPoint;
156+begin
157+ if (Sender is TButton) and //Tarkistetaan että tapahtuman tultiin näppäimen painalluksella
158+ TryStrToInt(TButton(Sender).Caption, i) // ja onko sen teksti kokonaisluku
159+ then
160+ begin
161+ if Puzzle15.CanMove(TButton(Sender).Caption) then
162+ begin
163+ point := Puzzle15.Change(TButton(Sender).Caption);
164+ TButton(Sender).Left:= point.x* TButton(Sender).Width;
165+ TButton(Sender).Top := point.y* TButton(Sender).Height;
166+ end;
167+ end;
168+end;
169+
170+end.
171+```
172+
173+### Unit1.lfm
174+
175+``` pascal
176+object Form1: TForm1
177+ Left = 362
178+ Height = 184
179+ Top = 162
180+ Width = 432
181+ Caption = '15Puzzle'
182+ OnCreate = FormCreate
183+ OnDestroy = FormDestroy
184+ LCLVersion = '1.6.0.4'
185+end
186+```
187+
188+### unitGameBoard.pas
189+
190+``` pascal
191+unit unitGameBoard;
192+
193+{$mode objfpc}{$H+}
194+
195+interface
196+
197+uses
198+ Classes, SysUtils;
199+
200+const
201+ GB_MAX_BUTTONS = 15;
202+ GB_MAX_X = 4;
203+ GB_MAX_Y = 4;
204+ GB_EMPTY_PLACE ='-';
205+type
206+
207+ { TGameBoard }
208+
209+ TGameBoard = class
210+ private
211+ GameArray:array[1..GB_MAX_X, 1..GB_MAX_Y] of string;
212+ function ValidPoint(a_point:TPoint):boolean;
213+ public
214+ constructor Create;
215+ function ButtonPlace(a_name:string):TPoint;
216+ function CanMove(a_name:string):Boolean;
217+ function Change(a_name: string): TPoint;
218+ procedure RandomArray;
219+ destructor Destroy; override;
220+ end;
221+implementation
222+
223+{ TGameBoard }
224+
225+function TGameBoard.ValidPoint(a_point: TPoint): boolean;
226+begin
227+ result := true;
228+ if a_point.y > GB_MAX_Y then result := false;
229+ if a_point.x > GB_MAX_X then result := false;
230+ if a_point.y < 1 then result := false;
231+ if a_point.x < 1 then result := false;
232+end;
233+
234+constructor TGameBoard.Create;
235+var
236+ i, x, y : integer;
237+begin
238+ i := 1;
239+ for y := 1 to GB_MAX_Y do
240+ for x := 1 to GB_MAX_X do
241+ begin
242+ if i < GB_MAX_BUTTONS+1
243+ then GameArray[x,y] := IntToStr(i)
244+ else GameArray[x,y] := GB_EMPTY_PLACE;
245+ inc(i);
246+ end;
247+ RandomArray;
248+end;
249+
250+function TGameBoard.ButtonPlace(a_name: string): TPoint;
251+var
252+ x,y:integer;
253+begin
254+ result.x := 0;
255+ result.y := 0;
256+ for y := 1 to GB_MAX_Y do
257+ for x := 1 to GB_MAX_X do
258+ if GameArray[x,y] = a_name then
259+ begin
260+ result.x := x;
261+ result.y := y;
262+ end;
263+end;
264+
265+function TGameBoard.CanMove(a_name: string): Boolean;
266+var
267+ empty, point:TPoint;
268+begin
269+ result := false;
270+ empty := ButtonPlace( GB_EMPTY_PLACE );
271+ point := ButtonPlace(a_name);
272+ if (abs(empty.x-point.x)=1) and (empty.y=point.y) then result := true;
273+ if (abs(empty.y-point.y)=1) and (empty.x=point.x) then result := true;
274+end;
275+
276+function TGameBoard.Change(a_name: string): TPoint;
277+var
278+ empty, point:TPoint;
279+begin
280+ empty := ButtonPlace( GB_EMPTY_PLACE );
281+ result := empty;
282+ point := ButtonPlace(a_name);
283+ GameArray[point.x, point.y] := GB_EMPTY_PLACE;
284+ GameArray[empty.x, empty.y] := a_name;
285+end;
286+
287+procedure TGameBoard.RandomArray;
288+var
289+ j,i:integer;
290+ name:string;
291+ point,point2:TPoint;
292+begin
293+ for i := 0 to 1000 do
294+ begin
295+ j := random(4);
296+ point := ButtonPlace( GB_EMPTY_PLACE );
297+ point2 := point;
298+ case j of
299+ 0: point2.x := point.x-1;
300+ 1: point2.x := point.x+1;
301+ 2: point2.y := point.y-1;
302+ 3: point2.y := point.y+1;
303+ end;
304+ if ValidPoint( point2 ) then
305+ begin
306+ name := GameArray[point2.x, point2.y];
307+ GameArray[point.x, point.y] := name;
308+ GameArray[point2.x, point2.y] := GB_EMPTY_PLACE;
309+ end;
310+ end;
311+end;
312+
313+destructor TGameBoard.Destroy;
314+begin
315+ inherited Destroy;
316+end;
317+
318+end.
319+```
320+
321+## Katso myös
322+
323+- [[TButton/fi|TButton]]
324+
325+---
326+*From the Free Pascal wiki, page "15-puzzle/fi", as it stood on 2022-08-06 after a change by Kai Burghardt, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history