15-puzzle/fi
15-peli

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.
Luodaan ohjelmakoodi
- Luo uusi tyhjä graafinen sovellus lomakkeella Form1
- Muuta lomakkeen Form1 ominaisuus caption arvoon 15Puzzle'.
- Lisää uusi käännösyksikkö unitGameBoard.pas
- Luodaan OnCreate tapahtumakäsittelijä lomakkeelle, käyttämällä komponenttimuokkaimen tapahtumat-välilehteä, valitsemalla OnCreate tapahtuma, klikkaamalla sen [...] painiketta tai kaksoisklikkaamalla painiketta lomakkeella.
- Lisää siihen seuraava koodi:
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
aButton: TButton;
point:TPoint;
begin
Randomize;
Puzzle15:= TGameBoard.Create;
i := 1;
while i < 16 do
begin //luodaan 15 painiketta
aButton:=TButton.Create(Self); //luodaan Button, Owner on Form1, kun painike myöhemmin julkaistaan
aButton.Parent:=Self; //määrittää, missä se on näytettävä
aButton.Caption:=IntToStr(i); //Painikkeessa näkyvä teksti
aButton.Width:=aButton.Height; //Painike on neliö
point := Puzzle15.ButtonPlace(aButton.Caption);
aButton.Left:= point.x* aButton.Width; //painikkeen vasemman reunan etäisyys
aButton.Top := point.y* aButton.Height;
aButton.OnClick:=@aButtonClick; //painikkeen tapahtumakäsittelijä
inc(i);
end;
Self.Height:=aButton.Height*6; //lomakkeen korkeuden määritys
Self.Width:=aButton.Width*6; //lomakkeen leveyden määritys
end;- Luodaan komponenttimuokkaimella tapahtumakäsittelijä tapahtumalle FormDestroy, klikkaamalla sen painiketta [...].
- Täydennetään tapahtuman koodi seuraavaksi:
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(Puzzle15);
end;- Seuraavaksi luodaan tapahtumankäsittelijä painikkeiden klikkaukselle.
- Lähdekoodieditorissa siirrytään luokan TForm1 esittelyn private osaan.
- Lisää aliohjelma
procedure aButtonClick (Sender: TObject);ja paina näppäimiäCtrl+Shift+c(Koodin täydennys aktivoituu ja luo aliohjelman rungonprocedure TForm1.aButtonClick (Sender: TObject) ;. - Täydennetään se tälläiseksi:
procedure TForm1.aButtonClick(Sender: TObject); //Painikkeen tapahtumankäsittelijä
var
i:integer;
point : TPoint;
begin
if (Sender is TButton) and //Tarkistetaan että tapahtuman tultiin näppäimen painalluksella
TryStrToInt(TButton(Sender).Caption, i) // ja onko sen teksti kokonaisluku
then
begin
if Puzzle15.CanMove(TButton(Sender).Caption) then
begin
point := Puzzle15.Change(TButton(Sender).Caption);
TButton(Sender).Left:= point.x* TButton(Sender).Width;
TButton(Sender).Top := point.y* TButton(Sender).Height;
end;
end;
end;Lähdekoodi
unit1.pas
unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
unitGameBoard;
type
{ TForm1 }
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ private declarations }
Puzzle15:TGameBoard;
procedure aButtonClick(Sender: TObject);
public
{ public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i : Integer;
aButton: TButton;
point:TPoint;
begin
Randomize;
Puzzle15:= TGameBoard.Create;
i := 1;
while i < 16 do
begin //luodaan 15 painiketta
aButton:=TButton.Create(Self); //luodaan Button, Owner on Form1, kun painike myöhemmin julkaistaan
aButton.Parent:=Self; //määrittää, missä se on näytettävä
aButton.Caption:=IntToStr(i); //Painikkeessa näkyvä teksti
aButton.Width:=aButton.Height; //Painike on neliö
point := Puzzle15.ButtonPlace(aButton.Caption);
aButton.Left:= point.x* aButton.Width; //painikkeen vasemman reunan etäisyys
aButton.Top := point.y* aButton.Height;
aButton.OnClick:=@aButtonClick; //painikkeen tapahtumakäsittelijä
inc(i);
end;
Self.Height:=aButton.Height*6; //lomakkeen korkeuden määritys
Self.Width:=aButton.Width*6; //lomakkeen leveyden määritys
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
FreeAndNil(Puzzle15);
end;
procedure TForm1.aButtonClick(Sender: TObject); //Painikkeen tapahtumankäsittelijä
var
i:integer;
point : TPoint;
begin
if (Sender is TButton) and //Tarkistetaan että tapahtuman tultiin näppäimen painalluksella
TryStrToInt(TButton(Sender).Caption, i) // ja onko sen teksti kokonaisluku
then
begin
if Puzzle15.CanMove(TButton(Sender).Caption) then
begin
point := Puzzle15.Change(TButton(Sender).Caption);
TButton(Sender).Left:= point.x* TButton(Sender).Width;
TButton(Sender).Top := point.y* TButton(Sender).Height;
end;
end;
end;
end.Unit1.lfm
object Form1: TForm1
Left = 362
Height = 184
Top = 162
Width = 432
Caption = '15Puzzle'
OnCreate = FormCreate
OnDestroy = FormDestroy
LCLVersion = '1.6.0.4'
endunitGameBoard.pas
unit unitGameBoard;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils;
const
GB_MAX_BUTTONS = 15;
GB_MAX_X = 4;
GB_MAX_Y = 4;
GB_EMPTY_PLACE ='-';
type
{ TGameBoard }
TGameBoard = class
private
GameArray:array[1..GB_MAX_X, 1..GB_MAX_Y] of string;
function ValidPoint(a_point:TPoint):boolean;
public
constructor Create;
function ButtonPlace(a_name:string):TPoint;
function CanMove(a_name:string):Boolean;
function Change(a_name: string): TPoint;
procedure RandomArray;
destructor Destroy; override;
end;
implementation
{ TGameBoard }
function TGameBoard.ValidPoint(a_point: TPoint): boolean;
begin
result := true;
if a_point.y > GB_MAX_Y then result := false;
if a_point.x > GB_MAX_X then result := false;
if a_point.y < 1 then result := false;
if a_point.x < 1 then result := false;
end;
constructor TGameBoard.Create;
var
i, x, y : integer;
begin
i := 1;
for y := 1 to GB_MAX_Y do
for x := 1 to GB_MAX_X do
begin
if i < GB_MAX_BUTTONS+1
then GameArray[x,y] := IntToStr(i)
else GameArray[x,y] := GB_EMPTY_PLACE;
inc(i);
end;
RandomArray;
end;
function TGameBoard.ButtonPlace(a_name: string): TPoint;
var
x,y:integer;
begin
result.x := 0;
result.y := 0;
for y := 1 to GB_MAX_Y do
for x := 1 to GB_MAX_X do
if GameArray[x,y] = a_name then
begin
result.x := x;
result.y := y;
end;
end;
function TGameBoard.CanMove(a_name: string): Boolean;
var
empty, point:TPoint;
begin
result := false;
empty := ButtonPlace( GB_EMPTY_PLACE );
point := ButtonPlace(a_name);
if (abs(empty.x-point.x)=1) and (empty.y=point.y) then result := true;
if (abs(empty.y-point.y)=1) and (empty.x=point.x) then result := true;
end;
function TGameBoard.Change(a_name: string): TPoint;
var
empty, point:TPoint;
begin
empty := ButtonPlace( GB_EMPTY_PLACE );
result := empty;
point := ButtonPlace(a_name);
GameArray[point.x, point.y] := GB_EMPTY_PLACE;
GameArray[empty.x, empty.y] := a_name;
end;
procedure TGameBoard.RandomArray;
var
j,i:integer;
name:string;
point,point2:TPoint;
begin
for i := 0 to 1000 do
begin
j := random(4);
point := ButtonPlace( GB_EMPTY_PLACE );
point2 := point;
case j of
0: point2.x := point.x-1;
1: point2.x := point.x+1;
2: point2.y := point.y-1;
3: point2.y := point.y+1;
end;
if ValidPoint( point2 ) then
begin
name := GameArray[point2.x, point2.y];
GameArray[point.x, point.y] := name;
GameArray[point2.x, point2.y] := GB_EMPTY_PLACE;
end;
end;
end;
destructor TGameBoard.Destroy;
begin
inherited Destroy;
end;
end.Katso myös
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.
Talk about this page
Nobody has opened a bench for this page yet. Sign in to open one.
