/* * graphics.c */ #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <math.h> #include <stdio.h> #include <stdlib.h> /* * */ #include "status.h" #include "board.h" #include "rule.h" #include "graphics.h" /* * */ #define R_SIZE 20 #define C_SIZE (R_SIZE*2-1) #define S_SIZE 2 #define G_SIZE (S_SIZE*2+1) #define F_SIZE (C_SIZE+G_SIZE) #define W_SIZE (F_SIZE*BOARD_SIZE+G_SIZE) #define H_SIZE (W_SIZE/2) #define lPos(N) (G_SIZE+(N)*(C_SIZE+G_SIZE)-H_SIZE) #define cPos(N) (lPos(N)+S_SIZE+1+R_SIZE) /* * */ #define PART 100 // 分割数 /* * */ static void circle( int x, int y, int color ) { int i, n = PART; float cx = (float) cPos(x) / H_SIZE; float cy = (float) cPos(y) / H_SIZE; float r = (float) R_SIZE / H_SIZE; float px; float py; double rate; switch ( color ) { case WHITE: glColor3f(1.0, 1.0, 1.0); // 描画物体に白色を設定 break; case BLACK: glColor3f(0.0, 0.0, 0.0); // 描画物体に黒色を設定 break; } glBegin(GL_POLYGON); // ポリゴンの描画 // 円を描画 for (i = 0; i < n; i++) { // 座標を計算 rate = (double)i / n; px = r * cos(2.0 * M_PI * rate) + cx; py = r * sin(2.0 * M_PI * rate) + cy; glVertex3f(px, py, 0.0); // 頂点座標を指定 } glEnd(); // ポリゴンの描画終了 } /* * */ static void line( int px1, int py1, int px2, int py2 ) { glBegin(GL_LINES); glVertex3f(((float)px1)/H_SIZE,((float)py1)/H_SIZE,0.0); glVertex3f(((float)px2)/H_SIZE,((float)py2)/H_SIZE,0.0); glEnd(); } /* * */ static void draw_board ( char board[BOARD_SIZE][BOARD_SIZE] ) { int x; int y; glColor3f(1.0, 1.0, 1.0); for ( x = 0; x <= BOARD_SIZE; x++ ) { line ( -H_SIZE, lPos(x), lPos(BOARD_SIZE)+H_SIZE, lPos(x) ); line ( lPos(x), -H_SIZE, lPos(x), lPos(BOARD_SIZE)+H_SIZE ); } for ( x = 0; x < BOARD_SIZE; x++ ) { for ( y = 0; y < BOARD_SIZE; y++ ) { if ( board [ x ][ y ] != EMPTY ) { circle ( x, BOARD_SIZE - 1 - y, board [ x ][ y ] ); } } } } /* * */ static char displayBoard[BOARD_SIZE][BOARD_SIZE]; static char color = BLACK; static void display(void) { glClearColor(0.0, 0.4, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT); // glPushMatrix(); // glColor3f(1.0, 1.0, 1.0); draw_board ( displayBoard ); // glPopMatrix(); // glutSwapBuffers(); glFlush(); } /* * */ static void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); glShadeModel(GL_FLAT); } /* * */ static void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { int px = x/F_SIZE; int py = y/F_SIZE; /* 人間が打つ */ if ( playable ( displayBoard, px, py, color ) == YES ) { printf ( "%d, %d\n", px, py ); play_hand ( displayBoard, px, py, color ); color = get_oposit_color ( color ); display(); /* コンピュータがうつ */ /* 方針:(コンピュータの思考アルゴリズム) 左上から始めて 左から右 上から下にむかって うてる所があれば、打つ */ { int cpx; int cpy; /* コンピュータがおく場所 */ for ( cpy = 0; cpy < 8; cpy++ ) { for ( cpx = 0; cpx < 8; cpx++ ) { if ( playable ( displayBoard, cpx, cpy, color ) == YES ) { play_hand ( displayBoard, cpx, cpy, color ); color = get_oposit_color ( color ); printf ( "%d, %d\n", cpx, cpy ); display(); cpy = 8; /* 外を終了 */ break; /* 内側を終了 */ } } } } } } break; case GLUT_MIDDLE_BUTTON: if (state == GLUT_DOWN) { } break; case GLUT_RIGHT_BUTTON: if (state == GLUT_DOWN) { } break; default: break; } } /* * */ void graphics_init ( int argc, char** argv ) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); // glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(W_SIZE, W_SIZE); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); init(); glutDisplayFunc(display); // glutReshapeFunc(reshape); glutMouseFunc(mouse); glutMainLoop(); } /* * */ void update_graphic_board ( char board[BOARD_SIZE][BOARD_SIZE] ) { int x; int y; for ( x = 0; x < BOARD_SIZE; x++ ) { for ( y = 0; y < BOARD_SIZE; y++ ) { displayBoard[x][y] = board[x][y]; } } } /* * */
#include <stdio.h> void main(int argc, char *argv[] ) { double x; printf ( "x=%f\n", x ); /* 書くのは勝手だが.. */ /* x に何がはっているかわからないので、 結果は予想できない */ }
#include <stdio.h> void f1() { int x; /* f1 で宣言された変数は.. */ } void f2() { printf ( "x=%d\n", x ); /* f2 では利用できない */ }
#include <stido.h> void main(int argc, char *argv[] ) { int i = 1; { int j = 2; /* j は内側のブロック内で宣言 */ printf ( "i=%d\n", i ); /* これも OK */ /* ブロックの外の変数は参照可能 */ printf ( "j=%d\n", j ); /* これも OK */ } /* ブロックをぬけると j はなくなる */ printf ( "i=%d\n", i ); /* これは OK */ printf ( "j=%d\n", j ); /* これは NG */ return 0; }
#include <stdio.h> int g; /* 大域変数 */ void f1(void) { printf ( "g = %d\n", g ); /* OK */ } int main(int argc, char *argv[] ) { g = 1; /* いきなり変数に代入できる */ f1(); /* 「g = 1」が表示される */ g = 3; f1(); /* 「g = 3」が表示される */ return 0; }
#include <stdio.h> void f1() { static int v = 1; /* 変数 v を 静的変数として宣言 */ /* 値は、プログラム開始時に一度だけ 1 が代入される */ printf ( "v=%d\n", v ); /* v の値を表示する */ v = v + 1; /* v の値をふやす */ } int main ( int argc, char *argv[] ) { f1(); /* この時は、v = 1 が表示される */ f1(); /* この時は、... ? */ return 0; }
#include <stdio.h> void f1() { int v = 1; /* 変数 v を 局所変数として宣言 */ /* 値はブロックに入った時に毎回 1 が代入される */ printf ( "v=%d\n", v ); /* v の値を表示する */ v = v + 1; /* v の値をふやす */ } /* v が局所変数なので、v は捨てられる.. (せっかく 1 を加えても意味がない) */ int main ( int argc, char *argv[] ) { f1(); /* この時は、v = 1 が表示される */ f1(); /* この時は、... ? */ return 0; }
「変数」について学んだ事 最初の「変数」は、「引数の『仮引数(変数)』」だった void func ( int x, char *m ) { printf ( "x=%d, m=%s\n", x, m ); /* %d <= x の値 %s <= m の値 */ /* 「x=1, m=abc\n」が表示される */ /* 「x=987, m=english\n」が表示される */ } main() { func ( 1, "abc" ); 変数 x に 1 変数 m に "abc" が割り当たる。 func ( 987, "english" ); } 次に出て来たのは、関数(ブロック)の中での 変数宣言と代入 main(){ int i; /* 新しい変数 i を int 型で宣言 */ double x; /* 新しい変数 x を double 型で宣言 */ /* これの変数には、値が「割り当てられていない」 */ /* しかし、変数は、値が割り当てられていない 状態で、利用するのは(普通は..)望みの結果に ならない */ printf ( "x=%f\n", x ); /* 書くのは勝手だが.. */ /* x に何がはっているかわからないので、 結果は予想できない */ /* 変数の値を割り当てる「代入文」も学んだ */ x = 1.2345; /* 変数 x の内容が「1.2345」と確定する */ printf ( "x=%f\n", x ); /* 「x=1.2345」と表示される事が確定する */ /* cf. 関数の引数の値が定まる場合と同じ.. */ } == 大域変数 (グローバル=バリアブル) 今迄の変数(局所変数[auto 変数])との「型式的(表現上)」な違い これまでは、関数のブロックの「中」で変数宣言されていた ブロック(関数)の中でしか使えない ある関数内の変数は、他の関数から利用できない 大域変数は、関数のブロックの「外」で変数宣言されていた 複数の関数から、その変数が利用できる 大域変数は局所変数に比べて、利用できる範囲が広い この「利用できる範囲」の事を「スコープ(有効範囲)」と呼ぶ 変数の種類 | 大域変数 | 局所変数 | 静的変数 -----------+---------------+-------------------------+---------- 空間 スコープ | プログラム全体 | 変数宣言されたブロック内| ブロック(ファイル)内 時間 エクステンション| 常時(永遠) | ブッロク内の実行時 | 常時 大域変数はプログラムが開始した直後から有効で プログラムが終了する直前まで利用可能 <=> 局所変数は、ブロックに入った時から有効になり ブロックから出る時に失われる 関数の外で static 宣言すると その静的変数のスコープはファイル内になる(全域にならない) dir の意味付け program 意味付け 頭 x_dir y_dir 0 上 x_dir[0] = 0 (x 方向は変化なし) y_dir[0] = -1(y 方向は 1 減る) これは「上」という意味を表す 1 左上 2 左 .. .. 7 右上
なし。