石取りゲーム 応用

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
heath

石取りゲーム 応用

#1

投稿記事 by heath » 14年前

はじめまして。今、石取りゲームを作成し8割完成しているのですが、じゃんけんを用いた先手・後手の決定機能を
追加したいのですが、どのように変えればよいかわかりません。どうか手助けをお願いします!
<機能>
・じゃんけんによる先手・後手の決定機能
・石を置いた場所を記録し、リプレイする機能(完了)
・相手の石を挟む(上下左右など)と自分のものにできる
 オセロのような機能(完了)
*じゃんけんのプログラムは作成済みです。

長いプログラムですがよろしくお願いします。

コード:



#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <time.h>

#define MASU 6 //MASUの数値を変えると盤面の大きさが変わります

int banshow(HANDLE);
int Locate(HANDLE, int, int);
int check_location(int, int); //すでに駒がおかれていないかどうか調べる
int judge();
int stonerecord(int, int);
int replay(HANDLE, int);

//int comp_put(char *); //下記のように引数を変更しています。
int comp_put(HANDLE, char *); //コンピュータが駒を置きます

int IsStoneGet(HANDLE, int, int, BOOL);

int search_pos(HANDLE, char *); //相手の駒が取れる位置を探します
int set_loc(HANDLE, int, int, char *);
int is_getcorner(char *); //4隅に駒が置けるかどうかを調べます


int ban[MASU][MASU];
int comp; //対戦相手がコンピュータの時1, その他0
int compsente; //コンピュータが先手1, 後手0


struct _tagRec {
    int row;
    int col;
} Rec[MASU * MASU];

int main()
{
    HANDLE hOut;
    char cMoji, szTxt[8];
    BOOL bOrd = TRUE; //FALSE:後手 TRUE:先手
    int i, row =0, col=0, jud, tekazu; //何手で勝負がついたか;
    char location[8]; //位置指定 A2, B1,など
    char *sente = "先手", *gote = "後手";
    char order[8], hantei[16], yesno[8];

	system("cls");

    hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    printf("コンピュータと対戦しますか(y/n)");
    gets(yesno);
    if (strcmp(yesno, "Y") == 0 || strcmp(yesno, "y") == 0) {
        comp = 1;
        printf("あなたが先手になりますか(y/n)");
        gets(yesno);
        if (strcmp(yesno, "Y") == 0 || strcmp(yesno, "y") == 0) {
            compsente = 0;
        } else {
            compsente = 1;
        }
    } else {
        comp = 0;
    }
    
    Locate(hOut, 0, 0);
    printf("                                     ");
    Locate(hOut, 0, 1);
    printf("                                     ");

    banshow(hOut);

    for (i = 0; i < MASU * MASU; i++) {
        if (bOrd)
            strcpy(order, sente);
        else
            strcpy(order, gote);
INP:
        Locate(hOut, 28, MASU + 2);
        printf("       ");
        
            Locate(hOut, 0, MASU + 2);
            printf("位置を指定してください(%s)", order);
        if (comp == 0 || (comp == 1 && compsente == 1 && !bOrd) || (comp == 1 && compsente == 0 && bOrd)) {
            gets(location);
        } else {

            comp_put(hOut,location);

        }
        if (location[0] == '0')
            return -1;
        if (isalpha(location[0]) == 0) {
            Locate(hOut, 0, MASU + 3);
            printf("指定が違います");
            goto INP;
        }
        if (isupper(location[0]) == 0)
            cMoji = toupper(location[0]);
        else
            cMoji = location[0];
        row = cMoji - 'A';
        if (row < 0 || row > MASU - 1) {
            Locate(hOut, 0, MASU + 3);
            printf("行の指定が違います");
            goto INP;
        }

        if (isdigit(location[1]) != 0 && isdigit(location[2]) != 0 && location[3] == '\0') {
            szTxt[0] = location[1];
            szTxt[1] = location[2];
            szTxt[2] = '\0';
            col = atoi(szTxt) - 1;
        } else if (isdigit(location[1]) != 0 && location[2] == '\0') {
            szTxt[0] = location[1];
            szTxt[1] = '\0';
            col = atoi(szTxt) - 1;
        } else {
            Locate(hOut, 0, MASU + 3);
            printf("列の指定が違います");
            goto INP;
        }
            
        if (col < 0 || col > MASU - 1) {
            Locate(hOut, 0, MASU + 3);
            printf("列の位置指定が違います");
            goto INP;
        }
        if (check_location(row, col) != 0) {
            Locate(hOut, 0, MASU + 3);
            printf("そこには置けません!");
            goto INP;
        }            
        if (bOrd)
            ban[row][col] = 1;
        else
            ban[row][col] = 2;
        IsStoneGet(hOut, row, col, bOrd);
        stonerecord(row, col);
        bOrd = !bOrd;
        banshow(hOut);
        Locate(hOut, 0, MASU + 3);
        printf("                         ");
        jud = judge();
        switch (jud) {
            case 0:
                strcpy(hantei, "");
                break;
            case 1:
                strcpy(hantei, "先手の勝ち");
                tekazu = i +1;
                break;
            case 2:
                strcpy(hantei, "後手の勝ち");
                tekazu = i + 1;
                break;
            default:
                strcpy(hantei, "内部エラー");
                break;
        }
        Locate(hOut, 0, MASU + 4);
        printf(hantei);
        if (jud != 0)
            break;
    }
    if (jud == 0) {
        printf("引き分けです");
        tekazu = MASU * MASU;
    }
    printf("\n\n");
    printf("再現しますか(Y/N)-->");
    gets(yesno);
    if (strcmp(yesno, "y") == 0 || strcmp(yesno, "Y") == 0) {
        replay(hOut, tekazu);
    }
    Locate(hOut, 0, MASU + 6);
    return 0;
}

int banshow(HANDLE hStdOut)
{
    int i, j;

    Locate(hStdOut, 0, 0);
    printf("   ");
    for (i = 0; i < MASU; i++) {
        printf("[%2d]", i + 1);
    }
    printf("\n");
    for (i = 0; i < MASU; i++) {
        printf("[%c]\n", i + 'A');
    }
    for (i = 0; i < MASU; i++) {
        for (j = 0; j < MASU; j++) {
            if (ban[i][j] == 1) {
                Locate(hStdOut, j * 4 + 4, i + 1);
                printf("○");
            }
            if (ban[i][j] == 2) {
                Locate(hStdOut, j * 4 + 4, i + 1);
                printf("×");
            }
        }
    }
    return 0;
}

int Locate(HANDLE hOut, int x, int y)
{
    COORD dwPos;
    dwPos.X = (SHORT)x;
    dwPos.Y = (SHORT)y;

    if (SetConsoleCursorPosition(hOut, dwPos) == 0)
        return -1;
    else
        return 0;
}

int check_location(int row, int col)
{
    if (ban[row][col] == 0)
        return 0;
    else
        return -1;
}

int judge() //戻り値 1:先手の勝ち 2:後手の勝ち 0:勝敗はまだ
{
    int i, j, rseki[MASU], rwa[MASU], cseki[MASU], cwa[MASU];
    int cross1seki = 1, cross1wa = 0, cross2seki = 1, cross2wa = 0;

    // 配列の初期化
    for (i = 0; i < MASU; i++) {
        rseki[i] = 1;
        rwa[i] = 0;
        cseki[i] = 1;
        cwa[i] = 0;
    }
    
    for (i = 0; i < MASU; i++) {
        for (j = 0; j < MASU; j++) {
            rseki[i] = rseki[i] * ban[i][j];
            rwa[i]   = rwa[i] + ban[i][j];
            cseki[i] = cseki[i] * ban[j][i];
            cwa[i]   = cwa[i] + ban[j][i];
        }
        cross1seki = cross1seki * ban[i][i];
        cross1wa   = cross1wa + ban[i][i];
        cross2seki = cross2seki * ban[MASU - 1 - i][i];
        cross2wa   = cross2wa + ban[MASU - 1 - i][i];
    }

    for (i = 0; i < MASU; i++) {
        if (rseki[i] != 0 && rwa[i] == MASU)
            return 1;
        if (rseki[i] != 0 && rwa[i] == MASU * 2)
            return 2;
        if (cseki[i] != 0 && cwa[i] == MASU)
            return 1;
        if (cseki[i] != 0 && cwa[i] == MASU * 2)
            return 2;
    }

    if (cross1seki != 0 && cross1wa == MASU)
        return 1;
    if (cross1seki != 0 && cross1wa == MASU * 2)
        return 2;
    if (cross2seki != 0 && cross2wa == MASU)
        return 1;
    if (cross2seki != 0 && cross2wa == MASU * 2)
        return 2;
    return 0;
}

int stonerecord(int row, int col)
{
    static int nTe = 1;

    Rec[nTe - 1].row = row;
    Rec[nTe - 1].col = col;
    nTe++;
    return 0;
}

int replay(HANDLE hOut, int tekazu)
{
    int i, j, stone;
    BOOL bSente = TRUE;
    //盤面初期化
    Locate(hOut, 0, MASU + 4);
    printf("                    ");
    Locate(hOut, 0, MASU + 2);
    printf("                                ");
    for (i = 0; i < MASU; i++) {
        for (j = 0; j < MASU; j++) {
            Locate(hOut, i * 4 + 4, j + 1);
            printf("    ");
            ban[i][j] = 0;
        }
    }

    for (i = 0; i < tekazu; i++) {
        if (bSente)
            stone = 1;
        else
            stone = 2;
        ban[Rec[i].row][Rec[i].col] = stone;
        IsStoneGet(hOut, Rec[i].row, Rec[i].col, bSente);
        banshow(hOut);
        bSente = !bSente;
        Locate(hOut, 0, MASU + 4);
        printf("再現中.....第%02d手目", i + 1);
        _getch();
    }
    return 0;
}

int comp_put(HANDLE hOut,char *loc)
{
    char a1, a2[4];
    int row, col;
//修正仕様
//まずsearch_pos関数を呼んで、相手の駒を取れる位置があるかどうかを調べ、取れたならreturnで戻ります。
//取れない場合は、is_getcorner関数を呼んで四隅が取れるかどうかを調査します。四隅に置けたならreturnで戻ります。
//四隅にも置けない場合は、今まで通りランダムな位置に置きます。 

    if (search_pos(hOut, loc) == 0)
        return 0;
    if (is_getcorner(loc) == 0)
        return 0

    srand((unsigned)time(NULL));

    while (1) {
        row = rand() % MASU;
        col = rand() % MASU;

        if (check_location(row, col) == 0)
            break;
    }

    a1 = (char)row + 'A';
    itoa(col + 1, a2, 10);
        
    loc[0] = a1;
    loc[1] = '\0';
    strcat(loc, a2);

    return 0;
}

int IsStoneGet(HANDLE hOut, int row, int col, BOOL bOrd)
{
    int jibun, aite;

    if (bOrd) {
        jibun = 1;
        aite = 2;
    } else {
        jibun = 2;
        aite = 1;
    }

    if (row - 2 >= 0 && col - 2 >=0 &&
        ban[row - 2][col - 2] == jibun && 
        ban[row - 1][col - 1] == aite) {
        ban[row - 1][col - 1] = jibun;
    }
    if (row - 2 >= 0 &&
        ban[row - 2][col] == jibun &&
        ban[row - 1][col] == aite) {
        ban[row - 1][col] = jibun;
    }
    if (row - 2 >= 0 && col + 2 < MASU &&
        ban[row - 2][col + 2] == jibun &&
        ban[row - 1][col + 1] == aite) {
        ban[row - 1][col + 1] = jibun;
    }
    if (col - 2 >= 0 &&
        ban[row][col - 2] == jibun &&
        ban[row][col - 1] == aite) {
        ban[row][col - 1] = jibun;
    }
    if (col + 2 < MASU &&
        ban[row][col + 2] == jibun &&
        ban[row][col + 1] == aite) {
        ban[row][col + 1] = jibun;
    }
    if (row + 2 < MASU && col - 2 >= 0 &&
        ban[row + 2][col - 2] == jibun &&
        ban[row + 1][col - 1] == aite) {
        ban[row + 1][col - 1] = jibun;
    }
    if (row + 2 < MASU &&
        ban[row + 2][col] == jibun &&
        ban[row + 1][col] == aite) {
        ban[row + 1][col] = jibun;
    }
    if (row + 2 < MASU && col + 2 < MASU &&
        ban[row + 2][col + 2] == jibun &&
        ban[row + 1][col + 1] == aite) {
        ban[row + 1][col + 1] = jibun;
    }
    return 0;
}


//相手の駒が取れる位置を探します
int search_pos(HANDLE hOut, char *loc)
{
    int i, j, jibun, aite;

    if (compsente == 1) {
        jibun = 1;
        aite = 2;
    } else {
        jibun = 2;
        aite = 1;
    }

    for (i = 0; i < MASU - 2; i++) {
        for (j = 0; j < MASU; j++) {
            if (ban[i][j] == 0 && ban[i + 1][j] == aite && ban[i + 2][j] == jibun) {
                set_loc(hOut, i, j, loc);
                return 0;
            }
        }
    }
    for (i = 2; i < MASU; i++) {
        for (j = 0; j < MASU; j++) {
            if (ban[i][j] == 0 && ban[i - 1][j] == aite && ban[i - 2][j] == jibun) {
                set_loc(hOut, i, j, loc);
                return 0;
            }
        }
    }
    for (i = 0; i < MASU; i++) {
        for (j = 0; j < MASU - 2; j++) {
            if (ban[i][j] == 0 && ban[i][j + 1] == aite && ban[i][j + 2] == jibun) {
                set_loc(hOut, i, j, loc);
                return 0;
            }
        }
    }
//不足分のプログラムを以下に記述してください。
for (i = 2; i < MASU; i++) {
        for (j = 0; j < MASU; j++) {
            if (ban[i][j] == 0 && ban[i - 1][j - 1] == aite && ban[i - 2][j -2] == jibun) {
                set_loc(hOut, i, j, loc);
                return 0;
            }
        }
    }
for (i = 0; i < MASU - 2; i++) {
        for (j = 0; j < MASU; j++) {
            if (ban[i][j] == 0 && ban[i + 1][j - 1] == aite && ban[i + 2][j - 2] == jibun) {
                set_loc(hOut, i, j, loc);
                return 0;
            }
        }
    }


//ここまで。
    return -1;
}

int set_loc(HANDLE hOut, int row, int col, char *loc)
{
    char szBuf[8], szTxt[256];

    loc[0] = 'A' + row;
    loc[1] = '\0';
    itoa(col + 1, szBuf, 10);
    strcat(loc, szBuf);
    sprintf(szTxt, "PCは(%s)に駒を置いてあなたの石を取ります。何かキーを押してください。", loc);
    Locate(hOut, 0, MASU + 5);
    printf(szTxt);
    _getch();
    Locate(hOut, 0, MASU + 5);
    printf("                                                                         ");
    return 0;
}

//4隅に駒が置けるかどうかを調べます
int is_getcorner(char *loc)
{
    if (ban[0][0] == 0) {
        strcpy(loc, "A1");
        return 0;
    }
    if (ban[0][MASU - 1] == 0) {
        sprintf(loc, "A%d", MASU);
        return 0;
    }


 if (ban[MASU - 1][0] == 0) {
        sprintf(loc, "%c1", MASU + 'A'-1);
        return 0;
    }
 if (ban[MASU - 1][MASU - 1] == 0) {
        sprintf(loc, "%c%d", MASU + 'A'-1,MASU);
        return 0;
    }


    return -1;
}




のり

Re: 石取りゲーム 応用

#2

投稿記事 by のり » 14年前

申し訳ないけど全部みてませんが、
プログラムは
プレイヤー→AIの順で自分の手を決めるように組んでいるのですか?

質問は後の後の手のときには
AI→プレイヤーというようにしたいということですよね?

でしたらループの中で何回もifを見ないようにするために、
後の手のときは、
プレイヤー→AIがループで繰り返し行われるとして、
ループに入る前にAIのプログラムを入れれば良いのでは??
ifでくくって

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 石取りゲーム 応用

#3

投稿記事 by softya(ソフト屋) » 14年前

これは猫でもわかるプログラミングのものと酷似していますが中身は理解されていますか? 
現在の先手・後手を決定している変数名を書いてみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

“C言語何でも質問掲示板” へ戻る