#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <iostream.h>
#include <string.h>
struct vektor{double x,y;};
struct objekt{double x,y,vx,vy;int id,pom,col;void *image;};
int minx=10,maxx=630,miny=10,maxy=390;
double zem[640];
objekt e[40];
typedef char *str;
div_t pom;
int score1=0,score2=0,mat1=0,mat2=0,zs=0;
void beep(int a,int b)
{
sound(a);
delay(b);
nosound();
}
void kreslyscore(void)
     {
  settextstyle(6,0,1);
  str po;
  setviewport(10,miny+maxy+30,629,miny+maxy+60,1);
  clearviewport();
  sprintf(po,"%d",score1);
  setcolor(GREEN);
  outtextxy(1,2,po);
  sprintf(po,"%d",score2);
  setcolor(RED);
  outtextxy(555,2,po);
  setviewport(0,0,639,479,1);
     }
void vykreslimat(void)
     {
str po;
settextstyle(6,0,3);
setviewport(200,miny+maxy+1,500,miny+maxy+29,1);
clearviewport();
sprintf(po,"%d",mat1);
setcolor(GREEN);
outtextxy(0,0,po);
sprintf(po,"%d",mat2);
setcolor(RED);
outtextxy(230,0,po);
setviewport(0,0,639,479,1);
     }
int max(int m,int a,int b,int c,int d,int e) /*hlada maximum*/
{
 int po[6]={m,a,b,c,d,e};
 int vysl=po[0];
 for (int i=0;i<5;i++) if (po[i+1]>vysl) vysl=po[i+1];
 return vysl;
}
int menu(int pocetp,str meno,str a,str b,str c,str d,str e) /*MENU*/
{
 settextstyle(6,0,3);
 setfillstyle(1,0);
 setcolor(15);
 int vyska=(textheight(a))*(pocetp+1)+25;
 int sirka=20+max(textwidth(meno),textwidth(a),textwidth(b),textwidth(c),textwidth(d),textwidth(e));
 pom=div((getmaxx()-sirka),2);int x=pom.quot;
 pom=div((getmaxy()-vyska-50),2);int y=pom.quot;
 int aktual=1;
 unsigned size=imagesize(x,y,x+sirka,y+vyska);
 void *imag;
 imag = malloc(size);
 getimage(x,y,x+sirka,y+vyska,imag);
 str pole[5]={a,b,c,d,e};
 bar(x,y,x+sirka,y+vyska);
 rectangle(x+2,y+2,x+sirka-2,y+vyska-2);
 pom=div(sirka-textwidth(meno),2);
 rectangle(x+5,y+5,x+sirka-5,y+5+textheight(meno)+10);
 setcolor(2);
 outtextxy(x+pom.quot,y+5,meno);
 int klav=0;
 while(klav !=13)
    {
 for(int i=1;i<pocetp+1;i++)
       {
      setcolor(4);
      if (i==aktual) setcolor(9);
      pom=div(sirka-textwidth(pole[i-1]),2);
      outtextxy(x+pom.quot,y+10+textheight(meno)+(textheight(a))*(i-1),pole[i-1]);
       }
  klav=getch();
  if (klav==80) aktual++;
  if (klav==72) aktual--;
  if (aktual==0) aktual=pocetp;
  pom=div(aktual,pocetp);
  if (pom.rem==0) aktual=pocetp;
     else aktual=pom.rem;
   }
 putimage(x,y,imag,0);
 free(imag);
 return aktual;
}
void vykresliegg(double p,double q,double dir,int col)
   {
 setcolor(col);
 setfillstyle(1,col);
 fillellipse(p,q,7,7);
 if (dir==0)
   {
  setcolor(15);
  setfillstyle(1,15);
  fillellipse(p-4,q-4,4,4);fillellipse(p+4,q-4,4,4);
  setcolor(0);
  setfillstyle(1,0);
  fillellipse(p-3,q-3,2,2);fillellipse(p+3,q-3,2,2);
  line(p-3,q+4,p+3,q+4);
    }
 else
    {
  setcolor(15);
  setfillstyle(1,15);
  fillellipse(p+dir*4,q-4,4,4);
  setcolor(0);
  setfillstyle(1,0);
  fillellipse(p+dir*5,q-3,2,2);
  line(p+dir*3,q+4,p+dir*6,q+4);
    }
   }
objekt iniobj(double x,double y,double vx,double vy,int id,int col,int pom)
{                                          /*inicializujeme objekt*/
void *im;
int size;
objekt ee;
ee.id=id;
ee.x=x;
ee.y=y;
ee.pom=pom;
ee.vx=vx;
ee.vy=vy;
ee.col=col;
if (id<=2) size=imagesize(0,0,16,15);
   else size=imagesize(0,0,4,4);
im=malloc(size);
if (id<=2) getimage(x-8,y-8,x+8,y+7,im);
  else getimage(x-2,y-2,x+2,y+2,im);
ee.image=im;
return ee;
}
int osetriobjekty(int pocetobj)  /*Urobime zmenu polohy objektov a animaciu*/
{
for (int i=1;i<=pocetobj;i++)
  {
 if (e[i].id<=2) putimage(e[i].x-8,e[i].y-8,e[i].image,COPY_PUT);
     else putimage(e[i].x-2,e[i].y-2,e[i].image,COPY_PUT);
 e[i].y+=e[i].vy;
 e[i].x+=e[i].vx;
 if (e[i].id<=2)
    {
   if (e[i].y+9>zem[e[i].x])
      {
    e[i].y=zem[e[i].x]-8;      /*Dopad na podlozku*/
    e[i].vy=-e[i].vy+1.5;
    if (e[i].vx!=0) beep(200,8);
      }
      else e[i].vy+=0.4; /*Gravitacia*/
   if ((e[i].x+9>=maxx)||(e[i].x-9<=minx)) {beep(200,8);e[i].x=e[i].x-e[i].vx;e[i].vx=-e[i].vx;}
   if ((e[i].y)-9<=miny) {e[i].y=miny+9;e[i].vy=-e[i].vy;beep(200,8);}
   if (abs(e[i].y+8-zem[e[i].x])<=1)
	 {
      e[i].vx=e[i].vx*.9;
      if ((abs(e[i].vx)<.01)&&(abs(e[i].vy)<0.01)) {e[i].vx=0;e[i].vy=0;}
	 }
    }
  else      /*bomba*/
       {
     if ((e[i].x+3>=maxx)||(e[i].x-3<=minx)) {beep(200,4);e[i].x=e[i].x-e[i].vx;e[i].vx=-e[i].vx;}
     if (e[i].y-3<miny) {beep(200,4);e[i].y=miny+3;e[i].vy=-e[i].vy;}
     if (e[i].y+3>zem[e[i].x])
	 {
       e[i].y=zem[e[i].x]-3;      /*Dopad na podlozku*/
       e[i].vy=-e[i].vy;
       beep(200,4);
	 }
	else e[i].vy+=.4;
     e[i].pom--;
       }
  }
for (i=1;i<=pocetobj;i++) if (e[i].id>2)
	     {
       for (int c=1;c<=pocetobj;c++)
	  if ((c!=i)&&(e[c].id>2)&&(((e[i].x-e[c].x)*(e[i].x-e[c].x)+(e[i].y-e[c].y)*(e[i].y-e[c].y))<=64))
		     {
		   e[i].pom=0;  /*Zrazka dvoch bomb*/
		   e[c].pom=0;
		     }
       if ((((e[1].x-e[i].x)*(e[1].x-e[i].x)+(e[1].y-e[i].y)*(e[1].y-e[i].y))<121)&&(i>2)&&(e[i].pom<198))
		   {
		 e[i].pom=0;    /*Prvy hrac+bomba*/
		 score2++;
		 zs=1;
		 beep(500,9);beep(450,8);beep(400,7);
		   }
       if ((((e[2].x-e[i].x)*(e[2].x-e[i].x)+(e[2].y-e[i].y)*(e[2].y-e[i].y))<121)&&(i>2)&&(e[i].pom<198))
		   {
		 e[i].pom=0;     /*Druhy hrac+bomba*/
		 score1++;
		 zs=1;
		 beep(500,9);beep(450,8);beep(400,7);
		   }
	     }
for (i=1;i<=pocetobj;i++)  if ((e[i].pom<=0)&&(e[i].id>2))  /*bomba buchne*/
	  {
	 if (e[i].col==e[1].col) e[1].pom--;
	       else e[2].pom--;
	 free(e[i].image);
	 for (int u=i;u<pocetobj;u++) e[u]=e[u+1];
	 pocetobj--;
	  }
for (int j=1;j<=pocetobj;j++)
   {
  if (e[j].id<=2) getimage(e[j].x-8,e[j].y-8,e[j].x+8,e[j].y+7,e[j].image);
     else getimage(e[j].x-2,e[j].y-2,e[j].x+2,e[j].y+2,e[j].image);
   }
double r;
for (int h=1;h<=pocetobj;h++)
   {
  if (e[h].vx<0) r=-1;
      else if (e[h].vx>0) r=1;
	       else r=0;
  if (e[h].id<=2) vykresliegg(e[h].x,e[h].y,r,e[h].col);
     else {setcolor(e[h].col);setfillstyle(1,e[h].col);fillellipse(e[h].x,e[h].y,2,2);}
   }
return pocetobj;
}
void text(int x,int y,int dela,int velkost,int col,str text)
{
settextstyle(6,0,velkost);
setcolor(col);
for (int i=1;i<=strlen(text);i++)
	   {
	 setviewport(x,y,x+textwidth(text),y+textheight(text),1);
	 clearviewport();
	 setviewport(0,0,639,479,1);
	 outtextxy(x,y,text+strlen(text)-i);
	 delay(dela);
	   }
}
void intro(void)
{
text(170,100,100,15,11,"SAMO");
text(210,300,20,7,5,"Presents");
delay(1500);
cleardevice();
text(200,50,50,10,4,"COOL");
text(170,250,40,10,9,"NAREZ");
delay(1500);
cleardevice();
setcolor(15);
for (int ii=1;ii<=11;ii++)
       {
     cleardevice();
     settextstyle(6,0,ii);
     outtextxy(15*ii,15*ii,"BIMBO");
     outtextxy(639-15*ii-textwidth("BIMBO"),15*ii,"BIMBO");
     outtextxy(15*ii,479-15*ii-textheight("BIMBO"),"BIMBO");
     outtextxy(639-15*ii-textwidth("BIMBO"),479-15*ii-textheight("BIMBO"),"BIMBO");

     beep(100+40*ii,30);
     delay(100);
       }
delay(1500);
}
void main()
{
int gdriver = DETECT, gmode, errorcode;
initgraph(&gdriver, &gmode, "c:\\borlandc\\bgi\\");
errorcode = graphresult();
if (errorcode != grOk)
{
   printf("Graphics error: %s\n", grapherrormsg(errorcode));
   printf("Press any key to halt:");
   getch();
   exit(1);
}
double p=50,q=maxy-10;
int pocet=2;
int klav=0,vrat=0,matches=1,q1=0,q2=0,zm=0;
intro();
do
{
cleardevice();
q1=0;q2=0;score1=0;score2=0;mat1=0;mat2=0;
while ((vrat!=1)&&(q1!=1))
  {
 settextstyle(6,0,10);
 setcolor(YELLOW);
 outtextxy(177,0,"BIMBO");
 outtextxy(180,3,"BIMBO");
 settextstyle(6,0,1);
 setcolor(11);
 outtextxy(500,400,"1999-SAMO");
 vrat=menu(4,"Main Menu","Start game","Matches","About","Quit game","");
 if (vrat==2) matches=menu(5,"Number of matches","1","2","3","4","5");
 if (vrat==3)
	  {
       cleardevice();
       text(210,5,70,6,10,"B I M B O");
       text(250,70,5,3,13,"Version:1.0");
       text(225,100,20,5,11,"BY SAMO");
       text(250,170,5,4,14,"Controls:");
       text(70,210,10,3,GREEN,"PLAYER 1:");text(450,210,10,3,RED,"PLAYER 2:");
       text(70,250,10,2,GREEN,"LEFT: LEFT arrow");text(450,250,10,2,RED,"LEFT: x");
       text(70,290,10,2,GREEN,"RIGHT: RIGHT arrow");text(450,290,10,2,RED,"RIGHT: c");
       text(70,330,10,2,GREEN,"JUMP: UP arrow");text(450,330,10,2,RED,"JUMP: d");
       text(70,370,10,2,GREEN,"FIRE: Enter");text(450,370,10,2,RED,"FIRE: Tab");
       text(240,410,20,2,12,"PRESS ANY KEY");
       int kl=getch();
       cleardevice();
	  }
 if (vrat==4) q1=1;
  }
cleardevice();
if (q1!=1)
      {
 e[1]=iniobj(p+30,q,0,0,1,GREEN,0);
 e[2]=iniobj(p+500,q,0,0,2,RED,0);
 pocet=2;
 setcolor(11);
 zem[minx]=maxy-1;
 for (int i=minx;i<maxx;i++)
    {
   zem[i+1]=zem[i];
   line(i,zem[i],i,maxy);
    }
 rectangle(minx,miny,maxx,maxy);
 rectangle(0,0,639,479);
 line (0,maxy+miny,639,maxy+miny);
 line (0,0,minx,miny);line(639,0,maxx,miny);line(0,maxy+miny,minx,maxy);line(maxx,maxy,639,maxy+miny);
 settextstyle(6,0,2);
 setcolor(GREEN);
 outtextxy(10,miny+maxy+1,"Player 1");
 setcolor(RED);
 outtextxy(564,miny+maxy+1,"Player 2");
 vykreslimat();
 kreslyscore();
    }
while ((q2!=1)&&(q1!=1)&&(mat1<matches)&&(mat2<matches))
    {
    settextstyle(6,0,2);
    setcolor(GREEN);
    klav=0;
    if (kbhit()) klav=getch();
    if (klav==27)
       {
      vrat=menu(2,"   Quit?   ","Yes","No","","","");
      if (vrat==1) q2=1;
      vrat=0;
       }
    if (klav==72) e[1].vy=-10;
    if (klav==77) e[1].vx=2;
    if (klav==75) e[1].vx=-2;
    if ((klav==13)&&(e[1].pom<3))
	 {
	e[1].pom++;
	if (e[1].vx<0) vrat=-1;
	   else if (e[1].vx>0) vrat=1;
		   else vrat=0;
	pocet++;
	e[pocet]=iniobj(e[1].x+vrat*10,e[1].y-10,4*vrat,-3.5,3,e[1].col,200);
	 }
    if (klav==120) e[2].vx=-2;
    if (klav==99) e[2].vx=2;
    if (klav==100) e[2].vy=-10;
    if ((klav==9)&&(e[2].pom<3))
	 {
	e[2].pom++;
	if (e[2].vx<0) vrat=-1;
	   else if (e[2].vx>0) vrat=1;
		   else vrat=0;
	pocet++;
	e[pocet]=iniobj(e[2].x+vrat*10,e[2].y-10,4*vrat,-3.5,3,e[2].col,200);
	 }
    pocet=osetriobjekty(pocet);
    if (zs==1) kreslyscore();
    zs=0;
    if (score1>=10)
	       {
	     vrat=menu(1,"Player 1 wins the match","Press Enter","","","","");
	     vrat=0;
	     mat1++;
	     score1=0;
	     score2=0;
	     zm=1;
	     kreslyscore();
	       }
    if (score2>=10)
	       {
	     vrat=menu(1,"Player 2 wins the match","Press Enter","","","","");
	     vrat=0;
	     mat2++;
	     score1=0;
	     score2=0;
	     zm=1;
	     kreslyscore();
	       }
    if (zm==1)
		{
	     vykreslimat();
	     setviewport(minx+1,miny+1,maxx-1,maxy-1,1);
	     clearviewport();
	     setviewport(0,0,639,479,1);
	     e[1]=iniobj(p,q,0,0,1,GREEN,0);
	     e[2]=iniobj(p+500,q,0,0,2,RED,0);
	     pocet=2;
	     zm=0;
		}
    delay(15);
    }

if (q1!=1) {
if (mat1==matches) vrat=menu(1,"Player 1 wins the Bimbo...Congratulation!","Press Enter","","","","");
if (mat2==matches) vrat=menu(1,"Player 2 wins the Bimbo...Congratulation!","Press Enter","","","","");
	   }
vrat=0;
}
while (q1!=1);
closegraph();
cout<<"Thank you for playing B I M B O";
getch();
}