七行プログラミング

このエントリーをはてなブックマークに追加
354トリッキーの1
int put,turn,all,done,pass,count,cur,i,
    // 盤状態:横9*縦10で、使用は8*8
    // 0:無し 1:1player 2:2player 3:改行
    // y*9+xというイメージ。0行目と9行目は番兵
    map[90]={0},
    // 盤を走査する場合、縦横斜め方向に向かうために足されるべき数
    dir[]={-10,-9,-8,-1,1,8,9,10};
void check()
// putに駒を置いた場合ひっくり返せる枚数をallに足す
{
  if(map[put]==0)
    for(i=0;i<8;i++)
    // 8方向走査
    {
      // dir[i]の方向の相手のコマの数を確認
      for(count=0,cur=put+dir[i];map[cur]==3-turn;cur+=dir[i])
        count++;
      if(count && map[cur]==turn)
      // 1枚以上存在し、その上端が自分のコマだったら
      {
        all+=count;
        cur=put;
        if(done)
        // doneがtrueの場合は、実際にひっくり返す
          do map[cur]=turn,cur+=dir[i]; while(map[cur]!=turn);
      }
    }
}
// mapに対応するオセロ駒&改行
char *h="・○●\n";
int main()
{
  // 初期化
  for(i=1,map[41]=map[49]=2;i<10;map[i++*9]=3)
    map[40]=map[50]=turn=pass=1;
  /* for(i=1;i<10;i++) map[i*9]=3;
    map[9*4+4]=map[9*5+5]=1;map[9*4+5]=map[9*5+4]=2;
    turn=pass=1; */
  for(;;all=done=0) // ループのたびにallとdoneを初期化(セミコロン1個削除するため)
  {
    // 盤の表示。今回のデータ構造だとこれで表示できる
    // ついでにdone=0でcheckを呼び、何枚駒を置けるのチェック
    for(put=9;put<82;++put)
      check(),printf("%.2s",&h[map[put]*2]);
    if(all)
      // 1枚でも駒が置けた場合はcomは左上から走査、人は置けるまで繰り返す
      // 置けた(=allの値が変わった)らturn終了
      for(done=all=pass=put=8;all==8;check())
        turn-2?(scanf("%d %d",&put,&i),put+=i*9):++put;
    else if(pass)
      // 駒を置けない。s=0にしてフラグを立てる
      pass=0,printf("pass");
    else
      // 両者とも駒を置けないので終了
      break;
    turn=3-turn; // turn交代:1->2,2->1
  }
  return 0;
}