#include <stdio.h>
#include <stdlib.h>
#define DEBUG 1
#ifdef ONLINE_JUDGE
#define DEBUG 0
#endif
struct pt {
int i, j;
};
int grid[15];
char line[111];
int fig_counts[7] = {2,4,4,1,2,4,2};
int fig_heights[7][4] = {
{1,4},
{2,3,3,2},
{2,3,2,3},
{2},
{2,3},
{2,3,2,3},
{2,3},
};
int figs[7][4][4] = {
{ // I
{(1<<0)|(1<<1)|(1<<2)|(1<<3)},
{(1<<0),(1<<0),(1<<0),(1<<0)},
},
{ // J
{(1<<0)|(1<<1)|(1<<2),(1<<0)},
{(1<<0)|(1<<1),(1<<1),(1<<1)},
{(1<<0),(1<<0),(1<<0)|(1<<1)},
{(1<<2),(1<<0)|(1<<1)|(1<<2)},
},
{ // L
{(1<<0)|(1<<1)|(1<<2),(1<<2)},
{(1<<0)|(1<<1),(1<<0),(1<<0)},
{(1<<0),(1<<0)|(1<<1)|(1<<2)},
{(1<<1),(1<<1),(1<<0)|(1<<1)},
},
{ // O
{(1<<0)|(1<<1),(1<<0)|(1<<1)},
},
{ // S
{(1<<0)|(1<<1),(1<<1)|(1<<2)},
{(1<<1),(1<<0)|(1<<1),(1<<0)},
},
{ // T
{(1<<0)|(1<<1)|(1<<2),(1<<1)},
{(1<<0),(1<<0)|(1<<1),(1<<0)},
{(1<<1),(1<<0)|(1<<1)|(1<<2)},
{(1<<1),(1<<0)|(1<<1),(1<<1)},
},
{ // Z
{(1<<1)|(1<<2),(1<<0)|(1<<1)},
{(1<<0),(1<<0)|(1<<1),(1<<1)},
},
};
void print() {
for (int i = 14; i >= 0; i–) {
for (int j = 0; j < 15; j++) {
printf("%c “, grid[i] & (1<<j) ? ‘#’ : ‘.’);
}
printf(”\n");
}
}
/////////////////////////////////////////////////////////
/*
*/
int type;
int move;
bool cvis[15][15];
int cdi[4] = {0, 1, 0, -1};
int cdj[4] = {1, 0, -1, 0};
int visit(int i, int j) {
int size = 1;
cvis[i][j] = true;
for (int d = 0; d < 4; d++) {
int ni = i + cdi[d];
int nj = j + cdj[d];
if (0 <= ni && ni < 15 && 0 <= nj && nj < 15) {
if (!cvis[ni][nj]) {
size += visit(ni, nj);
}
}
}
return size;
}
double compute_score(int rot, int i, int j, int clears) {
int holes = 0;
for (int I = 0; I < 15; I++) {
for (int J = 0; J < 15; J++) {
cvis[I][J] = (grid[I] & (1<<J)) != 0;
}
}
for (int J = 0; J < 15; J++) {
if (!cvis[14][J]) {
visit(14, J);
}
}
for (int I = 0; I < 15; I++) {
for (int J = 0; J < 15; J++) {
if (!cvis[I][J]) {
holes += visit(I, J);
}
}
}
int height = 0;
int bump = 0;
int prev = 0;
for (int J = 0; J < 15; J++) {
int I = 14;
while (I >= 0 && !(grid[I] & (1<<J))) I–;
height += ++I;
if (J) {
bump += abs(prev - I);
prev = I;
}
}
#define aa -0.510066
#define bb 0.760666
#define cc -0.35663
#define dd -0.184483
return aa * height + bb * clears + cc * holes + dd * bump + ((double)rand() / RAND_MAX) * 0.001;
}
/////////////////////////////////////////////////////////
int rrot;
int ri, rj;
double rscore;
int do_move(int rot, int i, int j) {
for (int I = 0; I < fig_heights[type][rot]; I++) {
grid[i + I] |= figs[type][rot][I] << j;
}
// clear lines
int curr = 0;
for (int i = 0; i < 15; i++) {
if (grid[i] != (1<<15)-1) grid[curr++] = grid[i];
}
int clears = 0;
while (curr < 15) clears++, grid[curr++] = 0;
return clears;
}
int _grid[15];
void compute_move_pos(int rot, int i, int j) {
for (int i = 0; i < 15; i++) _grid[i] = grid[i];
int clears = do_move(rot, i, j);
double score = compute_score(rot, i, j, clears);
if (rscore < score) {
rscore = score;
rrot = rot;
ri = i;
rj = j;
}
for (int i = 0; i < 15; i++) grid[i] = _grid[i];
}
bool vis[16][15];
int good[16][15];
pt queue[16*15];
int di[3] = {-1, 0, 0};
int dj[3] = {0, 1, -1};
void compute_move_rot(int rot) {
for (int i = 0; i <= 15; i++) {
for (int j = 0; j < 15; j++) {
vis[i][j] = false;
good[i][j] = 0;
}
}
int q = 1;
queue[0].i = 15;
queue[0].j = 0;
vis[15][0] = true;
for (int f = 0; f < q; f++) {
int i = queue[f].i;
int j = queue[f].j;
if (i + fig_heights[type][rot] <= 15) {
bool good = false;
for (int h = 0; h < fig_heights[type][rot]; h++) {
int I = i + h;
if (!I || (grid[I-1] & (figs[type][rot][h] << j))) {
good = true;
break;
}
}
if (good) {
compute_move_pos(rot, i, j);
}
}
for (int d = 0; d < 3; d++) {
int ni = i + di[d];
int nj = j + dj[d];
if (0 <= ni && ni <= 15 && 0 <= nj && nj < 15 && !vis[ni][nj]) {
if (!good[ni][nj]) {
// compute_good
good[ni][nj] = 2;
for (int h = 0; h < fig_heights[type][rot]; h++) {
if (ni + h >= 15) break;
if (((figs[type][rot][h] << nj) >= 1<<15) || (grid[ni + h] & (figs[type][rot][h] << nj))) {
good[ni][nj] = 1;
break;
}
}
}
if (good[ni][nj] == 2) {
queue[q].i = ni;
queue[q].j = nj;
vis[ni][nj] = true;
q++;
}
}
}
}
}
void compute_move(int fix) {
rscore = -1e111;
if (fix >= 0) {
compute_move_rot(fix);
} else {
// compute valid positions
for (int rot = 0; rot < fig_counts[type]; rot++) {
compute_move_rot(rot);
}
}
}
int main() {
srand(11);
for (move = 0;; move++) {
scanf("%s", line);
char ptype = *line;
if (ptype == ‘1’ || ptype == ‘2’) {
scanf("%d", &type);
type–;
int fix = -1;
if (ptype == ‘2’) {
scanf("%s", line);
fix = *line - ‘a’;
}
if (DEBUG) {
printf("new piece\n");
for (int i = fig_heights[type][0] - 1; i >= 0; i--) {
for (int j = 0; j < 4; j++) {
printf("%c ", figs[type][0][i] & (1<<j) ? '#' : '.');
}
printf("\n");
}
}
compute_move(fix);
printf("%c %d %d\n", 'a' + rrot, 15 - ri, rj + 1);
fflush(stdout);
do_move(rrot, ri, rj);
if (DEBUG) print();
} else break;
}
if (DEBUG) printf("DONE. moves=%d\n", move);
}