Jump to content

Recommended Posts

Posted

Olá pessoa..mais uma vez a incomodar..

peço desculpa, mas encontrei o jogo do tetris em c e gostava de analisar e perceber como foi elaborado no entanto colocam 3 ficheiros:

1- um com o jogo em si e que tem este código e tem o nome gra.c:

2 -tem um segundo que é a codificação de uma biblioteca

3 - e outro ficheiro chamado peças.def..

nem sei o que é, este ultimo ficheiro!!

é assim só queria executar isto mas não consigo...complio o primeiro ficheiro e da erros..tenho de fazer alguma coisa??

agradeço a quem me puder ajudar!!

/***************************************************************************/
/* TETRIS    ***************************************************************/
/***************************************************************************/

/*
programado por ivantgmoraes@yahoo.com.br
ficarei feliz em receber seu e-mail

compilado com Borland Turbo C 2.0
*/

#include "defs.h"

#define QX 15
#define QY 20
#define P 4
#define CHARAPAGADOR 219
#define DESLIGADOCOLOR 0
#define LIGADOCOLOR    2
#define EFEITOBREAKCOLOR 4
#define VIRADIREITA    0
#define VIRAESQUERDA   1
#define EFEITODELAY    200
int BarSizeX, BarSizeY;
int BarzinhoSizeX, BarzinhoSizeY;
struct linesettingstype LineInfo;

int Grade[QX][QY];
int Peca[P][P];
int PosX, PosY;
int Rotacionador = VIRADIREITA;

#define INTERRUPT_BIOS_CLOCK  0x1c
void interrupt far (*rotina_original)();
int TimerContador = 0;
int TimerDelay = 10;
int TimerEvent = 0;
int TimerPlay = 1;
int TimerContadorColor = 0;
int TimerDelayColor = 3;
int TimerEventColor = 0;

int ContaPeca = 0;
int Pontos = 0;
int Fase = 1;
int Record = 0;

/***************************************************************************/
void interrupt far Timer(void)
{
if(TimerPlay)
{
  if (++TimerContador >= TimerDelay)
  {
   TimerEvent = 1;  TimerContador = 0;
  }
}
if (++TimerContadorColor == TimerDelayColor)
{
  TimerEventColor = 1;  TimerContadorColor = 0;
}
}
/***************************************************************************/
void Pause(void)
{
TimerPlay = 0;
}
/***************************************************************************/
void Go(void)
{
TimerPlay = 1;
}
/***************************************************************************/
void MostraPontos(void)
{
int i;
char Msg[16];
for(i = 0; i < 15; i++) Msg[i] = CHARAPAGADOR; Msg[15] = NULL;

setcolor(DESLIGADOCOLOR);
outtextxy((((MaxX-BarSizeX)/2)),
            ((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
            Msg);

outtextxy((((MaxX-BarSizeX)/2)+BarSizeX)-textwidth(Msg),
            ((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
            Msg);
outtextxy(MaxX-30-textwidth(Msg), MaxY-(textheight(Msg)*2), Msg);

setcolor(4);
itoa(Fase,Msg,10);
outtextxy((((MaxX-BarSizeX)/2)),
            ((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
            Msg);
itoa(Pontos,Msg,10);
outtextxy((((MaxX-BarSizeX)/2)+BarSizeX)-textwidth(Msg),
            ((MaxY-BarSizeY)/2)-(textheight(Msg)*2),
            Msg);
itoa(Record,Msg,10);
outtextxy(MaxX-30-textwidth(Msg), MaxY-(textheight(Msg)*2), Msg);

}
/***************************************************************************/
void Close(char *msg)
{
disable();
setvect(INTERRUPT_BIOS_CLOCK, rotina_original);
enable();
closegraph();
printf(msg);
SaveRecord();
exit(0);
}
/***************************************************************************/
void CalculaXY(void)
{
MaxX = getmaxx();
MaxY = getmaxy();
MaxColors = getmaxcolor() + 1;
BarSizeX = MaxX/3;
BarSizeX = BarSizeX - (BarSizeX%QX);
BarSizeY = MaxY-(MaxY/4);
BarSizeY = BarSizeY - (BarSizeY%QY);
BarzinhoSizeX = (BarSizeX/QX);
BarzinhoSizeY = (BarSizeY/QY);
getlinesettings( &LineInfo );
}
/***************************************************************************/
void ZeraGrade(void)
{
int x, y;
for(x = 0; x < QX; x++)
  for(y = 0; y < QY; y++)
   Grade[x][y] = 0;
}
/***************************************************************************/
void SorteiaPeca(void)
{
int x, y;
int sorteio;
randomize();
sorteio = rand()%(NUMERO_DE_PECAS);
for(x = 0; x < P; x++)
  for(y = 0; y < P; y++)
   Peca[x][y] = XPeca[sorteio][x][y]; 
}
/***************************************************************************/
void DesenhaGrade(void)
{
int x, y;
for(x = 0; x < QX; x++)
  for(y = 0; y < QY; y++)
  {
   if(Grade[x][y])  { Quadrado(x,y); }
   else             QuadradoOff(x,y);   
  }
}
/***************************************************************************/
void DesenhaPeca(int x, int y)
{
int ix, iy;
for(ix = 0; ix < P; ix++)
  for(iy = 0; iy < P; iy++)
   if(Peca[ix][iy]) Quadrado(x+ix,y+iy);
}
/***************************************************************************/
void LimpaPeca(int x, int y)
{
int ix, iy;
for(ix = 0; ix < P; ix++)
  for(iy = 0; iy < P; iy++)
   if(Peca[ix][iy]) QuadradoOff(x+ix,y+iy);
}
/***************************************************************************/
int Move(int Mov)
{
if((Mov == DIREITA) && ValidaMov(Mov))
{
  LimpaPeca(PosX,PosY);
  PosX++;
  DesenhaPeca(PosX,PosY); 
}
else if((Mov == ESQUERDA) && ValidaMov(Mov))
{
  LimpaPeca(PosX,PosY);
  PosX--;
  DesenhaPeca(PosX,PosY);
}
else if((Mov == CIMA) && ValidaMov(Mov))
{
  LimpaPeca(PosX, PosY);
  ViraPeca(Peca, Rotacionador);
  DesenhaPeca(PosX, PosY);
}
else if((Mov == BAIXO))
{
  if(ValidaMov(Mov))
  {
   LimpaPeca(PosX,PosY);
   PosY++;
   DesenhaPeca(PosX,PosY);
  }
  else { NovaPeca(); return(0); }
}
else if(Mov == ESPACO)
{
   while(Move(BAIXO))delay(EFEITODELAY);
} 
return(1);
}
/***************************************************************************/
int ValidaMov(int Mov)
{
int ix, iy;
int TempPeca[P][P];
int TempPosX = PosX, TempPosY = PosY;

memcpy(TempPeca, Peca, sizeof(int[P][P])); 
if     (Mov == DIREITA)  TempPosX++;
else if(Mov == ESQUERDA) TempPosX--;
else if(Mov == BAIXO)    TempPosY++;
else if(Mov == CIMA)     ViraPeca(TempPeca,Rotacionador);
for(ix = 0; ix < P; ix++)
{
  for(iy = 0; iy < P; iy++)
  {
   if(Grade[ix+TempPosX][iy+TempPosY]&&TempPeca[ix][iy]) return(0);
   if(TempPeca[ix][iy] && 
     (((ix+TempPosX) > QX-1) ||
     ((ix+TempPosX)  < 0)    ||
     ((iy+TempPosY)  > QY-1) ||
     ((iy+TempPosY)  < 0)))
    return(0);
  }
}
return(1);
}
/***************************************************************************/
void MarcaGrade(void)
{
int ix, iy;

for(ix = 0; ix < P; ix++)
  for(iy = 0; iy < P; iy++)
   if(Peca[ix][iy]) Grade[ix+PosX][iy+PosY] = Peca[ix][iy];
QuebraLinha();

}
/***************************************************************************/
void QuebraLinha(void)
{
int x, y, yy;
int LinhasBreak[QY];
static int TempGrade[QX][QY];
int ContaQuebra = 0;
int Quebra = 1;
int FaseSave;
for(y = 0; y < QY; y++) LinhasBreak[y] = 1;

for(y = 0; y < QY; y++)
  for(x = 0; x < QX; x++)
  {
   LinhasBreak[y] = LinhasBreak[y] && Grade[x][y];
   TempGrade[x][y] = Grade[x][y];
  }
for(y = 0; y < QY; y++)
{
  Quebra = (Quebra || LinhasBreak[y]);
  if(LinhasBreak[y]) ContaQuebra++;
}
if(Quebra)
{
  for(yy = y = QY-1; y >= 1; y--)
  {
   if(!LinhasBreak[y])
   {
    for(x = 0; x < QX; x++)
     Grade[x][yy] = TempGrade[x][y];
    yy--;
   }
   else
   {
    for(x = QX-1; x >= 0; x--)
    {
     QuadradoColor(x,y,EFEITOBREAKCOLOR); delay(EFEITODELAY);
    }
    for(x = QX-1; x >= 0; x--)
    {
     QuadradoOff(x,y); delay(EFEITODELAY);
    }
   }
  }
  DesenhaGrade();
  for(;ContaQuebra;ContaQuebra--) Pontos += (ContaQuebra*Fase);
  if(LinhasBreak[QY-1])
  {
   for(y = 0; y < QY; y++) for(x = 0; x < QX; x++)
    {
     QuadradoColor(x,y,random(MaxColors-1)+1); delay(EFEITODELAY/3);
    }
   for(y = 0; y < QY; y++) for(x = 0; x < QX; x++)
    {
     QuadradoOff(x,y); delay(EFEITODELAY/3);
    }
   FaseSave = Fase++;
   Pontos += Fase*50;
   TimerDelay = 10;
   ContaPeca = 0;
   ZeraGrade();
   Grade[(int)QX/2][QY-1] = 1;
   for(y = QY-1; (y >= 1)&&(FaseSave); y--,FaseSave--) for(x = QX-1; x >= 0; x--)
     Grade[x][y-1] = random(2);
  }
  MostraPontos();
  DesenhaGrade();
}
}
/***************************************************************************/
void ViraPeca(int PPeca[P][P], int Direcao)
{
int x,y, vx, vy;
int PecaVira[P][P];

for(x = 0, vx = P-1; x < P; x++, vx--)
  for(y = P-1, vy = 0; y >= 0; y--, vy++)
   if(Direcao == VIRADIREITA)
    PecaVira[vy][x] = PPeca[x][y];
   else
    PecaVira[vx][vy] = PPeca[y][vx];
for(x = P-1; x >= 0; x--)
  for(y = 0; y < P; y++)
   PPeca[y][x] = PecaVira[y][x];
}
/***************************************************************************/
void NovaPeca(void)
{
ContaPeca++;
if     (ContaPeca > 200){ TimerDelay = 1; }
else if(ContaPeca > 120){ TimerDelay = 3; }
else if(ContaPeca > 70) { TimerDelay = 5; }
else if(ContaPeca > 35) { TimerDelay = 7; }
MarcaGrade();
PosX = QX/2; PosY = 0;
SorteiaPeca();
DesenhaPeca(PosX,PosY);
if(!ValidaMov(0)) Close("Game Over");
}
/***************************************************************************/
void Tabuleiro(void)
{
int i;
rectangle((MaxX-BarSizeX)/2,(MaxY-BarSizeY)/2,
           ((MaxX-BarSizeX)/2)+BarSizeX,((MaxY-BarSizeY)/2)+BarSizeY);
for(i = 0; i < QX; i++)
{
  line(((MaxX-BarSizeX)/2)+(BarzinhoSizeX*i), (MaxY-BarSizeY)/2,
      (((MaxX-BarSizeX)/2))+(BarzinhoSizeX*i),((MaxY-BarSizeY)/2) + BarSizeY);
}
for(i = 0; i < QY; i++)
{
  line((MaxX-BarSizeX)/2,((MaxY-BarSizeY)/2)+(BarzinhoSizeY*i),
      ((MaxX-BarSizeX)/2)+BarSizeX,((MaxY-BarSizeY)/2)+(BarzinhoSizeY*i));
}
}
/***************************************************************************/
int Quadrado(int x, int y)
{
int L = LineInfo.thickness+2;
if((x>=QX)||(y>=QY)) Close("coordenadas invalidas ");
setfillstyle(SOLID_FILL, LIGADOCOLOR); 
bar((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x))+L,
      (((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y))+L,
      ((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x)) + BarzinhoSizeX) -L,
      ((((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y)) + BarzinhoSizeY) -L);
}
/***************************************************************************/
int QuadradoOff(int x, int y)
{
int L = LineInfo.thickness+1;
if((x>=QX)||(y>=QY)) Close("coordenadas invalidas Off");
setfillstyle(SOLID_FILL, DESLIGADOCOLOR); 
bar((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x))+L,
      (((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y))+L,
      ((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x)) + BarzinhoSizeX) -L,
      ((((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y)) + BarzinhoSizeY) -L);
}
/***************************************************************************/
int QuadradoColor(int x, int y, int Color)
{
int L = LineInfo.thickness+1;
if((x>=QX)||(y>=QY)) Close("coordenadas invalidas Off");
setfillstyle(SOLID_FILL, Color); 
bar((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x))+L,
      (((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y))+L,
      ((((MaxX-BarSizeX)/2)+(BarzinhoSizeX*x)) + BarzinhoSizeX) -L,
      ((((MaxY-BarSizeY)/2)+(BarzinhoSizeY*y)) + BarzinhoSizeY) -L);
}
/***************************************************************************/
void LoadRecord(void)
{
int ind;
ind = open("Record.dat", O_BINARY|O_RDONLY);
if(ind != -1)
  read(ind, &Record, sizeof(int));
}
/***************************************************************************/
void SaveRecord(void)
{
int ind;
if(Record < Pontos) Record = Pontos;
ind = open("Record.dat",O_BINARY|O_RDWR|O_CREAT,S_IWRITE|S_IREAD);
if(ind != -1)
  write(ind, &Record, sizeof(int));
}

/***************************************************************************/
/**** main *****************************************************************/
/***************************************************************************/
void main(void)
{
int i, tecla;
int gdriver = DETECT, gmode, errorcode;

initgraph(&gdriver, &gmode, "");

rotina_original = getvect(INTERRUPT_BIOS_CLOCK);
disable();
setvect(INTERRUPT_BIOS_CLOCK, Timer);
enable();

LoadRecord();
/* setgraphmode(0); */
CalculaXY();
ZeraGrade();
Grade[(int)QX/2][QY-1] = 1;
rectangle(0,0,MaxX,MaxY); rectangle(4,4,MaxX-4,MaxY-4);
Tabuleiro();
DesenhaGrade();
SorteiaPeca();
DesenhaPeca(PosX = QX/2, PosY = 0);
MostraPontos();

Pause(); bioskey(0); Go();

for(;
{
  while(!bioskey(1))
  {
   if(TimerEventColor)
   {
    QuadradoColor(QX/2,QY-1,random(MaxColors-1)+1);
    TimerEventColor = 0;
   }
   if(TimerEvent)
   {
    Move(BAIXO);
    TimerEvent = 0;
   }
  }
  tecla = bioskey(0);
  Pause();
  if(tecla == ESC) break;
  else if(tecla == DIREITA)  Move(DIREITA);
  else if(tecla == ESQUERDA) Move(ESQUERDA);
  else if(tecla == BAIXO)    Move(BAIXO);
  else if(tecla == ESPACO)   Move(ESPACO);
  else if(tecla == CIMA)     Move(CIMA);
  else if(tecla == ENTER)    Rotacionador = !Rotacionador;
  Go();
}
Close("Jogo finalizado corretamente");
}

Ficheiro 2 - da biblioteca

/* defs.h */

#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<graphics.h>
#include<fcntl.h>
#include<io.h>
#include<sys/stat.h>
#include "pecas.def"

/* definicoes para bioskey */
#define ESC             283
#define ESPACO          14624
#define CIMA            18432
#define BAIXO           20480
#define DIREITA         19712
#define ESQUERDA        19200
#define ENTER           7181


int    MaxX, MaxY;
int    MaxColors;

void interrupt far rotina(void);
void Pause(void);
void Go(void);
void MostraPontos(void);
void Close(char *msg);
void CalculaXY(void);
void ZeraGrade(void);
void SorteiaPeca(void);
void DesenhaGrade(void);
void DesenhaPeca(int x, int y);
void LimpaPeca(int x, int y);
int Move(int Mov);
int ValidaMov(int Mov);
void MarcaGrade(void);
void NovaPeca(void);
void Tabuleiro(void);
int Quadrado(int x, int y);
int QuadradoOff(int x, int y);
int QuadradoColor(int x, int y, int Color);
void ViraPeca(int Peca[][], int Direcao);
void QuebraLinha(void);
void LoadRecord(void);
void SaveRecord(void);


e o ultimo ficheiro um com extensão. def

pecas.def

/*
  Pecas do jogo
*/

#ifndef X_PECAS_DEF
#define X_PECAS_DEF

#define NUMERO_DE_PECAS 7
const int XPeca[NUMERO_DE_PECAS][4][4] =

                             {{{0,1,0,0},
                               {0,1,0,0},
                               {0,1,0,0},
                               {0,1,0,0}},

                              {{0,1,0,0},
                               {0,1,0,0},
                               {0,1,1,0},
                               {0,0,0,0}},

                              {{0,0,1,0},
                               {0,0,1,0},
                               {0,1,1,0},
                               {0,0,0,0}},

                              {{0,1,0,0},
                               {0,1,1,0},
                               {0,0,1,0},
                               {0,0,0,0}},

                              {{0,0,1,0},
                               {0,1,1,0},
                               {0,1,0,0},
                               {0,0,0,0}},

                              {{0,0,0,0},
                               {0,1,1,0},
                               {0,1,1,0},
                               {0,0,0,0}},

                              {{0,1,0,0},
                               {0,1,1,0},
                               {0,1,0,0},
                               {0,0,0,0}}};


#endif
Posted

Este codigo usa muitas extensoes de C que nao existem nos compiladores actuais.

Sem (grandes) alteracoes, nao é possivel compila-lo (a nao ser que tenhas uma maquina onde possas instalar o Borland Turbo C 2.0).

What have you tried?

Não respondo a dúvidas por PM

A minha bola de cristal está para compor; deve ficar pronta para a semana.

Torna os teus tópicos mais atractivos e legíveis usando a tag CODE para colorir o código!

Posted

Olá mais uma vez..queria perceber este jogo,

alguém sabe porque que a peça quando chega ao final da matriz desaparece??

como posso fazer para ficar??

e fazer uma função para associar as teclas é muito dificil??

por favor..alguém me ajude!!

aqui está o código:

/*

2.
Tetris em C, esse jogo é formado por conbinacoes do posicionamento das matrizes

3.
o obijetivo é : fazer um jogo em C usando recurssos simples do sistema, sem muita frescura,

4.
descrever o fuxo do programa para que com isso, outros jogos possam ser criados da mesma forma

5.
Este programa é software livre: você pode redistribuí-lo e / ou modificá-lo sob os termos da

6.
GNU General Public License conforme publicada pela Free Software Foundation, tanto a versão 3 da

7.
Licença, ou (por sua opção) qualquer versão posterior.

8.
a unica obrigação é preservar a referencia ao autor do codigo.

9.
voce pode contribuir com o desenvolvimento do projeto entrando no site www.compudy.com.br

10.
ou por e-main: hudymoreira@gmail.com

11.
htetrisC.0.0.0.1

12.


13.
- Compile através do Dev-Cpp ou CodeBlocks

14.
*/




#include <stdio.h>





int f1(int v1,int v2,int v3,int v4 ,int v5 ,int pec){


    int i, ps[9];


    for(i=0;i<=9;i++){


        ps[i] = 176;


    }




     int pc1(){


        if (i == v1 ){


            ps[3] = 176;


            ps[4] = 254;


            ps[5] = 176;


        }





        if (i == v2 ){


            ps[3] = 254;

            ps[4] = 254;


            ps[5] = 254;


        }





        if (i == v3 ){


            ps[3] = 176;


            ps[4] = 176;


            ps[5] = 176;

        }


    }





    int pc2(){


        if (i == v1 ){

            ps[3] = 254;
            ps[4] = 254;


            ps[5] = 254;


            ps[6] = 254;


        }





        if (i == v2 ){


            ps[3] = 176;


            ps[4] = 176;

            ps[5] = 176;


            ps[6] = 176;


        }


    }


    int pc3(){


        if (i == v1 ){


            ps[3] = 254;


            ps[4] = 254;


            ps[5] = 254;

        }


        if (i == v2 ){


            ps[3] = 254;


            ps[4] = 176;


            ps[5] = 176;


        }





        if (i == v3 ){


            ps[3] = 176;


            ps[4] = 176;


            ps[5] = 176;


        }


    }


    int pc4(){


        if (i == v1 ){


            ps[3] = 254;


            ps[4] = 254;


        }





        if (i == v2 ){


            ps[3] = 254;


            ps[4] = 254;

         }


        if (i == v3 ){


            ps[3] = 176;


            ps[4] = 176;


        }


    }





    int pc5(){


        if (i == v1 ){


            ps[3] = 254;


            ps[4] = 254;


            ps[5] = 176;


        }


        if (i == v2 ){


            ps[3] = 176;


            ps[4] = 254;


            ps[5] = 254;


        }



        if (i == v3 ){


            ps[3] = 176;

            ps[4] = 176;


            ps[5] = 176;


        }

    }





    printf("\t\t%c%c%c%c%c%c%c%c%c%c%c%c\n",201,205,205,205,205,205,205,205,205,205,205,187);





    for(i=1; i<=20; i++){


        switch(pec){


            case  1 :


                pc1();


                break;


            case  2 :


                pc2();


                break;


            case  3 :


                pc3();


                break;

            case  4 :


                pc4();


                break;


            case  5 :


                pc5();


                break;


            default :


                pc1();

        }


        printf("\t\t%c%c%c%c%c%c%c%c%c%c%c%c\n",186,ps[0],ps[1],ps[2],ps[3],ps[4],ps[5],ps[6],ps[7],ps[8],ps[9],186);


    }





    printf("\t\t%c%c%c%c%c%c%c%c%c%c%c%c\n",200,205,205,205,205,205,205,205,205,205,205,188);

}





int jogo(int pec){


    int g, po[2];


    po[0] = 1;


    po[1] = 2;


    po[2] = 3;

    po[3] = 4;

    po[4] = 5;





    for (g=1; g<39; g++){

        f1(po[0],po[1],po[2],po[3],po[4],pec);


        po[0]++;


        po[1]++;


        po[2]++;


        po[3]++;


        po[4]++;

        _sleep(700); system("cls");


    }


}







int main(){


    int i;


    //for (i=1;i<=5;i++){ jogo(i);}


    jogo(1);


    jogo(2);


    jogo(3);

    jogo(4);

    jogo(5);

    getch();

}
Posted

o codigo fica dificil de se perceber quando existem paragrafos exagerados, ma' conduta de programacao(funcoes dentro de funcoes), nomes de variaveis pouco explicitos, sem nenhum comentario...etc... basicamente o codigo esta muito mau(pelo o menos para mim).

Na minha opiniao devias procurar algum tetris em Allegro. Fazer um jogo em "Consola" e' um bocado mau, existem por ai alguns muito bons, mas este que puseste aqui, nem um jogo e'...

Por muito mais que que estude só aprendo uma coisa, que ainda tenho muita coisa para aprender.

A beleza de um código está em decompor problemas complexos em pequenos blocos simples.

"learn how to do it manually first, then use the wizzy tool to save time."

"Kill the baby, don't be afraid of starting all over again. Fail soon, learn fast."

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.