Тетрис - исправить ошибки Undefined reference - C (СИ)
Формулировка задачи:
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<iostream.h>
#include<graphics.h>
#include<dos.h>
#include<time.h>
#include<string.h>
#include<windows.h>
#define EMPTY 0
#define STATIC 2
#define DYNAMIC 1
#define RIGHT 77
#define DOWN 80
#define LEFT 75
#define ENTER 32
#define ENTER1 13
#define UP 72
#define ESC 27
typedef struct
{
int **mpt;
int size_i;
int size_j;
int vert;
/*Matr();
~Matr();
friend void ReadStdFile(Matr*,int);
friend void Vert(Matr&);
friend Matr** Preobr(Matr*,int);*/
}Matr;
typedef struct
{
int x,y;
int type;
int pol;
}Figure;
typedef struct
{
Matr **p;
int **ar_old;
int **color_ar_old;
int **ar;
int **color_ar;
int size_i;
int size_j;
int unsigned lines;
unsigned long score;
unsigned long record;
unsigned long lastres;
Figure a;
int level;
/*Glass(){};
Glass(Matr**);
~Glass();
int Fall();
int Move(int);
int Rotate();
int Do(int);
void Draw(void**);
int Create(int,int,int,int,int);
void Destr();
void CopyMas();
void LeftPanel();
void Score(int);*/
}Glass;
void gotoxy(int xpos, int ypos);
void CreateGlass(Glass *it,Matr** p);
void DeleteGlass(Glass *it);
int CreateGlass(Glass *it);
void DestrGlass(Glass *it);
int Do(Glass *it,int type);
int Fall(Glass *it);
int Move(Glass *it,int key);
void Draw(Glass *it,void **sd);
void InitMatr(Matr *it);
void DeleteMatr(Matr *it);
void ReadStdFile(Matr *p,int N);
void** PreobrGraph(int N);
void Vert(Matr &p);
Matr** Preobr(Matr *p,int N);
void CopyMas(Glass *it);
void LeftPanel(Glass *it);
void DrawFut(int *type,void **gp,Matr *p);
void Score(Glass *it,int d);
void Menu(char *str1);
void gotoxy(int xpos, int ypos)
{
COORD scrn;
HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
scrn.X = xpos; scrn.Y = ypos;
SetConsoleCursorPosition(hOuput,scrn);
}
void CreateGlass(Glass *it, Matr** p_)
{
int i;
FILE *f=fopen("Tetris.rec","r");
if (f)
{
fscanf(f,"%li\n",&(it->record));
fscanf(f,"%li\n",&(it->lastres));
fclose(f);
}
it->p=p_;
it->size_i=20;
it->size_j=10;
it->lines=0;
it->level=1;
it->score=0;
it->ar=(int**)malloc(sizeof(int*)*it->size_i);
for (int i=0;i<it->size_i;i++)
{
it->ar[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->ar[i][j]=EMPTY;
}
it->ar_old=(int**)malloc(sizeof(int*)*it->size_i);
for (i=0;i<it->size_i;i++)
{
it->ar_old[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->ar_old[i][j]=STATIC;
}
it->color_ar=(int**)malloc(sizeof(int*)*it->size_i);
for (i=0;i<it->size_i;i++)
{
it->color_ar[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->color_ar[i][j]=EMPTY;
}
it->color_ar_old=(int**)malloc(sizeof(int*)*it->size_i);
for (i=0;i<it->size_i;i++)
{
it->color_ar[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->color_ar_old[i][j]=EMPTY;
}
};
void DeleteGlass(Glass *it)
{
for (int i=0;i<it->size_i;i++)
{
free(it->ar[i]);
free(it->color_ar[i]);
free(it->ar_old[i]);
free(it->color_ar_old[i]);
}
free(it->ar);
free(it->color_ar);
free(it->ar_old);
free(it->color_ar_old);
}
int CreateGlass(Glass *it,int x_,int y_,int type_,int pol_,int d)
{
int flag=1;
for (int i=0;i<it->p[type_][pol_].size_i;i++)
for (int j=0;j<it->p[type_][pol_].size_j;j++)
{
if ((y_+j<0 || y_+j>=it->size_j) || ((it->p[type_][pol_].mpt[i][j]==1 && it->ar[x_+i][y_+j]==2) && (d==LEFT || d==RIGHT || d==0 || d==ENTER)))
flag=2;
if ((it->p[type_][pol_].mpt[i][j]==1 && it->ar[x_+i][y_+j]==2 && d==DOWN) || x_+i==it->size_i)
flag=0;
}
if (flag==2 && d==0)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]==1)
{
it->ar[i][j]=STATIC;
it->color_ar[i][j]=it->a.type;
}
}
return 0;
}
if (flag==1)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]==1)
{
it->ar[i][j]=EMPTY;
it->color_ar[i][j]=type_;
}
}
for (int i=0;i<it->p[type_][pol_].size_i;i++)
for (int j=0;j<it->p[type_][pol_].size_j;j++)
if (it->ar[x_+i][y_+j]!=2)
if (it->p[type_][pol_].mpt[i][j]==1)
{
it->ar[x_+i][y_+j]=1;
it->color_ar[x_+i][y_+j]=type_;
}
it->a.x=x_;
it->a.y=y_;
it->a.type=type_;
it->a.pol=pol_;
}
else if (flag==0)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]==1)
{
it->ar[i][j]=STATIC;
it->color_ar[i][j]=it->a.type;
}
}
DestrGlass(it);
}
else if (flag==2) return 0;
return flag;
}
void DestrGlass(Glass *it)
{
int flag;
for (int i=it->size_i-1;i>=0;i--)
{
flag=1;
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]!=STATIC)
{
flag=0;
}
}
if (flag)
{
for (int i_=i;i_>0;i_--)
{
for (int j_=0;j_<it->size_j;j_++)
{
it->ar[i_][j_]=it->ar[i_-1][j_];
it->color_ar[i_][j_]=it->color_ar[i_-1][j_];
}
}
for (int j_=0;j_<it->size_j;j_++)
{
it->ar[0][j_]=0;
it->color_ar[0][j_]=0;
}
it->lines++;
Score(it,100);
LeftPanel(it);
if (1+it->lines/10>it->level)
{
gotoxy(1,3);
it->level=1+it->lines/10;
}
DestrGlass(it);
}
}
}
int Do(Glass *it,int type)
{
if (!CreateGlass(it,0,(it->size_j-it->p[type][0].size_j)/2,type,0,0)) return 0;
else return 1;
}
int Fall(Glass *it)
{
if (!CreateGlass(it,it->a.x+1,it->a.y,it->a.type,it->a.pol,DOWN)) return 0;
else return 1;
}
int Move(Glass *it,int key)
{
switch(key)
{
case RIGHT:
{
if (!CreateGlass(it,it->a.x,it->a.y+1,it->a.type,it->a.pol,RIGHT)) return 0;
else return 1;
}
case LEFT:
{
if (!CreateGlass(it,it->a.x,it->a.y-1,it->a.type,it->a.pol,LEFT)) return 0;
else return 1;
}
case DOWN:
{
Score(it,1);
if (!CreateGlass(it,it->a.x+1,it->a.y,it->a.type,it->a.pol,DOWN)) return 0;
else return 1;
}
case ENTER:
{
if (!CreateGlass(it,it->a.x,it->a.y,it->a.type,(it->a.pol+1)%it->p[it->a.type][0].vert,ENTER)) return 0;
else return 1;
}
}
}
void Draw(Glass *it,void **sd)
{
int pos_x=(getmaxx()-it->size_j*20)/2,pos_y=(getmaxy()-it->size_i*20)/2;
setcolor(WHITE);
rectangle(pos_x,pos_y,pos_x+it->size_j*20+1,pos_y+it->size_i*20+1);
for(int i=0;i<it->size_i;i++)
{
for (int j=0;j<it->size_j;j++)
{
if(it->ar_old[i][j]!=it->ar[i][j] || it->color_ar_old[i][j]!=it->color_ar[i][j])
{
switch(it->ar[i][j])
{
case STATIC:
{
setfillstyle(SOLID_FILL,DARKGRAY);
putimage(pos_x+j*20+1,pos_y+i*20+1,sd[it->color_ar[i][j]],0);
break;
}
case DYNAMIC:
{
putimage(pos_x+j*20+1,pos_y+i*20+1,sd[it->a.type],0);
break;
}
case EMPTY:
{
setfillstyle(SOLID_FILL,BLACK);
bar(pos_x+j*20+1,pos_y+i*20+1,pos_x+(j+1)*20,pos_y+(i+1)*20);
//setfillstyle(SOLID_FILL,WHITE);
//fillellipse(pos_x+j*20+10,pos_y+i*20+10,1,1);
//bar(pos_x+j*20+1,pos_y+i*20+1,pos_x+(j+1)*20,pos_y+(i+1)*20);
break;
}
}
}
}
}
CopyMas(it);
}
void InitMatr(Matr *it)
{
it->vert=0;
it->size_i=0;
it->size_j=0;
it->mpt=NULL;
}
void DeleteMatr(Matr *it)
{
int i;
for (i=0;i<it->size_i;i++)
{
free(it->mpt[i]);
}
free(it->mpt);
}
void ReadStdFile(Matr *p,int N)
{
FILE *f=NULL;
f=fopen("std.fig","r");
if (f)
{
int i,u,v;
char h[2];
h[1]='\0';
for (i=0;i<N;i++)
{
h[0]=fgetc(f);
p[i].size_i=atoi(h);
h[0]=fgetc(f);
p[i].size_j=atoi(h);
p[i].mpt=new int*[p[i].size_i];
getc(f);
for (u=0;u<p[i].size_i;u++)
{
p[i].mpt[u]=new int[p[i].size_j];
for (v=0;v<p[i].size_j;v++)
{
h[0]=fgetc(f);
p[i].mpt[u][v]=atoi(h);
}
getc(f);
}
}
}
else
{
cout << "\nfile 'std.fig' not found!\n";
getch();
}
fclose(f);
}
void** PreobrGraph(int N)
{
cleardevice();
int mas[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned int size=imagesize(1,1,20,20);
void **sd=(void **)malloc(7*sizeof(void*));
for (int i=0;i<N;i++)
{
sd[i]=malloc(size);
/*setfillstyle(SOLID_FILL,mas[i]);
bar(1,1,20,20);*/
setfillstyle(SOLID_FILL,BLACK);
bar(1,1,20,20);
setcolor(WHITE);
line(1,4,1,16);
line(20,4,20,16);
line(4,1,16,1);
line(4,20,16,20);
line(1,4,4,1);
line(1,16,4,20);
line(16,1,20,4);
line(16,20,20,16);
/*setfillstyle(SOLID_FILL,mas[i]);
floodfill(10,10,WHITE);*/
setfillstyle(SOLID_FILL,mas[i+8]);
bar(4,4,17,17);
setcolor(BLACK);
rectangle(4,4,17,17);
getimage(1,1,20,20,sd[i]);
}
return sd;
}
void Vert(Matr &p)
{
int flag=0;
for (int i=0;i<p.size_i;i++)
{
for (int j=0;j<p.size_j;j++)
{
if (p.mpt[i][j]!=p.mpt[p.size_i-i-1][p.size_j-j-1]) flag=1;
}
}
if (flag) p.vert=4;
else if (p.size_i==p.size_j) p.vert=1;
else p.vert=2;
}
Matr** Preobr(Matr *p,int N)
{
Matr **p1=(Matr**)malloc(sizeof(Matr*)*N);
for (int i=0;i<N;i++)
{
Vert(p[i]);
p1[i]=(Matr*)malloc(sizeof(Matr)*p[i].vert);
for (int j=0;j<p[i].vert;j++)
{
if (j%2!=0)
{
p1[i][j].size_i=p[i].size_j;
p1[i][j].size_j=p[i].size_i;
}
else
{
p1[i][j].size_i=p[i].size_i;
p1[i][j].size_j=p[i].size_j;
}
p1[i][j].vert=p[i].vert;
p1[i][j].mpt=(int**)malloc(sizeof(int*)*p1[i][j].size_i);
for (int k=0;k<p1[i][j].size_i;k++)
{
p1[i][j].mpt[k]=(int*)malloc(sizeof(int)*p1[i][j].size_j);
for (int l=0;l<p1[i][j].size_j;l++)
{
if (j==0)
{
p1[i][j].mpt[k][l]=p[i].mpt[k][l];
}
else if (j==1)
{
p1[i][j].mpt[k][p1[i][j].size_j-l-1]=p[i].mpt[l][k];
}
else if (j==2)
{
p1[i][j].mpt[k][l]=p[i].mpt[p[i].size_i-k-1][p[i].size_j-l-1];
}
else if (j==3)
{
p1[i][j].mpt[k][l]=p[i].mpt[l][p[i].size_i-k];
}
}
}
}
}
return p1;
}
void CopyMas(Glass *it)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
it->ar_old[i][j]=it->ar[i][j];
it->color_ar_old[i][j]=it->color_ar[i][j];
}
}
void LeftPanel(Glass *it)
{
int i;
int x=20,y=40;
char str[]="Score:";
setcolor(WHITE);
settextstyle(0,HORIZ_DIR,4);
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(x,y,str);
char scorestr[7];
itoa(it->score,scorestr,10);
int dif=6-strlen(scorestr);
scorestr[6]='\0';
int len=strlen(scorestr);
for (int i=0;i<len;i++)
{
scorestr[5-i]=scorestr[len-i-1];
}
for (i=0;i<dif;i++)
{
scorestr[i]='0';
}
setfillstyle(SOLID_FILL,BLACK);
bar(x,y+textheight(str)*1.1,x+textwidth(str),y+2*textheight(str)*1.1);
outtextxy(x,y+textheight(str)*1.1,scorestr);
settextstyle(5,HORIZ_DIR,4);
char str2[]="Lines:";
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(x,y+3*textheight(str)*1.1,str2);
char linestr[5];
itoa(it->lines,linestr,10);
bar(x+textwidth(str2),y+3*textheight(str)*1.1,x+textwidth(str2)+50,y+3*textheight(str)*1.1+textheight(linestr));
outtextxy(x+textwidth(str2),y+3*textheight(str)*1.1,linestr);
char str1[]="Level:";
settextjustify(LEFT_TEXT,TOP_TEXT);
char levelstr[5];
outtextxy(x,y+4*textheight(str)*1.1,str1);
itoa(it->level,levelstr,10);
bar(x+textwidth(str1),y+4*textheight(str)*1.1,x+textwidth(str1)+50,y+4*textheight(str)*1.1+textwidth(str1));
outtextxy(x+textwidth(str1),y+4*textheight(str)*1.1,levelstr);
settextstyle(3,HORIZ_DIR,1);
char str3[]="Record:";
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(x,y+3*textheight(str2)*1.1,str3);
char recordstr[10];
sprintf(recordstr,"%li",it->record);
outtextxy(x+textwidth(str3),y+3*textheight(str)*1.1,recordstr);
char str4[]="Last result:";
settextjustify(LEFT_TEXT,TOP_TEXT);
char lastresstr[10];
outtextxy(x,y+4*textheight(str)*1.1,str4);
sprintf(lastresstr,"%li",it->lastres);
outtextxy(x+textwidth(str4),y+4*textheight(str)*1.1,lastresstr);
}
void DrawFut(int *type,void **gp,Matr *p)
{
setfillstyle(SOLID_FILL,BLACK);
int x=500,y=50;
setfillstyle(LTSLASH_FILL,DARKGRAY);
bar(x-10,y-10,x+100+10,y+400+10);
setcolor(WHITE);
rectangle(x,y,x+100,y+400);
settextstyle(TRIPLEX_FONT,VERT_DIR,3);
char str1[]="NEXT";
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(x-3,y+10,str1);
char str2[]="1";
settextstyle(TRIPLEX_FONT,HORIZ_DIR,3);
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(x,y+130,str2);
char str3[]="2";
outtextxy(x,y+230,str3);
char str4[]="3";
outtextxy(x,y+330,str4);
for (int i=0;i<4;i++)
{
if (i==0)
{
setfillstyle(SOLID_FILL,BLACK);
bar(x,y,x+100,y+100);
setcolor(WHITE);
rectangle(x,y,x+100,y+100);
}
for (int j=0;j<p[type[i]].size_i;j++)
for (int k=0;k<p[type[i]].size_j;k++)
{
if (p[type[i]].mpt[j][k]==1)
putimage(x+(100-p[type[i]].size_j*20)/2+20*k,y+i*100+(100-p[type[i]].size_i*20)/2+20*j,gp[type[i]],0);
}
}
}
void Score(Glass *it,int d)
{
it->score+=d;
LeftPanel(it);
}
void Menu(char *str1)
{
int x=20,y=300;
int old_choice=0;
int choice=0;
int ch;
char str2[]="Control";
char str3[]="Exit";
settextjustify(LEFT_TEXT,TOP_TEXT);
settextstyle(7,HORIZ_DIR,3);
setfillstyle(SOLID_FILL,DARKGRAY);
setcolor(WHITE);
outtextxy(x,y,str1);
setcolor(DARKGRAY);
outtextxy(x,y+textheight(str1),str2);
outtextxy(x,y+textheight(str1)+textheight(str2),str3);
while(1)
{
ch=getch();
switch(ch)
{
case DOWN:
{
old_choice=choice;
if (choice==2) choice=0;
else choice++;
break;
}
case UP:
{
old_choice=choice;
if (choice==0) choice=2;
else choice--;
break;
}
case ENTER1:
{
switch(choice)
{
case 0:
{
setfillstyle(SOLID_FILL,BLACK);
bar(x,y,x+180,y+3*textheight(str1));
return;
}
case 1:
{
settextstyle(2,HORIZ_DIR,5);
setcolor(WHITE);
setfillstyle(SOLID_FILL,BLACK);
outtextxy(x+15,y+80,"BACKSPACE - ROTATE");
outtextxy(x+15,y+80+10,"ESC - EXIT");
outtextxy(x+15,y+80+10+10,"ARROWS - MOVE");
getch();
setcolor(DARKGRAY);
settextstyle(7,HORIZ_DIR,3);
bar(x+15,y+80,x+180,y+80+50);
break;
}
case 2:
{
setfillstyle(SOLID_FILL,BLACK);
bar(x,y,x+180,y+3*textheight(str1));
exit(1);
}
}
}
default:
{
continue;
}
}
setcolor(WHITE);
switch(choice)
{
case 0:
{
outtextxy(x,y,str1);
break;
}
case 1:
{
outtextxy(x,y+textheight(str1),str2);
break;
}
case 2:
{
outtextxy(x,y+textheight(str1)+textheight(str2),str3);
break;
}
}
setcolor(DARKGRAY);
switch(old_choice)
{
case 0:
{
outtextxy(x,y,str1);
break;
}
case 1:
{
outtextxy(x,y+textheight(str1),str2);
break;
}
case 2:
{
outtextxy(x,y+textheight(str1)+textheight(str2),str3);
break;
}
}
}
}
main()
{
int i;
cleardevice();
//randomize();
Matr *p=(Matr*)malloc(sizeof(Matr)*7);
for (int i=0;i<7;i++)
InitMatr(&p[i]);
ReadStdFile(p,7);
Matr **p1;
p1=Preobr(p,7);
int gd=0,gmode=0;
initgraph(&gd,&gmode,"");
cleardevice();
void **gp=PreobrGraph(7);
Glass field;
CreateGlass(&field,p1);
clock_t mark;
double step=0.5;
cleardevice();
setfillstyle(XHATCH_FILL,WHITE);
bar(0,0,getmaxx(),20);
bar(0,getmaxy()-20,getmaxx(),getmaxy());
setlinestyle(SOLID_LINE, 0, 2);
setcolor(WHITE);
line(0,20,getmaxx(),20);
line(0,getmaxy()-20,getmaxx(),getmaxy()-20);
setlinestyle(SOLID_LINE, 0, 1);
int esc_flag=0;
int type[4];
for(i=0;i<4;i++)
{
type[i]=rand()%7;
}
LeftPanel(&field);
while(Do(&field,type[0]))
{
for (i=0;i<3;i++)
{
type[i]=type[i+1];
}
type[3]=rand()%7;
DrawFut(type,gp,p);
Draw(&field,gp);
do
{
mark=clock();
Draw(&field,gp);
while((double)(clock()-mark)/CLK_TCK<step/field.level)
{
if(kbhit())
{
int ch=0;
ch=getch();
if(ch==RIGHT || ch==LEFT || ch==DOWN || ch==ENTER)
{
if (Move(&field,ch))
{
Draw(&field,gp);
}
}
else if (ch==UP)
{
Score(&field,10);
while(Fall(&field));
}
else if (ch==ESC)
{
Menu("Resume Game");
esc_flag=1;
break;
}
}
}
//if (esc_flag) break;
}
while(Fall(&field));
//if (esc_flag) break;
}
settextstyle(4,0,5);
setcolor(WHITE);
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(10,360,"Game Over");
if (field.score>field.record)
{
settextstyle(5,0,3);
setcolor(WHITE);
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(20,400,"New record!");
FILE *f=fopen("Tetris.rec","w");
if (f)
{
fprintf(f,"%li\n%li\n",field.score,field.score);
fclose(f);
}
}
else
{
FILE *f=fopen("Tetris.rec","w");
if (f)
{
fprintf(f,"%li\n%li\n",field.record,field.score);
fclose(f);
}
}
int ch;
do
{
ch=getch();
}
while(ch!=ESC);
closegraph();
for (i=0;i<7;i++)
{
free(p1[i]);
DeleteMatr(&p[7]);
}
free(p1);
free(p);
DeleteGlass(&field);
}Решение задачи: «Тетрис - исправить ошибки Undefined reference»
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<graphics.h>
#include<dos.h>
#include<time.h>
#include<string.h>
#include<windows.h>
#define EMPTY 0
#define STATIC 2
#define DYNAMIC 1
#define RIGHT 77
#define DOWN 80
#define LEFT 75
#define ENTER 32
#define ENTER1 13
#define UP 72
#define ESC 27
typedef struct
{
int **mpt;
int size_i;
int size_j;
int vert;
/*Matr();
~Matr();
friend void ReadStdFile(Matr*,int);
friend void Vert(Matr&);
friend Matr** Preobr(Matr*,int);*/
}Matr;
typedef struct
{
int x,y;
int type;
int pol;
}Figure;
typedef struct
{
Matr **p;
int **ar_old;
int **color_ar_old;
int **ar;
int **color_ar;
int size_i;
int size_j;
int unsigned lines;
unsigned long score;
unsigned long record;
unsigned long lastres;
Figure a;
int level;
/*Glass(){};
Glass(Matr**);
~Glass();
int Fall();
int Move(int);
int Rotate();
int Do(int);
void Draw(void**);
int Create(int,int,int,int,int);
void Destr();
void CopyMas();
void LeftPanel();
void Score(int);*/
}Glass;
//void gotoxy(int xpos, int ypos);
void CreateGlass(Glass *it,Matr** p);
void DeleteGlass(Glass *it);
int CreateGlass(Glass *it);
void DestrGlass(Glass *it);
int Do(Glass *it,int type);
int Fall(Glass *it);
int Move(Glass *it,int key);
void Draw(Glass *it,void **sd);
void InitMatr(Matr *it);
void DeleteMatr(Matr *it);
void ReadStdFile(Matr *p,int N);
void** PreobrGraph(int N);
void Vert(Matr &p);
Matr** Preobr(Matr *p,int N);
void CopyMas(Glass *it);
void LeftPanel(Glass *it);
void DrawFut(int *type,void **gp,Matr *p);
void Score(Glass *it,int d);
void Menu(char *str1);
/*void gotoxy(int xpos, int ypos)
{
COORD scrn;
HANDLE hOuput = GetStdHandle(STD_OUTPUT_HANDLE);
scrn.X = xpos; scrn.Y = ypos;
SetConsoleCursorPosition(hOuput,scrn);
}*/
void CreateGlass(Glass *it, Matr** p_)
{
int i;
FILE *f=fopen("Tetris.rec","r");
if (f)
{
fscanf(f,"%li\n",&(it->record));
fscanf(f,"%li\n",&(it->lastres));
fclose(f);
}
it->p=p_;
it->size_i=20;
it->size_j=10;
it->lines=0;
it->level=1;
it->score=0;
it->ar=(int**)malloc(sizeof(int*)*it->size_i);
for (int i=0;i<it->size_i;i++)
{
it->ar[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->ar[i][j]=EMPTY;
}
it->ar_old=(int**)malloc(sizeof(int*)*it->size_i);
for (i=0;i<it->size_i;i++)
{
it->ar_old[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->ar_old[i][j]=STATIC;
}
it->color_ar=(int**)malloc(sizeof(int*)*it->size_i);
for (i=0;i<it->size_i;i++)
{
it->color_ar[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->color_ar[i][j]=EMPTY;
}
it->color_ar_old=(int**)malloc(sizeof(int*)*it->size_i);
for (i=0;i<it->size_i;i++)
{
it->color_ar[i]=(int*)malloc(sizeof(int)*it->size_j);
for (int j=0;j<it->size_j;j++)
it->color_ar_old[i][j]=EMPTY;
}
};
void DeleteGlass(Glass *it)
{
for (int i=0;i<it->size_i;i++)
{
free(it->ar[i]);
free(it->color_ar[i]);
free(it->ar_old[i]);
free(it->color_ar_old[i]);
}
free(it->ar);
free(it->color_ar);
free(it->ar_old);
free(it->color_ar_old);
}
int CreateGlass(Glass *it,int x_,int y_,int type_,int pol_,int d)
{
int flag=1;
for (int i=0;i<it->p[type_][pol_].size_i;i++)
for (int j=0;j<it->p[type_][pol_].size_j;j++)
{
if ((y_+j<0 || y_+j>=it->size_j) || ((it->p[type_][pol_].mpt[i][j]==1 && it->ar[x_+i][y_+j]==2) && (d==LEFT || d==RIGHT || d==0 || d==ENTER)))
flag=2;
if ((it->p[type_][pol_].mpt[i][j]==1 && it->ar[x_+i][y_+j]==2 && d==DOWN) || x_+i==it->size_i)
flag=0;
}
if (flag==2 && d==0)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]==1)
{
it->ar[i][j]=STATIC;
it->color_ar[i][j]=it->a.type;
}
}
return 0;
}
if (flag==1)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]==1)
{
it->ar[i][j]=EMPTY;
it->color_ar[i][j]=type_;
}
}
for (int i=0;i<it->p[type_][pol_].size_i;i++)
for (int j=0;j<it->p[type_][pol_].size_j;j++)
if (it->ar[x_+i][y_+j]!=2)
if (it->p[type_][pol_].mpt[i][j]==1)
{
it->ar[x_+i][y_+j]=1;
it->color_ar[x_+i][y_+j]=type_;
}
it->a.x=x_;
it->a.y=y_;
it->a.type=type_;
it->a.pol=pol_;
}
else if (flag==0)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]==1)
{
it->ar[i][j]=STATIC;
it->color_ar[i][j]=it->a.type;
}
}
DestrGlass(it);
}
else if (flag==2) return 0;
return flag;
}
void DestrGlass(Glass *it)
{
int flag;
for (int i=it->size_i-1;i>=0;i--)
{
flag=1;
for (int j=0;j<it->size_j;j++)
{
if (it->ar[i][j]!=STATIC)
{
flag=0;
}
}
if (flag)
{
for (int i_=i;i_>0;i_--)
{
for (int j_=0;j_<it->size_j;j_++)
{
it->ar[i_][j_]=it->ar[i_-1][j_];
it->color_ar[i_][j_]=it->color_ar[i_-1][j_];
}
}
for (int j_=0;j_<it->size_j;j_++)
{
it->ar[0][j_]=0;
it->color_ar[0][j_]=0;
}
it->lines++;
Score(it,100);
LeftPanel(it);
if (1+it->lines/10>it->level)
{
//gotoxy(1,3);
it->level=1+it->lines/10;
}
DestrGlass(it);
}
}
}
int Do(Glass *it,int type)
{
if (!CreateGlass(it,0,(it->size_j-it->p[type][0].size_j)/2,type,0,0)) return 0;
else return 1;
}
int Fall(Glass *it)
{
if (!CreateGlass(it,it->a.x+1,it->a.y,it->a.type,it->a.pol,DOWN)) return 0;
else return 1;
}
int Move(Glass *it,int key)
{
switch(key)
{
case RIGHT:
{
if (!CreateGlass(it,it->a.x,it->a.y+1,it->a.type,it->a.pol,RIGHT)) return 0;
else return 1;
}
case LEFT:
{
if (!CreateGlass(it,it->a.x,it->a.y-1,it->a.type,it->a.pol,LEFT)) return 0;
else return 1;
}
case DOWN:
{
Score(it,1);
if (!CreateGlass(it,it->a.x+1,it->a.y,it->a.type,it->a.pol,DOWN)) return 0;
else return 1;
}
case ENTER:
{
if (!CreateGlass(it,it->a.x,it->a.y,it->a.type,(it->a.pol+1)%it->p[it->a.type][0].vert,ENTER)) return 0;
else return 1;
}
}
}
void Draw(Glass *it,void **sd)
{
int pos_x=(getmaxx()-it->size_j*20)/2,pos_y=(getmaxy()-it->size_i*20)/2;
setcolor(WHITE);
rectangle(pos_x,pos_y,pos_x+it->size_j*20+1,pos_y+it->size_i*20+1);
for(int i=0;i<it->size_i;i++)
{
for (int j=0;j<it->size_j;j++)
{
if(it->ar_old[i][j]!=it->ar[i][j] || it->color_ar_old[i][j]!=it->color_ar[i][j])
{
switch(it->ar[i][j])
{
case STATIC:
{
setfillstyle(SOLID_FILL,DARKGRAY);
putimage(pos_x+j*20+1,pos_y+i*20+1,sd[it->color_ar[i][j]],0);
break;
}
case DYNAMIC:
{
putimage(pos_x+j*20+1,pos_y+i*20+1,sd[it->a.type],0);
break;
}
case EMPTY:
{
setfillstyle(SOLID_FILL,BLACK);
bar(pos_x+j*20+1,pos_y+i*20+1,pos_x+(j+1)*20,pos_y+(i+1)*20);
//setfillstyle(SOLID_FILL,WHITE);
//fillellipse(pos_x+j*20+10,pos_y+i*20+10,1,1);
//bar(pos_x+j*20+1,pos_y+i*20+1,pos_x+(j+1)*20,pos_y+(i+1)*20);
break;
}
}
}
}
}
CopyMas(it);
}
void InitMatr(Matr *it)
{
it->vert=0;
it->size_i=0;
it->size_j=0;
it->mpt=NULL;
}
void DeleteMatr(Matr *it)
{
int i;
for (i=0;i<it->size_i;i++)
{
free(it->mpt[i]);
}
free(it->mpt);
}
void ReadStdFile(Matr *p,int N)
{
FILE *f=NULL;
f=fopen("std.fig","r");
if (f)
{
int i,u,v;
char h[2];
h[1]='\0';
for (i=0;i<N;i++)
{
h[0]=fgetc(f);
p[i].size_i=atoi(h);
h[0]=fgetc(f);
p[i].size_j=atoi(h);
p[i].mpt=new int*[p[i].size_i];
getc(f);
for (u=0;u<p[i].size_i;u++)
{
p[i].mpt[u]=new int[p[i].size_j];
for (v=0;v<p[i].size_j;v++)
{
h[0]=fgetc(f);
p[i].mpt[u][v]=atoi(h);
}
getc(f);
}
}
}
else
{
printf("\nfile 'std.fig' not found!\n");
getch();
}
fclose(f);
}
void** PreobrGraph(int N)
{
cleardevice();
int mas[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
unsigned int size=imagesize(1,1,20,20);
void **sd=(void **)malloc(7*sizeof(void*));
for (int i=0;i<N;i++)
{
sd[i]=malloc(size);
/*setfillstyle(SOLID_FILL,mas[i]);
bar(1,1,20,20);*/
setfillstyle(SOLID_FILL,BLACK);
bar(1,1,20,20);
setcolor(WHITE);
line(1,4,1,16);
line(20,4,20,16);
line(4,1,16,1);
line(4,20,16,20);
line(1,4,4,1);
line(1,16,4,20);
line(16,1,20,4);
line(16,20,20,16);
/*setfillstyle(SOLID_FILL,mas[i]);
floodfill(10,10,WHITE);*/
setfillstyle(SOLID_FILL,mas[i+8]);
bar(4,4,17,17);
setcolor(BLACK);
rectangle(4,4,17,17);
getimage(1,1,20,20,sd[i]);
}
return sd;
}
void Vert(Matr &p)
{
int flag=0;
for (int i=0;i<p.size_i;i++)
{
for (int j=0;j<p.size_j;j++)
{
if (p.mpt[i][j]!=p.mpt[p.size_i-i-1][p.size_j-j-1]) flag=1;
}
}
if (flag) p.vert=4;
else if (p.size_i==p.size_j) p.vert=1;
else p.vert=2;
}
Matr** Preobr(Matr *p,int N)
{
Matr **p1=(Matr**)malloc(sizeof(Matr*)*N);
for (int i=0;i<N;i++)
{
Vert(p[i]);
p1[i]=(Matr*)malloc(sizeof(Matr)*p[i].vert);
for (int j=0;j<p[i].vert;j++)
{
if (j%2!=0)
{
p1[i][j].size_i=p[i].size_j;
p1[i][j].size_j=p[i].size_i;
}
else
{
p1[i][j].size_i=p[i].size_i;
p1[i][j].size_j=p[i].size_j;
}
p1[i][j].vert=p[i].vert;
p1[i][j].mpt=(int**)malloc(sizeof(int*)*p1[i][j].size_i);
for (int k=0;k<p1[i][j].size_i;k++)
{
p1[i][j].mpt[k]=(int*)malloc(sizeof(int)*p1[i][j].size_j);
for (int l=0;l<p1[i][j].size_j;l++)
{
if (j==0)
{
p1[i][j].mpt[k][l]=p[i].mpt[k][l];
}
else if (j==1)
{
p1[i][j].mpt[k][p1[i][j].size_j-l-1]=p[i].mpt[l][k];
}
else if (j==2)
{
p1[i][j].mpt[k][l]=p[i].mpt[p[i].size_i-k-1][p[i].size_j-l-1];
}
else if (j==3)
{
p1[i][j].mpt[k][l]=p[i].mpt[l][p[i].size_i-k];
}
}
}
}
}
return p1;
}
void CopyMas(Glass *it)
{
for (int i=0;i<it->size_i;i++)
for (int j=0;j<it->size_j;j++)
{
it->ar_old[i][j]=it->ar[i][j];
it->color_ar_old[i][j]=it->color_ar[i][j];
}
}
void LeftPanel(Glass *it)
{
int i;
int x=20,y=40;
char str[]="Score:";
setcolor(WHITE);
settextstyle(0,HORIZ_DIR,4);
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(x,y,str);
char scorestr[7];
itoa(it->score,scorestr,10);
int dif=6-strlen(scorestr);
scorestr[6]='\0';
int len=strlen(scorestr);
for (int i=0;i<len;i++)
{
scorestr[5-i]=scorestr[len-i-1];
}
for (i=0;i<dif;i++)
{
scorestr[i]='0';
}
setfillstyle(SOLID_FILL,BLACK);
bar(x,y+textheight(str)*1.1,x+textwidth(str),y+2*textheight(str)*1.1);
outtextxy(x,y+textheight(str)*1.1,scorestr);
settextstyle(5,HORIZ_DIR,4);
char str2[]="Lines:";
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(x,y+3*textheight(str)*1.1,str2);
char linestr[5];
itoa(it->lines,linestr,10);
bar(x+textwidth(str2),y+3*textheight(str)*1.1,x+textwidth(str2)+50,y+3*textheight(str)*1.1+textheight(linestr));
outtextxy(x+textwidth(str2),y+3*textheight(str)*1.1,linestr);
char str1[]="Level:";
settextjustify(LEFT_TEXT,TOP_TEXT);
char levelstr[5];
outtextxy(x,y+4*textheight(str)*1.1,str1);
itoa(it->level,levelstr,10);
bar(x+textwidth(str1),y+4*textheight(str)*1.1,x+textwidth(str1)+50,y+4*textheight(str)*1.1+textwidth(str1));
outtextxy(x+textwidth(str1),y+4*textheight(str)*1.1,levelstr);
settextstyle(3,HORIZ_DIR,1);
char str3[]="Record:";
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(x,y+3*textheight(str2)*1.1,str3);
char recordstr[10];
sprintf(recordstr,"%li",it->record);
outtextxy(x+textwidth(str3),y+3*textheight(str)*1.1,recordstr);
char str4[]="Last result:";
settextjustify(LEFT_TEXT,TOP_TEXT);
char lastresstr[10];
outtextxy(x,y+4*textheight(str)*1.1,str4);
sprintf(lastresstr,"%li",it->lastres);
outtextxy(x+textwidth(str4),y+4*textheight(str)*1.1,lastresstr);
}
void DrawFut(int *type,void **gp,Matr *p)
{
setfillstyle(SOLID_FILL,BLACK);
int x=500,y=50;
setfillstyle(LTSLASH_FILL,DARKGRAY);
bar(x-10,y-10,x+100+10,y+400+10);
setcolor(WHITE);
rectangle(x,y,x+100,y+400);
settextstyle(TRIPLEX_FONT,VERT_DIR,3);
char str1[]="NEXT";
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(x-3,y+10,str1);
char str2[]="1";
settextstyle(TRIPLEX_FONT,HORIZ_DIR,3);
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(x,y+130,str2);
char str3[]="2";
outtextxy(x,y+230,str3);
char str4[]="3";
outtextxy(x,y+330,str4);
for (int i=0;i<4;i++)
{
if (i==0)
{
setfillstyle(SOLID_FILL,BLACK);
bar(x,y,x+100,y+100);
setcolor(WHITE);
rectangle(x,y,x+100,y+100);
}
for (int j=0;j<p[type[i]].size_i;j++)
for (int k=0;k<p[type[i]].size_j;k++)
{
if (p[type[i]].mpt[j][k]==1)
putimage(x+(100-p[type[i]].size_j*20)/2+20*k,y+i*100+(100-p[type[i]].size_i*20)/2+20*j,gp[type[i]],0);
}
}
}
void Score(Glass *it,int d)
{
it->score+=d;
LeftPanel(it);
}
void Menu(char *str1)
{
int x=20,y=300;
int old_choice=0;
int choice=0;
int ch;
char str2[]="Control";
char str3[]="Exit";
settextjustify(LEFT_TEXT,TOP_TEXT);
settextstyle(7,HORIZ_DIR,3);
setfillstyle(SOLID_FILL,DARKGRAY);
setcolor(WHITE);
outtextxy(x,y,str1);
setcolor(DARKGRAY);
outtextxy(x,y+textheight(str1),str2);
outtextxy(x,y+textheight(str1)+textheight(str2),str3);
while(1)
{
ch=getch();
switch(ch)
{
case DOWN:
{
old_choice=choice;
if (choice==2) choice=0;
else choice++;
break;
}
case UP:
{
old_choice=choice;
if (choice==0) choice=2;
else choice--;
break;
}
case ENTER1:
{
switch(choice)
{
case 0:
{
setfillstyle(SOLID_FILL,BLACK);
bar(x,y,x+180,y+3*textheight(str1));
return;
}
case 1:
{
settextstyle(2,HORIZ_DIR,5);
setcolor(WHITE);
setfillstyle(SOLID_FILL,BLACK);
outtextxy(x+15,y+80,"BACKSPACE - ROTATE");
outtextxy(x+15,y+80+10,"ESC - EXIT");
outtextxy(x+15,y+80+10+10,"ARROWS - MOVE");
getch();
setcolor(DARKGRAY);
settextstyle(7,HORIZ_DIR,3);
bar(x+15,y+80,x+180,y+80+50);
break;
}
case 2:
{
setfillstyle(SOLID_FILL,BLACK);
bar(x,y,x+180,y+3*textheight(str1));
exit(1);
}
}
}
default:
{
continue;
}
}
setcolor(WHITE);
switch(choice)
{
case 0:
{
outtextxy(x,y,str1);
break;
}
case 1:
{
outtextxy(x,y+textheight(str1),str2);
break;
}
case 2:
{
outtextxy(x,y+textheight(str1)+textheight(str2),str3);
break;
}
}
setcolor(DARKGRAY);
switch(old_choice)
{
case 0:
{
outtextxy(x,y,str1);
break;
}
case 1:
{
outtextxy(x,y+textheight(str1),str2);
break;
}
case 2:
{
outtextxy(x,y+textheight(str1)+textheight(str2),str3);
break;
}
}
}
}
main()
{
int i;
cleardevice();
//randomize();
Matr *p=(Matr*)malloc(sizeof(Matr)*7);
for (int i=0;i<7;i++)
InitMatr(&p[i]);
ReadStdFile(p,7);
Matr **p1;
p1=Preobr(p,7);
int gd=0,gmode=0;
initgraph(&gd,&gmode,"");
cleardevice();
void **gp=PreobrGraph(7);
Glass field;
CreateGlass(&field,p1);
clock_t mark;
double step=0.5;
cleardevice();
setfillstyle(XHATCH_FILL,WHITE);
bar(0,0,getmaxx(),20);
bar(0,getmaxy()-20,getmaxx(),getmaxy());
setlinestyle(SOLID_LINE, 0, 2);
setcolor(WHITE);
line(0,20,getmaxx(),20);
line(0,getmaxy()-20,getmaxx(),getmaxy()-20);
setlinestyle(SOLID_LINE, 0, 1);
int esc_flag=0;
int type[4];
for(i=0;i<4;i++)
{
type[i]=rand()%7;
}
LeftPanel(&field);
while(Do(&field,type[0]))
{
for (i=0;i<3;i++)
{
type[i]=type[i+1];
}
type[3]=rand()%7;
DrawFut(type,gp,p);
Draw(&field,gp);
do
{
mark=clock();
Draw(&field,gp);
while((double)(clock()-mark)/CLK_TCK<step/field.level)
{
if(kbhit())
{
int ch=0;
ch=getch();
if(ch==RIGHT || ch==LEFT || ch==DOWN || ch==ENTER)
{
if (Move(&field,ch))
{
Draw(&field,gp);
}
}
else if (ch==UP)
{
Score(&field,10);
while(Fall(&field));
}
else if (ch==ESC)
{
Menu("Resume Game");
esc_flag=1;
break;
}
}
}
//if (esc_flag) break;
}
while(Fall(&field));
//if (esc_flag) break;
}
settextstyle(4,0,5);
setcolor(WHITE);
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(10,360,"Game Over");
if (field.score>field.record)
{
settextstyle(5,0,3);
setcolor(WHITE);
settextjustify(LEFT_TEXT,TOP_TEXT);
outtextxy(20,400,"New record!");
FILE *f=fopen("Tetris.rec","w");
if (f)
{
fprintf(f,"%li\n%li\n",field.score,field.score);
fclose(f);
}
}
else
{
FILE *f=fopen("Tetris.rec","w");
if (f)
{
fprintf(f,"%li\n%li\n",field.record,field.score);
fclose(f);
}
}
int ch;
do
{
ch=getch();
}
while(ch!=ESC);
closegraph();
for (i=0;i<7;i++)
{
free(p1[i]);
DeleteMatr(&p[7]);
}
free(p1);
free(p);
DeleteGlass(&field);
}
Объяснение кода листинга программы
Ошибка Undefined reference обычно указывает на то, что компилятор не может найти определенную функцию или переменную, которые были использованы в коде. В данном случае, ошибка может быть связана с функцией Do, которую вы используете в цикле while.
Также, в коде присутствуют некоторые проблемы с использованием функций и переменных. Например, функция Move вызывается только в том случае, если получен определенный ввод пользователя (RIGHT, LEFT, DOWN или ENTER). Это может привести к тому, что ваш код не будет работать должным образом.
Ваш код также содержит некоторые ошибки в использовании функций initgraph и settextjustify. Функция initgraph должна быть вызвана до того, как вы сможете использовать функции графического ввода-вывода, такие как settextjustify.
Пожалуйста, проверьте ваш код и внесите необходимые изменения. Если у вас возникнут дополнительные вопросы, не стесняйтесь задавать их.