• 締切済み

3目並べのプログラムについての質問です

以下のようにプログラムをつくりました #include <stdio.h> #include <stdlib.h> #include <time.h> void cleanSquare(void); void hand(char); void hand_CPU(char); void printSquare(void); void judge(void); void three(char, char, char); char square[3][3]; int nokori = 9; int main( void ) { cleanSquare(); printSquare(); while(1) { printf("Your turn.\n"); printf("Input (x,y) :"); hand('o'); printf("CPU chose (x,y):"); hand_CPU('x'); } } void cleanSquare(void) { int x, y; for(x = 0; x < 3; x++) { for(y = 0; y < 3; y++ ) { square[x][y] = ' '; } } } void hand(char mark) { int h, v; scanf("%1d%1d", &h, &v); while(square[h][v] != ' ' ) { printf("%1d-%1dは埋まっています。再入力(横縦):", h, v); scanf("%1d%1d", &h, &v); } square[h][v] = mark; nokori--; printSquare(); judge(); if(!nokori) { printf("引き分け\n"); exit(1); } } void hand_CPU(char mark) { int h, v; srand(time(NULL)); //scanf("%1d%1d", &h, &v); h = rand() % 3; v = rand() % 3; printf("(%d,%d)\n", h, v); while(square[h][v] != ' ' ) { printf("%1d-%1dは埋まっています。再入力(横縦):", h, v); scanf("%1d%1d", &h, &v); } square[h][v] = mark; nokori--; printSquare(); judge(); if(!nokori) { printf("Tie \n"); exit(1); } } void printSquare(void) { int cnt; printf("\n 0 1 2\n"); printf(" -------------\n"); for(cnt = 0; cnt < 3; cnt++) { printf("%1d| %c | %c | %c |\n", cnt, square[0][cnt], square[1][cnt], square[2][cnt]); printf(" -------------\n"); } } void judge(void) { int x, y; for(y = 0; y < 3; y++) { three(square[0][y], square[1][y], square[2][y]); for(x = 0; x < 3; x++) { three(square[x][0], square[x][1], square[x][2]); three(square[0][0], square[1][1], square[2][2]); three(square[2][0], square[1][1], square[0][2]); } } } void three(char a, char b, char c) { if(a == ' ') { return; } if(a == b && b == c) { if(a == 'o') { printf("Win! \n"); } else { printf("Lose. \n"); } exit(1); } return; } 以前、学校の課題としてでたものを復習していたのですが、わからない部分がでてきました。 このプログラムを次のように改造したいのですが、どのように改造すればいいのかわかりません 1.ゲーム全体を関数化する main関数でこの関数を呼び出すと何回もゲームができるようにする int game(int n)と宣言しようと考えています 2.マス目の大きさを関数game()が引数として受け取ったnを、n×nのマス目でゲームができるようにする nは、ゲームごとにmain関数で入力 10×10までの大きさ 3.自分の番の時に、座標を入力する時に負の値が入力されたら、ゲームを終了させる 4.勝敗の記録と表示 例えば、引き分けを0、勝ちを1、負けを2、途中終了を-1 を戻り値として返すようにして、途中終了以外の場合はゲームの成績を 勝ち:3、負け:2、引き分け:0のように表示する 5.ゲーム終了後に続けるか、やめるかの選択 文字を一文字入力して、'y'なら1を返し、'n'なら0を返す それ以外の文字だったら、再入力させるという処理を関数化する int newgame(void)として宣言しようと考えています また、この関数の戻り値が0の場合プログラムの終了、1なら新しいゲームの開始 です。長くて申し訳ないですm(_ _)m よろしくお願いしますm(_ _)m

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

1. main関数も「関数」です。 とりあえず、 int main( void ) を int game(int n)に書き換えて、 新しく int main(void) { game(0); } とでも加えれば、1回だけはできます。 2回以上続けられないのは、exit を使っているからです。 game関数を呼び出しても、いろんなところから強制的にプログラム終了されてしまうため、制御できないのです。 exitは本当に致命的なエラーのときだけにして、通常はreturnで呼び出し側に戻るようにします。 例えば、 関数three は 戻り値をintにして -1: ○がそろった 0:揃ってない +1:×がそろった を返すようにします。WinだのLoseだのは、ここではやりません。 threeの結果を呼び出し側のjudgeで受けます。 この戻り値で0で無いものがあれば、それがこの局面での勝敗です。 そこで、同じく-1,0,1を返します。 それを呼び出した側で受け取って... と次々呼び出した側に戻していきます。 最終的に、どこかで、 if ( result==-1) { printf ("Win");}て感じに戻り値で分岐すればいいのです。 例えば、game()までこのように戻していくと、main関数内で result=game(3); if (result==-1) { printf("WIN"); countWin ++ ; } else if (result==1) { ... とすれば、4.も実現が容易です。

関連するQ&A

  • プログラムC

    前にも質問したのですがヒルベルト曲線を用いて画像をスキャンするプログラムとビットマップの画像を読み込むプログラムを用いてお互いの座標を関連付けてヒルベルト曲線の座標にビットマップの1画素ずつの値を代入したいのですがどうしてもうまくいかなく質問しました。 前に質問した物はhttp://oshiete1.goo.ne.jp/kotaeru.php3?q=1106704 にあります。ヒルベルトは質問覧にビットマッピはNO2の補足にあります。プログラムを書くと800字を超えてしまうのでそのようにしました。 ヒルベルトは他に #include<stdio.h> int x,y; int n; void RUL(int n),DLU(int n),LDR(int n),URD(int n); main() { scanf("%d",&n); printf("#位相%dのヒルベルト曲線\n",n); x=0; y=0;printf("(%d %d) ",x,y); RUL(8); } void RUL(int n) { if(n<=0) {return;} URD(n-1);x=x+1;printf("(%d %d)",x,y); RUL(n-1);y=y+1;printf("(%d %d)",x,y); RUL(n-1);x=x-1;printf("(%d %d)",x,y); DLU(n-1); } void DLU(int n) { if(n<=0) {return;} LDR(n-1);y=y-1;printf("(%d %d)",x,y); DLU(n-1);x=x-1;printf("(%d %d)",x,y); DLU(n-1);y=y+1;printf("(%d %d)",x,y); RUL(n-1); } void LDR(int n) { if(n<=0) {return;} DLU(n-1);x=x-1;printf("(%d %d)",x,y); LDR(n-1);y=y-1;printf("(%d %d)",x,y); LDR(n-1);x=x+1;printf("(%d %d)",x,y); URD(n-1); } void URD(int n) { if(n<=0) {return;} RUL(n-1);y=y+1;printf("(%d %d)",x,y); URD(n-1);x=x+1;printf("(%d %d)",x,y); URD(n-1);y=y-1;printf("(%d %d)",x,y); LDR(n-1); } があります。

  • ヒルベルト曲線のプログラム(C言語)

    私は画像の勉強をしています。それで従来の水平スキャンではなく2次元相関をたもったまま1次元配列に変換できるヒルベルトスキャンとBWT変換とエントロピー符号化を用いて圧縮する方法を勉強しています。しかしヒルベルトのほうができなくて困っています。 プログラムの実行結果でヒルベルト曲線通る座標を示すプログラムを教えてください。だいたいは書けましたがうまくいきません。プログラムは #include<stdio.h> int x,y; main() { int n; void RUL(int n),DLU(int n),LDR(int n),URD(int,n); scanf("%d",&n); printf("#位相%dのヒルベルト曲線\n",n); x=0; y=0;printf("%d\n",x,y); RUL(n);printf("\n"); } void RUL(int n) { if(n<=0) {return;} URD(n-1);x=x+1;printf("%d %d\n",x,y); RUL(n-1);y=y+1;printf("%d %d\n",x,y); RUL(n-1);x=x-1;printf("%d %d\n",x,y); DLU(n-1); } void DLU(int n) { if(n<=0) {return;} LDR(n-1);y=y-1;printf("%d %d\n",x,y); DLU(n-1);x=x-1;printf("%d %d\n",x,y); DLU(n-1);y=y+1;printf("%d %d\n",x,y); RUL(n-1); } void LDR(int n) { if(n<=0) {return;} DLU(n-1);x=x-1;printf("%d %d\n",x,y); LDR(n-1);y=y-1;printf("%d %d\n",x,y); LDR(n-1);x=x+1;printf("%d %d\n",x,y); URD(n-1); } void URD(int n) { if(n<=0) {return;} RUL(n-1);y=y+1;printf("%d %d\n",x,y); URD(n-1);x=x+1;printf("%d %d\n",x,y); URD(n-1);y=y-1;printf("%d %d\n",x,y); LDR(n-1); } です。それをBWT変換とエントロピー符号にかけ圧縮させその圧縮率を求めその後画像はちゃんと戻るかを調べるために復元のプログラムを書かないいけませんがそのプログラムがわかりません。教えてください。

  • プログラムに詳しい方教えてください!

    #include<stdio.h> void fxl(int x,int y); int main(void) { int a,b,m,n; printf("整数aの値を入力\n"); scanf("%d",&b); printf("整数bの値を入力\n"); scanf("%d",&b); m=a; n=b; fxl(m,n); printf("a=%dとb=%dを加算した値は%d\n",ab,m); printf("a=%dからb=%dを減算した値は%d\n",ab,n); return 0; } void fxl(int x,int y) { int j,k; j=x; k=y; x=j+k; y=j-k; } このプログラムを作ってみたのはいいのですが、参照渡しを使って正常に足し算、引き算をするにはどうすればよいのでしょうか。

  • CUDAプログラムが実行できません。

    行列の加算プログラムを作成したいのですが、どうもGPUとのやり取りがうまくいってないみたいです。 コンパイルは通るのですが、ホスト側で0を渡して計算結果をデバイス側から返すはずなのですが、計算結果ではなく0が返ってきます。 なので、GPUとのやり取りの部分だけを抜粋したプログラムを載せるので、ご指摘よろしくお願いします。 環境はUbuntu12.04.、CUDA5.0、GPUはtesla k20です。 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <cublas.h> #define N 64 #define BLOCK 16 __global__ void matrixMul(int* inMatA); int main(int argc,char** argv){ //cudaError_t CuErr; int matrixSize=sizeof(unsigned int)*N*N; int* hMatA; hMatA=(int*)malloc(matrixSize); int x,y; for(x=0;x<N;x++){ for(y=0;y<N;y++){ hMatA[x*N+y]=1; } } printf("hMatA \n"); for(x=0;x<N;x++){ for(y=0;y<N;y++){ printf("%d ",hMatA[x*N+y]); } printf("\n"); } int* dMatA; cudaMalloc((void**)&dMatA, matrixSize); cudaMemcpy(dMatA, hMatA, matrixSize, cudaMemcpyHostToDevice); dim3 block(BLOCK,BLOCK); dim3 grid(N/BLOCK,N/BLOCK); matrixMul<<<grid,block>>>(dMatA); cudaThreadSynchronize(); cudaMemcpy(hMatA, dMatA, matrixSize, cudaMemcpyDeviceToHost); printf("hMatA \n"); for(x=0;x<N;x++){ for(y=0;y<N;y++){ printf("%d ",hMatA[x*N+y]); } printf("\n"); } free(hMatA); cudaFree(hMatA); cudaThreadExit(); } __global__ void matrixMul(int* inMatA){ int x,y; for(y=0;y<N;y++){ for(x=0;x<N;x++){ inMatA[x+y*N]=0; } } }

  • このプログラムの復元処理教えでください。助けてくだ

    #include <stdio.h> int main(void) { char a[51]; char b[101]; char c[51]; int i,k; int cnt; printf("文字例-->"); scanf("%s",a); i = 0; k = 0; while(a[i] !='\0') { cnt = 0; b[k] = a[i]; while(b[k] = a[i]) { cnt++; i++; } k++; b[k] = cnt + 48; k++; } b[k]='\0'; printf("b=%s\n",b); printf("c=%s\n",c); //-------------------------------------------------- getchar(); return 0; }

  • Cの九九を表示するプログラムについて

    九九の表示を変えたいんですけど #include <stdio.h> int main(void) { int x,y; for (x = 1;x <= 9;x++) { for (y = 1;y <= 9;y++) { printf(" %2d ", x * y); } printf("\n"); } return 0; } これを実行すると 1 2 3 4 5 6 7 8 9 2 4 6 8 10 12 14 16 18 . . 9 . . . . . . . 81 となるのですが、これを 1 * 1 1 * 2 1 * 3 . . . 1 * 9 1 * 2 . . 1 * 9 . . . . . 9 * 9 と表示させたいのですがどなたか知恵を貸していただきませんでしょうか?

  • for文を使ったプログラムで困っています

    for文を使って、10000からある数xを何回引けるか?またその残りを求めるプログラム(例:10000から3000は3回引くことができ、残りは1000である。)を作りたいのですが、引く回数が1多くなってしまいます。どこがいけないかわからないので困っています。よろしくおねがいします。 #include<stdio.h> void main() { int x; int Sa = 10000; int y; printf("10000以下の数を入力してください:"); scanf("%d",&x); for(y = 1; y*x <= 10000 ; y++) { Sa = Sa - x; } printf("10000から%d回引くことができます。\n",y); printf("残りは%dです。",Sa); }

  • ラベリング処理プログラム

    画像のラベリング処理プログラムを作っているんですが どうもうまく実行できません。よければ教えていただけないでしょうか。 #include<stdio.h> #include<stdlib.h> int column, row; unsigned char val[4] = {0,0,0,0}; unsigned char tmp[255]; int pos_y[4] = {-1, 0, 1, 0}; int pos_x[4] = {0, 1, 0, -1}; int i, j, x, y, label, level, label1; int label_count = 1; unsigned char *in, *out; void labeling_main(); void labeling_search(); void labeling_main() { for(i = 0; i < y; i++){ for(j = 0; j < x; j++){ printf("aaa\n"); if(out[i * x + j] == 255){ printf("bbb\n"); fflush(stdout); out[i * x + j] = label_count; labeling_search(label_count, i, j); label_count++; } } } } void labeling_search(int label_count, int x, int y) { for(i = 0; i < 4; i++){ if(out[(pos_y[i] + y) * x + (pos_x[i] + x)] == 255){ out[(pos_y[i] + y) * x + (pos_x[i] + x)] = label_count; labeling_search(label_count,(pos_y[i]+y),(pos_x[i]+x)); } } printf("ccc\n"); } int main(int argc, char *argv[]) { int result; int head, Magic; unsigned char *image, *in, *out, *res, *ros; FILE *fin, *fout; if(argc!=3){ printf("Usage : %s input output\n",argv[0]); exit(1); } fin = fopen(argv[1],"rb"); /* -------------------- ヘッダ取得ここから -------------------- */ fgets(tmp,255,fin); if(tmp[0]!='P') return 0; sscanf(tmp,"P%d",&Magic); if(Magic < 1 || Magic > 6) return 0; do fgets(tmp,255,fin); while(tmp[0]=='#'); sscanf(tmp,"%d %d",&x,&y); if(x < 1 || y < 1) return 0; fgets(tmp,255,fin); sscanf(tmp,"%d",&level); /* ヘッダの確認 */ printf("P%d\n",Magic); printf("%d %d\n",x,y); printf("%d\n",level); /* 画素の読み込み */ in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in,sizeof(unsigned char),x*y,fin); fout = fopen(argv[2],"wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); out = (unsigned char *)malloc(sizeof(unsigned char) *x*y); //2値画像 for (i = 0; i < y; i++) { for (j = 0; j < x; j++){ if(in[i * x + j] > 120){ out[i * x + j] = 0; }else if(in[i * x + j] <= 120){ out[i * x + j] = 255; } } } labeling_main(); printf("Max label number:%d\n",label_count); free(in); free(out); fclose(fin); fclose(fout); } コンパイルは通るのですが実行するとlabeling_mainの if文でセグメンテーションが出てしまいます。

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結

    プログラムの練習問題をやっていたのですが、練習問題の答えのような実行結果にならないので教えていただけませんか? 下記に記したプログラムを実行すると x=9 y=-9 [ 9]*[-9]=[ -81],[ 9]*[-8]=[ -72],[ 9]*[-7]=[ -63],・・・・ ・・・・ [10]*[-9]=[ -90],[10]*[-8]=[-80],・・・・ ・・・・ のようになるのですが、 x=9 y=-9 [ 9]*[-9]=[ -81],[10]*[-9]=[-90],・・・ [ 9]*[-8]=[ -72],[10]*[-8]=[-80],・・・ [ 9]*[-7]=[ -63],・・・ ・・・・ のようにするためにはどうすればいいですか? #include <stdio.h> int main(void) { int x,y,m,n; printf("x="); scanf("%d",&x); printf("y="); scanf("%d",&y); for(m=x;m<=x+3;m++) { printf("\n"); for(n=y;n<=y+14;n++) { printf("[%2d]*[%2d]=[%4d],",m,n,m*n); } printf("\n"); } return(0); }