2017-01-19 17 views
2

私は現在、if文を多く必要とするゲームを作っています。ユーザーが指定された座標をクリックするかどうかを確認します。以下のコードは完全に正常に動作しますが、これを行うための効率的な方法(このコードだけでなく、一般的なコード)にも問題があります。このためCプログラミングの複数のif/else if文を単純化する方法

if((mx > 78) && (mx < 113) && (my > 157) && (my < 191)) ifff(0, 0, 78, 157, 113, 191); 
else if((mx > 116) && (mx < 150) && (my > 157) && (my < 191)) ifff(1, 0, 116, 157, 150, 191); 
else if((mx > 153) && (mx < 188) && (my > 157) && (my < 191)) ifff(2, 0, 153, 157, 188, 191); 
else if((mx > 196) && (mx < 230) && (my > 157) && (my < 191)) ifff(3, 0, 196, 157, 230, 191); 
else if((mx > 233) && (mx < 267) && (my > 157) && (my < 191)) ifff(4, 0, 233, 157, 267, 191); 
else if((mx > 270) && (mx < 303) && (my > 157) && (my < 191)) ifff(5, 0, 270, 157, 303, 191); 
else if((mx > 311) && (mx < 345) && (my > 157) && (my < 191)) ifff(6, 0, 311, 157, 345, 191); 
else if((mx > 348) && (mx < 384) && (my > 157) && (my < 191)) ifff(7, 0, 348, 157, 384, 191); 
else if((mx > 388) && (mx < 421) && (my > 157) && (my < 191)) ifff(8, 0, 388, 157, 421, 191); 

else if((mx > 78) && (mx < 113) && (my > 194) && (my < 229)) ifff(0, 1, 78, 194, 113, 229); 
else if((mx > 116) && (mx < 150) && (my > 194) && (my < 229)) ifff(1, 1, 116, 194, 150, 229); 
else if((mx > 153) && (mx < 188) && (my > 194) && (my < 229)) ifff(2, 1, 153, 194, 188, 229); 
else if((mx > 196) && (mx < 230) && (my > 194) && (my < 229)) ifff(3, 1, 196, 194, 230, 229); 
else if((mx > 233) && (mx < 267) && (my > 194) && (my < 229)) ifff(4, 1, 233, 194, 267, 229); 
else if((mx > 270) && (mx < 303) && (my > 194) && (my < 229)) ifff(5, 1, 270, 194, 303, 229); 
else if((mx > 311) && (mx < 345) && (my > 194) && (my < 229)) ifff(6, 1, 311, 194, 345, 229); 
else if((mx > 348) && (mx < 384) && (my > 194) && (my < 229)) ifff(7, 1, 348, 194, 384, 229); 
else if((mx > 388) && (mx < 421) && (my > 194) && (my < 229)) ifff(8, 1, 388, 194, 421, 229); 

else if((mx > 78) && (mx < 113) && (my > 231) && (my < 266)) ifff(0, 2, 78, 231, 113, 266); 
else if((mx > 116) && (mx < 150) && (my > 231) && (my < 266)) ifff(1, 2, 116, 231, 150, 266); 
else if((mx > 153) && (mx < 188) && (my > 231) && (my < 266)) ifff(2, 2, 153, 231, 188, 266); 
else if((mx > 196) && (mx < 230) && (my > 231) && (my < 266)) ifff(3, 2, 196, 231, 230, 266); 
else if((mx > 233) && (mx < 267) && (my > 231) && (my < 266)) ifff(4, 2, 233, 231, 267, 266); 
else if((mx > 270) && (mx < 303) && (my > 231) && (my < 266)) ifff(5, 2, 270, 231, 303, 266); 
else if((mx > 311) && (mx < 345) && (my > 231) && (my < 266)) ifff(6, 2, 311, 231, 345, 266); 
else if((mx > 348) && (mx < 384) && (my > 231) && (my < 266)) ifff(7, 2, 348, 231, 384, 266); 
else if((mx > 388) && (mx < 421) && (my > 231) && (my < 266)) ifff(8, 2, 388, 231, 421, 266); 

else if((mx > 78) && (mx < 113) && (my > 231) && (my < 266)) ifff(0, 3, 78, 231, 113, 266); 
else if((mx > 116) && (mx < 150) && (my > 231) && (my < 266)) ifff(1, 3, 116, 231, 150, 266); 
else if((mx > 153) && (mx < 188) && (my > 231) && (my < 266)) ifff(2, 3, 153, 231, 188, 266); 
else if((mx > 196) && (mx < 230) && (my > 231) && (my < 266)) ifff(3, 3, 196, 231, 230, 266); 
else if((mx > 233) && (mx < 267) && (my > 231) && (my < 266)) ifff(4, 3, 233, 231, 267, 266); 
else if((mx > 270) && (mx < 303) && (my > 231) && (my < 266)) ifff(5, 3, 270, 231, 303, 266); 
else if((mx > 311) && (mx < 345) && (my > 231) && (my < 266)) ifff(6, 3, 311, 231, 345, 266); 
else if((mx > 348) && (mx < 384) && (my > 231) && (my < 266)) ifff(7, 3, 348, 231, 384, 266); 
else if((mx > 388) && (mx < 421) && (my > 231) && (my < 266)) ifff(8, 3, 388, 231, 421, 266); 
+0

「else if」ステートメントの4番目のブロックは、copy'n'paste-itisに苦しんでいます。 3番目のブロックと同じy範囲( 'my> 231 && my <266')を持っているので、範囲が一致すると3番目のブロックが優先され、そうでなければ、一連の繰り返し失敗するテストの –

答えて

2

interval treesのようなデータ構造があり、このデータ構造に関するアルゴリズムのMITのコースからCormenから章や、いくつかの講義を参照してください。

3

基本的な考え方は、データ構造内のコード内の各行/ブロック内のデータを表現し、それらのデータ構造の配列を作成してループする方法を見つけることです。

最も簡単なことは、これらの各条件について必要なデータを保持する配列を作成することです。例えば

[78, 113, 157, 191] # represents first if statement 

そして、あなたは、上記の各セクションを持っている9つの条件を表すであろう9ようなアレイのアレイを作成することができます。

次に、4つのそのような配列の配列を作成します。ここで、各メンバーはコード内の各セクションを表すことになります。

for (i=0; i<4; i++) 
    for (j=0; j<9; j++) 
     if (mx > my_map[i][j][0]) && (mx < my_map[i][j][1]) ... 
      ifff(j, i, my_map[i][j][0], .... 

あなたが読み上で簡単になりますこれは、構造体の代わりに、配列を使用することができますが、それはだから、私は例を与えることはできません。同じよう

それらのすべてを

最後に、あなただけのループ、異なるセクションが表すはずのものがコードからはっきりと分かりません。

1

あなたのインターバルの中でいくつかの構造が設定されているようです。それは読書の規則を破るだろうが、すべてが価格を持って、もちろん

if ((mx > 78) && (mx < 113) 
    if (condition on my) 
    else if (condition on my) 
    ... 
else if (condition on mx) 
    if (condition on my) 
    else if (condition on my) 
    ... 

((mx > 78) && (mx < 113))はそのあとのように、コード内でその構造を反映することができる...数回使用されています。あなたも(アイデアは、一度任意の条件をテストすることがある)以上分解することがあります。

if (mx > 78) 
     if (mx < 113) 
      if (first condition on my) 
       if (second condition on my) 
    ... 
1

私はコメントで述べたように、else if文のあなたの第4ブロックはcopy'n'paste-ITISに苦しんでいます。第3ブロックと同じy範囲(my > 231 && my < 266)を持っています。したがって、範囲が一致すると3番目のブロックが優先され、一致しない場合は失敗する一連のテストを繰り返し実行するだけなので、使用することは決してありません。

しかし、あなたがはるかに優れたテーブルのカップル、検索機能、およびこのようなifff()機能への単一の呼び出しで表すことができ、かなり明確な構造を持っている:このデータでは

struct Range 
{ 
    int lo; 
    int hi; 
    int key; 
}; 

static const struct Range x_range[] = 
{ 
    { 78, 113, 0 }, 
    { 116, 150, 1 }, 
    { 153, 188, 2 }, 
    { 196, 230, 3 }, 
    { 233, 267, 4 }, 
    { 270, 303, 5 }, 
    { 311, 345, 6 }, 
    { 348, 384, 7 }, 
    { 388, 421, 8 }, 
}; 
enum { NUM_X_RANGE = sizeof(x_range)/sizeof(x_range[0]) }; 

static const struct Range y_range[] = 
{ 
    { 157, 191, 0 }, 
    { 194, 229, 1 }, 
    { 231, 266, 2 }, 
    { 268, 299, 3 }, /* Guessed range */ 
}; 
enum { NUM_Y_RANGE = sizeof(y_range)/sizeof(y_range[0]) }; 

static inline int range_lookup(int val, const struct Range *range, int num_ranges) 
{ 
    for (int i = 0; i < num_ranges; i++) 
    { 
     if (val > range[i].lo && val < range[i].hi) 
      return i; 
    } 
    return -1; 
} 

extern void ifff_range(int mx, int my); 
extern void ifff(int xkey, int ykey, int xlo, int ylo, int xhi, int yhi); 

void ifff_range(int mx, int my) 
{ 
    int xr = range_lookup(mx, x_range, NUM_X_RANGE); 
    int yr = range_lookup(my, y_range, NUM_Y_RANGE); 
    if (xr != -1 && yr != -1) 
     ifff(x_range[xr].key, y_range[yr].key, 
      x_range[xr].lo, y_range[yr].lo, 
      x_range[xr].hi, y_range[yr].hi); 
} 

を構造体のキー値は配列の行のインデックスと同じなので、構造体からキーを削除することができます。 ルックアップが失敗する方法はたくさんあります。たとえば、mx == 114またはmy == 192は常に失敗します。

関連する問題