Sign in Join
Wiki copytemporary

15-puzzle/fi

English · Français · Suomi

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

pascal
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;
pascal
procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Puzzle15);
end;
pascal
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

pascal
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

pascal
object Form1: TForm1
  Left = 362
  Height = 184
  Top = 162
  Width = 432
  Caption = '15Puzzle'
  OnCreate = FormCreate
  OnDestroy = FormDestroy
  LCLVersion = '1.6.0.4'
end

unitGameBoard.pas

pascal
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.

Revision 2, last changed by WikiArchive .

Talk about this page

Nobody has opened a bench for this page yet. Sign in to open one.