Фрагмент для ознакомления
FormMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);vari,j,k,currP:integer;r,r1:trect;begin If (ssLeft in Shift) = false thenbeginifstep>2 thenbeginmpanel.Height:=97; mpanel.Visible:=false;end;exit;end;//Еслибыл Attachifstep=5 thenbeginpx:=px+ix;py:=py+iy;step:=4;end;ifstep<>4 then exit;GetRgnBox(arrReg[PointXY(pnum).x,PointXY(pnum).y],r);//Чтобы пазлы не выходили за рамки окнаi:=round(r.width*outBorder/100);j:=round(r.height*outBorder/100);ifx-px+i<0 then x:=px-i;ify-py+j<=0 then y:=py-j;ifx-px+r.width-i>clientwidth then x:=clientwidth-r.width+px+i;ify-py+r.height-j>clientheight then y:=clientheight-r.height+py+j;//ДвигаемпазлсперерисовкойbeginarrPuzzle[pnum,0]:=x-px;arrPuzzle[pnum,1]:=y-py;sscr.Canvas.FillRect(rect(0,0,sscr.Width,sscr.Height));sscr.canvas.Draw(0,0,scr); sscr.canvas.Draw(arrPuzzle[pnum,0],arrPuzzle[pnum,1],arrImg[PointXY(pnum).x,PointXY(pnum).y]);canvas.Draw(0,0,sscr);end;//Ищем совместимые детали пазла по набору текущихпазлов в группеk:=2;whilearrPuzzle[pnum,k]<>0 dobegincurrP:=arrPuzzle[pnum,k];//Проверяем возможных соседей справаif currP mod cntX <> 0 thenbegini:=inarray(currP+1);ifi<>pnum thenbeginGetRgnBox(arrReg[PointXY(i).x,PointXY(i).y],r1);if(abs(arrPuzzle[pnum,0]-r.Left-arrPuzzle[i,0]+r1.Left)<=AccPuzzle)and(ABS(arrPuzzle[pnum,1]-r.Top-arrPuzzle[i,1]+r1.Top)<=AccPuzzle) thenbeginattach(pnum,i); ProgressBar1.Position:=ProgressBar1.Position+round(1/(cntX*cntY)*100);break;end;end;end;//Проверяем возможных соседей слеваifcurrP mod cntX <> 1 thenbegini:=inarray(currP-1);ifi<>pnum thenbeginGetRgnBox(arrReg[PointXY(i).x,PointXY(i).y],r1);if(abs(arrPuzzle[pnum,0]-r.Left-arrPuzzle[i,0]+r1.Left)<=AccPuzzle)and(ABS(arrPuzzle[pnum,1]-r.Top-arrPuzzle[i,1]+r1.Top)<=AccPuzzle) thenbeginattach(pnum,i); ProgressBar1.Position:=ProgressBar1.Position+round(1/(cntX*cntY)*100);break;end;end;end;//Проверяем возможных соседей сверхуifcurrP>cntX thenbegini:=inarray(currP-cntX);ifi<>pnum thenbeginGetRgnBox(arrReg[PointXY(i).x,PointXY(i).y],r1);if(abs(arrPuzzle[pnum,0]-r.Left-arrPuzzle[i,0]+r1.Left)<=AccPuzzle)and(ABS(arrPuzzle[pnum,1]-r.Top-arrPuzzle[i,1]+r1.Top)<=AccPuzzle) thenbeginattach(pnum,i); ProgressBar1.Position:=ProgressBar1.Position+round(1/(cntX*cntY)*100);break;end;end;end;//Проверяем возможных соседей снизуifcurrP<=cntX*cntY-cntX thenbegini:=inarray(currP+cntX);ifi<>pnum thenbeginGetRgnBox(arrReg[PointXY(i).x,PointXY(i).y],r1);if(abs(arrPuzzle[pnum,0]-r.Left-arrPuzzle[i,0]+r1.Left)<=AccPuzzle)and(ABS(arrPuzzle[pnum,1]-r.Top-arrPuzzle[i,1]+r1.Top)<=AccPuzzle) thenbeginattach(pnum,i); ProgressBar1.Position:=ProgressBar1.Position+round(1/(cntX*cntY)*100);break;end;end;end;inc(k);end;end;//Основная процедура присоединения пазлов друг к другуprocedureTfrmMain.attach(x,y:integer);vari,j,i1,j1:integer;b:tbitmap;r:trect;nameWinner, FileName:string;f:TextFile;begin//СтыкуемточноarrPuzzle[y,0]:=arrPuzzle[x,0]-round(ind[PointXY(x).x-1,PointXY(x).y-1].x)+round(ind[PointXY(y).x-1,PointXY(y).y-1].x); arrPuzzle[y,1]:=arrPuzzle[x,1]-round(ind[PointXY(x).x-1,PointXY(x).y-1].y)+round(ind[PointXY(y).x-1,PointXY(y).y-1].y);//ЩелчокifchBoxSound.Checked then sndPlaySound(PChar(pD1), snd_ASync or snd_Memory);//Объединяем группыi1:=arrPuzzle[x,2];j1:=arrPuzzle[y,2];GetRgnBox(arrReg[PointXY(i1).X,PointXY(i1).y],r);ix:=r.Left;iy:=r.Top;i:=3;whilearrPuzzle[x,i]<>0 do inc(i);j:=2;whilearrPuzzle[y,j]<>0 dobeginarrPuzzle[x,i]:=arrPuzzle[y,j];arrPuzzle[y,j]:=0;inc(i);inc(j);end;//Делаем новую картинку пазлаb:=tbitmap.Create;b.Width:=currX;b.Height:=currY; b.Canvas.Brush.Color:=clwhite; b.PixelFormat:=pf24bit;b.TransparentColor := clWhite; b.Transparent:=true;b.Canvas.FillRect(rect(0,0,currX,currY)); b.Canvas.Brush.Bitmap:=origImage1.Picture.Bitmap; CombineRgn(arrReg[PointXY(i1).X,PointXY(i1).y],arrReg[PointXY(i1).X,PointXY(i1).y],arrReg[PointXY(j1).X,PointXY(j1).y],RGN_OR); PaintRgn (b.Canvas.Handle,arrReg[PointXY(i1).x,PointXY(i1).y]);GetRgnBox(arrReg[PointXY(i1).x,PointXY(i1).y],r);arrImg[PointXY(x).X,PointXY(x).Y].Width:=r.Width;arrImg[PointXY(x).X,PointXY(x).Y].height:=r.height;arrImg[PointXY(x).X,PointXY(x).Y].canvas.FillRect(rect(0,0,r.Width,r.height));arrImg[PointXY(x).X,PointXY(x).Y].canvas.Draw(-r.Left,-r.Top,b);ifr.Lefty) and(i<>x) and (arrPuzzle[i,2]<>0) thenscr.canvas.Draw(arrPuzzle[i,0],arrPuzzle[i,1],arrImg[PointXY(I).X,PointXY(I).Y]);end;//Завершение игры, если пазл собран полностьюifarrPuzzle[x,cntX*cntY+1]<>0 thenbeginProgressBar1.Position:=100;ifchBoxSound.Checked then SndPlaySound(PChar(pD2), snd_ASync or snd_Memory); Timer1.Enabled:=false; // выключаемтаймерShowMessage('Поздравляем! Пазлсобранполностью!');repeat //вводим имя победителяnameWinner := InputBox('Игра "Пазл"', 'Пожалуйста, укажите своё имя', '');untilnameWinner <> ''; FileName:='Winner.txt';AssignFile(f,FileName);//записываем в файл имя и время игрыif not FileExists(FileName) thenbeginRewrite(f);CloseFile(f);end;Append(f);Writeln(f,NameWinner);Writeln(f,Format('%2.2d:%2.2d',[_timeGame div 60,_timeGame mod 60]));CloseFile(f);end;end;procedureTfrmMain.FormMouseUp(Sender: TObject; Button: TMouseButton;//ОбработкаотпусканийкнопкимышиShift: TShiftState; X, Y: Integer);beginifstep=4 thenbeginstep:=3; scr.canvas.Draw(arrPuzzle[pnum,0],arrPuzzle[pnum,1],arrImg[PointXY(pnum).x,PointXY(pnum).y]);end;end;procedureTfrmMain.FormPaint(Sender: TObject);beginifstep=3 then canvas.Draw(0,0,scr)end;procedureTfrmMain.FormResize(Sender: TObject);vari,k:integer;begincasestep of0:exit;1,2:beginorigImage.Left:=round((clientwidth-20)/2-origImage.Width/2); origImage.top:=round((clientheight+mPanel.Height)/2-origImage.height/2); origImage1.Top:=origImage.Top; origImage1.Left:=origImage.Left; origImageMini.top:=0;end;3:beginorigImageMini.top:=0; origImageMini.Visible:=true; origImage1.Align:=alclient; //раскидываетнавсёокноscr.Width:=clientwidth; scr.Height:=clientheight+0; sscr.Width:=clientwidth; sscr.Height:=clientheight;fork:=1 to ost dobegini:=ptab[k];if arrPuzzle[i,2]<>0 then scr.canvas.Draw(arrPuzzle[i,0],arrPuzzle[i,1],arrImg[PointXY(i).x,PointXY(i).y]);end;canvas.Draw(0,0,scr);end;end;end;//показывает панель с кнопками, если мышка заезжает вверх в полосу высотой 30procedureTfrmMain.WMNCMOUSEMOVE(var msg: tmessage);beginif(mpanel.Visible=false)and(mouse.CursorPos.Y-frmMain.top<=40) then mpanel.Visible:=true;end;procedureTfrmMain.origImageMiniMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginorigImage1.Visible:=true;end;procedureTfrmMain.origImageMiniMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);beginorigImage1.Visible:=false;end;procedureTfrmMain.ostPaint;vari,j:integer;beginscr.Canvas.FillRect(rect(0,0,scr.width,scr.Height));forj:=1 to ost dobegini:=ptab[j];if arrPuzzle[i,2]<>0 then scr.canvas.Draw(arrPuzzle[i,0],arrPuzzle[i,1],arrImg[PointXY(i).x,PointXY(i).y]);end;Canvas.Draw(0,0,scr);end;//СохранениеигрыprocedureTfrmMain.SaveGame;varlen,i,j:integer;n:string;size:cardinal;data: pointer;beginifsPuzzleDialog.Execute thenbeginn:=ChangeFileExt(ExtractFileName(sPuzzleDialog.Filename),'');AssignFile(F, extractfilepath(sPuzzleDialog.FileName)+n+'.pzl');Rewrite(F,1);hist:= TBytesStream.Create;//Сохраняемпеременныеfori := 0 to 7 doBlockWrite(F, per[i]^, SizeOf(per[i]^));//Сохраняем ptab, arrPuzzle, imfori := 1 to ost dobeginBlockWrite(F, ptab[i], SizeOf(ptab[i]));forj := 0 to cntX*cntY+1 doBlockWrite(F, arrPuzzle[ptab[i],j], SizeOf(arrPuzzle[ptab[i],j]));arrImg[PointXY(ptab[i]).X,PointXY(ptab[i]).Y].SaveToStream(hist);len:=Length(hist.Bytes);BlockWrite(F, Len, SizeOf(Len));BlockWrite(F, hist.Bytes[0], Len); hist.Clear;end;//сохраняемрегионыfori := 1 to cntX doforj := 1 to cntY dobeginsize := GetRegionData (arrReg[i,j], SizeOf (RGNDATA), nil);data := GlobalAllocPtr(GPTR, size);GetRegionData(arrReg[i,j], size, data);hist.Write(data^,size);GlobalFreePtr(data);BlockWrite(F, size, SizeOf(size));BlockWrite(F, hist.Bytes[0], size);hist.Clear;end;// Сохраняем мини-изображениеorigImageMini.Picture.Bitmap.SaveToStream(hist);len:=Length(hist.Bytes);BlockWrite(F, Len, SizeOf(Len));BlockWrite(F, hist.Bytes[0], Len); hist.Clear;//СохраняемподсказкуorigImage1.Picture.Bitmap.SaveToStream(hist);len:=Length(hist.Bytes);BlockWrite(F, Len, SizeOf(Len));BlockWrite(F, hist.Bytes[0], Len);//Сохраняеммассивыind, gaCurr, vaCurrforj:= 0 to cntY dofori:= 0 to cntX dobeginBlockWrite(F, ind[i,j].x, SizeOf(ind[i,j].x));BlockWrite(F, ind[i,j].y, SizeOf(ind[i,j].y));BlockWrite(F, gaCurr[i,j], SizeOf(gaCurr[i,j]));BlockWrite(F, vaCurr[i,j], SizeOf(vaCurr[i,j]));end; hist.Free;CloseFile(F);end;end;procedureTfrmMain.Timer1Timer(Sender: TObject);beginbegin//Считаем время, прошедшее с начала игрыinc(_timeGame); frmMain.Caption:='Игра "Пазлы" | '+'Времяигры: '+Format('%2.2d:%2.2d',[_timeGame div 60,_timeGame mod 60]);end;end;//ЗагрузкаигрыprocedureTfrmMain.LoadGame;varlen,i,j:integer;size:cardinal;data: PRgnData;beginAssignFile(F, oImgDialog.FileName);reset (f,1);hist:= TBytesStream.Create;//Загружаемпеременныеfori := 0 to 7 doBlockRead(F, per[i]^, SizeOf(per[i]^));setlength(arrImg,cntX+1,cntY+1);setlength(ptab,cntX*cntY+1);setlength(arrPuzzle,cntX*cntY+1,cntX*cntY+3);//Загружаем ptab, arrPuzzle, imfori := 1 to ost dobeginBlockread(F, ptab[i], SizeOf(ptab[i]));forj := 0 to cntX*cntY+1 doBlockread(F, arrPuzzle[ptab[i],j], SizeOf(arrPuzzle[ptab[i],j]));Blockread(F, Len, SizeOf(Len));hist.SetSize(len);Blockread(F,hist.Bytes[0],Len);arrImg[PointXY(ptab[i]).X,PointXY(ptab[i]).Y]:=tbitmap.Create;arrImg[PointXY(ptab[i]).X,PointXY(ptab[i]).Y].PixelFormat:=pf24bit;arrImg[PointXY(ptab[i]).X,PointXY(ptab[i]).Y].TransparentColor:= clWhite;arrImg[PointXY(ptab[i]).X,PointXY(ptab[i]).Y].Transparent:=true;arrImg[PointXY(ptab[i]).X,PointXY(ptab[i]).Y].LoadFromStream(hist); hist.Clear;end;//Загружаемрегионыsetlength(arrReg,cntX+1,cntY+1);fori := 1 to cntX doforj := 1 to cntY dobegindeleteobject(arrReg[i,j]);Blockread(F, size, SizeOf(size));hist.SetSize(size);Blockread(F,hist.Bytes[0],size);data:= GlobalAllocPtr(GPTR,hist.size);hist.Read(data^, hist.Size);arrReg[i,j]:=ExtCreateRegion(nil, hist.Size, data^);GlobalFreePtr(data); hist.Clear;end;//Загружаеммини-изображениеBlockread(F, Len, SizeOf(Len));hist.SetSize(len);Blockread(F,hist.Bytes[0],Len); origImageMini.Visible:=true;origImageMini.Picture.Bitmap.LoadFromStream(hist); hist.Clear;//ЗагружаемподсказкуBlockread(F, Len, SizeOf(Len));hist.SetSize(len);Blockread(F,hist.Bytes[0],Len); origImage1.Visible:=false;origImage1.Picture.Bitmap.LoadFromStream(hist); origImage1.Align:=alclient; origImage1.Center:=true; origImage1.Proportional:=true;//Загружаеммассивыind, gaCurr, vaCurrSetLength (ind,cntX+1,cntY+1);setlength(gaCurr,cntX+1,cntY+1);setlength(vaCurr,cntX+1,cntY+1);forj:= 0 to cntY dofori:= 0 to cntX dobeginBlockread(F, ind[i,j].x, SizeOf(ind[i,j].x));Blockread(F, ind[i,j].y, SizeOf(ind[i,j].y));Blockread(F, gaCurr[i,j], SizeOf(gaCurr[i,j]));Blockread(F, vaCurr[i,j], SizeOf(vaCurr[i,j]));end; hist.Free;CloseFile(F); frmMain.Resize; bBtnPuzzleLineShow.Enabled:=false;bBtnSlice.Enabled:=false;end;//Функция вертикальных траекторийfunctionTfrmMain.vertical(x1,x2,x3,x4:real):tgpgraphicspath;varPoints: array [0..10] of TGPPointF;k,n,k1,k2:real;dex,dey,dx,dy:real;beginpCurr:=0;result:=tgpgraphicspath.Create();if(x1=0) or (x1=currX) thenresult.AddLine(x1,x2,x3,x4) elsebegin//Строим первые две опорных точки по угловым точкамpoints[0].X:=x1; points[0].y:=x2;points[10].X:=x3; points[10].y:=x4;ifpoints[0].X<>points[10].x thenbegink:= (points[0].y-points[10].y)/(points[0].X-points[10].x); //Угловойкоэффициентпрямойn:=-1/k; //Угловой коэффициент нормалиend else begink:=0;n:=0;end; dex:=points[10].X-points[0].X;//Истинная середина прямой, тогда как dexx - минимальная абсолютная, без учета искаженийdey:=points[10].y-points[0].y;//Строим две опорных точки перед шейкой, они плавающие и не зависят от абсолютной dexxk1:=(1-2*round(random));dx:=k1*dey*defHead/100;dy:=dx*n;points[1].X:=points[0].X+dex*0.2+dx;points[1].y:=points[0].y+dey*0.2+dy;points[9].X:=points[0].X+dex*0.8+dx;points[9].y:=points[0].y+dey*0.8+dy;//Строим опорные точки шейкиdy:=dexx*0.08;points[2].y:=points[0].y+dey*0.5-dy;points[8].y:=points[0].y+dey*0.5+dy;ifk<>0 then dx:=-dy/k else dx:=0;points[2].X:=points[0].X+dex*0.5+dx;ifk<>0 then dx:=dy/k else dx:=0;points[8].X:=points[0].X+dex*0.5+dx;//Строим удаленную точку головкиk1:=-k1;dx:=k1*dexx/3.6;dy:=dx*n;points[5].X:=points[0].X+dex*0.5+dx;points[5].y:=points[0].y+dey*0.5+dy;//Строим четыре опорных точки головкиk2:=dexx*0.12;dx:=k1*dexx/4.5;dy:=dx*n-k2;ifk<>0 then dx:=dx+dy/k;points[4].X:=points[0].X+dex*0.5+dx;points[4].y:=points[0].y+dey*0.5+dy;dx:=k1*dexx/4.5;dy:=dx*n+k2;ifk<>0 then dx:=dx+dy/k;points[6].X:=points[0].X+dex*0.5+dx;points[6].y:=points[0].y+dey*0.5+dy; k2:=dexx*0.14;dx:=k1*dexx/10;dy:=dx*n-k2;ifk<>0 then dx:=dx+dy/k;points[3].X:=points[0].X+dex*0.5+dx;points[3].y:=points[0].y+dey*0.5+dy;dx:=k1*dexx/10;dy:=dx*n+k2;ifk<>0 then dx:=dx+dy/k;points[7].X:=points[0].X+dex*0.5+dx;points[7].y:=points[0].y+dey*0.5+dy;result.AddCurve(PGPPointF(@Points),11,e9/100);pCurr:=round(k1);end;end;//ФункциягоризонтальныхтраекторийfunctionTfrmMain.gorizontal(x1,x2,x3,x4:real):tgpgraphicspath;varPoints: array [0..10] of TGPPointF;k,n,k1,k2:real;dex,dey,dx,dy:real;beginpCurr:=0;result:=tgpgraphicspath.Create();if(x2=0) or (x2=currY) thenresult.AddLine(x1,x2,x3,x4) elsebegin//Строим первые две опорных точки по угловым точкамpoints[0].X:=x1; points[0].y:=x2;points[10].X:=x3; points[10].y:=x4;ifpoints[0].y<>points[10].y thenbegink:= (points[0].x-points[10].x)/(points[0].y-points[10].y); //Угловойкоэффициентпрямойn:=-1/k; //Угловой коэффициент нормалиend else begink:=0;n:=0;end; dex:=points[10].X-points[0].X;//Истинная середина прямой, тогда как dexx - минимальная абсолютная, без учета искаженийdey:=points[10].y-points[0].y;//Строим две опорных точки перед шейкой, они плавающие и не зависят от абсолютной dexxk1:=(1-2*round(random));dy:=k1*dex*defHead/100;dx:=dy*n;points[1].X:=points[0].X+dex*0.2+dx;points[1].y:=points[0].y+dey*0.2+dy;points[9].X:=points[0].X+dex*0.8+dx;points[9].y:=points[0].y+dey*0.8+dy;//Строим опорные точки шейкиdx:=dexx*0.08;points[2].x:=points[0].x+dex*0.5-dx;points[8].x:=points[0].x+dex*0.5+dx;ifk<>0 then dy:=-dx/k else dy:=0;points[2].y:=points[0].y+dey*0.5+dy;ifk<>0 then dy:=dx/k else dy:=0;points[8].y:=points[0].y+dey*0.5+dy;//Строим удаленную точку головкиk1:=-k1;dy:=k1*dexx/3.6;dx:=dy*n;points[5].y:=points[0].y+dey*0.5+dy;points[5].x:=points[0].x+dex*0.5+dx;//Строим четыре опорных точки головкиk2:=dexx*0.12;dy:=k1*dexx/4.5;dx:=dy*n-k2;ifk<>0 then dy:=dy+dx/k;points[4].y:=points[0].y+dey*0.5+dy;points[4].x:=points[0].x+dex*0.5+dx;dy:=k1*dexx/4.5;dx:=dy*n+k2;ifk<>0 then dy:=dy+dx/k;points[6].y:=points[0].y+dey*0.5+dy;points[6].x:=points[0].x+dex*0.5+dx; k2:=dexx*0.14;dy:=k1*dexx/10;dx:=dy*n-k2;ifk<>0 then dy:=dy+dx/k;points[3].y:=points[0].y+dey*0.5+dy;points[3].x:=points[0].x+dex*0.5+dx;dy:=k1*dexx/10;dx:=dy*n+k2;ifk<>0 then dy:=dy+dx/k;points[7].y:=points[0].y+dey*0.5+dy;points[7].x:=points[0].x+dex*0.5+dx;result.AddCurve(PGPPointF(@Points),11,e9/100);pCurr:=round(k1);end;end;//Перевод координат из под мышки в номер пазлаfunctionTfrmMain.PointXY(x:integer):TPoint;vari:integer;begini:=ceil(x/cntX); PointXY.Y:=i; PointXY.X:=x-(i-1)*cntX;end;//Поиск пазла на наличие конкретного текаfunctionTfrmMain.inarray(x:integer):integer;vari,j:integer;beginfori := 1 to ost dobeginj:=2;whilearrPuzzle[ptab[i],j]<>0 dobeginifarrPuzzle[ptab[i],j]=x thenbegininarray:=ptab[i]; exit;end;inc(j);end;end;end;end.unitOutWinnerUnit;interfaceusesWinapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons;typeTOutWinnerFrm = class(TForm) OutWinnerMemo: TMemo; BitBtn1: TBitBtn;procedureBitBtn1Click(Sender: TObject);procedureFormActivate(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varOutWinnerFrm: TOutWinnerFrm;implementation{$R *.dfm}procedureTOutWinnerFrm.BitBtn1Click(Sender: TObject);beginOutWinnerFrm.Close;end;procedureTOutWinnerFrm.FormActivate(Sender: TObject);var f:TextFile; FileName, timeGame, Name:String;cnt,i:integer;begini:=1; OutWinnerMemo.Lines.Clear; FileName:='Winner.txt';AssignFile(f,FileName);if not FileExists(FileName) thenbeginShowMessage('Статистика отсутствует!');endelsebeginReset(f);while not Seekeof(f) dobeginReadln(f,Name);Readln(f,timeGame);OutWinnerMemo.Lines.Add(inttostr(i)+'. '+ Name +', время: '+timeGame);inc(i);end;end;CloseFile(f);end;end.ПРИЛОЖЕНИЕ B. Алгоритм программыБлок-схема общего алгоритма.Блок-схема загрузки новой картинки в игруБлок-схема рисования сетки пазловБлок-схема алгоритма выбора пазла левой кнопкой мышиБлок-схема сохранения игрыБлок-схема алгоритма загрузки сохраненной игрыБлок-схема алгоритма разрезания изображения на деталиБлок-схема перерисовки окнаБлок-схема алгоритма перемещения деталиБлок-схема алгоритма присоединения
1.Архангельский, А.Я. Программирование в Delphi: Учебник по классическим версиям Delphi /А.Я. Архангельский. – М.: Бином-Пресс, 2013. – 816 c.
2.Белов, В.В. Программирование в Delphi: процедурное, объектно-ориентированное, визуальное: Учебное пособие для вузов / В.В. Белов, В.И. Чистякова. – М.: РиС, 2014. – 240 c.
3.Клейменова Е.М. АНАЛИЗ СОВРЕМЕННЫХ ЯЗЫКОВ ПРОГРАММИРОВАНИЯ // Материалы VIII Международной студенческой электронной научной конференции «Студенческий научный форум» – [Электронный ресурс] – Режим доступа: http://www.scienceforum.ru/2016/1508/20094 (дата обращения: 09.12.2023).
4.Коржинский С. Изучаем Delphi. Практическое пособие для изучения программирования в среде Borland Delphi. [Электронный ресурс] URL: http://www.snkey.net/support/books/delphi10.pdf
5.Осипов Д. Л. Delphi. Программирование для Windows, OS X, iOS и Android. – СПб.: БХВ-Петербург, 2014. – 464 с.
6.Осипов, Д. Delphi. Профессиональное программирование / Д. Осипов. – СПб.: Символ-плюс, 2015. – 1056 c.
7. Петрова, И.А. Объектно-ориентированное программирование: лабораторный практикум для студентов направления 09.03.01 (230100.62) «Информатика и вычислительная техника» очной и заочной форм обучения / И.А. Петрова. – Красноярск: СибГТУ, 2015. – 123с. Текст: непосредственный.
8.Разработка игры Пазлы на С++ для Android – [Электронный ресурс] – Режим доступа: https://pro-prof.com/archives/5795 (дата обращения: 09.12.2023)
9.Семухин С. О. Сравнительный анализ языков программирования // Научно-методический электронный журнал «Концепт». – 2015. – Т. 35. – С. 166–170. – [Электронный ресурс] – Режим доступа: http://e-koncept.ru/2015/95588.htm (дата обращения: 09.12.2023)
10.GDI+ – графическое ядро нового поколения . Часть 2. Работа с примитивами и изображениями. – [Электронный ресурс] – Режим доступа: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=781 (дата обращения: 09.12.2023).
11.Фленов М. Е. Библия Delphi. – 3-е изд., перераб. и доп. – СПб.: БХВ-Петербург, 2011. – 688 с.
12. Фролов Александр, Фролов Григорий. Графический интерфейс GDI в Microsoft Windows. Работа с контекстом отображения. Области – [Электронный ресурс] – Режим доступа: https://frolov-lib.ru/books/bsp/v14/ch2_5.htm (дата обращения: 09.12.2023).