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
・・・・・・・・
・・・・・・・・
・・○・・・・・
・・○○●・・・
・・○○○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
・・○・・・・・
・●●●●・・・
・・○○○・・・
・・・・・・・・
・・・・・・・・
・・・・・・・・
すごひ
むむむ・・・・変なことするより配列素直に使った方が良いのかな??
ちょっと悔しい・・・・
さすがです。
>>337 うわ、マジでオセロですか?コンピュータと対戦ですか?
信じられない・・
つーかinclude含めて7行だし。
>>337 うぁ、凄いー!!
今コード展開してるんですが、、、あまりに凄すぎて笑えてくる
見るべきところの多いコードで、参考になりまくりだ、ありがとう。
344 :
トリッキーの1:2001/08/22(水) 00:42
>>340=300
このスレの初期の頃の砂嵐プログラムで、効率的な削り方を覚えました。
あれ、今年の3月だったんだなぁ。懐かしいというか(笑)。
>>343 ありがとうです。番兵を駆使してとにかくif文から逃げました。
後はもう小手先のテクニックでひたすら1文字ずつ……。
途中の三項演算子のトリックに気付いて、やっと7行が見えましたね。
>>337 等幅で見てたらなんか芸術を感じた
コードに圧倒された気分だ。とにかくすげぇ
346 :
デフォルトの名無しさん:2001/08/22(水) 02:34
感動age
本当にどうでもいいがグローバル h は消去できるね
しかし文字数を減らすと綺麗に7行にならない。
すごい
感動した
348 :
デフォルトの名無しさん:2001/08/22(水) 03:33
sageさせるかぁぁぁぁぁ!!!!!!!!!
349 :
デフォルトの名無しさん:2001/08/22(水) 04:44
今までちょっといんちきだったけど、正真証明、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で載せておきます。参考になれば幸いです。
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;
}