LoginSignup
1
0

C言語でマルバツゲームの実装と構造体のリスト構造の作成

Last updated at Posted at 2024-02-13

概要

記事を読んでいただきありがとうございます。
cの勉強を目的にゲームを作成しましたので、
ゲームの質にはこだわっておりません。
メモ書き程度に書いておりますのでご了承下さい。

今回はC言語でマルバツゲームとリスト構造を作成してみました。

GitHub

コードは上記にあります。ご参照下さい。

コード(マルバツゲーム)

以下はメインファイルになります。

#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <time.h>
#define FULL_CELL 9 //すべてのマス目数
#define SIDE 3 //一辺のマス目数
#define ZERO 0  //座標
#define ONE 1 //座標
#define TWO 2 //座標
#define UNDECI 0 //未記入
#define CIRCLE 1 //私の駒(丸印)
#define CROSS 2 //PCの駒(×印)

typedef enum{MY_T,PC_T}TURN;


typedef struct BOARD{
    int** masu;
    int yoko,tate;
    bool pc_win_flag;
    bool me_win_flag;
    int pc_tate,pc_yoko;
    TURN turn;
}BOARD;

//プロトタイプ宣言
void makeArray(BOARD *test); //碁盤の座標の生成
void freeArray(BOARD *test); //碁盤の座標の削除
void setup(BOARD test); //初期値の碁盤の配置
void show(BOARD test); //碁盤の表示
void select(BOARD *test); //駒を置く
void judge(BOARD *test);


int main(void) {
    BOARD test;
    test.turn = MY_T;
    test.me_win_flag = false,test.pc_win_flag = false;
    srand((unsigned int)time(NULL));
    makeArray(&test);
    setup(test);
    show(test);
    while ((test.me_win_flag == false) && (test.pc_win_flag == false))
    {
        select(&test);
        judge(&test);
        show(test);
    }
    printf("FINISH\n");
    if (test.me_win_flag == true) printf("YOU WIN\n");
    else printf("PC WIN\n");
    freeArray(&test);

}
void select(BOARD *test){
    if (test->turn == MY_T)
    {
        test->yoko = -1,test->tate = -1;
        bool select_flag = false;
        while (select_flag == false)
        {
            printf("select yoko(0-2)>>>\n");
            scanf("%d",&test->yoko);
            printf("select tate(0-2)>>>\n");
            scanf("%d",&test->tate);
            if ((test->yoko < ZERO) ||(test->yoko > TWO) ||(test->tate < ZERO) ||(test->tate > TWO) )
            {
                printf("again_\n");
                select_flag = false;
            }
            else
            {
                if (test->masu[test->yoko][test->tate] == UNDECI)
                {
                    select_flag = true;
                    test->masu[test->yoko][test->tate] = CIRCLE;
                    break;
                }
                else
                {
                    printf("again_\n");
                    select_flag = false;
                }
                
            }
        
        }

    }else
    {
        printf("PC_");
        test->pc_yoko = -1,test->pc_tate = -1;
        bool pc_select = false;
        while (pc_select == false)
        {
            printf("PC:select yoko(0-2)>>>\n");
            scanf("%d",&test->pc_yoko);
            printf("PC:select tate(0-2)>>>\n");
            scanf("%d",&test->pc_tate);
            if ((test->pc_yoko < ZERO) ||(test->pc_yoko > TWO) ||(test->pc_tate < ZERO) ||(test->pc_tate > TWO) )
            {
                printf("again_\n");
                pc_select = false;
            }
            else
            {
                if (test->masu[test->pc_yoko][test->pc_tate] == UNDECI)
                {
                    pc_select = true;
                    test->masu[test->pc_yoko][test->pc_tate] = CROSS;
                    break;
                }
                else
                {
                    printf("again_\n");
                    pc_select = false;
                }
                
            }
        }
        

    }

}
    

void setup(BOARD test){
    for (int yoko = 0; yoko < SIDE; yoko++)
    {
        for (int tate = 0; tate < SIDE; tate++)
        {
            test.masu[yoko][tate] = UNDECI;
            
        }
    }
}
void show(BOARD test){
    int circle_num = 0,cross_num = 0,undeci_num = 0; 
    for (int  yoko = 0; yoko < SIDE; yoko++)
    {
        for (int tate = 0; tate < SIDE; tate++)
        {
            switch (test.masu[yoko][tate])
            {
                case CIRCLE:circle_num++;break;
                case CROSS:cross_num++;break;
                case UNDECI:undeci_num++;break;
                default:break;
            }
            
        }
    }
    if (test.turn == MY_T) printf("########YOUR TURN########\n");
    else printf("##########PC TURN########\n");
    
    printf("\n");
    printf("ME:o>>>%d\n",circle_num);
    printf("PC:x>>>%d\n",cross_num);
    printf("\n");
    printf("  012\n");
    for (int  yoko = 0; yoko < SIDE; yoko++)
    {
        printf("%-2d",yoko);
        for (int tate = 0; tate < SIDE; tate++)
        {
            switch (test.masu[yoko][tate])
            {
                case CIRCLE:printf("o");break;
                case CROSS:printf("x");break;
                case UNDECI:printf("-");break;
                default:break;
            }
            
        }
        printf("\n");
    }
    printf("#########################\n");
}
void makeArray(BOARD* test){
    test->masu = (int**)calloc(SIDE,sizeof(int*));
    for (int i = 0; i < SIDE; i++)
    {
        test->masu[i] = (int *)calloc(SIDE,sizeof(int));
    }
    
}
void freeArray(BOARD* test){
    for (int i = 0; i < SIDE; i++)
    {
        free(test->masu[i]);
    }
    free(test->masu);

}
void judge(BOARD *test){
    test->me_win_flag = false,test->pc_win_flag = false;
    int win_num = SIDE;
    int mark = -1;
    if (test->turn == MY_T)
    {
        mark = CIRCLE;
    }else{
        mark = CROSS;
    }
    //横方向
    for (int yoko = 0; yoko < SIDE; yoko++)
    {
        int count = 0;
        for (int tate = 0; tate < SIDE; tate++)
        {
            if (test->masu[yoko][tate] == mark)
            {
                count++;
            }
            
        }
        if (count == win_num)
        {
            if (mark == CIRCLE)test->me_win_flag = true;
            else test->pc_win_flag = true;
            count = 0;
            printf("yoko_flag");
            break;
        }
    }

    //縦方向
    for (int tate = 0; tate < SIDE; tate++)
    {
        int count = 0;
        for (int yoko = 0; yoko < count; yoko++)
        {
            if (test->masu[yoko][tate] == mark)
            {
                count++;
            }
        }
        if (count == win_num)
        {
            if (mark == CIRCLE)test->me_win_flag = true;
            else test->pc_win_flag = true;
            count = 0;
            printf("tate_flag");
            break;
        }
    }
    
    //右下
    int count = 0;
    for (int k = 0; k < SIDE; k++)
    {
        if (test->masu[k][k] == mark)
        {
            count++;
        }
    }
    if (count == win_num)
    {
        if (mark == CIRCLE)test->me_win_flag = true;
        else test->pc_win_flag = true;
        printf("migisita_flag");
    }

    //左下
    count = 0;
    for (int k = 0; k < SIDE; k++)
    {
        if (test->masu[k][2 - k] == mark)
            {
                count++;
            }
            
    }
    if (count == win_num)
    {
        if (mark == CIRCLE)test->me_win_flag = true;
        else test->pc_win_flag = true;
        printf("hidarisita_flag");
    }
    count = 0;

    if ((test->me_win_flag == false) && (test->pc_win_flag == false))
    {
        if(mark == CIRCLE) test->turn = PC_T;
        else test->turn = MY_T;
    }

}

コード(構造体のリスト構造)

・2つの構造体をリスト構造にするために、
 メンバに同じ型のポインタを含める。

以下では、2つのスコアを入力し、足す値を入力すると、
2つのスコアそれぞれが足される仕様にした

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#define ADD(x,y) (x + y) //関数形式のマクロの使用

typedef struct DATA{
    int before_score;
    int after_score;
    struct DATA *next; 
}DATA;

int main (void){
    DATA first_data;
    DATA second_data;
    DATA *pdata; //同じ型へのポインタ

    first_data.next = &second_data;
    second_data.next = NULL;

    bool score_flag = false;
    int add_score;
    do
    {
        printf("first subject input\n");
        scanf("%d",&first_data.before_score);
        printf("second subject input\n");
        scanf("%d",&second_data.before_score);
        printf("add score input\n");
        scanf("%d",&add_score);

        if ((0 <= first_data.before_score) && (first_data.before_score <= 100) &&
            (0 <= second_data.before_score) && (second_data.before_score <= 100) &&
            (0 <= add_score) && (add_score <= 100))
        {
            score_flag = true;
        }
        else
        {
            printf("input agein\n");
        }
        
    } while (score_flag == false);
    
    first_data.after_score = ADD(first_data.before_score,add_score);
    second_data.after_score = ADD(second_data.before_score,add_score);
    
    //ポインタ構造体から値を取得する
    for (pdata  = &first_data; pdata != NULL; pdata = pdata->next)
    {
        printf("score>>>%d\n",pdata->after_score);
    }
    
    return 0;
    

}
1
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0