七行プログラミング

このエントリーをはてなブックマークに追加
337トリッキーの1
面白い題材が上がっていたので復帰します(笑)
7行オセロ、人間対無能AIです。

#include <stdio.h>
int p,t,a,d,c,v,i,m[90]={0},s,r[]={-10,-9,-8,-1,1,8,9,10};void k(){if(m[p]==0)
for(i=0;i<8;i++){for(c=0,v=p+r[i];m[v]==3-t;v+=r[i])c++;if(c&&m[v]==t){a+=c;v=
p;if(d)do m[v]=t,v+=r[i];while(m[v]!=t);}}}char*h="・○●\n";int main(){for(i=
1,m[41]=m[49]=2;i<10;m[i++*9]=3)m[40]=m[50]=t=s=1;for(;;a=d=0){for(p=9;p<82;++
p)k(),printf("%.2s",&h[m[p]*2]);if(a)for(d=a=s=p=8;a==8;k())t-2?(scanf("%d %d"
,&p,&i),p+=i*9):++p;else if(s)s=0,printf("pass");else break;t=3-t;}return 0;}

もはやインデントを揃えた位では元のコードが読めなくなってしまっていますが、
もしコメント付き変数名まとものバージョンを欲しい方がいれば上げます。
338トリッキーの1:2001/08/21(火) 23:58
人間の入力は、「X軸 Y軸」と半角で入力します。
置けない場所を指定した場合は再度入力してください。
X=55などの変な入力をチェックしていないので、即クラッシュします。
両者置けなくなったらプログラム終了です。自分で数えてください。
もっとも、このコンピュータは激弱ですので負けようがないとおもいますが(笑


・・・・・・・・
・・・・・・・・
・・・・・・・・
・・・○●・・・
・・・●○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
3 5

・・・・・・・・
・・・・・・・・
・・・・・・・・
・・・○●・・・
・・○○○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・

・・・・・・・・
・・・・・・・・
・・・・・・・・
・・●●●・・・
・・○○○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
1 1
3 3

・・・・・・・・
・・・・・・・・
・・○・・・・・
・・○○●・・・
・・○○○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・

・・・・・・・・
・・・・・・・・
・・○・・・・・
・●●●●・・・
・・○○○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
339デフォルトの名無しさん:2001/08/22(水) 00:06
すごひ
340300:2001/08/22(水) 00:21
むむむ・・・・変なことするより配列素直に使った方が良いのかな??
ちょっと悔しい・・・・
さすがです。
341デフォルトの名無しさん:2001/08/22(水) 00:23
>>337
うわ、マジでオセロですか?コンピュータと対戦ですか?
信じられない・・
342デフォルトの名無しさん:2001/08/22(水) 00:25
つーかinclude含めて7行だし。
343327:2001/08/22(水) 00:28
>>337
うぁ、凄いー!!
今コード展開してるんですが、、、あまりに凄すぎて笑えてくる
見るべきところの多いコードで、参考になりまくりだ、ありがとう。
344トリッキーの1:2001/08/22(水) 00:42
>>340=300
このスレの初期の頃の砂嵐プログラムで、効率的な削り方を覚えました。
あれ、今年の3月だったんだなぁ。懐かしいというか(笑)。

>>343
ありがとうです。番兵を駆使してとにかくif文から逃げました。
後はもう小手先のテクニックでひたすら1文字ずつ……。
途中の三項演算子のトリックに気付いて、やっと7行が見えましたね。
345デフォルトの名無しさん:2001/08/22(水) 01:17
>>337
等幅で見てたらなんか芸術を感じた
コードに圧倒された気分だ。とにかくすげぇ
346デフォルトの名無しさん:2001/08/22(水) 02:34
感動age
347デフォルトの名無しさん:2001/08/22(水) 03:15
本当にどうでもいいがグローバル h は消去できるね
しかし文字数を減らすと綺麗に7行にならない。
すごい
感動した
348デフォルトの名無しさん:2001/08/22(水) 03:33
sageさせるかぁぁぁぁぁ!!!!!!!!!
349デフォルトの名無しさん:2001/08/22(水) 04:44
>>337
まともヴァージョンアプきぼん!
350デフォルトの名無しさん:2001/08/22(水) 06:59
>>337
コメント付きバージョンUPきぼん!!
351デフォルトの名無しさん:2001/08/22(水) 09:56
>>337
すげぇ…アンタハッカーだよ!
352300:2001/08/22(水) 10:46
今までちょっといんちきだったけど、正真証明、1行79字以内7行だと思う。
行き詰まったので次のネタ探し(^^;

#include <stdio.h>
long k,b=0,z[]={0x15,0x1041,0x10101,0x1110};char s[]=" 012",d(long a,long b){
return ((a&b)==b);};int h,i,j,l,main(){for(l=0;l<9;l++){puts(" 012");for
(i=0;i<3;i++){s[0]=i+'0';for(j=0;j<3;j++)s[j+1]=" xo"[b>>(i*6+j*2)&3];puts(s);}
if(d(k=(b>>(h=l%2)),z[0])||d(k>>6,z[0])||d(k>>12,z[0])||d(k,z[1])||d(k>>2,z[1])
||d(k>>4,z[1])||d(k,z[2])||d(k,z[3])){puts("x won\0o won"+h*6);return h;}
puts("O?\0X?"+h*3);scanf("%d,%d",&j,&i);b+=(2L-h)<<(i*6+j*2);}return 0;}
353トリッキーの1:2001/08/22(水) 11:25
皆さん反応サンクスです。エンジニア冥利につきます(笑)

>>347
マジで盲点でした。なるほど、確かにその通りです。
やっぱり一人でやるとどこかに盲点が出来るな……。
参考になりました。

>>350,351
次にsageで載せておきます。参考になれば幸いです。
354トリッキーの1:2001/08/22(水) 11:26
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;
}