popovIliya

Sample FlipFlop game

Feb 20th, 2021
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 10.15 KB | None | 0 0
  1. { Author Iliya Popov date create 09.12.2020 }
  2. unit GameFlipFlop;
  3.  
  4. interface
  5.  
  6. uses
  7.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  8.   System.Classes, Vcl.Graphics,
  9.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.StdCtrls;
  10.  
  11. type
  12.   TFlipFlopFrm = class(TForm)
  13.     DgMatrix: TDrawGrid;
  14.     sbtTesting: TButton;
  15.     sbtCreateList: TButton;
  16.     ListPositions: TListBox;
  17.     SaveMovementDlg: TSaveDialog;
  18.     SaveBtn: TButton;
  19.     sbtPerehod: TButton;
  20.     procedure DgMatrixDrawCell(Sender: TObject; ACol, ARow: Integer;
  21.       Rect: TRect; State: TGridDrawState);
  22.     procedure DgMatrixMouseDown(Sender: TObject; Button: TMouseButton;
  23.       Shift: TShiftState; X, Y: Integer);
  24.     procedure FormCreate(Sender: TObject);
  25.     procedure FormPaint(Sender: TObject);
  26.     procedure sbtTestingClick(Sender: TObject);
  27.     procedure sbtCreateListClick(Sender: TObject);
  28.     procedure SaveBtnClick(Sender: TObject);
  29.     procedure sbtPerehodClick(Sender: TObject);
  30.  
  31.   private
  32.     procedure loadGridSettings;
  33.     procedure ShowPole(w: word);
  34.     procedure Solution0(w0, w1: word; nStep: Integer);
  35.     procedure Solution(w0, w1: word; nStep: Integer);
  36.   public
  37.     { Public declarations }
  38.   end;
  39.  
  40. var
  41.   FlipFlopFrm: TFlipFlopFrm;
  42.  
  43. const
  44.  
  45.   matrixCol = 4;
  46.   matrixRol = 4;
  47.  
  48.   AllCells = matrixCol * matrixRol - 1;
  49.  
  50.  
  51. type
  52.   TStatus = Record
  53.     Range: Integer;
  54.  
  55.     Hod: TPoint;
  56.     Pred: word;
  57.   end;
  58.  
  59. var
  60.   // масив на полето(Матрица)
  61.   masPole: array [0 .. matrixCol - 1, 0 .. matrixRol - 1] of byte;
  62.   Status: array [word] of TStatus;
  63.  
  64.   AllPos: cardinal;
  65.  
  66. implementation
  67.  
  68. {$R *.dfm}
  69. { TFlipFlopFrm }
  70.  
  71. procedure TFlipFlopFrm.DgMatrixDrawCell(Sender: TObject; ACol, ARow: Integer;
  72.   Rect: TRect; State: TGridDrawState);
  73. var
  74.   i, j, n: Integer;
  75. begin
  76.  
  77.   case masPole[ACol, ARow] of
  78.     0:
  79.       self.DgMatrix.Canvas.Brush.Color := clWhite;
  80.   else
  81.     self.DgMatrix.Canvas.Brush.Color := clRed;
  82.   end;
  83.   self.DgMatrix.Canvas.FillRect(Rect);
  84.   // нечетен ред
  85.   n := 0;
  86.   for j := 0 to matrixRol - 1 do
  87.     for i := 0 to matrixCol - 1 do
  88.       if (i = ACol) or (j = ARow) then
  89.       begin
  90.         n := n + masPole[i, j];
  91.       end;
  92.   if odd(n) then
  93.     with Rect, self.DgMatrix.Canvas do
  94.       textrect(Rect, left + (right - left - textwidth('+')) div 2,
  95.         top + (bottom - top - textheight('+')) div 2, '+');
  96. end;
  97.  
  98. procedure TFlipFlopFrm.DgMatrixMouseDown(Sender: TObject; Button: TMouseButton;
  99.   Shift: TShiftState; X, Y: Integer);
  100. var
  101.   ACol, ARow: Integer;
  102.   i, j: Integer;
  103. begin
  104.  
  105.   self.DgMatrix.MouseToCell(X, Y, ACol, ARow);
  106.   if ssRight in Shift then
  107.     if masPole[ACol, ARow] = 1 then
  108.       masPole[ACol, ARow] := 0
  109.     else
  110.       masPole[ACol, ARow] := 1
  111.   else if ssLeft in Shift then
  112.  
  113.   begin
  114.     for j := 0 to matrixRol - 1 do
  115.       for i := 0 to matrixCol - 1 do
  116.         if (i = ACol) or (j = ARow) then
  117.          
  118.           masPole[i, j] := abs(masPole[i, j] - 1)
  119.   end;
  120.   self.DgMatrix.Invalidate;
  121. end;
  122.  
  123. procedure TFlipFlopFrm.FormCreate(Sender: TObject);
  124. var
  125.   i, j: Integer;
  126. begin
  127.   for j := 0 to matrixRol - 1 do
  128.     for i := 0 to matrixCol - 1 do
  129.      
  130.       masPole[i, j] := 0;
  131. end;
  132.  
  133. procedure TFlipFlopFrm.FormPaint(Sender: TObject);
  134. begin
  135.   loadGridSettings;
  136. end;
  137.  
  138. procedure TFlipFlopFrm.loadGridSettings;
  139. begin
  140.   //
  141.   self.DgMatrix.ColCount := matrixCol;
  142.   self.DgMatrix.RowCount := matrixRol;
  143.   self.DgMatrix.DefaultDrawing := False;
  144.   self.DgMatrix.FixedCols := 0;
  145.   self.DgMatrix.FixedRows := 0;
  146. end;
  147.  
  148. procedure TFlipFlopFrm.SaveBtnClick(Sender: TObject);
  149. var
  150.   F: textfile;
  151.   fn, s: string;
  152.   i, j: Integer;
  153.   w: word;
  154. begin
  155.  
  156.   SaveMovementDlg.DefaultExt := 'txt';
  157.  
  158.   SaveMovementDlg.Filter := 'Данни (*.txt)|*.TXT';
  159.  
  160.   SaveMovementDlg.FilterIndex := 1;
  161.   s := extractfilepath(application.exename) + 'res\';
  162.  
  163.   SaveMovementDlg.InitialDir := s;
  164.   SaveMovementDlg.Title := 'Записване на данните върху диска!';
  165.   SaveMovementDlg.filename := 'temp.txt';
  166.   if not SaveMovementDlg.Execute then
  167.     exit;
  168.   fn := SaveMovementDlg.filename;
  169.   assignfile(F, fn);
  170.   rewrite(F);
  171.  
  172.   for i := 0 to 65535 do
  173.   begin
  174.     s := '';
  175.     w := i;
  176.     for j := 0 to 15 do
  177.     begin
  178.    
  179.       if j mod 4 = 0 then
  180.         s := s + ' ';
  181.       if w and $8000 <> 0 then
  182.         s := s + '1'
  183.       else
  184.         s := s + '0';
  185.       w := w shl 1;
  186.     end;
  187.     s := inttostr(i) + '/' + s + '. Range= ' + inttostr(Status[i].Range) +
  188.       ' Ход= ' + inttostr(Status[i].Hod.X) + ' ' + inttostr(Status[i].Hod.Y) +
  189.       ' Pred= ' + inttostr(Status[i].Pred);
  190.     if Status[i].Range <> -1 then
  191.       writeln(F, s);
  192.   end;
  193.  
  194.   closefile(F);
  195.  
  196.   messagebeep(0)
  197.  
  198. end;
  199.  
  200.  
  201. procedure TFlipFlopFrm.ShowPole(w: word);
  202.  
  203. var
  204.   i, j: Integer;
  205. begin
  206.  
  207.   for j := 0 to matrixRol - 1 do
  208.     for i := 0 to matrixCol - 1 do
  209.     begin
  210.       if w and $8000 <> 0 then // клетка на фигурата
  211.         masPole[i, j] := 1
  212.       else
  213.         masPole[i, j] := 0; // фон на клетката
  214.       w := w shl 1;
  215.     end;
  216.  
  217.   self.DgMatrix.Invalidate;
  218. end;
  219.  
  220.  
  221. function XorBits(X, Y: byte; w: word): word;
  222. var
  223.   i, j: Integer;
  224. begin
  225.   Result := w;
  226.   for j := 0 to matrixRol - 1 do
  227.     for i := 0 to matrixCol - 1 do
  228.       if (i = X) or (j = Y) then
  229.       begin
  230.         masPole[i, j] := abs(masPole[i, j] - 1);
  231.         Result := Result xor (1 shl (AllCells - matrixCol * j - i));
  232.       end;
  233. end;
  234.  
  235. procedure TFlipFlopFrm.sbtCreateListClick(Sender: TObject);
  236. var
  237.   Hod: Integer;
  238.   flg: boolean;
  239.   i, j, k, w: word;
  240. begin
  241.   Hod := 0;
  242.   for i := 0 to 65535 do
  243.     Status[i].Range := -1;
  244.   Status[0].Range := 0;
  245.   AllPos := 1;
  246.   repeat
  247.     flg := False;
  248.     inc(Hod);
  249.     self.ListPositions.Items.add(inttostr(Hod));
  250.     for k := 0 to 65535 do
  251.       if Status[k].Range = Hod - 1 then
  252.       begin
  253.         for j := 0 to matrixRol - 1 do
  254.           for i := 0 to matrixCol - 1 do
  255.           begin
  256.             w := XorBits(i, j, k);
  257.             if Status[w].Range = -1 then
  258.             begin
  259.               flg := True;
  260.               Status[w].Range := Hod;
  261.               Status[w].Hod.X := i;
  262.               Status[w].Hod.Y := j;
  263.               Status[w].Pred := k;
  264.               inc(AllPos);
  265.             end;
  266.           end;
  267.       end;
  268.   until flg = False;
  269.   Showmessage('hod= ' + inttostr(Hod));
  270.   Showmessage('AllPos= ' + inttostr(AllPos));
  271. end;
  272.  
  273. procedure TFlipFlopFrm.sbtPerehodClick(Sender: TObject);
  274. begin
  275.   Solution(63897, 112, 5);
  276. end;
  277.  
  278. procedure TFlipFlopFrm.Solution0(w0, w1: word; nStep: Integer);
  279. label
  280.   nextHod, nextCell;
  281. var
  282.   Hod: Integer;
  283.   nCells: Integer;
  284.   nCell: array [0 .. 99] of Integer;
  285.   Pos: array [0 .. 99] of word;
  286.   Move: array [0 .. 99] of Integer;
  287.   X, Y: byte;
  288.   w: word;
  289.   variant: Integer;
  290.  
  291.   procedure SavePos;
  292.   var
  293.     w: word;
  294.     i, j: Integer;
  295.     X, Y: Integer;
  296.     s: string;
  297.   begin
  298.     for i := 1 to Hod do
  299.     begin
  300.       s := '';
  301.       w := Pos[i];
  302.       for j := 0 to 15 do
  303.       begin
  304.         if w and $8000 <> 0 then
  305.           s := s + '1'
  306.         else
  307.           s := s + '0';
  308.         w := w shl 1;
  309.       end;
  310.       self.ListPositions.Items.add('Hod= ' + inttostr(i) + ' Pos= ' + s);
  311.       X := Move[i] mod 4;
  312.       Y := Move[i] div 4;
  313.       self.ListPositions.Items.add('Move= ' + inttostr(X) + ' ' + inttostr(Y));
  314.     end;
  315.   end;
  316.  
  317. begin
  318.   variant := 0;
  319.   nCells := 16;
  320.   Hod := 0;
  321.   Pos[0] := w0;
  322.   Move[0] := -1;
  323. nextHod:
  324.   inc(Hod);
  325.   nCell[Hod] := -1;
  326.   Pos[Hod] := Pos[Hod - 1];
  327. nextCell:
  328.   inc(nCell[Hod]);
  329.   if nCell[Hod] > nCells then
  330.   begin
  331.     dec(Hod);
  332.     if Hod < 0 then
  333.     begin
  334.       Showmessage('OK');
  335.       exit;
  336.     end;
  337.     Goto nextCell
  338.   end;
  339.   if nCell[Hod] <> Move[Hod - 1] then
  340.   begin
  341.     X := nCell[Hod] mod 4;
  342.     Y := nCell[Hod] div 4;
  343.     w := XorBits(X, Y, Pos[Hod - 1]);
  344.     Pos[Hod] := w;
  345.     Move[Hod] := nCell[Hod];
  346.     if w = w1 then
  347.     begin // намерен!
  348.       inc(variant);
  349.       self.ListPositions.Items.add('намерени варианти= ' + inttostr(variant));
  350.       self.ListPositions.Items.add('Hod= ' + inttostr(Hod) + ' x= ' +
  351.         inttostr(X) + ' y= ' + inttostr(Y) + ' Pos[Hod]= ' +
  352.         inttostr(Pos[Hod]));
  353.       SavePos;
  354.     end;
  355.   end;
  356.  
  357.   if Hod < nStep then
  358.     goto nextHod;
  359.   goto nextCell
  360. end;
  361.  
  362. procedure TFlipFlopFrm.Solution(w0, w1: word; nStep: Integer);
  363. label
  364.   nextHod, nextCell;
  365. var
  366.   Hod: Integer;
  367.   nCells: Integer;
  368.   nCell: array [0 .. 99] of Integer;
  369.   Pos: array [0 .. 99] of word;
  370.   Move: array [0 .. 99] of Integer;
  371.   X, Y: byte;
  372.   w: word;
  373.  
  374.   procedure SavePos;
  375.   var
  376.     w: word;
  377.     i, j: Integer;
  378.     X, Y: Integer;
  379.     s: string;
  380.   begin
  381.     for i := 1 to Hod do
  382.     begin
  383.       s := '';
  384.       w := Pos[i];
  385.       for j := 0 to 15 do
  386.       begin
  387.         if w and $8000 <> 0 then
  388.           s := s + '1'
  389.         else
  390.           s := s + '0';
  391.         w := w shl 1;
  392.       end;
  393.       self.ListPositions.Items.add('Hod= ' + inttostr(i) + ' Pos= ' + s);
  394.       X := Move[i] mod 4;
  395.       Y := Move[i] div 4;
  396.       self.ListPositions.Items.add('Move= ' + inttostr(X) + ' ' + inttostr(Y));
  397.       self.ListPositions.Items.add('');
  398.     end;
  399.   end;
  400.  
  401. begin
  402.   nCells := 16;
  403.   Hod := 0;
  404.   Pos[0] := w0;
  405.   nCell[0] := -1;
  406.   Move[0] := -1;
  407. nextHod:
  408.   inc(Hod);
  409.   nCell[Hod] := nCell[Hod - 1];
  410.   Pos[Hod] := Pos[Hod - 1];
  411. nextCell:
  412.   inc(nCell[Hod]);
  413.   if nCell[Hod] > nCells then
  414.   begin
  415.     dec(Hod);
  416.     if Hod < 0 then
  417.     begin
  418.       Showmessage('OK');
  419.       exit;
  420.     end;
  421.     Goto nextCell
  422.   end;
  423.   X := nCell[Hod] mod 4;
  424.   Y := nCell[Hod] div 4;
  425.   w := XorBits(X, Y, Pos[Hod - 1]);
  426.   Pos[Hod] := w;
  427.   Move[Hod] := nCell[Hod];
  428.   if w = w1 then
  429.   begin
  430.     SavePos;
  431.     ShowPole(w);
  432.     exit;
  433.   end;
  434.   if Hod < nStep then
  435.     goto nextHod;
  436.   goto nextCell
  437. end;
  438.  
  439. procedure TFlipFlopFrm.sbtTestingClick(Sender: TObject);
  440. var
  441.   i, j: Integer;
  442.   w: word;
  443. begin
  444.   for j := 0 to matrixRol - 1 do
  445.     for i := 0 to matrixCol - 1 do
  446.     begin
  447.       w := XorBits(i, j, 0);
  448.       ShowPole(w);
  449.       Showmessage(inttostr(w));
  450.     end;
  451. end;
  452.  
  453. end.
Advertisement
Add Comment
Please, Sign In to add comment