通常我们写代码的时候,写之前都要整理分析好逻辑,要做到分段分块来写,以便于代码阅读和后期维护
这里我将代码分为三个文件:
- game.h 头文件通常用来完成函数声明、头文件的引用、宏定义变量
- game.c 用于游戏功能函数的实现
- test.c 作为代码测试的入口
- 游戏主界面
- 棋盘初始化
- 棋盘打印
- 玩家下棋
- 判断输赢
- 电脑下棋
- 判断输赢
我们玩游戏要么开始游戏,要么退出游戏,那么我们主界面就可以设计为两个选择
输入1,开始游戏
输入0,退出游戏
如果玩家输入其他值则提示输入错误
而且可以以循环的方式来实现多次玩游戏
棋盘初始化三子棋是三行三列,我们可以用一个二维数组数来实现
首先要初始化棋盘数据为空格!
用两个for循环初始化即可
棋盘打印棋盘打印可以分开为数据加"|'
然后再打印"___",实现的时候最下面一行不需要,条件控制j-1即可
玩家下棋这里需要注意玩家输入的坐标是从1开始的;
而数组定义是从0开始;
所以玩家输入坐标需要减1才是二维数组里面的坐标
电脑下棋我们可以用rand()%3函数来生成0~2随机数
实现电脑下棋
输赢判断玩家或者电脑落子之后判断棋盘是否下满,下满则为平局
玩家或者电脑落子之后判断是否形成三行、三列、对角线
如果是则判定胜利,不是则游戏继续
实现代码 game.h#pragma once #include#include #include #define ROW 3//宏定义棋盘大小 #define COL 3 //初始化棋盘 void initboard(char board[ROW][COL], int row, int col); //打印棋盘 void displayboard(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); //判断输赢 //玩家赢 --'*' // //电脑赢 --'#' // //平均-----'q' // //继续-----'c' char is_win(char board[ROW][COL], int row, int col);
为了后期持续维护开发,棋盘大小等变量都使用宏定义
game.c#define _CRT_SECURE_NO_WARNINGS #include"game.h" //初始化棋盘 void initboard(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { board[i][j] = ' '; } } } //打印棋盘 void displayboard(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { //数据 for (j = 0; j < col; j++) { printf(" %c ", board[i][j]); if (j < col - 1) printf("|");//分割线 } printf("n");//换行 //分隔行 if (i < row - 1) { for (j = 0; j < col; j++) { printf("___"); if (j < col - 1) printf("|"); } } printf("n"); } } //玩家下棋 void player_move(char board[ROW][COL], int row, int col) { printf("玩家下棋:>n"); int x = 0; int y = 0; while (1) { 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) { int x = 0; int y = 0; printf("电脑下棋>n"); while (1) { x = rand() % row;//rand()%n产生0到n-1之间的一个随机值 y = rand() % col;// if (board[x][y] == ' ') { board[x][y] = '#'; break; } } } //判断棋盘下满 int is_full(char board[ROW][COL], int row, int col) { int i = 0; int j = 0; for (i = 0; i < row; i++) { for (j = 0; j < col; j++) { if (board[i][j] == ' ') { return 0;//游戏继续 } } } return 1;//游戏平局 } //输赢判断 char is_win(char board[ROW][COL], int row, int col) { int i = 0; //三行 for (i = 0; i < row; i++) { if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][2] != ' ') { return board[i][2]; } } //三列 for (i = 0; i < col; i++) { if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' ') { return board[i][2]; } } //对角线 if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[2][2] != ' ') { return board[0][0]; } if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[2][0] != ' ') { return board[0][2]; } //平局游戏结束 if (1 == is_full(board, row, col)) { return 'q'; } //游戏继续 return 'c'; }
函数功能都进行了备注以便于理解和分析
test.c#define _CRT_SECURE_NO_WARNINGS #include"game.h" void menu()//菜单界面 { printf("*****************************n"); printf("******* 1. play *****n"); printf("******* 0. exit *****n"); printf("*****************************n"); } void game() { //数据存储到一个字符的二维数组中,玩家下棋是'*' ,电脑下棋是’#' . char board[ROW][COL] = { 0 };//数组的内容应该是全部空格 initboard(board, ROW, COL);//初始化棋盘 //打印棋盘 displayboard(board,ROW,COL); //下棋 char ret = 0; while (1) { player_move(board, ROW, COL);//玩家下棋 displayboard(board, ROW, COL);//打印棋盘 ret = is_win(board, ROW, COL);//输赢判断 if (ret != 'c') { break;// } computer_move(board, ROW, COL);//电脑下棋 displayboard(board, ROW, COL);//打印棋盘 ret = is_win(board, ROW, COL);//输赢判断 if (ret != 'c') { break; } } if (ret == '*') { printf("玩家赢n"); } if (ret == '#') { printf("电脑赢n"); } else { printf("平局n"); } } void test() { int input = 0; do { menu();//调用主菜单 printf("请选择:>"); scanf("%d", &input); switch (input) { case 1: game();//调用游戏模块 break; case 0: printf("退出游戏n"); break; default: printf("选择错误!n"); break; } } while (input); } int main() { test();//测试入口 return 0; }总结:
写代码之前先整理逻辑笔记,避免逻辑错误,写完总结归纳便于加深理解,提升思维逻辑能力
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)