一.三子棋轮廓
- 游戏开始
- 打印目录,并让玩家选择是否玩游戏
- 当玩游戏我们需要一个棋盘
- 用二维数组存放下子位置,创建棋盘模样
- 玩家走,电脑走
- 判断输赢
- 游戏结束
实现目录
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';
}