一.三子棋轮廓
游戏开始
打印目录,并让玩家选择是否玩游戏
当玩游戏我们需要一个棋盘
用二维数组存放下子位置,创建棋盘模样
玩家走,电脑走
判断输赢
游戏结束
实现目录
1.打印目录
2.玩家选择
3.创建一个二维数组
4.打印棋盘
5.玩家走
6.电脑走/玩家走
7.判断输赢
全部代码
二.根据轮廓来实现三子棋
附:下面的内容,皆以代码的形式直接展示,其代码为什么这么些附有注释。
1.打印目录
void mnue() { printf("**********************\n"); printf("******* 1. play ****\n"); printf("******* 0. exit ****\n"); printf("**********************\n"); } ... mnue(); ....
2.玩家选择
void mnue() { printf("**********************\n"); printf("******* 1. play ****\n"); printf("******* 0. exit ****\n"); printf("**********************\n"); } int main() { int input = 0; do//首先利用do while循环的先执行一道再判断进行打印目录并让玩家选择是否玩游戏 { mnue(); printf("是否玩游戏(1/0):>"); scanf("%d",&input);//玩家选择1.玩游戏 0.退出游戏 switch (input) { case 1: printf("猜数字游戏\n"); game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while(input); return 0; }
当我们选择1玩游戏时我们就会来到case1,并进到game()函数内
game函数:
3.创建一个二维数组
分析:创建这些空间,即可以下子的空位置,并初始化成空格
// test.c #include"game.h" void game() { char arr[ROW][COL] = {0}; //创建一个ROW行的,COL列的数组arr来存等一下 下子的位置 init(arr, ROW, COL); ... // game.h #define ROW 3 #define COL 3 //在头文件中用define定义常量这样就可以更方便的去修改这个棋盘的行,列 //如此时打印的棋盘大小是3*3的我们若想增大棋盘就可以直接在define处修改而不是 //一个一个的去修改行与列 void init(char arr[ROW][COL], int r, int c);//inti函数的声明,为了让inti函数可以在game.c中用 // game.c void init(char arr[ROW][COL], int r, int c) { int i = 0; int j = 0; for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { arr[i][j] = ' ';//现将数组内的所有内容,先置成空格 } } }
此处用到了分源管理,创建一个自己的头文件(管理定义的常量,和函数的声明,和库函数所需的头文件),既然是头文件我们在使用时就要定义(#include"game.h")
4.打印棋盘
观察:可以发现棋盘由第一行和第二行循环打印而成(只不过有个别限制)的一组
分析:首先用循环打印第一行(第一行由将要下的子 %c 和 | 组成 ),并且限制不打印最后一个 ' | '
其次用循环打印第二行( 第二行 由 --- 和 | 组成),并且限制不打印最后一个 ' | '
最后把第一行与第二行看成一组循环打印,并且限制不打印最后一个第二行
//test.c ... void game() { ... print(arr, ROW, COL); ... //game.h //打印棋盘 void print(char arr[ROW][COL],int r,int c);//声明 //game.c void print(char arr[][COL], int r, int c) { int i = 0; int j = 0; for (i = 0; i < r; i++)//打印时要小于行的大小 { //此处分开一行一行打印是为了当我们改变行列时可以跟着改变打印 //的行列数 for (j = 0; j < c; j++) //打印时要小于列的大小 { printf(" %c ", arr[i][j]); //第一行由将要下的子 %c 和 | 组成 if (j < c - 1) //其中 | 在最后不用打印 printf("|"); } printf("\n"); if (i < r - 1) //第二行在最后不用打印 { for (j = 0; j < c; j++) { printf("---") ; //第二行 有 --- 和 | 组成 if (j < c - 1) // | 在最后不用打印 printf("|"); } printf("\n"); } }
开始下棋:玩家走一步,电脑走一步,不停的走直到一方胜利或则平局
5.玩家走
分析:当玩家输入坐标(因正常人并不知道数组下标所以要对应的-1)时在对应的坐标下入子('0') ,并打印玩家下子后的棋盘
//test.c .... while(1) { play_move(arr, ROW, COL); print(arr, ROW, COL); ... game.h ... //玩家走 void play_move(char arr[ROW][COL], int r, int c); game.c void play_move(char arr[][COL], int r, int c) { int x = 0; int y = 0; while(1) { printf("玩家走:>"); scanf("%d %d", &x, &y); printf("\n"); if (x > 0 && x <= ROW && y > 0 && y <= COL)//首先判断玩家下的子是否满足行列范围 { //x-1 ,y-1 因为一般人认为第一行第一列为1 1 if (arr[x - 1][y - 1] == ' ')//当这个位置是空的就可以下子 { arr[x - 1][y - 1] = 'O';//将这个位置下成 '0' break; } else { printf("该空已被占请重新输入\n"); } } else { printf("错误输入,请重新输入\n"); } } }
6.电脑走
分析:要让电脑走,其实就是传入两个随机值并将产生坐标下入子'X'
//test.c void game() { while(1) { ... comput_move(arr, ROW, COL); print(arr, ROW, COL); ... } int main() { srand((unsigned int)time(NULL)); .... game.h //电脑走 void comput_move(char arr[ROW][COL], int r, int c); game.c void comput_move(char arr[][COL], int r, int c) { printf("电脑走\n"); while (1) { int x = rand() % r;//产生随机数模上行表示其大小范围是 0~r-1(2) int y = rand() % c;//同上列的范围是0~r-1(2) if (arr[x][y] == ' ')//不用想人一样加else,电脑若不对就再循环 { arr[x][y] = 'X'; break; } } }
7.判断输赢
分析:
赢:
一行或者一列全部都为一种棋子时;对角线全部都为一种棋子时
平局:
先判断输赢,当输赢判断完发现并没有人赢时,再看这个二维数组的空间内是否还有空位置,若没了就代表平局,
谁都没赢:继续比赛
test.c while() { ... char re = 0;//储存返回的值 ... re = is_win(arr, ROW, COL);//函数判断是否赢了,并返回一个值 if (re != 'Q')//当返回的并不是继续游戏时 { break;//跳出下子循环 } ... } if(re == 'O') { printf("恭喜玩家赢了\n"); } else if (re == 'B') { printf("平局\n"); } else { printf("电脑都比你吊\n"); } game.h char is_win(char arr[ROW][COL], int r, int c); game.c int is_full(char arr[ROW][COL], int r, int c) { int i = 0; int j = 0; int k = 0; for (i = 0; i < c; i++) { for (j = 0; j < r; j++) { if (arr[i][j] == ' ')//用循环判断数组内还有没有空格 { k = 1; return k;//当有空格时将k置成1返回,代码有空格 } } } return k;//当k没有变成1,就会返回初始化的k 0 } char is_win(char arr[][COL], int r, int c) { int j = 0; for (j = 0; j < r; j++)//用一行一行,一列一列的查 { if (arr[j][0] == arr[j][1]&&arr[j][1] == arr[j][2] && arr[j][1] !=' ') //判断一行 return arr[j][1];//当一行全部相等时返回其中的一个子 if (arr[0][j] == arr[1][j] && arr[1][j] == arr[2][j] && arr[1][j] !=' ') //判断一列 return arr[1][j]; } //判断两对角线是否相等 if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ') return arr[1][1]; if(arr[1][2] == arr[1][1] && arr[3][1] == arr[1][1] && arr[1][1] != ' ') return arr[1][1]; //判断还有没有空位置若没则平局 int f = is_full(arr, ROW, COL); if (f == 0)//如果返回0 就代表没有空格了平局了 { return 'B'; } return 'Q';//当返回1时就代表还有空格可以继续游戏 }
全部代码
test.c
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" void game() { while (getchar() != '\n') { ; } char re = 0;//声明存储是否赢了的标志 char arr[ROW][COL] = {0}; init(arr, ROW, COL); print(arr, ROW, COL); while (1) { play_move(arr, ROW, COL); print(arr, ROW, COL); /*printf("电脑走\n");*/ Sleep(2000); re = is_win(arr, ROW, COL); if (re != 'Q') { break; } system("cls"); comput_move(arr, ROW, COL); print(arr, ROW, COL); re = is_win(arr, ROW, COL); if (re != 'Q') { break; } } if(re == 'O') { printf("恭喜玩家赢了\n"); } else if (re == 'B') { printf("平局\n"); } else { printf("电脑都比你吊\n"); } } void mnue() { printf("**********************\n"); printf("******* 1. play ****\n"); printf("******* 0. exit ****\n"); printf("**********************\n"); } int main() { srand((unsigned int)time(NULL)); int input = 0; do { mnue(); printf("是否玩游戏(1/0):>"); scanf("%d",&input); switch (input) { case 1: printf("猜数字游戏\n"); game(); break; case 0: printf("退出游戏\n"); break; default: printf("输入错误,请重新输入\n"); break; } } while(input); return 0; }
game.h:
#pragma once #include<stdio.h> #include<windows.h> #include<stdlib.h> #include<time.h> #define ROW 3 #define COL 3 //棋盘初始化 void init(char arr[ROW][COL], int r, int c); //玩家走 void play_move(char arr[ROW][COL], int r, int c); //电脑走 void comput_move(char arr[ROW][COL], int r, int c); //打印棋盘 void print(char arr[ROW][COL], int r, int c); //判断输赢 char is_win(char arr[ROW][COL], int r, int c);
game.c:
#define _CRT_SECURE_NO_WARNINGS 1 #include"game.h" int is_full(char arr[ROW][COL], int r, int c) { int i = 0; int j = 0; int k = 0; for (i = 0; i < c; i++) { for (j = 0; j < r; j++) { if (arr[i][j] == ' ') { k = 1; return k; } } } return k; } void init(char arr[ROW][COL], int r, int c) { int i = 0; int j = 0; for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { arr[i][j] = ' '; } } } void print(char arr[][COL], int r, int c) { int i = 0; int j = 0; for (i = 0; i < c; i++) { for (j = 0; j < c; j++) { printf(" %c ", arr[i][j]); if (j < c - 1) printf("|"); } printf("\n"); if (i < r - 1) { for (j = 0; j < c; j++) { printf("---"); if (j < c - 1) printf("|"); } printf("\n"); } } } void play_move(char arr[][COL], int r, int c) { int x = 0; int y = 0; while(1) { printf("玩家走:>"); scanf("%d %d", &x, &y); printf("\n"); if (x > 0 && x <= ROW && y > 0 && y <= COL) { if (arr[x - 1][y - 1] == ' ') { arr[x - 1][y - 1] = 'O'; break; } else { printf("该空已被占请重新输入\n"); } } else { printf("错误输入,请重新输入\n"); } } } void comput_move(char arr[][COL], int r, int c) { printf("电脑走\n"); while (1) { int x = rand() % c; int y = rand() % r; if (arr[x][y] == ' ') { arr[x][y] = 'X'; break; } } } char is_win(char arr[][COL], int r, int c) { int i = 0; int j = 0; for (j = 0; j < r; j++) { if (arr[j][i] == arr[j][i + 1] && arr[j][i+1] == arr[j][i+2] && arr[j][i+1] != ' ') return arr[j][i+1]; if (arr[i][j] == arr[i+1][j] && arr[i+1][j] == arr[i+2][j] && arr[i+1][j] != ' ') return arr[i+1][j]; } if (arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ') return arr[1][1]; if(arr[1][2] == arr[1][1] && arr[3][1] == arr[1][1] && arr[1][1] != ' ') return arr[1][1]; int f = is_full(arr, ROW, COL); if (f == 0) { return 'B'; } return 'Q'; }