/*
* 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 右上
なし。