15-puzzle/fr

From Free Pascal wiki
Revision as of 07:52, 1 February 2020 by GAN (talk | contribs) (Fixed syntax highlighting)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

English (en) suomi (fi) français (fr)

Taquin

puzzle15.png

Le taquin est un casse-tête avec des pièces glissantes qui consiste en un cadre de tuiles carrées numérotées dans un ordre aléatoire avec une tuile manquante. Le but du jeu consiste à replacer les tuiles dans l'ordre à l'aide de glissements qui utilise la place vide.

Créer le code

  • Créer une nouvelle application IHM avec la fiche Form1
  • Changer le titre de Form1 en 15Puzzle'.
  • Ajouter la nouvelle unité unitGameBoard.pas
  • Créer le gestionnaire d'événement OnCreate pour la fiche, en cliquant sur votre fiche, utiliser l'inspecteur d'objets, l'onglet Evénement, sélectionner OnCreate et cliquer sur le bouton [...] ou double-cliquer directement sur la fiche.
  • Ajouter le code suivant :
procedure TForm1.FormCreate(Sender: TObject);
var
  i : Integer;
  aButton: TButton;
  point:TPoint;
begin
  Randomize;
  Puzzle15:= TGameBoard.Create;
  i := 1;
  while i < 16 do
    begin                              //create 15 Buttons
      aButton:=TButton.Create(Self);   //create Button, Owner is Form1, where the button is released later
      aButton.Parent:=Self;            //determine where it is to be displayed
      aButton.Caption:=IntToStr(i);    //Captions of the buttons
      aButton.Width:=aButton.Height;   //Width should correspond to the height of the buttons
      point := Puzzle15.ButtonPlace(aButton.Caption);
      aButton.Left:= point.x* aButton.Width;    //Distance from left
      aButton.Top := point.y* aButton.Height;

      aButton.OnClick:=@aButtonClick; //the event handler for the button -> will be created yet
      inc(i);
    end;
  Self.Height:=aButton.Height*6;      //Height of the form should correspond to the height of the buttons
  Self.Width:=aButton.Width*6;        //Width of the form to match the width of all buttons
end;
  • Créer dans l'inspecteur d'objet, le gestionnaire pour l'événement FormDestroy, en cliquant sur le bouton [...].
  • Ajouter le code suivant dans le gestionnaire :
procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Puzzle15);
end;
  • Maintenant vous devez créer le gestionnaire d'événement pour les clics de bouton.
  • Dans l'éditeur de source, en entrant dans la section private de votre classe TForm1.
  • Ajouter la procédure aButtonClick(Sender: TObject); and ensuite pressez la touche Ctrl+ Shift+c (la complétion de code devient active et crée la procédure TForm1.aButtonClick(Sender: TObject);.
  • Coller le code suivant :
procedure TForm1.aButtonClick(Sender: TObject);  //the event handler for the button
var
  i:integer;
  point : TPoint;
begin
  if (Sender is TButton) and                     //called the event handler of a button out?
     TryStrToInt(TButton(Sender).Caption, i)       //then try to convert the label in a integer
    then
      begin
        if Puzzle15.CanMove(TButton(Sender).Caption) then
          begin
            point := Puzzle15.Change(TButton(Sender).Caption);
            TButton(Sender).Left:= point.x* TButton(Sender).Width;    //Distance from left
            TButton(Sender).Top := point.y* TButton(Sender).Height;
          end;
      end;
end;

Code source

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  //create 15 Buttons
      aButton:=TButton.Create(Self);    //create Button, Owner is Form1, where the button is released later
      aButton.Parent:=Self;             //determine where it is to be displayed
      aButton.Caption:=IntToStr(i);     //Captions of the buttons
      aButton.Width:=aButton.Height;    //Width should correspond to the height of the buttons
      point := Puzzle15.ButtonPlace(aButton.Caption);
      aButton.Left:= point.x* aButton.Width;    //Distance from left
      aButton.Top := point.y* aButton.Height;
      aButton.OnClick:=@aButtonClick;   //the event handler for the button -> will be created yet
      inc(i);
    end;
  Self.Height:=aButton.Height*6;        //Height of the form should correspond to the height of the buttons
  Self.Width:=aButton.Width*6;       //Width of the form to match the width of all buttons
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FreeAndNil(Puzzle15);
end;

procedure TForm1.aButtonClick(Sender: TObject);  //the event handler for the button
var
  i:integer;
  point : TPoint;
begin
  if (Sender is TButton) and                     //called the event handler of a button out?
     TryStrToInt(TButton(Sender).Caption, i)       //then try to convert the label in a integer
    then
      begin
        if Puzzle15.CanMove(TButton(Sender).Caption) then
          begin
            point := Puzzle15.Change(TButton(Sender).Caption);
            TButton(Sender).Left:= point.x* TButton(Sender).Width;    //Distance from left
            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'
end

unitGameBoard.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] := '-';
  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.

Voir aussi