程序|这个三子棋,输了就要接受惩罚哦!

目录

三子棋的定义和玩法
游戏大体框架
开始界面
游戏主体
初始化棋盘
画出棋盘
开始下棋
玩家下棋的部分
电脑下棋的部分
判断输赢的部分
判断平局的部分
惩罚部分实现
完整代码
main.c文件
game.h文件
game.c文件
三子棋的定义和玩法 三字棋是一种流传已久的民间游戏,双方互相在棋盘上放上棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现棋盘摆满却还没有决定胜负的情况,也就是平局的情况。

程序|这个三子棋,输了就要接受惩罚哦!
文章图片

今天,我们试着通过编程实现三子棋小游戏,玩家与电脑下三子棋(电脑并不是人工智能,完全随机在棋盘上下子),玩家输了或者平了,都要接受惩罚。
游戏大体框架 开始界面 我们在开始的时候打印菜单,并且提醒玩家选择是否进行游戏,(选1或者0),选1开始游戏,玩完一局可以继续玩,选择0退出程序。

int main() { int input = 1; menu(); while (input)//只能输入0的时候才能退出,实现可以反复游玩 { printf("请选择:\n"); scanf("%d", &input); switch (input) { case 1: printf("游戏开始\n"); game(); //后文提到的游戏主体 break; case 0: printf("游戏结束\n"); system("pause"); break; default: printf("选择错误,重新选择!\n"); //选择错误可以返回重新选择 break; } } return 0; }

menu函数用于封装菜单

void menu() { printf("*********************************\n"); printf("*****欢迎游玩三子棋!************\n"); printf("*****made by 东条希尔薇**********\n"); printf("*******1.play***************\n"); printf("*******0.exit***************\n"); printf("*********************************\n"); }

这是实际打印出的开始界面
程序|这个三子棋,输了就要接受惩罚哦!
文章图片


游戏主体 用game函数封装,并且在其中封装若干可能会用上的自定义函数
void game()


初始化棋盘
因为这是一个三字棋,所以需要一个数组存放我们已经下过的棋子,在这里我们使用二维数组,首先创建一个足够存放3*3棋子的数组
char board[ROW][COL]; //ROW,COL已经在头文件中用define定义为3,方便后期的维护

然后进行初始化,用一个函数封装
void make_board(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ' '; //将数组中所有元素初始化为空格 } } }

画出棋盘
这是我们期望画出的棋盘
其中o代表空格
x代表数组中存放的元素
程序|这个三子棋,输了就要接受惩罚哦!
文章图片

在画出这个棋盘时,我们可以将每两行当成一组来循环打印输出
一行元素
一行分割线
程序|这个三子棋,输了就要接受惩罚哦!
文章图片



void display_board(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf(" %c ", board[i][j]); //打印数组中已经存放的元素,包含空格 if (j != col - 1) { printf("|"); //在分隔处打印分割线,最后一个不需要打印 } } printf("\n"); if (i != row - 1)//在最后一行不需要打印分割线 { for (int j = 0; j < col; j++)//打印分隔线 { printf("---"); if (j != col-1) { printf("|"); } } printf("\n"); } } }

这是打印出的棋盘
程序|这个三子棋,输了就要接受惩罚哦!
文章图片

开始下棋易知,玩家和电脑下棋,是回合制,需要用循环控制
while (1) { player_move(board, ROW, COL); display_board(board, ROW, COL); //每次走完子,打印棋盘 computer_move(board, ROW, COL); display_board(board, ROW, COL); }

玩家下棋的部分 【程序|这个三子棋,输了就要接受惩罚哦!】通过输入坐标的方式让玩家走子,直接上代码
void player_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("请输入坐标\n"); scanf("%d,%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col)//这里判断玩家输入的坐标是否超出范围 { if (board[x - 1][y - 1] == ' ')//判断该坐标是否有棋子 { board[x - 1][y - 1] = '*'; //下棋 break; } else { printf("此坐标已被占用!\n"); } } else { printf("坐标非法,重新输入!\n"); } } }

电脑下棋的部分 随机走子,直接上代码
void computer_move(char board[ROW][COL], int row, int col) { printf("电脑走\n"); while (1) { int x = rand() % row; int y = rand() % col; //随机生成坐标,需要引入stdlib头文件 if (board[x][y] == ' ')//如果随机生成的坐标没有元素,就走子,有,就继续生成 { board[x][y] = '#'; break; } } }

当然,为了使每次随机的结果都不一样,需要在主函数中使用srand函数
srand((unsigned int)time(NULL));

这是走过一回合的效果
程序|这个三子棋,输了就要接受惩罚哦!
文章图片

判断输赢的部分判断每一个竖行,每一个横行,两个对角线是否摆满了某一方的棋子
char iswin(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { if (board[i][1] == board[i][0] && board[i][1] == board[i][2]&&board[i][1]=='*') return board[i][1]; if (board[i][1] == board[i][0] && board[i][1] == board[i][2] && board[i][1] == '#') return board[i][1]; } for (int j = 0; j < col; j++) { if (board[1][j] == board[0][j] && board[1][j] == board[2][j]&&board[1][j]=='*') return board[1][j]; if (board[1][j] == board[0][j] && board[1][j] == board[2][j] && board[1][j] == '#') return board[1][j]; } if (board[1][1] == board[0][0] && board[1][1] == board[2][2]&&board[1][1]=='*') return board[1][1]; if (board[1][1] == board[0][0] && board[1][1] == board[2][2] && board[1][1] == '#') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&&board[1][1]=='*') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] == '#') return board[1][1]; int ret = isdraw(board, ROW, COL); //后文中的判断平局的部分 if (ret == 1) return 'Q'; else return 'C'; }

在game主体中加入
ret = iswin(board, ROW, COL); if (ret != 'C') break; if (ret == '*') { printf("恭喜你,你赢了!\n"); } else if (ret == '#') { printf("真笨,没有加人工智能的电脑你都能输\n"); system("pause"); } else if (ret == 'Q') { printf("真笨,没有加人工智能的电脑你都能平局\n"); system("pause"); }

判断平局的部分 需要判断棋盘中是否已经摆满棋子
int isdraw(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; }

惩罚部分实现 输了或者平了,都要接受关机惩罚!
关机部分的实现
else if (ret == '#') { printf("真笨,没有加人工智能的电脑你都能输\n"); printf("请接受关机惩罚!\n"); system("shutdown -s -t 10"); //输了的话,接受最重的惩罚 system("pause"); } else if (ret == 'Q') { printf("真笨,没有加人工智能的电脑你都能平局\n"); printf("请接受关机惩罚!\n"); system("shutdown -s -t 60"); printf("不过,如果你承认你是猪,就放过你!(直接在下面打出“我是猪”)\n"); char input1[10] = { 0 }; while (1) { printf("请输入\n"); scanf("%s", input1); if (0 == strcmp(input1, "我是猪")) { system("shutdown -a"); system("pause"); break; } } }}

完整代码 main.c文件
//main.c#include"game.h" void game() { char board[ROW][COL]; make_board(board, ROW, COL); display_board(board, ROW, COL); char ret = 0; while (1) { player_move(board, ROW, COL); display_board(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'C') break; computer_move(board, ROW, COL); display_board(board, ROW, COL); ret = iswin(board, ROW, COL); if (ret != 'C') break; } if (ret == '*') { printf("恭喜你,你赢了!\n"); } else if (ret == '#') { printf("真笨,没有加人工智能的电脑你都能输\n"); printf("请接受关机惩罚!\n"); system("shutdown -s -t 10"); system("pause"); } else if (ret == 'Q') { printf("真笨,没有加人工智能的电脑你都能平局\n"); printf("请接受关机惩罚!\n"); system("shutdown -s -t 60"); printf("不过,如果你承认你是猪,就放过你!(直接在下面打出“我是猪”)\n"); char input1[10] = { 0 }; while (1) { printf("请输入\n"); scanf("%s", input1); if (0 == strcmp(input1, "我是猪")) { system("shutdown -a"); system("pause"); break; } } }}int main() { int input = 1; srand((unsigned int)time(NULL)); menu(); while (input) { printf("请选择:\n"); scanf("%d", &input); switch (input) { case 1: printf("游戏开始\n"); game(); break; case 0: printf("游戏结束\n"); system("pause"); break; default: printf("选择错误,重新选择!\n"); break; } } return 0; }

game.h文件
//game.h#pragma once #define _CRT_SECURE_NO_WARNINGS 1 #include #include #include #include #define ROW 3 #define COL 3 void menu(); void make_board(char board[ROW][COL], int row, int col); void display_board(char board[ROW][COL], int row, int col); void player_move(char board[ROW][COL], int row, int col); void computer_move(char board[ROW][COL], int row, int col); char iswin(char board[ROW][COL], int row, int col); int isdraw(char board[ROW][COL], int row, int col);

game.c文件
#include "game.h"void menu() { printf("*********************************\n"); printf("*****欢迎游玩三子棋!************\n"); printf("*****made by 东条希尔薇**********\n"); printf("*******1.play***************\n"); printf("*******0.exit***************\n"); printf("*********************************\n"); }void make_board(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { board[i][j] = ' '; } } }void display_board(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j != col - 1) { printf("|"); } } printf("\n"); if (i != row - 1) { for (int j = 0; j < col; j++) { printf("---"); if (j != col-1) { printf("|"); } } printf("\n"); } } }void player_move(char board[ROW][COL], int row, int col) { int x = 0; int y = 0; while (1) { printf("请输入坐标\n"); scanf("%d,%d", &x, &y); if (x >= 1 && x <= row && y >= 1 && y <= col) { if (board[x - 1][y - 1] == ' ') { board[x - 1][y - 1] = '*'; break; } else { printf("此坐标已被占用!\n"); } } else { printf("坐标非法,重新输入!\n"); } } }void computer_move(char board[ROW][COL], int row, int col) { printf("电脑走\n"); while (1) { int x = rand() % row; int y = rand() % col; if (board[x][y] == ' ') { board[x][y] = '#'; break; } } }char iswin(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { if (board[i][1] == board[i][0] && board[i][1] == board[i][2]&&board[i][1]=='*') return board[i][1]; if (board[i][1] == board[i][0] && board[i][1] == board[i][2] && board[i][1] == '#') return board[i][1]; } for (int j = 0; j < col; j++) { if (board[1][j] == board[0][j] && board[1][j] == board[2][j]&&board[1][j]=='*') return board[1][j]; if (board[1][j] == board[0][j] && board[1][j] == board[2][j] && board[1][j] == '#') return board[1][j]; } if (board[1][1] == board[0][0] && board[1][1] == board[2][2]&&board[1][1]=='*') return board[1][1]; if (board[1][1] == board[0][0] && board[1][1] == board[2][2] && board[1][1] == '#') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0]&&board[1][1]=='*') return board[1][1]; if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] == '#') return board[1][1]; int ret = isdraw(board, ROW, COL); if (ret == 1) return 'Q'; else return 'C'; }int isdraw(char board[ROW][COL], int row, int col) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (board[i][j] == ' ') { return 0; } } } return 1; }

由于作者水平有限,代码中有任何不足与疏漏在所难免。希望大佬能提出你们宝贵的意见!

    推荐阅读