Гра “Збери картинку” – аналог гри “15”, але, на відміну від останньої, на фішках намальовані не цифри, а фрагменти картинки. Завдання гравця – розташувати фішки в правильному порядку. Гра закінчується, коли картинка буде зібрана Програма завантажує картинку з файлу формату BMP, ім’я якого вказано в командному рядку запуску програми, або з файлу, який знаходиться в каталозі програми. Якщо в каталозі програми кілька файлів із розширенням bmp, то буде завантажено перший за порядком файл. Під час повторної активізації гри в результаті вибору в рядку меню команди Нова гра завантажується наступний файл із розширенням bmp.

Код написання програми
#include "math.h"
#include Math.hpp
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
#define W 4
#define H 4
int wc, hc; // розмір клітинки
byte pole[H][W]; // ігрове поле
byte ex,ey; // координати порожньої клітинки
bool GameOver;
AnsiString fn; // ім'я bmp-файлу (картинка)
TSearchRec SearchRec; // результат пошуку файлу
Graphics::TBitmap *pic = new Graphics::TBitmap();
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
pic = new Graphics::TBitmap();
}
void __fastcall TForm1::FormShow(TObject *Sender)
{
NewGame();
}
void __fastcall TForm1::NewGame()
{
static int Tag = 0;
// завантажити файл ілюстрації
if (( ParamCount() == 0 ) && (Tag == 0 )) Tag = 1;
switch ( Tag )
{
case 0 : // ім'я файлу - з командного рядка
fn = ParamStr(1);
Tag = 1;
break;
case 1: // вибрати перший за порядком bmp-файл
{
FindFirst("*.bmp",faAnyFile,SearchRec);
fn = SearchRec.Name;
Tag = 2;
}
break;
case 2: // вибрати наступний bmp-файл
{
if ( FindNext(SearchRec) != 0)
FindFirst("*.bmp",faAnyFile,SearchRec);
fn = SearchRec.Name;
}
break;
}
// завантажити ілюстрацію
try {
pic->LoadFromFile(fn);
}
catch (EFOpenError &e)
{
MessageDlg("Помилка доступу до файлу ілюстрації",
mtWarning, TMsgDlgButtons () << mbOK << mbHelp, 0) ;
return;
}
// визначити розмір клітинки
wc = pic->Width / W;
hc = pic->Height / H;
// встановити розмір форми
ClientWidth = wc * W;
ClientHeight = hc * H;
// вихідне (правильне) положення фішок
int k = 1;
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
pole[i][j] = k++;
GameOver = false;
Mixer(); // перемішати фішки
ShowPole(); // відобразити ігрове поле
}
void __fastcall TForm1::Mixer()
{
int x1,y1;
int x2,y2;
int d;
Randomize();
x1 = 3; y1 = 3; // див. опис масиву stp
for ( int i = 0; i < 150; i++) // кількість перестановок
{
do {
x2 = x1;
y2 = y1;
// виберемо фішку, що примикає до порожньої клітинки,
// яку перемістимо в порожню клітину
d = RandomRange(1,5);
switch ( d ) {
case 1: x2--; break;
case 2: x2++; break;
case 3: y2--; break;
case 4: y2++; break;
}
}
while ((x2 < 0) || (x2 >= W) ||
(y2 < 0) || (y2 >= H)) ;
/* тут визначили фішку, яку
треба перемістити в порожню клітинку */
pole[y1][x1] = pole[y2][x2];
pole[y2][x2] = 16;
x1 = x2;
y1 = y2;
};
// запам'ятаємо координати порожньої клітинки
ex = x1;
ey = y1;
}
void __fastcall TForm1::ShowPole()
{
TRect src, dst; // фрагмент картинки і область її
// її відображення на поверхні форми
int sx,sy;
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
{
// Перетворюємо номер фрагмента картинки в
// координати лівого
/ верхнього кута області-джерела
sx = ((pole[i][j]- 1) % W) * wc;
sy = ((pole[i][j]- 1) / H) * hc;
src = Bounds(sx,sy,wc,hc);
dst = Bounds(j*wc,i*hc,wc,hc);
if (( pole[i][j] != 16 ) || GameOver )
// фрагмент картинки
Canvas->CopyRect(dst,pic->Canvas,src);
else
{
// порожня клітинка
Canvas->Brush->Style = bsSolid;
Canvas->Brush->Color = clBtnFace;
Canvas->Rectangle(dst);
}
}
if (N4->Checked)
{
// вивести номер фішки
Canvas->Brush->Style = bsClear;
for (int i = 0; i < H; i++)
for (int j = 0; j < W; j++)
Canvas->TextOutA(wc*j,hc*i, IntToStr(pole[i][j]));
}
}
void __fastcall TForm1::FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y)
{
int cx,cy; // координати клітини
cx = X / wc;
cy = Y / hc;
Move (cx,cy); // перемістити обрану клітину в сусідню
// вільну
}
bool Finish();
void __fastcall TForm1::Move(int cx, int cy)
{
if ( ( abs(cx - ex) == 1 && cy-ey == 0 ) ||
( abs(cy - ey) == 1 && cx-ex == 0 ))
{
// перемістити фішку з (сх,су) в (ех,еу)
pole[ey][ex] = pole[cy][cx];
pole[cy][cx] = 16;
ex = cx;
ey = cy;
// відмалювати поле
ShowPole();
if ( Finish () )
{
GameOver = true;
ShowPole();
int r = MessageDlg ("Мета досягнута! "
"Ще раз (інша картинка)?",
mtInformation,
TMsgDlgButtons() << mbYes << mbNo, 0);
if ( r == mrNo )
Form1->Close(); // завершити роботу програми
else
{
NewGame();
ShowPole();
}
}
}
}
bool Finish()
{
bool result;
int row, col;
int k = 1;
result = true; // нехай фішки в потрібному порядку
for (row = 0; row < H; row++)
{
if ( pole[row][col] == k )
k++;
else {
result = false;
break;
}
if ( ! result ) break;
}
return (result);
void __fastcall TForm1::FormPaint(TObject *Sender)
{
ShowPole();
}
void __fastcall TForm1::N1Click(TObject *Sender)
{
NewGame();
}
void __fastcall TForm1::N4Click(TObject *Sender)
{
N4->Checked = !N4->Checked;
ShowPole() ;
}
Файл .h:
public: // User declarations
void __fastcall TForm1::NewGame();
void __fastcall TForm1::Mixer();
void __fastcall TForm1::ShowPole();
void __fastcall TForm1::Move(int cx, int cy);
__fastcall TForm1(TComponent* Owner);
програмування