C 1009
#include <stdio.h>
#define L for(n=0;n<18;++n)
int T[19]={54,561,99,306,785,23,547,116,802,71,275,116,39,562,114,305,51,4369,15},W[19]={3,2,3,2,2,3,2,3,2,3,2,3,3,2,3,2,2,1,4},O[7]={0,2,4,8,12,16,17},R[7]={2,2,4,4,4,1,2},G[18],F[24],t=0,I,x,y,S[99],X[99],Y[99],N[99],s,M=0,i,j,k,l,m,n,h,c;char B[99],*C="SZLJTOI";void A(){for(m=0;m<24;++m)F[m]=0;for(m=0;m<4;++m)F[y+m]=(T[I]>>(m*4)&15)<<x;}void D(){S[s]=0;L S[s]+=(G[n]|F[n])==1023;S[s]=200*(S[s])+199;for(m=0;m<10;++m){l=0;L{h=(G[n]|F[n])&1<<m;l|=h;S[s]-=l&&!h;}}}int E(){A();c=0;L c|=G[n]&F[n];return !c;}int main(){S[0]=0;gets(B);while(C[t]!=B[0])++t;I=O[t];L{G[n]=0;gets(B);for(m=0;m<10;++m)G[n]|=(B[m]=='+')?(1<<m):0;}s=0;D();for(i=0;i<R[t];++i){for(x=0;x<10-W[I];x++){y=0;while(E())y++;--y;++s;A();D();if(S[s]>M)M=S[s];X[s]=x;Y[s]=y;N[s]=I;}I++;}for(i=1;i<s;++i)if(S[i]==M){j=i;x=X[i];y=Y[i];I=N[i];A();for(n=1;n<18;++n){for(m=0;m<10;++m)printf((G[n]&1<<m)!=0?"+":((F[n]&1<<m)!=0?"#":" "));printf("\n");}}printf("%dL %dH\n",S[j]/200,S[0]%200-S[j]%200);}
Here is the ungolfed version
#include <stdio.h>
int tiles[19] = {54,561,99,306,785,23,547,116,802,71,275,116,39,562,114,305,51,4369,15};
int widths[19] = {3,2,3,2,2,3,2,3,2,3,2,3,3,2,3,2,2,1,4};
char *codes = "SZLJTOI";
int offsets[7] = {0,2,4,8,12,16,17};
int transformations[7] = {2,2,4,4,4,1,2};
int gameField[18], tileField[24];
int i,j,k,l,m,n,h;
char buffer[99];
int tile=0, tileIndex;
int xpos, ypos;
int scores[99], xplacements[99], yplacements[99], tindex[99];
int scoreIndex, maxScore=0;
void readGame()
{
gets(buffer);
while (codes[tile]!=buffer[0]) ++tile;
tileIndex = offsets[tile];
for (n=0;n<18;++n)
{
gameField[n] = 0;
gets(buffer);
for (m=0; m<10;++m)
gameField[n] |= (buffer[m]=='+')?(1<<m):0;
}
}
void writeGame()
{
for (n=1;n<18;++n)
{
for (m=0; m<10;++m)
printf( (tileField[n] & 1<<m) != 0 ? "#" :((gameField[n] & 1<<m) != 0 ? "+" :" "));
printf("\n");
}
}
void placeTile()
{
for (m=0;m<24;++m) tileField[m] = 0;
for (m=0;m<4;++m)
tileField[ypos+m] = (tiles[tileIndex]>>(m*4) & 15) << xpos;
}
void score()
{
scores[scoreIndex] = 0;
for (n=0;n<18;++n)
if ((gameField[n] | tileField[n])==1023) scores[scoreIndex]++;
scores[scoreIndex] = 200*(scores[scoreIndex]) + 199;
for (m=0;m<10;++m)
{
l=0;
for (n=0;n<18;++n)
{
h = (gameField[n] | tileField[n]) & 1<<m;
l |= h;
scores[scoreIndex] -= l && !h;
}
}
}
int noCollision()
{
placeTile();
int coll = 0;
for (n=0;n<18;++n) coll |= gameField[n] & tileField[n];
return !coll;
}
int main()
{ scores[0] = 0;
readGame();
scoreIndex = 0;
score();
for (i=0; i<transformations[tile]; ++i)
{
for (xpos=0; xpos<10-widths[tileIndex]; xpos++)
{
ypos = 0;
while (noCollision()) ypos++;
--ypos;
++scoreIndex;
placeTile();
score();
if (scores[scoreIndex]>maxScore) maxScore=scores[scoreIndex];
xplacements[scoreIndex] = xpos;
yplacements[scoreIndex] = ypos;
tindex[scoreIndex] = tileIndex;
}
tileIndex++;
}
for (i=1;i<scoreIndex; ++i)
if (scores[i]==maxScore)
{
j=i;
xpos = xplacements[i];
ypos = yplacements[i];
tileIndex = tindex[i];
placeTile();
writeGame();
}
printf("%dL %dH\n", scores[j]/200, scores[0]%200-scores[j]%200);
}
I saw that the main source of lengthy code would probably be the definition of the tiles. So I decided to represent them as bit patterns in a 4x4 bit array. This results in 16 bits that easily fit into a single int
. The tiles
array holds all the patterns for the 19 possible rotations of the 7 tiles.
When compiling, ignore the warning that gets
is deprecated. I know it is but it is the shortest way of reading a line from the input.