worms.c: formatting of complicated conditionals
Kragen Javier Sitaker
kragen at canonical.org
Thu Jul 3 03:37:02 EDT 2008
// Diomidis Spinellis's book "Code Reading: An Open Source
// Perspective" has this messy code in chapter 2
// > http://www.spinellis.gr/codereading/spinellisch02.pdf
// from netbsdsrc/games/worms/worms.c:419:
op = &(!x ? (!y ? upleft : (y == bottom ? lowleft : left)) :
(x == last ? (!y ? upright : (y == bottom ? lowright : right)) :
(!y ? upper : (y == bottom ? lower : normal))))[w->orientation];
// He rewrites it as follows, the idea being to improve its
// readability:
struct options *locations[3][3] = {
{upleft, upper, upright},
{left, normal, right},
{lowleft, lower, lowright},
};
int xlocation, ylocation;
// Determine x offset
if (x == 0)
xlocation = 0;
else if (x == last)
xlocation = 2;
else
xlocation = 1;
// Determine y offset
if (y == 0)
ylocation = 0;
else if (y == bottom)
ylocation = 2;
else
ylocation = 1;
op = &(locations[ylocation][xlocation])[w->orientation];
// In my opinion, the above is actually worse than the original, as a
// result of being so much longer. However, then Spinellis suggests
// this version, which he credits to Guy Steele:
op =
&( !y ? (!x ? upleft : x!=last ? upper : upright ) :
y!=bottom ? (!x ? left : x!=last ? normal : right ) :
(!x ? lowleft : x!=last ? lower : lowright )
)[w->orientation];
// I agree that the code needs rewriting, but inspired by Scheme, I
// would do it without magic numbers, without nine separate variables
// for the struct options pointers, and with conditions and their
// consequents on the same line:
struct bar { struct options *left, *middle, *right } upper, middle, lower;
struct bar *a = (y == 0 ? &upper :
y == bottom ? &lower :
&middle);
struct options *b = (x == 0 ? a->left :
x == last ? a->right :
a->middle);
op = &b[w->orientation];
More information about the Kragen-tol
mailing list