二维数组应用 -- 五子棋游戏

简单

只有一个玩家,无交互,无胜负判断

#include<stdio.h>
#define BOARD_SIZE 15
int main(){
    char board[BOARD_SIZE][BOARD_SIZE];
    //初始化
    for(int i = 0; i < BOARD_SIZE; i++){
        for(int j = 0; j < BOARD_SIZE; j++){
            board[i][j] = '.';
        }
    }
    //循环条件,游戏是否继续
    char decision = 'y';
    while(decision == 'y' || decision == 'Y'){
        //打印棋盘
        for(int i = 0; i < BOARD_SIZE; i++){
            for(int j = 0; j < BOARD_SIZE; j++){
                printf("%c ", board[i][j]);
            }
            printf("\n");
        }
        //输入落子位置
        printf("please input piece position (0 - %d), spacing by space\n", BOARD_SIZE - 1);
        int x;
        int y; 
        scanf("%d %d", &x, &y);
        //是否可以落子
        if(x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE && board[x][y] == '.'){
            board[x][y] = 'x';
        }else{
            printf("Invalid inputs!Please input again\n");
        }
        //是否继续游戏
        printf("continue?(y or n)\n");
        getchar();
        scanf("%c", &decision);
        //清屏
        printf("\033[H\033[J");
    }
    printf("GAME OVER!");
    return 0;
}

printf(“\033[H\033[J”)实现屏幕刷新的原理

        printf("\033[H\033[J"); 能实现屏幕刷新的原因在于它利用了 ANSI 转义序列(ANSI escape sequences)来控制终端显示。这些序列是由 ESC(\033 或 \x1B)字符开头的字符串,后面跟着一些指令字符。具体来说:
\033[H:这个序列将光标移动到屏幕的左上角。\033 是 ESC 字符(ASCII 值为 27),[ 是开始一个控制序列的字符,H 是光标定位命令。它等同于 \033[1;1H,即将光标移动到第 1 行第 1 列。
\033[J:这个序列清除从光标位置到屏幕末端的所有内容。J 是清屏命令。
        当这两个序列组合在一起使用时,首先将光标移动到屏幕的左上角,然后从光标位置(也就是屏幕的左上角)清除到屏幕末端,这样就达到了刷新屏幕的效果。

进阶

有两个玩家交互,且可以检测胜负
重点:
① 游戏获胜条件?
② 两个玩家如何交互

胜负判断函数中的方向检测:
① 单看当前位置的正方向:
在这里插入图片描述
② 单看当前位置的反方向:
在这里插入图片描述
③ 从整个for循环来看(两个一组):
在这里插入图片描述
自己仿写时出现的问题:
① 棋盘打印函数传参出错(传二维数组时写成了board[BOARD_SIZE][BOARD_SIZE],传的是一个字符,而且数组下标还越界了)
② 交换玩家部分逻辑判断有问题,逻辑有点混乱(我想的是board[x][y]==current_player,此种写法或许需要再引入一个变量记录用户)

#include<stdio.h>

#define BOARD_SIZE 15
#define DEFAULT_PIECE '.'
#define PLAYER_ONE_PIECE 'O'
#define PLAYER_TWO_PIECE 'X'

//打印当前棋盘
void print_board(char board[BOARD_SIZE][BOARD_SIZE]);
//胜负判定
char check_winner(char board[BOARD_SIZE][BOARD_SIZE], int x, int y, int current_player);

int main(){
    char board[BOARD_SIZE][BOARD_SIZE];
    //初始化
    for(int i = 0; i < BOARD_SIZE; i++){
        for(int j = 0; j < BOARD_SIZE; j++){
            board[i][j] = DEFAULT_PIECE;
        }
    }
    //当前玩家
    char current_player = PLAYER_ONE_PIECE;
    char winner = DEFAULT_PIECE;
    while(winner == DEFAULT_PIECE){
        print_board(board);
        //输入落子位置
        printf("player %c: please input piece position (0 - %d), spacing by space\n", current_player, BOARD_SIZE - 1);
        int x;
        int y;
        scanf("%d %d", &x, &y);
        //是否可以落子
        if(x >= 0 && x < BOARD_SIZE && y >= 0 && y < BOARD_SIZE && board[x][y] == DEFAULT_PIECE){
            board[x][y] = current_player;
            //检测获胜者
            winner = check_winner(board, x, y, current_player);
            //交换玩家
            current_player = (current_player == PLAYER_ONE_PIECE) ? PLAYER_TWO_PIECE : PLAYER_ONE_PIECE;
        }else{
            printf("Invalid inputs!Please input again\n");
            continue;
        }
        //是否有人获胜
        if(winner != DEFAULT_PIECE){
            print_board(board);
            printf("Winner is %c", current_player);
            break;
        }
    }
    return 0;
}

void print_board(char board[BOARD_SIZE][BOARD_SIZE]){
    for(int i = 0; i < BOARD_SIZE; i++){
        for(int j = 0; j < BOARD_SIZE; j++){
            printf("%c ", board[i][j]);
        }
        printf("\n");
    }
}

char check_winner(char board[BOARD_SIZE][BOARD_SIZE], int x, int y, int current_player){
    int direction[4][2] = {{0, 1}, {1, 0}, {1, 1}, {1, -1}};
    for(int i = 0; i < 4; i++){
        //连续棋子数
        int count = 1;
        int dx = direction[i][0];
        int dy =  direction[i][1];
        //检测当前位置的正方向
        int tx = x + dx;
        int ty = y + dy;
        while(tx >= 0 && tx < BOARD_SIZE && ty >= 0 && ty < BOARD_SIZE && board[tx][ty] == current_player){
            count ++;
            tx += dx;
            ty += dy;
        }

        //检测当前位置的反方向
        tx = x - dx;
        ty = y - dy;
        while(tx >= 0 && tx < BOARD_SIZE && ty >= 0 && ty < BOARD_SIZE && board[tx][ty] == current_player){
            count ++;
            tx -= dx;
            ty -= dy;
        }
        if(count >= 5){
            return current_player;
        }
    }
    return DEFAULT_PIECE;
}

内容出处

c语言课程

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值