• 締切済み

○×ゲーム

○×ゲーム ○×ゲームをつくろうとしてるのですがどうプログラムを組んでいいのか分りません。ポインタとクラスを使って作りたいのですがどなたか教えていただけないでしょうか。 途中までのプログラムを載せておきます。ここからどうすればいいのか教えてください。 #include<iostream> #include<cstdlib> #include<ctime> #define NON 0 #define MARU 1 #define BATU 2 #define MAX_HEIGHT 3 #define MAX_WIDTH 3 using namespace std; int g_mas[MAX_WIDTH][MAX_HEIGHT]; class Game{ public: void Clear(); void Player(int *width, int *height); bool Draw(); } void Game::Clear() { for(int width=0; width<MAX_WIDTH; width++) { for(int height=0; height<MAX_HEIGHT; height++) { g_mas[MAX_WIDTH][MAX_HEIGHT] = NON; } } } void Game::Player(int width, int height) { } bool Game::Draw() { for(int width=0; i<MAX_WIDTH; width++) { for(int height=0; i<MAX_HEIGHT; height++) { if(g_mas[MAX_WIDTH][MAX_HEIGHT] == NON) { return 0; //引分けじゃない時、0を返す } } } return 1; //引分けだった時、1を返す } int main() { int width, height; Game g; g.Clear(); srand((unsigned int)time(NULL)); }

みんなの回答

回答No.2

プロンプトなら、入力系のメソッドを変更して、次のような感じ。 メインプログラムのイメージも追加しました。 //***************** // 入力系 //***************** // ユーザーに次の一手を入力させて、その値を取得する。 bool GetNextMove(/* out */ int *prow, /* out */ int *pcolumn, /* out */ int *pnew_value) const ; //***************** // 判定系 //***************** // ゲーム終了かどうか(すべてのマスが埋まっているか判定) bool IsEnd(void) const ; //***************** // メインプログラムのイメージ //***************** main() {     Game game ;     // 初期化     game.InitStatus() ;     // 状態を表示     game.Redraw() ;     // ゲームする     while (! game.IsEnd())     {         // 次の一手を取得         int row, column, new_value ;         GetNextMove(&row, &column, &new_value) ;         // 状態を変更         game.SetStatus(row, column, new_value) ;         // 最新の状態を表示         game.Redraw() ;     } ;     // 勝ち負けを表示     switch (game.WhichIsWin())     {     case MARU :         printf("MARU won !!\n") ;         break ;     case BATU :         printf("BATU won !!\n") ;         break ;     case NON :     default :         printf("Draw !!\n") ;         break ;     } ; } ;

回答No.1

まず、クラスの設計をきちんとなさるとよいと思います。 およそ、以下のような変数とメソッドが定義されていれば、組み合わせて実現できると思います。 //***************** // 状態の定義 //***************** int m_mas[MAX_WIDTH][MAX_HEIGHT] ; int m_next_player ; // 次のプレーヤー。MARU or BATU int m_counter ; // すでに埋まったマスの数 //***************** // 描画情報の定義 //***************** #define CELL_PIX_WIDTH 100 // 1マスのピクセル幅 #define CELL_PIX_HEIGHT 100 // 1マスのピクセル高さ //***************** // 描画系...描くだけ。 //***************** void Redraw()...画面をクリアして、マス目や、今の状態( ○×)を描く。 //***************** // ロジック系 //***************** // 状態(g_mas/g_next_playerなど)を初期化する void InitStatus(void) ; // マスに新しい値をセットする。すでにMARU/BATUがセットされていたらfalseを返す。 bool SetStatus(int row, int column, int new_value) ; //***************** // 判定系 //***************** // セルの状態NON/MARU/BATUのいずれかを返す。 int GetStatus(int row, int column) const ; // どっちが勝ったかNON/MARU/BATUを返す。 int WhichIsWin(void) const ; //***************** // 入力系 //***************** // どのマスがクリックされたか判定する。 // どのマスもクリックされていなければ、falseを返す。 bool GetCellIndex(/* in */ POINT point, /* out */ int *prow, /* out */ int *pcolumn) const ;

shamal1988
質問者

お礼

ありがとうございます。

shamal1988
質問者

補足

仕様について話してなかったので補足します。 プロンプト上で動くタイプの○×ゲームでXとYを指定して○か×を付ける感じです。 あとプレイヤが交互にマスを指定するタイプなのでコンピュータとの対戦は無しです。 //例  1 2 3 1 2 3 X軸を指定してください: Y軸を指定してください:

関連するQ&A

  • クイックソート

    #include<stdio.h> #include<stdlib.h> #define MAX 10 int comp(const void *i,const void *j); int main(void) { int sort[MAX], i ; for(i=0 ; i<MAX ; i++){ sort[i] = rand(); } qsort(sort, MAX, sizeof(int), comp); for( i=0; i<MAX ; i++) printf("%d\n", sort[i]); return 0; } int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } これはクイックソートのプログラムなのですが、 int comp (const void *i, const void *j) { return *(int*)i - *(int*)j; } この部分がわかりません。ここでソートしているのですか?

  • int型の表せる範囲

    VC++6.0 on win2kです。 int型の表せる範囲は3万ぐらいまでだと思っていたのですが、 #include <stdio.h> #define Max 1000000 void main(){ for(int i=0;i<Max;i++){ printf("%d\n",i); } } というプログラムを走らせると普通に出ます。 int型の範囲とは何を意味するのでしょうか?

  • C言語の問題について

    下のプログラムにおいて実行結果は 02134 になります。 この02134になる過程は分かるのですが、時間がかかってしまいます。 iListとiGeneをいちいち紙に書き出さなければならないのでしょうか? 法則的なものが存在するとすれば、教えてください。 #include<stdio.h> #define MAX 5 void func(int *iGene); int main(void) { int i; int iGene[MAX]={0,1,0,0,0}; func(iGene); for(i=0;i<MAX;i++) { printf("%d",iGene[i]); } return (0); } void func(int *iGene) { int i,j; int iBuff; int iList[MAX]; for(i=0;i<MAX;i++) { iList[i]=i; } for(i=0;i<MAX;i++) { iBuff=iList[iGene[i]]; for(j=iGene[i]+1;j<MAX-i;j++) { iList[j-1]=iList[j]; } iGene[i]=iBuff; } } よろしくお願いします。

  • 式を変更して画像を作りたいです

    以下のプログラムはカラー画像を作成し、MAX_REPEAT回コピーした後、PPMファイルとして出力するものです。 画像作成部分の式を変更し、画像を作ろうと思いますが、アイディアがあれば参考にしたいので教えてください。 簡単でけっこうですから是非お願いします。 gcc -Wall -O2 -DCIP ファイル名でコンパイルします。 PPMファイルはdisplay tmp.ppmで表示します。 convert tmp.ppm tmp.jpgでjpg形式に変換できます。 #include <stdio.h> #include <stdlib.h> #include <math.h> //mathライブラリを利用する場合はコンパイル時に -lm #define MAX_REPEAT 1 //コピー繰り返し回数 #define SIZE 500 //画像サイズ(行=列) #ifdef CSQ #define DIM1 3 #define DIM2 SIZE #define DIM3 SIZE #endif #ifdef CIP #define DIM1 SIZE #define DIM2 SIZE #define DIM3 3 #endif typedef unsigned char UCHAR; void write_ppm_csq(UCHAR [][DIM2][DIM3],char *,int ,int); void write_ppm_cip(UCHAR [][DIM2][DIM3],char *,int ,int); void error1(char *); /* 画像のコピー */ void copy3dimg(UCHAR res[][DIM2][DIM3],UCHAR org[][DIM2][DIM3],int dim1,int dim2,int dim3) { int i,j,k; for(i=0;i<dim1;i++) for(j=0;j<dim2;j++) for(k=0;k<dim3;k++) res[i][j][k]=org[i][j][k]; } int main(void) { int repeat; UCHAR org[DIM1][DIM2][DIM3]; /* 作成画像 */ UCHAR res[DIM1][DIM2][DIM3]; /* コピー先画像 */ /* 画像の作成 */ { int i,j,k; for(i=0;i<DIM1;i++) for(j=0;j<DIM2;j++) for(k=0;k<DIM3;k++) org[i][j][k]=(UCHAR)((i*j+10*j+k*k)%256); } /* 画像のコピー */ for(repeat=0;repeat<MAX_REPEAT;repeat++) copy3dimg(res,org,DIM1,DIM2,DIM3); /* ファイルへの出力 */ #ifdef CSQ write_ppm_csq(res,"./tmp.ppm",DIM3,DIM2); #endif #ifdef CIP write_ppm_cip(res,"./tmp.ppm",DIM2,DIM1); #endif return 0; } /* ファイルへの出力(CSQ) */ void write_ppm_csq(UCHAR data_buf[][DIM2][DIM3],char *fname,int width,int height) { FILE *fp; int m, n; if((fp = fopen(fname, "wb")) == NULL) { fprintf(stderr, "file(%s) can't open\n", fname) ; exit(1) ; } fprintf(fp, "P6\n") ; /* カラー画像かつバイナリーデータの記号 */ fprintf(fp, "%d %d\n", width, height) ; /* 画像の幅(列数)と高さ(行数) */ fprintf(fp, "255\n") ; /* 最大値 */ for(m=0;m<height;m++) for(n=0;n<width;n++) { fwrite(&data_buf[0][m][n], sizeof(UCHAR), 1, fp); fwrite(&data_buf[1][m][n], sizeof(UCHAR), 1, fp); fwrite(&data_buf[2][m][n], sizeof(UCHAR), 1, fp); } fclose(fp) ; } /* ファイルへの出力(CIP) */ void write_ppm_cip(UCHAR data_buf[][DIM2][DIM3],char *fname,int width,int height) { FILE *fp; if((fp = fopen(fname, "wb")) == NULL) { fprintf(stderr, "file(%s) can't open\n", fname) ; exit(1) ; } fprintf(fp, "P6\n") ; /* カラー画像かつバイナリーデータの記号 */ fprintf(fp, "%d %d\n", width, height) ; /* 画像の幅(列数)と高さ(行数) */ fprintf(fp, "255\n") ; /* 最大値 */ fwrite(&data_buf[0][0][0], sizeof(UCHAR), width*height*3, fp); fclose(fp) ; } /* エラー処理 */ void error1(char *message) { printf("%s\n",message); exit(1); }

  • ppmについて

    縦120横160のppm方式の画像sample01.ppmを改めてout.ppmとして出力するプログラム、 #include <stdio.h> #include <stdlib.h> #include <string.h> typedef unsigned char uchar; typedef struct _rgb_ { uchar r, g, b; } RGB; #define WIDTH 160 #define HEIGHT 120 int main(int argc, char **argv) { char s[16]; int i, j; RGB image[HEIGHT][WIDTH]; FILE *fp; fp = fopen("sample01.ppm", "r"); fgets(s, 16, fp); fgets(s, 16, fp); fgets(s, 16, fp); for(j = 0; j < HEIGHT; j++){ for(i = 0; i < WIDTH; i++){ image[j][i].r = (uchar)getc(fp); image[j][i].g = (uchar)getc(fp); image[j][i].b = (uchar)getc(fp); } } fclose(fp); fp = fopen("out.ppm", "w"); fprintf(fp, "P6\n"); fprintf(fp, "%d %d\n", WIDTH, HEIGHT); fprintf(fp, "255\n"); for(j = 0; j < HEIGHT; j++){ for(i = 0; i < WIDTH; i++){ (void)putc(image[j][i].r, fp); (void)putc(image[j][i].g, fp); (void)putc(image[j][i].b, fp); } } fclose(fp); return(EXIT_SUCCESS); } を学校のPCでコンパイルし、実行した時は普通に表示されたのですが、いざ家に持ち帰り、コンパイルし、実行したところ、画像が最初の方で途中できれてしまいます。 学校のコンパイラーはよくわからないのですが、 gcc xx.c のコマンドでコンパイルします。unix 自宅のPCはWINDOWS XPで、コンパイラはborland を使っています 。 bcc32 xx.c とコマンドするやつです。 どうすれば正常に表示されるのでしょうか、助けてください。

  • define で 配列

    #defineで配列を定義したいのですがこのようなことは可能でしょうか? ヘッダファイル(test.h)で #define MAX (2) int A[MAX]={20,30}; ソースファイルで #include <stdio.h> #include "test.h" int main(){ int i; for(i=0;i<MAX;i++){ printf("A[%d]=%d\n",i,A[i]); } return 0; } とやれば出来るのですが、このヘッダファイルを複数のソースで参照すると 多重定義であるとおこられてしまいます。 #defineで #define A[MAX] {20,30} のように配列を定義する方法は存在するのでしょうか? どなたか良い方法を御存じの方、ご教授お願いします。

  • 画像処理プログラム

    以下の問題でプログラムを改良したのですが合っていますか?間違ってたら教えてください 図3 は、画像中の全ての画素に対する、濃度値の頻度分布を示すヒストグラムの例である。サンプルプロググラムhistogram.c をもとに、入力画像の濃度値のヒストグラムを作成するプログラムを完成させる。 1. Histogram.c をそのまま実行すると、ダミーデータを用いた結果画像が出力される。 $ gcc □ Histogram.c -o □ Histogram ↓ $ ./Histogram ○○○.pgm □ Histogram.pgm ↓ 2. Histogram.c を次のように変更し、プログラムを完成させる。 (a)入力画像のヒストグラムを求める。 各画素を参照し、その画素値img[i][j] に対応する番号の配列histogram[0255] の値を1 増やす。 (b)頻度の最大値を求める。 濃度値i=0255 について調べ、もし頻度histogram[i] の値がそれまでの最大値max frequency より大きければ、最大値max frequency を更新する。 (c)ヒストグラム画像を作成する。 最大頻度を1 としたときの割合(histogram[i]/max frequency)を求め、それに画像の大きさH_height を掛けることで各濃度値のグラフの長さlength を求める。 length = H height * histogram[i] / max frequency #include <stdio.h> #include <stdlib.h> #define V_width 320 #define V_height 240 #define amp 1.0 #define GLEVEL 256 /* 最大階調 */ #define MAX_BRIGHTNESS 255 #define H_width GLEVEL #define H_height 256 int d[9]; int i, j, dat; float z, zz; unsigned char img [V_height][V_width]; /* input image */ unsigned char work[H_height][H_width]={0}; /* work space */ long int histogram[GLEVEL]={0}; /* ヒストグラム */ long int max_frequency=0; /* 頻度の最大値 */ float length; /* 頻度を表すグラフの長さ */ int main(int argc, char* argv[]) { FILE *fpi, *fpo; unsigned char data; char str[ 256]; int width, height; /* check arg number */ if (argc != 3) { fprintf(stderr, "Usage: %s [input] [output]\n", argv[0]); exit(1); } /* open input file */ if ((fpi = fopen(argv[1], "rb")) == NULL) { fprintf(stderr, "input file open error!\n"); exit(1); } /* open output file */ if ((fpo = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "output file open error!\n"); exit(1); } /* read PGM header */ while(1){ fgets(str, 256, fpi); if(str[0] == '#'){ fprintf( stderr, "%s", str); } else if( !strncmp( str, "P5", 2)){ fprintf( stderr, "This file is a PGM file.\n"); } else if( !strncmp( str, "255", 3)){ fprintf( stderr, "The file is opened.\n"); break; } else{ sscanf( str, "%d %d", &width, &height); fprintf( stderr, "SIZE: %3d x %3d\n", width, height); } } /* read data */ for (i=0; i<height; i++) { for (j=0; j<width; j++) { fread( &data, 1, 1, fpi); img[i][j] = data; } } /* (a) 入力画像のヒストグラムを求める */ for(i=0; i<height; i++){ for(j=0; j<width; j++){ // histogram([i][j])++; } } /* (b) 頻度の最大値を求める */ for ( i=0; i<GLEVEL; i++) { // if (histogram[i]>max_frequency) max_frequency = histogram[i]; } /* (c) ヒストグラム画像を作成する */ for (j=0; j<H_width; j++) { length = (float) H_height * j / H_width; //仮のデータ for (i=0; i<length; i++) { work[H_height-1-i][j] = MAX_BRIGHTNESS; length = H_height * histogram[i] / max_frequency } } /* write data */ fprintf(fpo,"P5\n %d %d\n 255\n", H_width, H_height); for (i= 0; i<H_height; i++) { for (j= 0; j<H_width; j++) { fwrite( &work[i][j], 1, 1, fpo); } } fclose(fpi); fclose(fpo); return 0; }

  • 画像を読み込んでヒストグラムを作るプログラム

    2値化画像を読み込んで、ヒストグラムを表示させるプログラムを作りたいのですが、 以下のソースを作成したのですが実行中にエラーが発生して困っています。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define width 640 #define height 480 int main(int argc, char* argv[]) { unsigned char image[640*480]; unsigned char header32[1078];//ビットマップ情報 int i; int *histogram; FILE *fp1; unsigned char buffer1[640*480]; for(i=0; i<640*480; i++) { image[i]=0; buffer1[i]=0; } fp1=fopen("koshimizu1.bmp","rb"); // fread(image,1,640*480,fp1); fread(header32,1,1078,fp1); fread(buffer1,width,height,fp1); fclose(fp1); for(i=0;i<256;i++){ histogram[i]=0; } for(i=0;i<640*480;i++){ histogram[image[i]]++; } for(i=0;i<256;i++){ printf("%d %d \n",i,histogram[i]); } return 0; }

  • 初心者です。 コンパイルのエラー

    import java.awt.*; import javax.swing.*; public class R11Sample1 extends JFrame { Rect r1 = new Rect(Color.red, 100, 100, 80, 60); Rect r2 = new Rect(new Color (0.5f, 1f, 0f, 0.7f), 150, 120, 60, 90); Oval = new Oval(Color.blue, 60, 50, 10, 10); JPanel panel = new JPanel() { public void paint(Graphics g) { Graphics2D g2 = (Graphics2D)g; r1.draw(g2); r2.draw(g2); } }; public R11Sample1() { setSize(400, 350); setDefaultCloseOperation(EXIT_ON_CLOSE); getContentPane().add(panel); } public static void main(String[] args) { new R11Sample1().setVisible (true); } } class Rect { Paint pat; int xpos, ypos, width, height; public Rect(Paint p, int x, int y, int w, int h) { pat = p; xpos = x; ypos = y; width = w; height = h; } public void draw(Graphics2D g) { g.setPaint(pat); g.fillRect(xpos-width/2, ypos-height/2, width, height); } } class Oval { Paint pat; int xpos, ypos, radius; public Oval(Paint p, int x, int y, int width, int height) { pat = p; xpos = x; ypos = y; width = w; height = h; } public void draw(Graphics2D g) { g.setPaint(pat); g.fillOval(xpos-width/2, ypos-height/2, width, height); } } これでコンパイルすると、 Identifierがありません といわれました。 どこを直せばいいのでしょうか。 また、全体的に間違ったところがあったら教えてください。

    • ベストアンサー
    • Java
  • 引数のみで出力

    問題として main内部を変更してはならない。 関数sub()でmainのループと同じ出力するようにせよ。 ただし、関数subで引数以外の変数を宣言してはならない。 また、広域変数を追加してはならない。 となっていて、色々とforループで出力させようと 配列にしたりポインタにしたりしたのですが forのiに比例する配列をどう組めばいいのか、わからないです。。。 mainの出力は 1 8 15 22 29 36 となっています。 これをsubでもできるように設定するみたいです。 #include <stdio.h> #define MAX 7 void sub(int [MAX]); int main() { int i; int x[MAX]; for (i = 0; i < MAX-1; ++i) { x[i] = 7*i+1; } x[MAX-1] = 0; for (i = 0; x[i] > 0; ++i) { printf("x = %d\n", x[i]); } printf("print again\n"); sub(x); return 0; } void sub(int a[MAX]) { // a[6]=0 // MAX 7 a[MAX-1]=0; for(a[MAX-1];a[MAX-7]<=MAX-1;++a[MAX-1]){ //a[MAX-1] = 7*a[MAX-1]+1; printf("a[%d] = %d\n",a[MAX-1],a[MAX-7]); } }