おふとんガレージ

技術的なことの忘備録とか

OpenGL入門 2日目

前回までの作業内容

  • ウィンドウを表示する
  • 初期状態の盤面生成

今回の作業内容

  • クリックされた座標を読み込む

次回以降の目標

  • オセロのルールに従った石が置けるかどうかの判定
  • 石を置いた後に周囲の石を反転させる。
  • 石が置けない場合、ゲームの終了を判定する。

othello.cpp(10/19時点)

#include <iostream>
#include <GLUT/GLUT.h>

#define BOARD_SIZE 8
#define NONE 0
#define BLACK 1
#define WHITE 2

using namespace std;
int screenWidth = 800, screenHeight = 800, turn = 0;
char board[BOARD_SIZE][BOARD_SIZE];

void showStone(){
    //盤面に配置された石の描画
    glPointSize(60);
    for(int i = 0; i < BOARD_SIZE; i++){
        for(int j = 0; j < BOARD_SIZE; j++){
            if(board[i][j] == BLACK){
                //黒石の描画
                glColor3d(0, 0, 0);
                glBegin(GL_POINTS);
                glVertex2i(120 + 80 * i, 120 + 80 * j);
                glEnd();
            }else if(board[i][j] == WHITE){
                //白石の描画
                glColor3d(1, 1, 1);
                glBegin(GL_POINTS);
                glVertex2i(120 + 80 * i, 120 + 80 * j);
                glEnd();
            }
        }
    }
}


void mouse(int button, int state, int x, int y){
    int i = 0, j = 0;
    cout << "turn : " << turn << endl;
    if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN){
        //ウィンドウ内をクリックしたときの処理
        cout << "(x, y) == (" << x << "," << y << ")" << endl;
        
   //クリックした箇所が盤上でない時→処理終了
        if(x < 80 || x > 720) return;
        if(y < 80 || y > 720) return;
        
        //クリックされた座標(x, y)から盤上の座標(i, j)への変換
        while(x > 80){
            x -= 80;
            i++;
        }
        
        while(y > 80){
            y -= 80;
            j++;
            
        }
        
        cout << i << " " << j << endl;
  
   //クリックされた箇所に新規に石を配置する
   //奇数ターンであれば黒、偶数ターンであれば白
        if(turn % 2 == 1){
            board[i - 1][j - 1] = WHITE;
            cout << "WHITE" << endl;
        }else{
            board[i - 1][j - 1] = BLACK;
            cout << "BLACK" << endl;
        }
        
        turn++;

   //描画実行
        showStone();
        glFlush();
    }
    
}

void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    //盤面のマス目作成
    glColor3d(0.0, 0.0, 0.0);
    glLineWidth(3);
    glBegin(GL_LINES);
    
    for(int i = 0; i <= BOARD_SIZE; i++){
        glVertex2i(80 + 80 * i, 720);
        glVertex2i(80 + 80 * i, 80);
        
        glVertex2i(80, 80 + 80 * i);
        glVertex2i(720, 80 + 80 * i);
    }
    glEnd();
    
    //盤面上の4点の描画
    glColor3d(0.0, 0.0, 0.0);
    glPointSize(10);
    glBegin(GL_POINTS);
        glVertex2i(240, 240);
        glVertex2i(240, 560);
        glVertex2i(560, 240);
        glVertex2i(560, 560);
    glEnd();
    
    showStone();
    glFlush(); //描画実行
    
    
}

void initialize(){
    //初期盤面生成
    glClearColor(0, 0.5, 0, 1); //背景色設定
    
    //以下石の初期配置
    for(int i; i < BOARD_SIZE * BOARD_SIZE; i++)
        board[i / BOARD_SIZE][i % BOARD_SIZE] = NONE;
    
    board[BOARD_SIZE / 2 - 1][BOARD_SIZE / 2] = BLACK;
    board[BOARD_SIZE / 2][BOARD_SIZE / 2 - 1] = BLACK;
    
    board[BOARD_SIZE / 2][BOARD_SIZE / 2] = WHITE;
    board[BOARD_SIZE / 2 - 1][BOARD_SIZE / 2 - 1] = WHITE;
}

int main(int argc, char* argv[]) {
    
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
    glutInitWindowPosition(100, 100);
    glutInitWindowSize(screenWidth, screenHeight);
    
    glutCreateWindow("Othello");
    gluOrtho2D(0, 800, 800, 0); //座標系指定
    initialize();

	glutMouseFunc(mouse);
    glutDisplayFunc(display);
    glutMainLoop();
    
    return 0;
}

実行結果

turn : 0
(x, y) == (523,435)
6 5
BLACK
turn : 1
turn : 1
(x, y) == (531,503)
6 6
WHITE
turn : 2
turn : 2
(x, y) == (468,521)
5 6
BLACK
turn : 3

f:id:zurvlk:20161019215017p:plainf:id:zurvlk:20161019215028p:plainf:id:zurvlk:20161019215038p:plainf:id:zurvlk:20161019215044p:plain

メモ

  • カウンターとして変数を利用する時に0で初期化することを忘れないようにする。
  • 敵AIを除けば石が置けるかどうかの判定が山場っぽい。がんばる。