else
return '0 0 0';
}
-
+vector PieceSize(float pc)
+{
+ if (pc == 1)
+ return '2 2 0'; // O
+ else if (pc == 2)
+ return '3 2 0'; // J
+ else if (pc == 3)
+ return '3 2 0'; // L
+ else if (pc == 4)
+ return '4 1 0'; // I
+ else if (pc == 5)
+ return '3 2 0'; // Z
+ else if (pc == 6)
+ return '3 2 0'; // S
+ else if (pc == 7)
+ return '3 2 0'; // T
+ else
+ return '0 0 0';
+}
vector PieceCenter(float pc)
{
if(pc == 1)
float PieceMetric(float x, float y, float rot, float pc)
{
float t;
- vector piece_dat;
- float wid;
+ vector ce;
// return bits of a piece
- wid = piece_dat_z + 1;
- piece_dat = PieceCenter(pc);
+ ce = PieceCenter(pc);
if (rot == 1) // 90 degrees
{
// x+cx, y+cy -> -y+cx, x+cy
// x = X-cx
// y = Y-cy
t = y;
- y = x - piece_dat_x + piece_dat_y;
- x = -t + piece_dat_x + piece_dat_y;
+ y = x - ce_x + ce_y;
+ x = -t + ce_x + ce_y;
}
else if (rot == 2)//180
{
- x = 2 * piece_dat_x - x;
- y = 2 * piece_dat_y - y;
+ x = 2 * ce_x - x;
+ y = 2 * ce_y - y;
}
else if (rot == 3) // 270
{
// x = X-cx
// y = Y-cy
t = y;
- y = -x + piece_dat_y + piece_dat_x;
- x = t - piece_dat_y + piece_dat_x;
+ y = -x + ce_y + ce_x;
+ x = t - ce_y + ce_x;
}
if (x < 1 || y < 1 || x > 4 || y > 2)
return 0;
- piece_dat = PieceShape(pc);
+ ce = PieceShape(pc);
if (y == 1)
- return GetXBlock(x, piece_dat_x); // first row
+ return GetXBlock(x, ce_x); // first row
else if (y == 2)
- return GetXBlock(x, piece_dat_y); // second row
+ return GetXBlock(x, ce_y); // second row
else
return 0; // illegal parms
};
+vector tet_piecemins;
+vector tet_piecemaxs;
+void PieceMinsMaxs(float rot, float pc)
+{
+ vector sz, ce;
+ float t;
+ vector v;
+
+ sz = PieceSize(pc);
+ ce = PieceCenter(pc);
+ // 1 = 2..2
+ // 2 = 2..3
+ // 3 = 1..3
+ // 4 = 1..4
+ tet_piecemins_x = floor(2.5 - sz_x * 0.5);
+ tet_piecemaxs_x = floor(2.0 + sz_x * 0.5);
+ tet_piecemins_y = 1;
+ tet_piecemaxs_y = sz_y;
+ if (rot == 1) // 90 degrees
+ {
+ t = tet_piecemins_y;
+ tet_piecemins_y = -tet_piecemins_x + ce_y + ce_x;
+ tet_piecemins_x = t - ce_y + ce_x;
+ t = tet_piecemaxs_y;
+ tet_piecemaxs_y = -tet_piecemaxs_x + ce_y + ce_x;
+ tet_piecemaxs_x = t - ce_y + ce_x;
+ // swap mins_y, maxs_y
+ t = tet_piecemins_y;
+ tet_piecemins_y = tet_piecemaxs_y;
+ tet_piecemaxs_y = t;
+ // TODO OPTIMIZE
+ }
+ else if (rot == 2)//180
+ {
+ v = tet_piecemins;
+ tet_piecemins = 2 * ce - tet_piecemaxs;
+ tet_piecemaxs = 2 * ce - v;
+ }
+ else if (rot == 3) // 270
+ {
+ t = tet_piecemins_y;
+ tet_piecemins_y = tet_piecemins_x - ce_x + ce_y;
+ tet_piecemins_x = -t + ce_x + ce_y;
+ t = tet_piecemaxs_y;
+ tet_piecemaxs_y = tet_piecemaxs_x - ce_x + ce_y;
+ tet_piecemaxs_x = -t + ce_x + ce_y;
+ // swap mins_x, maxs_x
+ t = tet_piecemins_x;
+ tet_piecemins_x = tet_piecemaxs_x;
+ tet_piecemaxs_x = t;
+ // TODO OPTIMIZE
+ }
+#ifdef VERIFY
+ print(vtos(tet_piecemins), "-");
+ print(vtos(tet_piecemaxs), "\n");
+ if(tet_piecemins_x > tet_piecemaxs_x)
+ error("inconsistent mins/maxs");
+ if(tet_piecemins_y > tet_piecemaxs_y)
+ error("inconsistent mins/maxs");
+ float i, j;
+ for(i = 1; i <= 4; ++i)
+ for(j = 1; j <= 4; ++j)
+ if(PieceMetric(i, j, rot, pc))
+ if(i < tet_piecemins_x || i > tet_piecemaxs_x || j < tet_piecemins_y || j > tet_piecemaxs_y)
+ error(sprintf("incorrect mins/maxs: %d %d in %d rot %d mins %v maxs %v\n", i, j, rot, pc, tet_piecemins, tet_piecemaxs));
+#endif
+}
/*
*********************************
void ClearPiece(float piece, float orgx, float orgy, float rot);
void CementPiece(float piece, float orgx, float orgy, float rot);
float bastet_profile_evaluate_time;
+float bastet_profile_checkmetrics_time;
float BastetSearch(float buf, float pc, float x, float y, float rot, float move_bias)
// returns best score, or -1 if position is impossible
{
string r;
float b;
float s, sm;
+ float t1, t2;
if(move_bias < 0)
return 0; // DO NOT WANT
bufstr_set(buf, b, "0"); // in case we READ that, not that bad - we already got that value in another branch then anyway
-#define ALWAYS_CHECK_METRICS
-#ifdef ALWAYS_CHECK_METRICS
+
+
+ t1 = gettime(GETTIME_HIRES);
if(CheckMetrics(pc, x, y, rot))
-#endif
{
+ t2 = gettime(GETTIME_HIRES);
+ bastet_profile_checkmetrics_time += (t2 - t1);
// try all moves
sm = 1;
s = BastetSearch(buf, pc, x-1, y, rot, move_bias - 1); if(s > sm) sm = s;
s = BastetSearch(buf, pc, x+1, y, rot, move_bias - 1); if(s > sm) sm = s;
s = BastetSearch(buf, pc, x, y, rot+1, move_bias - 1); if(s > sm) sm = s;
s = BastetSearch(buf, pc, x, y, rot-1, move_bias - 1); if(s > sm) sm = s;
-
-#ifndef ALWAYS_CHECK_METRICS
- if(CheckMetrics(pc, x, y+1, rot))
- {
-#endif
- s = BastetSearch(buf, pc, x, y+1, rot, move_bias + 2); if(s > sm) sm = s;
-#ifndef ALWAYS_CHECK_METRICS
- }
- else
- s = -1;
-#endif
+ s = BastetSearch(buf, pc, x, y+1, rot, move_bias + 2); if(s > sm) sm = s;
if(s < 0)
{
//print(sprintf("MAY CEMENT AT: %d %d %d\n", x, y, rot));
// moving down did not work - that means we can fixate the block here
- var float t1 = gettime(GETTIME_HIRES);
+ t1 = gettime(GETTIME_HIRES);
CementPiece(pc, x, y, rot);
s = BastetEvaluate();
ClearPiece(pc, x, y, rot);
- var float t2 = gettime(GETTIME_HIRES);
+ t2 = gettime(GETTIME_HIRES);
bastet_profile_evaluate_time += (t2 - t1);
if(s > sm) sm = s;
}
}
-#ifdef ALWAYS_CHECK_METRICS
else
+ {
+ t2 = gettime(GETTIME_HIRES);
+ bastet_profile_checkmetrics_time += (t2 - t1);
sm = -1; // impassible
-#endif
+ }
bufstr_set(buf, b, ftos(sm));
float b;
bastet_profile_evaluate_time = 0;
+ bastet_profile_checkmetrics_time = 0;
var float t1 = gettime(GETTIME_HIRES);
b = buf_create(); bastet_piece[0] = 1; bastet_score[0] = BastetSearch(b, 1, TET_START_PIECE_POS_x, 1+TET_START_PIECE_POS_y, TET_START_PIECE_POS_y, TET_WIDTH) + 100 * random() + bastet_piecetime[0]; buf_del(b);
b = buf_create(); bastet_piece[6] = 7; bastet_score[6] = BastetSearch(b, 7, TET_START_PIECE_POS_x, 1+TET_START_PIECE_POS_y, TET_START_PIECE_POS_y, TET_WIDTH) + 100 * random() + bastet_piecetime[6]; buf_del(b);
var float t2 = gettime(GETTIME_HIRES);
- dprint(sprintf("Time taken: %.6f seconds (of this, ev = %.2f%%)\n", t2 - t1, 100 * bastet_profile_evaluate_time / (t2 - t1)));
+ dprint(sprintf("Time taken: %.6f seconds (of this, ev = %.2f%%, cm = %.2f%%)\n", t2 - t1, 100 * bastet_profile_evaluate_time / (t2 - t1), 100 * bastet_profile_checkmetrics_time / (t2 - t1)));
// sort
float i, j, k, p, s;
{
// check to see if the piece, if moved to the locations will overlap
- float x, y;
+ float x, y, l;
// why did I start counting from 1, damnit
orgx = orgx - 1;
orgy = orgy - 1;
- for (y = 1; y < 5; y = y + 1)
+ PieceMinsMaxs(rot, piece);
+ for (y = tet_piecemins_y; y <= tet_piecemaxs_y; y = y + 1)
{
- for (x = 1; x < 5; x = x + 1)
+ l = GetLine(y + orgy);
+ for (x = tet_piecemins_x; x <= tet_piecemaxs_x; x = x + 1)
{
if (PieceMetric(x, y, rot, piece))
{
- if (GetSquare(x + orgx, y + orgy))
+ if (GetXBlock(x + orgx, l))
return FALSE; // uhoh, gonna hit something.
if (x+orgx<1 || x+orgx > TET_WIDTH || y+orgy<1 || y+orgy> TET_LINES)
return FALSE; // ouside the level
void ClearPiece(float piece, float orgx, float orgy, float rot) /*FIXDECL*/
{
-
float x, y;
// why did I start counting from 1, damnit
orgx = orgx - 1;
orgy = orgy - 1;
- for (y = 1; y < 5; y = y + 1)
+ PieceMinsMaxs(rot, piece);
+ for (y = tet_piecemins_y; y <= tet_piecemaxs_y; y = y + 1)
{
- for (x = 1; x < 5; x = x + 1)
+ for (x = tet_piecemins_x; x <= tet_piecemaxs_x; x = x + 1)
{
if (PieceMetric(x, y, rot, piece))
{
pcolor = mod(piece, 3) + 1;
- for (y = 1; y < 5; y = y + 1)
+ PieceMinsMaxs(rot, piece);
+ for (y = tet_piecemins_y; y <= tet_piecemaxs_y; y = y + 1)
{
- for (x = 1; x < 5; x = x + 1)
+ for (x = tet_piecemins_x; x <= tet_piecemaxs_x; x = x + 1)
{
if (PieceMetric(x, y, rot, piece))
{