学了C语言也有一段时间了,三子棋算是第一个自己编写的代码量上百行的程序。自己真正系统的写完之后,许多东西都有了一个明悟,收获颇丰。
首先,想要写一个稍微正式一点的程序出来,函数必不可少,有了函数,那么相应的就需要函数的声明,如果涉及到的函数较多,一个个在主文件里声明就显得代码很繁琐,而且跨文件使用的时候就又需要进行声明。
在这里,我把所有的 函数声明、定义常量,以及头文件统统打包到了"game.h"中,在后面的game.c,和test.c中都只需要一个
#include "game.h"的头文件即可电泳所有需要的头文件、函数声明、定义常量。可以精简代码量,而且更加美观简洁。
game.h
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#define ROW 3
#define COL 3
void init_board(char arr[ ROW][COL ],int row,int col );
void print_board(char arr[ ROW][COL ], int row, int col);
void new_game(char arr[ROW][COL],int row,int col);
void palyer_move(char arr[ROW][COL],int row,int col);
void computer_move(char arr[ROW][COL], int row, int col);
int is_win(char arr[ROW][COL], int row, int col);
int is_draw(char arr[ROW][COL], int row, int col);
game.c是保证程序逻辑的一个源文件。
主要思路有以下几个方面,
0是打印棋盘
1是玩家落子
2是判断输赢
3是电脑落子
4是判断输赢
然后 循环1-4,就形成了整个游戏的人机互动环节。(人机互动环节就是这个程序的难点所在,对于小白而言)
将思路理清之后,纯写代码就不难了。通篇写下来,基本不会报错。
代码方面主要涉及到函数以及二维数组的各种理解应用。
game.c
#include "game.h"
void new_game(char arr[ROW][COL], int row, int col)
{
print_board(arr, ROW, COL);
while (1)
{
palyer_move(arr, ROW, COL);
system("cls");
print_board(arr, ROW, COL);
if (is_win(arr, ROW, COL) == 1)
{
printf("恭喜你,你赢了!\n");
printf("\n");
system("pause");
system("cls");
break;
}
else if (is_win(arr, ROW, COL) == 0)
{
printf("你和电脑一样菜!");
printf("\n");
system("pause");
system("cls");
break;
}
computer_move(arr, ROW, COL);
system("cls");
print_board(arr, ROW, COL);
if (is_win(arr, ROW, COL) == 1)
{
printf("菜的抠脚!");
printf("\n");
system("pause");
system("cls");
break;
}
else if (is_win(arr, ROW, COL) == 0)
{
printf("你和电脑一样菜!");
printf("\n");
system("pause");
system("cls");
break;
}
}
}
void init_board(char* arr, int row, int col)
{
int sz = row*col;
for (int i = 0; i < sz; i++)
{
*(arr+i) = ' ';
}
}
void print_board(char arr[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 (j < col - 1)
printf(" %c |", arr[i][j]);
else
printf(" %c \n", arr[i][j]);
}
if (i<row-1)
printf("---+---+---\n");
}
}
void palyer_move(char arr[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("请输入要落子的坐标-》");
scanf("%d%d", &x, &y);
if (arr[x-1][y-1] ==' ')
{
arr[x-1][y-1] = '*';
}
}
void computer_move(char arr[ROW][COL], int row, int col)
{
while (1)
{
int x = rand() % row;
int y = rand() % col;
if (arr[x][y] == ' ')
{
arr[x][y] = '#';
break;
}
}
}
int is_win(char arr[ROW][COL], int row, int col)//判断是否胜利
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[2][i] != ' '
|| arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][2] != ' '
|| arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[2][2] != ' '
|| arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[2][0] != ' ')//判断条件这里写的不简洁。可以进一步精简;
return 1;//胜利返回 1;
}
if (is_draw(arr, ROW, COL) == 0)
return 0;//平局返回 0;
else
return -1;//继续返回-1;
}
int is_draw(char arr[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 (arr[i][j] == ' ')
return -1;//继续返回 -1;
}
}
return 0;//平局返回 0;
}
test.c
游戏的入口;
这里涉及到的东西没有很多
随机种子的设定
以及do while 内嵌 switch
#include "game.h"
void menu()
{
printf("* * * * * * * * * * * * * * * * * * * * * \n\n");
printf(" * * * * * * 1,开始游戏 * * * * * * * * \n\n");
printf(" * * * * * * 2,结束游戏 * * * * * * * * \n\n");
printf("* * * * * * * * * * * * * * * * * * * * * \n\n");
printf("请输入您的选择—》");
}
void test()
{
srand((unsigned int)time(NULL));
do
{
menu();
char arr[ROW][COL] = {
' ' };
init_board(arr, ROW, COL);
int input = 0;
scanf("%d", &input);
switch (input)
{
case 1: new_game(arr, ROW, COL);
break;
case 2: return;
break;
default: printf("您的输入有误,请重新输入!");
break;
}
} while (1);
}
int main()
{
test();
return 0;
}
三子棋游戏算是很简单的图形游戏,编写之前觉得头大如斗,写起来其实也就那么回事了,只要掌握了最基础语法,个关键字以及函数的理解及应用,再有就是理清逻辑,整理好思维,就能够写出来,这只是初窥门径,只要有了良好的编程思维、习惯,以及代码能力,一切困难都将会一一磨平。