目录
目录
1.什么是三子棋
1.什么是三子棋
三子棋是一种民间传统游戏。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。
2.模块化和思路
实现三子棋主要可以通过二维数组和循环来实现,可以采用模块化的方式来制作。
game.h的头文件里存放头文件,函数定义和自定义信息。
test.c 实现大体逻辑和游戏的主体功能。
game.c里面实现所有具体功能的函数。
test.c 大体逻辑:
其中打印菜单和玩游戏封装为两个函数menu()和game(),在game.h声明,在game.c实现。
define的使用:
在三子棋中,可以用3*3二维数组来记录两边下子的情况,对应的四子棋应该是4*4.为了不用改大量代码可以利用#定义行数和列数。如下图:在game.h写上define 相关语句,在相关函数出都用ROW,COL代替3,4,5就可以了。最后只要修改这两处的3即可拓展为N子棋。
注意那game.c里也要进行引用#define"game.h"。
game()函数的大体思路:
主要封装五个函数:
1初始化数组
init_arr(arr,ROW ,COL);
2打印棋盘
print_board(arr, ROW, COL);
3玩家下棋
player_game(arr, ROW, COL);
4电脑下棋
computer_game(arr, ROW, COL);
5判断输赢是否继续 返回值char四种: *->电脑赢 #->玩家赢 c->继续(continue) d->平局 (draw)
judge_winner(arr, ROW, COL);
注:玩家下‘#’ 电脑下‘*’
3.各函数具体实现
main函数 of test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
int main()
{
srand((unsigned int)time(NULL));//后面有用到随机数后面会回来补
int flag = 0;
do
{
menu();
scanf("%d", &flag);
if (1 == flag)
{
system("cls");
game();
}
else if (0 == flag)
{
printf("退出游戏\n");
}
else
{
printf("请输入有效数字!\n");
}
} while (flag);
return 0;
}
menu和game函数(封装五个函数) of game.c
void menu()
{
printf("---------welcom!---------\n");
printf("---------1.play ---------\n");
printf("---------0.exit ---------\n");
printf("-----请输入你的选择:>----\n");
}
//开始游戏
void game()
{
//0.创建数组并初始化
char arr[ROW][COL];
init_arr(arr,ROW ,COL);
//1.打印棋盘
print_board(arr, ROW, COL);
//2.循环下棋
char flag = 0;
do {
player_game(arr, ROW, COL);
flag = judge_winner(arr, ROW, COL);
if (flag != 'c')
break;
computer_game(arr, ROW, COL);
flag = judge_winner(arr, ROW, COL);
if (flag != 'c')
break;
} while (1);
if (flag == '*')
printf(" 很遗憾,你输了。\n\n\n");
else if (flag == '#')
printf(" 恭喜你,你赢了! \n\n\n");
else
{
printf(" 平局,游戏结束。\n\n\n");
}
/*
//3.玩家下棋
player_game(arr, ROW, COL);
//4.电脑下棋
computer_game(arr, ROW, COL);
//5.判断输赢 *-电脑赢 #-玩家赢 c-继续 d-平局
judge_winner(arr, ROW, COL);
*/
}
封装的五个函数 实现 of game.c
1初始化数组
init_arr(arr,ROW ,COL); //函数声明放到game.h
void init_arr(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
注释:全部初始化为字符空格,打印原始棋盘好对齐
2打印棋盘
print_board(arr, ROW, COL);//函数声明放到game.h
void print_board(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//第i行
int j = 0;
//打印每组的字符
for (j = 0; j < col; j++)
{
printf(" %c ", arr[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");
}
}
注:每个字符旁边打两个格,每i行下面打一排分隔符,最后一行不要分隔符。
以七子棋棋盘为例:
3玩家下棋
player_game(arr, ROW, COL);//函数声明放到game.h
void player_game(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
do {
printf("请输入您要下棋的坐标:>");
scanf("%d %d", &i, &j);
if (i > 0 && i < row + 1 && j>0 && j < col +1)
{
if (arr[i - 1][j - 1] == ' ')
{
arr[i - 1][j - 1] = '#';
break;
}
else
{
printf("当前坐标已被占用,请重新输入\n");
}
}
else
{
printf("您输入的坐标不合法,请重新输入\n");
}
} while (1);
print_board(arr, ROW, COL);
}
注:为了防止两种情况,一种已经下过了,一种坐标超过范围了,需要循环输入,直到下成功。
还要注意,玩家以为的坐标范围是1-N,1-N。而我们数组是0-N-1,需要减一。
最后要记得打印出棋盘。
4电脑下棋
computer_game(arr, ROW, COL);//函数声明放到game.h
void computer_game(char arr[ROW][COL], int row, int col)
{
printf("电脑下棋:>");
Sleep(700);
do {
int i = rand() % row;
int j = rand() % row;
if (arr[i][j] == ' ')
{
arr[i][j] = '*';
printf("(%d ,%d)\n", i + 1, j + 1);
break;
}
} while (1);
print_board(arr, ROW, COL);
}
注:用随机数实现产生坐标,为了避免坐标已经下过,用循环实现。最后要记得打印出棋盘。
5判断输赢是否继续
judge_winner(arr, ROW, COL);//函数声明放到game.h
char judge_winner(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//检验第i行
int j = 0;
int sum = 0;
for (j = 0; j < col; j++)
{
sum += arr[i][j];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
}
i = 0;
for (i = 0; i < row; i++)
{
//检验第i列
int j = 0;
int sum = 0;
for (j = 0; j < col; j++)
{
sum += arr[j][i];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
}
i = 0;
int sum = 0;
for (i = 0; i < row; i++)
{
sum += arr[i][i];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
i = 0;
int j = col - 1;
sum = 0;
for (i = 0, j = col - 1; i < row; i++, j--)
{
sum += arr[i][j];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
i = 0;
j = 0;
int flag = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][j] == ' ')
return 'c';
}
}
return 'd';
}
注:为了实现N子棋,可以把值加在一起,# *连了的话就会等于35*col 或者42*col。
分四种:行 列 两条对角线 每一种都需要遍历
4.完整代码和四子棋运行结果
game.h:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<time.h>
#define ROW 3
#define COL 3
//菜单打印
void menu();
//开始游戏
void game();
void init_arr(char arr[ROW][COL],int row,int col);
void print_board(char arr[ROW][COL], int row, int col);
void player_game(char arr[ROW][COL], int row, int col);
void computer_game(char arr[ROW][COL], int row, int col);
char judge_winner (char arr[ROW][COL], int row, int col);
game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
//菜单打印
void menu()
{
printf("---------welcom!---------\n");
printf("---------1.play ---------\n");
printf("---------0.exit ---------\n");
printf("-----请输入你的选择:>----\n");
}
//开始游戏
void game()
{
//0.创建数组并初始化
char arr[ROW][COL];
init_arr(arr,ROW ,COL);
//1.打印棋盘
print_board(arr, ROW, COL);
//2.循环下棋
char flag = 0;
do {
player_game(arr, ROW, COL);
flag = judge_winner(arr, ROW, COL);
if (flag != 'c')
break;
computer_game(arr, ROW, COL);
flag = judge_winner(arr, ROW, COL);
if (flag != 'c')
break;
} while (1);
if (flag == '*')
printf(" 很遗憾,你输了。\n\n\n");
else if (flag == '#')
printf(" 恭喜你,你赢了! \n\n\n");
else
{
printf(" 平局,游戏结束。\n\n\n");
}
/*
//3.玩家下棋
player_game(arr, ROW, COL);
//4.电脑下棋
computer_game(arr, ROW, COL);
//5.判断输赢 *-电脑赢 #-玩家赢 c-继续 d-平局
judge_winner(arr, ROW, COL);
*/
}
void init_arr(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
int j = 0;
for (j = 0; j < col; j++)
{
arr[i][j] = ' ';
}
}
}
void print_board(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//第i行
int j = 0;
for (j = 0; j < col; j++)
{
printf(" %c ", arr[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_game(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
do {
printf("请输入您要下棋的坐标:>");
scanf("%d %d", &i, &j);
if (i > 0 && i < row + 1 && j>0 && j < col +1)
{
if (arr[i - 1][j - 1] == ' ')
{
arr[i - 1][j - 1] = '#';
break;
}
else
{
printf("当前坐标已被占用,请重新输入\n");
}
}
else
{
printf("您输入的坐标不合法,请重新输入\n");
}
} while (1);
print_board(arr, ROW, COL);
}
void computer_game(char arr[ROW][COL], int row, int col)
{
printf("电脑下棋:>");
Sleep(700);
do {
int i = rand() % row;
int j = rand() % col;
if (arr[i][j] == ' ')
{
arr[i][j] = '*';
printf("(%d ,%d)\n", i + 1, j + 1);
break;
}
} while (1);
print_board(arr, ROW, COL);
}
char judge_winner(char arr[ROW][COL], int row, int col)
{
int i = 0;
for (i = 0; i < row; i++)
{
//检验第i行
int j = 0;
int sum = 0;
for (j = 0; j < col; j++)
{
sum += arr[i][j];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
}
i = 0;
for (i = 0; i < row; i++)
{
//检验第i列
int j = 0;
int sum = 0;
for (j = 0; j < col; j++)
{
sum += arr[j][i];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
}
i = 0;
int sum = 0;
for (i = 0; i < row; i++)
{
sum += arr[i][i];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
i = 0;
int j = col - 1;
sum = 0;
for (i = 0, j = col - 1; i < row; i++, j--)
{
sum += arr[i][j];
}
if (sum == 35 * col)
return '#';
if (sum == 42 * col)
return '*';
i = 0;
j = 0;
int flag = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (arr[i][j] == ' ')
return 'c';
}
}
return 'd';
}
test.c:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
int main()
{
srand((unsigned int)time(NULL));
int flag = 0;
do
{
menu();
scanf("%d", &flag);
if (1 == flag)
{
system("cls");
game();
}
else if (0 == flag)
{
printf("退出游戏\n");
}
else
{
printf("请输入有效数字!\n");
}
} while (flag);
return 0;
}
拓展为四子棋运行结果: