motu*2

DIV1目指して問題を解き続ける

TopCoder SRM 641 DIV2 Level2

概要

xy平面上にいくつかの点が与えられる。
この点の中から3つ選んで三角形を作った時、
原点が三角形の内部に含まれるような組み合わせが
何通りあるか求めよ。

解法

三角形がある点を内包するとき、
ベクトルの外積が同じ向きを向く。
この性質を利用する。

コード

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <climits>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <stack>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <sstream>
#include <functional>
#include <ctime>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n)  FOR(i,0,n)
#define CLEAR(d) memset((d), 0, (sizeof((d))))
#define ALL(c) (c).begin(), (c).end()
#define ABS(x) ((x < 0) ? -(x) : (x))
#define SORT(x) sort((x).begin(), (x).end())
#define RSORT(x) sort((x).begin(), (x).end(), greater<int>() )
#define SIZE(a) ((int)((a).size()))
#define MOD 1000000007
#define EPS 1e-7
#define PI  (acos(-1))
#define INF 10000000
struct edge { int to; int cost; };
//===================================================

class Point {
public:
    double x, y;
    Point() : x(0), y(0) {}
    Point(double x, double y) : x(x), y(y) {}
    Point operator + (Point p) { return Point(add(x, p.x), add(y, p.y)); }
    Point operator - (Point p) { return Point(add(x, -p.x), add(y, -p.y)); }
    Point operator * (double d) { return Point(x * d, y * d); }
    bool operator < (Point p) { return x == p.x ? y < p.y : x < p.x; }
    double add(double a, double b) {
        if (abs(a + b) < EPS * (abs(a) + abs(b))) return 0;
        return a + b;
    }
    double dot(Point p) { return add(x * p.x, y * p.y); }
    double det(Point p) { return add(x * p.y, -y * p.x); }
};

bool innerCheck(Point p1, Point p2, Point p3)
{
    Point p0 = Point(0.0, 0.0);
    double c1 = (p3 - p1).det(p1 - p0) + 0;
    double c2 = (p2 - p3).det(p3 - p0) + 0;
    double c3 = (p1 - p2).det(p2 - p0) + 0;
    if ((c1 > 0 && c2 > 0 && c3 > 0) || (c1 < 0 && c2 < 0 && c3 < 0)) {
        return true;
    }
    return false;
}


class TrianglesContainOriginEasy
{
public :
    int count(vector <int> x, vector <int> y)
    {
        int ans = 0;
        int size = x.size();
        vector<Point> vects;
        for (int i = 0; i < size; i++) {
            vects.push_back(Point((double)x[i], (double)y[i]));
        }
        for (int i = 0; i < size-2; i++) {
        	for (int j = i+1; j < size-1; j++) {
        		for (int k = j+1; k < size; k++) {
            		if (innerCheck(vects[i], vects[j], vects[k])) {
                		ans++;
                	}
                }
            }
        }
        return ans;
    }
};

TopCoder SRM 640 DIV2 Level2

概要

始めx=1とする。各ステップで2xか、2x+1に値を変えることができ、
最大k-1回までできる。
禁止の値リストがあり、この値にすることはできない。
作れる数字の合計を答える。

解法

tableを昇順にソートする。

図のように深さkの二分木となっているため、table[i]を親とすると
子要素は2^(table[i]の深さ - 二分木の深さ) - 2個ある。

合計を2^二分木の深さとし、子要素の数 + 1 だけ引いていく。

i番目の要素の親要素(0 ~ i-1)が、すでに使われていれば、引かないようにする。

親要素であるかどうかは、2で割っていって確かめる。

コード

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <climits>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <stack>
#include <queue>
#include <string>
#include <map>
#include <set>
#include <sstream>
#include <functional>
#include <ctime>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n)  FOR(i,0,n)
#define CLEAR(d) memset((d), 0, (sizeof((d))))
#define ALL(c) (c).begin(), (c).end()
#define ABS(x) ((x < 0) ? -(x) : (x))
#define SORT(x) sort((x).begin(), (x).end())
#define RSORT(x) sort((x).begin(), (x).end(), greater<int>() )
#define SIZE(a) ((int)((a).size()))
#define MOD 1000000007
#define EPS 1e-7
#define PI  (acos(-1))
#define INF 10000000
struct edge { int to; int cost; };
//===================================================

class NumberGameAgain
{
public :
    long long solve(int k, vector<long long> table)
    {

        long long sum = pow(2, k) - 2;
        sort(table.begin(), table.end());
        for (int i = 0; i < table.size(); i++) {
            int flag = 0;
            for (long long n = table[i] / 2; n >= 2; n /= 2) {
                for (int j = 0; j < i; j++) {
                    if (n == table[j]) {
                        flag = 1;
                        break;
                    }
                }
                if (flag) break;
            }
            if (flag) continue;
            int l2 = log2(table[i]);
            sum -= pow(2, k - l2) - 1;
        }
        return sum;
    }
};

AOJ 0108 Operation of Frequency of Appearance

概要

省略

解法

直前の状態を配列に保持して、それぞれの数を数えて配列を更新し、
直前の状態と比較する。
同じだったら終了。

sは12までだと思ってたけど違うみたい。
制約をちゃんと問題文に書いてほしいなあ。

コード

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define REP(i,n)  FOR(i,0,n)

int main()
{
    int n;
    while (1) {
        int cnt[13] = { 0 };
        cin >> n;
        if (n == 0) break;
        REP(i, n) cin >> cnt[i];
        int pre[13] = { 0 };
        for(int k = 0, f = 1; ; k++, f = 1) {
            int sum[100] = { 0 };
            REP(i, n) {
                pre[i] = cnt[i];
                sum[pre[i]]++;
            }
            REP(i, n) {
                cnt[i] = sum[pre[i]];
                if (cnt[i] != pre[i]) f = 0;
            }
            if (f) {
                cout << k << endl;
                REP(i, n) {
                    if (i < n - 1) printf("%d ", cnt[i]);
                    else printf("%d\n", cnt[i]);
                }
                break;
            }
        }
    }
    return 0;
}

AOJ 0107 Carry a Cheese

概要

立方体の縦、横、高さの長さが与えられる。
この立方体を半径rの円に接さないように通すことができるか。

解法

立方体の面の対角線が一番小さくなるように向けたとき、
対角線 / 2 が r より小さくなるなら接さない。

コード

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int x, y, h, n, r;
    while (1) {
        cin >> x >> y >> h;
        if (x == 0 && y == 0 && h == 0) break;
        int dia = min(min(x * x + y * y, x * x + h * h), y * y + h * h);
        cin >> n;
        for (int i = 0; i < n; i++) {
            cin >> r;
            cout << ((dia < r*r*4) ? "OK" : "NA") << endl;
        }
    }
    return 0;
}

AOJ 0106 Discounts of Buckwheat

概要

そば粉をnグラム買いたいと思っている。
3つの店での1袋当たりの単価と、量、
数袋買った時の割引料金が与えられるので、
一番安くなる組み合わせの金額を出力する。

解法

5000gまでしか与えられないので全探索で十分。
ngぴったりじゃないとダメなので、ngを超える
組み合わせは含まないように注意する。

コード

#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int n;
    while (1) {
        int ans = 1000000;
        cin >> n;
        if (n == 0) break;
        for (int a = 0; a <= 50; a++) {
            for (int b = 0; b <= 50; b++) {
                for (int c = 0; c <= 50; c++) {
                    int sum = (380 * (5 * (a / 5))) * 0.8 + (a % 5) * 380;
                    sum += (550 * (4 * (b / 4))) * 0.85 + (b % 4) * 550;
                    sum += (850 * (3 * (c / 3))) * 0.88 + (c % 3) * 850;
                    if (a * 200 + b * 300 + c * 500 == n) {
                        ans = min(ans, sum);
                    }
                }
            }
        }
        cout << ans << endl;
    }
    return 0;
}

AOJ 0105 Book Index

概要

語句とページ番号がいくつか与えられる。
辞書順に語句を表示し、対応するページ番号すべてを
昇順で出力する。

解法

STLのmapを使ってやる

コード

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
using namespace std;

int main()
{
    map<string, vector<int> > m;
    string s;
    int page;
    while (1) {
        cin >> s >> page;
        if (cin.eof()) break;
        m[s].push_back(page);
    }
    map<string, vector<int> >::iterator it = m.begin();
    while (it != m.end())
    {
        cout << (*it).first << endl;
        vector<int> v = (*it).second;
        sort(v.begin(), v.end());
        int size = v.size();
        for (int i = 0; i < size; i++) {
            if (i < size-1) printf("%d ", v[i]);
            else printf("%d\n", v[i]);
        }
        ++it;
    }

    return 0;
}

C言語で作る五目並べ

初めに

本稿はSLP KBIT Advent Calendar 2014 の12日目の記事です。

前書き

最近競技プログラミングしかやっていなかったので、たまにはGMVらしく
ゲームを作りたいと思います。
今回は比較的簡単に作れそうな五目並べC言語で作ってみたいと思います。
配列と関数の知識があれば作れるので、プログラミング初学者におすすめです!

ルール確認

まず、ゲームのルール・仕様を決めていきましょう。
ここを曖昧にしたままコーディングを始めると、後々修正が大変になります。

  • 盤面の大きさは10×10
  • 縦横斜めのいずれかに5つ自分の石を揃えれば勝ち
  • 6連以上も勝利とする
  • 三三などの禁止手はなし
  • 先手は黒の石

今回はシンプルにこんな感じにしましょう。

フロー

次に、ゲームの流れを確認しましょう。

  • ゲーム情報初期化
  • ゲーム開始
  • 順番に空マスに石を置いていく
  • 五連がそろえば結果を出力して終了

コーディング

仕様と大まかな流れを確認したので、実際にプログラムを書いていきましょう!

まず盤面の大きさと駒の色を定数として定義しておきましょう。

#define BOARD_SIZE 10      // 盤面サイズ 10 * 10
#define STONE_SPACE 0      // 盤面にある石 なし
#define STONE_BLACK 1      // 盤面にある石 黒
#define STONE_WHITE 2      // 盤面にある石 白

コード内で1や2などのマジックナンバーを書いてしまうと、
プログラムが読みずらくなってしまいます。
盤面サイズを定数として定義しておけば、この値を変えるだけで
盤面の大きさを自由に変えることができます。

盤面の石情報を管理する配列と、現在どちらのターンなのかを
格納する配列をmain文で宣言します。

int main()
{
    int board[BOARD_SIZE][BOARD_SIZE];
    int which_turn;
    return 0;
}

ここからいろいろ関数を宣言していきます。

盤面初期化

引数で渡した盤面の配列を、二重ループで回して
全て「STONE_SPACE」にしてやります。

void boardInit(int board[][BOARD_SIZE])
{
    int i, j;
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            board[i][j] = STONE_SPACE;
        }
    }
}

ゲーム初期化

盤面を初期化する関数の呼び出しと、which_turnを初期化してやります。
先手は黒なので、「STONE_BLACK」を格納します。

void gameInit(int board[][BOARD_SIZE], int *which_turn)
{
    boardInit(board);
    *which_turn = STONE_BLACK;
}

盤面出力

二重ループを回し、board[i][j]に対応する駒を出力します。
分かりやすいように、左と上に番号を出力しておきます。

void boardPrint(int board[][BOARD_SIZE])
{
    int i, j;
    printf("  ");
    for (i = 0; i < BOARD_SIZE; i++) {
        printf("%d ", i);
    }
    puts("");
    for (i = 0; i < BOARD_SIZE; i++) {
        printf("%d ", i);
        for (j = 0; j < BOARD_SIZE; j++) {
            switch (board[i][j]) {
            case STONE_SPACE: printf("・"); break;
            case STONE_BLACK: printf("●"); break;
            case STONE_WHITE: printf("○"); break;
            }
        }
        puts("");
    }
    puts("");
}

入力処理

正しい入力がくるまでループを回して入力を促します。
正しくない入力というのは、盤面の範囲外か
すでに石が置いてあるかです。
正しい入力がきたらループを抜け、その場所に石を置きます。

void inputPutPos(int board[][BOARD_SIZE], int which)
{
    int pos_x, pos_y;
    printf("%s", (which == 1) ? "●" : "○");
    printf("の番です。どこに置きますか\n> ");
    while (1) {
        scanf("%d %d", &pos_x, &pos_y);
        if (checkOutPos(pos_x, pos_y) && board[pos_y][pos_x] == STONE_SPACE) { break; }
        printf("不正な入力です\n> ");
    }
    board[pos_y][pos_x] = which;
}

手番交代処理

黒なら白に、白なら黒に変えます。

void changeTurn(int *which_turn)
{
    *which_turn = (*which_turn == STONE_BLACK) ? STONE_WHITE : STONE_BLACK;
}

範囲外チェック

引数で座標を渡し、範囲内なら1を、範囲外なら0を返します。

int checkOutPos(int x, int y)
{
    return (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE);
}

5連確認

引数で渡した座標から、下、右、斜め右下の順で盤面を見ていきます。
指定した座標の石が5連続いていれば1を返します。

int lenCheck(int board[][BOARD_SIZE], int x, int y)
{
    int i, j, len_flag;
    int dx[] = { 0, 1, 1 };
    int dy[] = { 1, 0, 1 };
    for (i = 0; i < 3; i++) {
        for (j = 1, len_flag = 1; j <= 4; j++) {
            if (board[y][x] != board[y+j*dy[i]][x+j*dx[i]]) {
                len_flag = 0;
                break;
            }
        }
        if (len_flag == 1) { return 1; }
    }
    return 0;
}

ゲーム終了処理

盤面を見て、5連があるか確認します。
あれば、結果を出力し、1を返します。

int gameEndProcess(int board[][BOARD_SIZE])
{
    int i, j, len_flag;
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            if (board[i][j] == STONE_SPACE) { continue; }
            if (lenCheck(board, j, i)) {
                printf("%sの勝ちです。\n", (board[i][j] == STONE_BLACK) ? "●" : "○");
                return 1;
            }
        }
    }
    return 0;
}

main文

必要な関数の定義がし終わったので、プロトタイプ宣言をして、
main文で使っていきます。

int main()
{
    // 変数宣言
    int board[BOARD_SIZE][BOARD_SIZE];
    int which_turn;
    
    // 初期処理
    gameInit(board, &which_turn);
    boardPrint(board);
    
    //---- メインループ
    while (1) {
        //--- 入力処理
        inputPutPos(board, which_turn);

        //--- 演算処理
        changeTurn(&which_turn);
        
        //--- 出力処理
        boardPrint(board);
        
        //--- 終了判定
        if (gameEndProcess(board)) { break; }
    }
    return 0;
}

コード

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define BOARD_SIZE 10      // 盤面サイズ 10 * 10
#define STONE_SPACE 0      // 盤面にある石 なし
#define STONE_BLACK 1      // 盤面にある石 黒
#define STONE_WHITE 2      // 盤面にある石 白

void inputPutPos(int board[][BOARD_SIZE], int which);
void changeTurn(int *which_turn);
int checkOutPos(int x, int y);
void gameInit(int board[][BOARD_SIZE], int *which_turn);
void boardInit(int board[][BOARD_SIZE]);
void boardPrint(int board[][BOARD_SIZE]);
int gameEndProcess(int board[][BOARD_SIZE]);
int lenCheck(int board[][BOARD_SIZE], int x, int y);

//=======================================================
// main
//=======================================================
int main()
{
    // 変数宣言
    int board[BOARD_SIZE][BOARD_SIZE];
    int which_turn;
    
    // 初期処理
    gameInit(board, &which_turn);
    boardPrint(board);
    
    //---- メインループ
    while (1) {
        //--- 入力処理
        inputPutPos(board, which_turn);

        //--- 演算処理
        changeTurn(&which_turn);
        
        //--- 出力処理
        boardPrint(board);
        
        //--- 終了判定
        if (gameEndProcess(board)) { break; }
    }
    return 0;
}

//-------------------------------------------------
// 置く場所入力
//-------------------------------------------------
void inputPutPos(int board[][BOARD_SIZE], int which)
{
    int pos_x, pos_y;
    
    printf("%s", (which == 1) ? "●" : "○");
    printf("の番です。どこに置きますか\n> ");
    while (1) {
        scanf("%d %d", &pos_x, &pos_y);
        if (checkOutPos(pos_x, pos_y) && board[pos_y][pos_x] == STONE_SPACE) { break; }
        printf("不正な入力です\n> ");
    }
    board[pos_y][pos_x] = which;
}

//-------------------------------------------------
// 手番交代処理
//-------------------------------------------------
void changeTurn(int *which_turn)
{
    *which_turn = (*which_turn == STONE_BLACK) ? STONE_WHITE : STONE_BLACK;
}

//-------------------------------------------------
// 範囲外チェック
//-------------------------------------------------
int checkOutPos(int x, int y)
{
    return (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE);
}

//-------------------------------------------------
// ゲーム情報初期化
//-------------------------------------------------
void gameInit(int board[][BOARD_SIZE], int *which_turn)
{
    boardInit(board);
    *which_turn = STONE_BLACK;
}

//-------------------------------------------------
// 盤面初期化
//-------------------------------------------------
void boardInit(int board[][BOARD_SIZE])
{
    int i, j;
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            board[i][j] = STONE_SPACE;
        }
    }
}

//-------------------------------------------------
// 盤面出力
//-------------------------------------------------
void boardPrint(int board[][BOARD_SIZE])
{
    int i, j;
    
    printf("  ");
    for (i = 0; i < BOARD_SIZE; i++) {
        printf("%d ", i);
    }
    puts("");
    for (i = 0; i < BOARD_SIZE; i++) {
        printf("%d ", i);
        for (j = 0; j < BOARD_SIZE; j++) {
            switch (board[i][j]) {
            case STONE_SPACE: printf("・"); break;
            case STONE_BLACK: printf("●"); break;
            case STONE_WHITE: printf("○"); break;
            }
        }
        puts("");
    }
    puts("");
}

//-------------------------------------------------
// ゲーム終了処理
//-------------------------------------------------
int gameEndProcess(int board[][BOARD_SIZE])
{
    int i, j, len_flag;
    
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            if (board[i][j] == STONE_SPACE) { continue; }
            if (lenCheck(board, j, i)) {
                printf("%sの勝ちです。\n", (board[i][j] == STONE_BLACK) ? "●" : "○");
                return 1;
            }
        }
    }
    return 0;
}

//-------------------------------------------------
// 5連確認
//-------------------------------------------------
int lenCheck(int board[][BOARD_SIZE], int x, int y)
{
    int i, j, len_flag;
    int dx[] = { 0, 1, 1 };
    int dy[] = { 1, 0, 1 };
    
    for (i = 0; i < 3; i++) {
        for (j = 1, len_flag = 1; j <= 4; j++) {
            if (board[y][x] != board[y+j*dy[i]][x+j*dx[i]]) {
                len_flag = 0;
                break;
            }
        }
        if (len_flag == 1) { return 1; }
    }
    return 0;
}

実行

f:id:mo2dx:20141210210733j:plain


完成!

これでコマンドプロンプト版の五目並べは完成です!
やったね!
でも、コマンドプロンプトだと操作しずらいし、
文字だけだと寂しいですよね・・・

じゃあ、GUIに移植してみよう!


DXライブラリ

GUIのゲームを作るとなるとライブラリが必要になります。
有名なものに、DirectXOpenGLなどがあります。
今回は使いやすいDXライブラリを使ってみましょう!

ダウンロード
DXライブラリ置き場 ダウンロードページ

設定
DXライブラリ置き場 使い方説明

↑でがんばって設定します。


プロジェクトの準備が終わったらコードを書いていきます。
内部処理はだいたい一緒なので、入力、出力の部分を変更します。
画像は自分で用意します。

コード

#include "DxLib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

#define BOARD_SIZE 10      // 盤面サイズ 10 * 10
#define STONE_SPACE 0      // 盤面にある石 なし
#define STONE_BLACK 1      // 盤面にある石 黒
#define STONE_WHITE 2      // 盤面にある石 白

int processLoop();
void loadImage();
int updateMouse();
int inputPutPos(int board[][BOARD_SIZE], int which);
void changeTurn(int *which_turn);
int checkOutPos(int x, int y);
void gameInit(int board[][BOARD_SIZE], int *which_turn);
void boardInit(int board[][BOARD_SIZE]);
void boardPrint(int board[][BOARD_SIZE]);
int gameEndProcess(int board[][BOARD_SIZE]);
int lenCheck(int board[][BOARD_SIZE], int x, int y);

// 画像ハンドル
int image_stone_w;
int image_stone_b;
int image_board;

// クリック状態
int click;

//=======================================================
// main
//=======================================================
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(TRUE);      // ウィンドウモードで起動する
    SetGraphMode(540, 540, 16);  // ウィンドウサイズ(540×540) 使用カラー16bit(65536色)
    SetWindowText("五目並べ");   // タイトル名
    if (DxLib_Init() == -1) { return -1; }   // DXライブラリ初期化
    if (SetDrawScreen(DX_SCREEN_BACK) != 0) { return -1; }  // 描画先を裏画面に

    int board[BOARD_SIZE][BOARD_SIZE];
    int which_turn;

    // デバッグ用コマンドプロンプト
    /*
    AllocConsole();
    FILE* fp;
    freopen_s(&fp, "CONOUT$", "w", stdout);
    freopen_s(&fp, "CONIN$", "r", stdin);
    */

    // 初期処理
    gameInit(board, &which_turn);
    loadImage();

    //---- メインループ
    while (processLoop() == 0) {
        //--- 入力処理
        if (inputPutPos(board, which_turn)) {
            changeTurn(&which_turn);
        }

        //--- 出力処理
        boardPrint(board);
        ScreenFlip();

        //--- 終了判定
        if (gameEndProcess(board)) { break; }
    }
    
    DxLib_End();
    return 0;
}

//-------------------------------------------------
// ループ処理
//-------------------------------------------------
int processLoop()
{
    if (ProcessMessage() != 0) { return -1; }
    if (ClearDrawScreen() != 0) { return -1; }
    if (updateMouse() != 0) { return -1; }
    return 0;
}

//-------------------------------------------------
// マウス入力状態更新
//-------------------------------------------------
int updateMouse()
{
    if (GetMouseInput() & MOUSE_INPUT_LEFT) {
        click++;
    }
    else {
        click = 0;
    }
    return 0;
}

//-------------------------------------------------
// 画像読み込み処理
//-------------------------------------------------
void loadImage()
{
    image_stone_w = LoadGraph("white_stone.png");
    image_stone_b = LoadGraph("black_stone.png");
    image_board = LoadGraph("board.png");
}

//-------------------------------------------------
// 置く場所入力
//-------------------------------------------------
int inputPutPos(int board[][BOARD_SIZE], int which)
{
    int pos_x, pos_y;

    if (click == 1) {
        GetMousePoint(&pos_x, &pos_y);
        pos_x = (pos_x - 25) / 50;
        pos_y = (pos_y - 25) / 50;
        if (checkOutPos(pos_x, pos_y) && board[pos_y][pos_x] == 0) {
            board[pos_y][pos_x] = which;
            return 1;
        }
    }
    return 0;
}

//-------------------------------------------------
// 手番交代処理
//-------------------------------------------------
void changeTurn(int *which_turn)
{
    *which_turn = (*which_turn == STONE_BLACK) ? STONE_WHITE : STONE_BLACK;
}

//-------------------------------------------------
// 範囲外チェック
//-------------------------------------------------
int checkOutPos(int x, int y)
{
    return (x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE);
}

//-------------------------------------------------
// ゲーム情報初期化
//-------------------------------------------------
void gameInit(int board[][BOARD_SIZE], int *which_turn)
{
    boardInit(board);
    *which_turn = STONE_BLACK;
}

//-------------------------------------------------
// 盤面初期化
//-------------------------------------------------
void boardInit(int board[][BOARD_SIZE])
{
    int i, j;
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            board[i][j] = STONE_SPACE;
        }
    }
}

//-------------------------------------------------
// 盤面出力
//-------------------------------------------------
void boardPrint(int board[][BOARD_SIZE])
{
    int i, j;
    DrawGraph(0, 0, image_board, TRUE);
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            if (board[i][j] == STONE_BLACK) {
                DrawGraph(j * 49, i * 49, image_stone_b, TRUE);
            }
            else if (board[i][j] == STONE_WHITE) {
                DrawGraph(j * 49, i * 49, image_stone_w, TRUE);
            }
        }
    }
}

//-------------------------------------------------
// ゲーム終了処理
//-------------------------------------------------
int gameEndProcess(int board[][BOARD_SIZE])
{
    int i, j;
    for (i = 0; i < BOARD_SIZE; i++) {
        for (j = 0; j < BOARD_SIZE; j++) {
            if (board[i][j] == STONE_SPACE) { continue; }
            if (lenCheck(board, j, i)) {
                return 1;
            }
        }
    }
    return 0;
}

//-------------------------------------------------
// 5連確認
//-------------------------------------------------
int lenCheck(int board[][BOARD_SIZE], int x, int y)
{
    int i, j, len_flag;
    int dx[] = { 0, 1, 1 };
    int dy[] = { 1, 0, 1 };

    for (i = 0; i < 3; i++) {
        for (j = 1, len_flag = 1; j <= 4; j++) {
            if (board[y][x] != board[y + j*dy[i]][x + j*dx[i]]) {
                len_flag = 0;
                break;
            }
        }
        if (len_flag == 1) { return 1; }
    }
    return 0;
}

実行結果


f:id:mo2dx:20141212001201p:plain


おわり

みんなゲーム作ろう!