- •1 Постановка задачі
- •2 Алгоритм розробки програми
- •3 Практична реалізація
- •3.1 Опис структури даних та вимоги до них
- •3.2 Опис стандартних функцій, що використовувалися у програмі
- •3.3 Опис функційкористувача
- •3.4 Опис модулів та їх призначення
- •4 Інструкції для роботи з програмою
- •5 Приклади тестування та результати роботи програми
- •Висновки
- •Література
- •Додаток а
- •Додаток б Лістинг модуляPiece
- •Додаток в Лістинг модуля Unit1
- •Додаток г Лістинг модуля Unit2
5 Приклади тестування та результати роботи програми
Рис.1Старотове вікно прогорами.
Рис.2 Початок нової гри.
Рис.3 Процес гри.
Рис.4 Завершення гри.
Висновки
Під час розробки курсового проекту язакріпив, поглибив та узагальнив знання, якими оволодів під час вивчення курсу, в набутті навичок використання основ алгоритмізації та програмування на алгоритмічних мовах високого рівня з використанням принципів об’єктно-орієнтованого проектування та програмування в середовищі «BorlandC++ Builder». Я застосував навички, набуті протягом навчання длястворення програми, для роботи з різними функціями. Ця програма дозволяєкористувачуграти в «Тетріс». Та під час гри користувач заробляєте очки та його рівень зростає.
Підвівши підсумки я зрозумів, що «BorlandC++ Builder» є гнучкою та алгоритмічною мовою програмування, і добре підходить як для початківця так і для досвідченого програміста. Широкий набір функцій та модульність дозволяє швидко та якісно створювати програмний продукт. Знання основ алгоритмізації та програмування з використанням принципів об’єктно-орієнтованого проектування ПЗ різних задач на ЕОМ необхідно для подальшого використання у розробці програмного забезпечення сучасних складних технічних систем та комп’ютерних систем управління.
Література
-
Архангельский А.Я. Программирование в C++ Builder, 7 изд.,Бином,2010. — 1304 с.
-
Бобровский С. Самоучитель программирования на C++ в системе C++ Builder. ДЕСС, 2003. — 810 с.
-
Культин Н.Б. Самоучитель C++ Builder., Высшая школа,2006. — 380 с.
-
Архангельский А.Я. C++ Builder 6 справочное пособие, 2005. — 635 с.
-
Алексанкин Т.А. BorlandC++, 2003— 540 с.
-
Ермолаев В., Сорока Т. C++ BuilderКнига рецептов, 2003. — 560 с.
-
Культин Н.Б. C++ Builderв задачах и примерах, 2000. — 400 с.
-
Бобровский С. Технологии C++ Builder.,2005. — 490 с.
-
Парта С. Язык программирования C++ Лекции и упражениния, 1999. – 630 с.
Додаток а
#include <vcl.h>
#pragma hdrstop
#include "Main.h"
#include "Piece.h"
#include "Unit1.h"
#include "Unit2.h"
#pragma package(smart_init)
#pragma resource "*.dfm"
const int MaxTiles = 320;
tPiece *Piece = NULL;
tPiece *nPiece = NULL;
TPanel *BoardTile[MaxTiles];
int BoardColHeight[MaxTiles * 16];
int BoardWidth;
int TimeLevel = 1000;
int Score = 0;
int DropHeight = 0;
int SkillLevel = 1;
int PieceCount = 0;
int SkillPcs[] = { 15, 30, 45, 60, 75, 90, 105, 120, 135, 150 };
int SkillSpd[] = { 1000, 900, 800, 700, 600, 500, 400, 300, 200, 100 };
int xNextPiece = 0;
int vubor = 0;
int Piecetype = 10;
bool debug = false;
TColor BaseColor;
TfrmMain *frmMain;
__fastcall TfrmMain::TfrmMain(TComponent* Owner) : TForm(Owner) {
randomize();
if(debug) BaseColor = clGray;
else BaseColor = clBlack;
BoardWidth = (Board->Width / 25);
for(int x = 0; x < MaxTiles; x++) {
BoardTile[x] = new TPanel(this);
BoardTile[x]->Height = 25;
BoardTile[x]->Width = 25;
Board->InsertControl(BoardTile[x]);
div_t N = div(x, BoardWidth);
BoardTile[x]->Left = N.rem * 25;
BoardTile[x]->Top = N.quot * 25;
if(debug) BoardTile[x]->Caption = x;
ShowTile(x, BaseColor, debug);
}}
void __fastcall TfrmMain::FormCreate(TObject *Sender) {
FeatureTestButton->Hide();
//Form1->Hide();
{
Panel1->Canvas->Brush->Color=clBlue;
Panel1->Canvas->Brush->Style=bsCross;
Panel1->Canvas->RoundRect(25,25,225,225,15,15);
}
return;}
void __fastcall TfrmMain::RemoveRow(int Row) {
// test->Caption = "Removed Row " + AnsiString(Row) + " ";
// for(int x = 0; x < BoardWidth; x++) ShowTile(Row + x, BaseColor, false);
int Start = Row + BoardWidth - 1;
int End = BoardWidth;
for(int x = Start; x > End; --x) {
int Target = x;
int Source = x - BoardWidth;
ShowTile(Target, BoardTile[Source]->Color, BoardTile[Source]->Color != BaseColor);
}
return;
}
void __fastcall TfrmMain::StickPiece(void) {
int ScoreAdd = SkillLevel * Piece->Blocks;
PieceTimer->Enabled = false;
int Corner = (Piece->Left / 25) + (BoardWidth * (Piece->Top / 25));
for(int x = 0; x < Piece->Blocks; x++) {
if(Piece->Divs[x]->Color == BaseColor) continue;
div_t N = div(x, (Piece->Width / 25));
int Tile = Corner + N.rem + (N.quot * BoardWidth);
ShowTile(Tile, Piece->Divs[x]->Color, true);
}
// Check for lines
int RowCount = 0;
for(int x = 0; x < (MaxTiles / BoardWidth); x++) {
int Row = x * BoardWidth;
bool RowDone = true;
for(int y = 0; y < BoardWidth; y++) if(BoardTile[Row + y]->Color == BaseColor) RowDone = false;
if(RowDone) {
RemoveRow(Row); RowCount++;
ScoreAdd = ScoreAdd + (BoardWidth * RowCount * SkillLevel);
}
// test->Caption = "Added " + AnsiString(ScoreAdd) + " ";
}
// Check for End Game
if(Piece->Top < 0) {
PieceTimer->Enabled = false;
sndPlaySound("EndGame.wav", SND_ASYNC | SND_FILENAME);
int result = Application->MessageBox("Играть еще ?", "Игра окончена!", MB_YESNO);
if(result == 6) btnStartClick(this);
return;
}
// Check Level
if(++PieceCount > SkillPcs[SkillLevel - 1]) {;
TimeLevel = SkillSpd[SkillLevel++];
test->Caption = "Level " + AnsiString(SkillLevel);
Beep();
}
// Calculate Score
Score = Score + ScoreAdd + DropHeight;
pScore->Caption = AnsiString(Score);
int NextPiece;
do {
NextPiece = (rand() % Piecetype) + 1;
} while (Piece->Kind == NextPiece);
NewPiece(NextPiece);
return;
}bool __fastcall TfrmMain::OnBottom(void) {
if((Piece->Top + 25) > Board->Height - Piece->Height) return(true); // Board Bottom
return(Collision(0));
}
bool __fastcall TfrmMain::Collision(int direction) {
// Direction: 0 = bottom, 1 = Left, 2 = Right, 3 = Rotation
int FirstBlock = ((Piece->Top / 25) * BoardWidth) + (Piece->Left / 25);
switch(direction) {
case 0: FirstBlock += BoardWidth; break;
case 1: FirstBlock--; break;
case 2: FirstBlock++; break;
case 3: FirstBlock = FirstBlock;
}
int Px = Piece->Height / 25;
int Py = Piece->Width / 25;
int Tile;
for(int x = 0; x < Px; x++) for(int y = 0; y < Py; y++) {
Tile = FirstBlock + (x * BoardWidth) + y;
if(Tile < 0) continue;
if(BoardTile[Tile]->Color == BaseColor) continue;
if(Piece->Divs[x * Py + y]->Color == BaseColor) continue;
return(true);
}
return(false);
}
void __fastcall TfrmMain::sbRotateClick(TObject *Sender) {
if(!Piece) return;
sndPlaySound("Rotate.wav", SND_ASYNC | SND_FILENAME);
PieceTimer->Interval = TimeLevel;
Piece->Rotate(0);
if(Collision(3)) { Piece->Rotate(0); Piece->Rotate(0); Piece->Rotate(0); }
if(Piece->Left < 0) Piece->Left = 0;
if(Piece->Left + Piece->Width > Board->Width) Piece->Left = Board->Width - Piece->Width;
return;
}
void __fastcall TfrmMain::btnStartClick(TObject *Sender) {
for(int x = 0; x < MaxTiles; x++) ShowTile(x, clGray, debug);
Score = 0;
pScore->Caption = Score;
PieceCount = 0;
SkillLevel = 1;
TimeLevel = SkillSpd[SkillLevel - 1];
test->Caption = "Level " + AnsiString(SkillLevel);
NewPiece((rand() % Piecetype) + 1);
return;
}
void __fastcall TfrmMain::ShowTile(int x, TColor TileColor, bool Seen) {
if(x < 0) return;
if(Seen) {
BoardTile[x]->Color = TileColor;
BoardTile[x]->BevelInner = bvRaised;
BoardTile[x]->BevelOuter = bvLowered;
BoardTile[x]->BringToFront();
return;
}
BoardTile[x]->Color = BaseColor;
BoardTile[x]->BevelInner = bvNone;
BoardTile[x]->BevelOuter = bvNone;
BoardTile[x]->SendToBack();
return;}void __fastcall TfrmMain::NewPiece(int Type) {
if(xNextPiece == 0) {
Piece = new tPiece(this, Type, BaseColor);
nPiece = new tPiece(this, Type, BaseColor);
xNextPiece = (rand() % Piecetype) + 1;
}delete(Piece);
delete(nPiece);
Piece = new tPiece(this, xNextPiece, BaseColor);
nPiece = new tPiece(this, Type, BaseColor);
xNextPiece = Type;
DropHeight = 0;
PieceTimer->Enabled = true;
PieceTimer->Interval = TimeLevel;
Board->InsertControl(Piece);
Piece->Left = (Board->Width - Piece->Width) / 2;
Piece->Left -= (Piece->Left % 25);
Piece->Top -= Piece->Height;
pNextPiece->InsertControl(nPiece);
nPiece->Left = (pNextPiece->Width - nPiece->Width) / 2;
nPiece->Top = (pNextPiece->Height - nPiece->Height) / 2;;
int count = 0;
for(int x = 0; x < MaxTiles; x++) {
bool show = (BoardTile[x]->Color != BaseColor);
if(show) { BoardTile[x]->BringToFront(); count = 0; }
if(count > BoardWidth) break;
//BoardTile[x]->SendToBack();
}return;
}void __fastcall TfrmMain::FormClose(TObject *Sender, TCloseAction &Action) {
if(Piece != NULL) delete(Piece);
void __fastcall TfrmMain::btnPauseClick(TObject *Sender) {
if(!Piece) return;
PieceTimer->Enabled = !PieceTimer->Enabled;
if(PieceTimer->Enabled) {
btnPause->Caption = "Pause";
sbRotate->Enabled = true;
sbLeft->Enabled = true;
sbRight->Enabled = true;
sbDrop->Enabled = true;
return;
}btnPause->Caption = "Continue";
sbRotate->Enabled = false;
sbLeft->Enabled = false;
sbRight->Enabled = false;
sbDrop->Enabled = false;return;
}void __fastcall TfrmMain::sbLeftClick(TObject *Sender) {
if(!Piece) return;
DropHeight = 0;
PieceTimer->Interval = TimeLevel;
if(Piece->Left > 0)
if(!Collision(1)) Piece->Left-=25;
return;
}void __fastcall TfrmMain::sbRightClick(TObject *Sender) {
if(!Piece) return;
DropHeight = 0;
PieceTimer->Interval = TimeLevel;
if(Piece->Left < Board->Width - Piece->Width)
if(!Collision(2)) Piece->Left+=25;
return;
}void __fastcall TfrmMain::sbDropClick(TObject *Sender) {
if(!Piece) return;
sndPlaySound("Drop.wav", SND_ASYNC | SND_FILENAME);
DropHeight = (Board->Height - Piece->Top) / 25;
PieceTimer->Interval = 25;
return;
}void __fastcall TfrmMain::Time(TObject *Sender) {
// sndPlaySound("Tick.wav", SND_ASYNC | SND_FILENAME); // Annoying !!!!!
// Determine if piece is on the Bottom
if(OnBottom()) {StickPiece();
return;
} // Lower the piece 1 square or 25 Pixels
Piece->Top+=25;
return;
}void __fastcall TfrmMain::FeatureTestButtonClick(TObject *Sender) {
sndPlaySound("Rotate.wav", SND_ASYNC | SND_FILENAME);
// play(BaseFolder + "\\Rotate.wav")
// AnsiString BaseFolder = ExtractFilePath(Application->ExeName);
// mPlay->FileName = BaseFolder + "\\Rotate.wav"; //specify video file
// mPlay->DeviceType = dtWaveAudio;
// mPlay->Open();
// mPlay->Play();
return;
}void __fastcall TfrmMain::FormKeyUp(TObject *Sender, WORD &Key,
TShiftState Shift)
{if (vubor==0) { sbLeft->Enabled=false; btnPause->Enabled=false;
btnStart->Enabled=false; BitBtn1->Enabled=false;
sbRight->Enabled=false; sbDrop->Enabled=false;
sbRotate->Enabled=false; }
if (Key==VK_LEFT) sbLeftClick(this);
if (Key=='P') btnPauseClick(this);
if (Key=='S') btnStartClick(this);
if (Key==VK_ESCAPE) Close();
if (Key==VK_RIGHT) sbRightClick(this);
if (Key==VK_DOWN) sbDropClick(this);
if (Key==VK_UP) sbRotateClick(this);
if (vubor==1){
sbLeft->Enabled=true; btnPause->Enabled=true;
btnStart->Enabled=true; BitBtn1->Enabled=true;
sbRight->Enabled=true; sbDrop->Enabled=true;
sbRotate->Enabled=true;
}}
void __fastcall TfrmMain::N3Click(TObject *Sender)
{frmMain->Close();
}void __fastcall TfrmMain::N2Click(TObject *Sender)
{Form1->Visible=true;
}void __fastcall TfrmMain::N4Click(TObject *Sender)
{AboutBox->Show();
}void __fastcall TfrmMain::N5Click(TObject *Sender)
{
for(int x = 0; x < MaxTiles; x++) ShowTile(x, clGray, debug);
Score = 0;
pScore->Caption = Score;
PieceCount = 0;
SkillLevel = 1;
TimeLevel = SkillSpd[SkillLevel - 1];
test->Caption = "Level " + AnsiString(SkillLevel);
NewPiece((rand() % Piecetype) + 1);
return;
}
void __fastcall TfrmMain::N6Click(TObject *Sender)
{
frmMain->Close();
}