首先,因为三子棋实现较为复杂,因此需要分模块编写,分为game.c,gsme.h和text.c模块。game.c中存放游戏实现的代码,game.h中存放有关游戏实现的函数声明,text.c里面放的是测试模块。
另外,写这种复杂的代码实现时,我们不能一次性写到底,需要每完成一部分就看程序是否能够成功执行,这样才能更有效的发现错误。
接下来进行一部部实现
首先,玩游戏需要有一个菜单,并且当用户不想继续玩的时候能够通过输入指定的值来进行退出游戏,我们可以把打印菜单封装成一个menu()函数,然后创建一个变量来接收用户输入的值,然后用switch语句来判断用户是否进行游戏,这里可以用一个do...while循环,进入时先判断用户是否想要玩游戏,然后当用户玩了很多把游戏不想玩的时候,可以退出循环。
下面是这部分的代码实现:
#include"game.h"
#include
#include
#include
void menu()
{
printf("******************\n");
printf("***** 1.play *****\n");
printf("***** 2.exit *****\n");
printf("******************\n");
printf("请选择:>");
}
void text(void)
{
int choice = 0;
do {
menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("三子棋\n");
Sleep(1000);
system("cls");
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误\n");
Sleep(1000);
system("cls");
break;
}
} while (choice);
}
int main()
{
text();
return 0;
}
这里运用了Sleep()函数和cls清空输出窗口函数,目的是为了让等下玩游戏时界面更加简洁,当然这里肯定不能打印一个三子棋就完事,所以应该用game()函数封装游戏的实现。
首先,要玩三子棋,肯定要先用一个二维数组储存落子的位置,在此之前,应该将每个位置都初始化为空格,并且为了让落子位置更加美观,我们需要打印一个棋盘,然后把玩家下棋封装成一个函数,电脑下棋封装成一个函数,然后每次下完棋之后需要判断是否有人胜利,如果胜利,结束游戏,如果平局,也结束游戏,如果都没有,那么游戏继续。可以创建函数is_win(),通过其的返回值来判断是否继续游戏。
接下来是全部代码实现:
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include
#include
#include
void menu()
{
printf("******************\n");
printf("***** 1.play *****\n");
printf("***** 0.exit *****\n");
printf("******************\n");
printf("请选择:>");
}
void game(void)
{
char c = 0;
char board[ROW][COL] = { 0 };
init_board(board,ROW,COL);
print_board(board,ROW,COL);
while(1)
{
player_move(board, ROW, COL);
system("cls");
print_board(board, ROW, COL);
c = is_win(board, ROW, COL);
//每次电脑和玩家下完都应该判断游戏是否结束
//如果玩家胜利,返回*,电脑胜利,返回#,平局返回Q,继续返回C
if (c != 'C')
break;
pc_move(board, ROW, COL);
Sleep(1000);
system("cls");
print_board(board, ROW, COL);
c = is_win(board, ROW, COL);
if (c != 'C')
break;
}
switch (c)
{
case '*':
printf("玩家胜利\n");
break;
case '#':
printf("电脑胜利\n");
break;
case 'Q':
printf("平局\n");
break;
}
}
void text(void)
{
srand((unsigned int)time(NULL));
int choice = 0;
do {
menu();
scanf("%d", &choice);
switch (choice)
{
case 1:
game();
Sleep(1000);
system("cls");
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("输入错误\n");
Sleep(1000);
system("cls");
break;
}
} while (choice);
}
int main()
{
text();
return 0;
}
#define ROW 3
#define COL 3
#include
void init_board(char arr[ROW][COL], int row, int col);
//初始化棋盘
void print_board(char arr[ROW][COL],int row,int col);
//打印棋盘
void player_move(char arr[ROW][COL],int row,int col);
//玩家下棋
void pc_move(char arr[ROW][COL],int row,int col);
//电脑下棋
char is_win(char arr[ROW][COL], int row, int col);
//判断输赢
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include
#include
int is_full(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++)
if (arr[i][j] == ' ')
return 0;
}
return 1;
}
void init_board(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++)
{
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_move(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("请输入下棋的坐标:>");
//这里需要判断玩家下棋的位置是否已经被下过棋以及下棋的范围是否准确
while(1)
{
scanf("%d %d", &i, &j);
if (i > 0 && (i - 1) < row && j > 0 && (j - 1) < col)
{
if (arr[i-1][j-1] == ' ')
{
arr[i-1][j-1] = '*';
break;
}
else
{
printf("该位置已被占用,请重新输入");
}
}
else
{
printf("输入错误,请重新输入");
}
}
}
void pc_move(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("电脑下棋\n");
while(1)
{
i = rand() % row;
j = rand() % col;
if (arr[i][j] == ' ')
{
arr[i][j] = '#';
break;
}
}
}
char is_win(char arr[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][0]!=' ')
{
return board[i][0];
}
}
//判断三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
//对角线
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
{
return board[1][1];
}
//平局?
if (is_full(board, row, col) == 1)
{
return 'Q';
}
//继续
//没有玩家或者电脑赢,也没有平局,游戏继续
return 'C';
}
这里发现,逻辑上有问题的只有判断输赢时的函数,用循环的形式判断输赢就可做到,其他地方都不需要变化。也就是说只需更换is_win函数中的代码即可
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
#include
#include
int is_full(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++)
if (arr[i][j] == ' ')
return 0;
}
return 1;
}
void init_board(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++)
{
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_move(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("请输入下棋的坐标:>");
//这里需要判断玩家下棋的位置是否已经被下过棋以及下棋的范围是否准确
while(1)
{
scanf("%d %d", &i, &j);
if (i > 0 && (i - 1) < row && j > 0 && (j - 1) < col)
{
if (arr[i-1][j-1] == ' ')
{
arr[i-1][j-1] = '*';
break;
}
else
{
printf("该位置已被占用,请重新输入");
}
}
else
{
printf("输入错误,请重新输入");
}
}
}
void pc_move(char arr[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
printf("电脑下棋\n");
while(1)
{
i = rand() % row;
j = rand() % col;
if (arr[i][j] == ' ')
{
arr[i][j] = '#';
break;
}
}
}
char is_win(char arr[ROW][COL], int row, int col)
{
//判断行
int i = 0;
char d = 0;
for (i = 0; i < row; i++)
{
int j = 0;
d = arr[i][0];
for (j = 1; j < col; j++)
if (d == arr[i][j]&&d!=' ')
continue;
else
break;
if (j == col)
return d;
}
//判断列
for (i = 0; i < col; i++)
{
int j = 0;
d = arr[0][i];
for (j = 1; j < row; j++)
if (d == arr[j][i]&&d!=' ')
continue;
else
break;
if (j == col)
return d;
}
//判主对角线
d = arr[0][0];
for (i = 1; i < col; i++)
{
if (d != arr[i][i])
break;
}
if (i == col&&d!=' ')
return d;
//判断斜对角线
d = arr[0][col-1];
for (i = 1; i < row; i++)
{
if (arr[i][col - 1 - i] != d)
break;
}
if(i == row&&d!=' ')
return d;
if (is_full(arr,ROW,COL))
return 'Q';
return 'C';
}
这样就能实现多子棋啦!!!