三子棋是一个简单的人机对战游戏在3*3的棋盘上,只要有一方下的子连成一条直线则显示游戏获胜,游戏结束。例如:
想要用C语言编写三子棋其实不难,主要把编程的思想顺利清楚就很容易实现了。编写三子棋游戏我们可以先建立一个 game.h文件作为头文件,用来声明函数和定义一些常亮,在定义一个game.c文件来实现具体的函数功能,最后定义一个text.c文件主要编写实现这也游戏的逻辑。
现在我们简单梳理一下要实现游戏的逻辑,首先玩家要玩游戏我们可以设置菜单函数供玩家选择是否玩游戏。
void menu()
{
printf("****************************\n");
printf("******* 0.exit ********\n");
printf("******* 1.play ********\n");
printf("****************************\n");
}
只有当玩家选择了play,表示玩家要玩游戏了,这就需要开始在棋盘下棋了,所以我们还要做的工作就是初始化棋盘。
void init_board (char board[ROWS][COLS], int rows, int cols)//初始化棋盘
{
int i = 0;
int j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
board[i][j] = ' ';
}
}
}
棋盘初始化好后,玩家和电脑就要下棋了,每次下完棋都要判断是否已经决出胜负,如果有一方胜利就停止本盘游戏。
void play_game(char board [ROWS][COLS])
{
while (1)
{
player_move(board);//玩家下棋
if (check_win(board) == 'p')//判断输赢
{
break;
}
printf_board(board,ROWS, COLS);
printf("***** 电脑下棋 ******\n");
computer_move(board);//电脑下棋
if (check_win(board) == 'c')
{
break;
}
Sleep(1000);
printf_board(board, ROWS, COLS);
}
printf("*************************\n");
if (check_win(board) == 'p')
{
printf("玩家获胜\n");
}
else
{
printf("电脑获胜\n");
}
printf_board(board, ROWS, COLS);
printf("\n");
memset(board,' ', ROWS*COLS*sizeof(char));
}
三子棋主要的逻辑就是这些,然后就是具体的函数实现。但是有几点要注意的问题很容易忽略:
1.在玩家下棋时对输入的坐标要进行判断,不能超过棋盘的范围,也不能输入的坐标已经被下过棋了,这也是不行的,需要重新输入坐标;
2.在菜单函数显示后用户进行选择时用到了枚举类型,初始化了玩家选择1就是玩游戏,选择0就是退出。
enum CH
{
PLAY = 1,
EXIT = 0
};
3. 在初始化棋盘时对棋盘的行列进行了宏定义,方便以后对程序的扩展,方便对行列重新定义。
#define ROWS 3//行
#define COLS 3//列
4.我在电脑下棋前加了一个Sleep(); 该函数主要为了在玩家下完棋后,延时输出电脑下棋的情况,使程序看起来更加有交互性. 注意别忘了他的头函数:
#include <windows.h>
下面是具体的代码实现:
1.text.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void play_game(char board [ROWS][COLS])
{
while (1)
{
player_move(board);//玩家下棋
if (check_win(board) == 'p')//判断输赢
{
break;
}
printf_board(board,ROWS, COLS);
printf("***** 电脑下棋 ******\n");
computer_move(board);//电脑下棋
if (check_win(board) == 'c')
{
break;
}
Sleep(1000);
printf_board(board, ROWS, COLS);
}
printf("*************************\n");
if (check_win(board) == 'p')
{
printf("玩家获胜\n");
}
else
{
printf("电脑获胜\n");
}
printf_board(board, ROWS, COLS);
printf("\n");
memset(board,' ', ROWS*COLS*sizeof(char));
}
void menu()
{
printf("****************************\n");
printf("******* 0.exit ********\n");
printf("******* 1.play ********\n");
printf("****************************\n");
}
void game()
{
int input = 1;
char board[ROWS][COLS] = { 0 };
init_board(board, ROWS, COLS);
//printf_board(board, ROWS, COLS);
srand((unsigned)time(NULL));
menu();
printf("请选择:");
scanf("%d", &input);
while (input)
{
switch(input)
{
case PLAY:
play_game(board);
break;
case EXIT:
break;
}
menu();
printf("请选择:");
scanf("%d", &input);
}
}
int main()
{
game();
system("pause");
return 0;
}
2.game.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void init_board (char board[ROWS][COLS], int rows, int cols)//初始化棋盘
{
int i = 0;
int j = 0;
for (i = 0; i < ROWS; i++)
{
for (j = 0; j < COLS; j++)
{
board[i][j] = ' ';
}
}
}
void printf_board(char board[ROWS][COLS], int rows, int cols)
{
int i = 0;
for (i = 0; i < ROWS; i++)
{
printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
if (i!=2)
printf("---|---|--- \n");
}
}
void player_move(char board[ROWS][COLS])//玩家玩
{
int x = 0;
int y = 0;
while (1)
{
printf("请输入坐标:");
scanf("%d%d", &x, &y);
if ((x>0 && x <= 3) && (y>0 && y <= 3))//判断坐标是否合法
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = 'X';
break;
}
else
{
printf("坐标被占用\n");
}
}
else
{
printf("坐标不合法\n");
}
}
}
void computer_move(char board[ROWS][COLS])//电脑玩
{
while (1)
{
int x = rand() % 3;
int y = rand() % 3;
if (board[x][y] == ' ')
{
board[x][y] = '0';
break;
}
}
}
char check_win(char board[ROWS][COLS])
{
//判断玩家获胜
for (int i = 0; i < ROWS; i++)
{
if (((board[i][0] == board[i][1])) && ((board[i][1]) == (board[i][2])) && (board[i][0] == 'X'))
return 'p';
}
for (int i = 0; i < COLS; i++)
{
if (((board[0][i] == board[1][i])) && ((board[1][i]) == (board[2][i])) && (board[0][i] == 'X'))
return 'p';
}
if (((board[0][0] == board[1][1])&&(board[1][1] == board[2][2])) && (board[2][2] == 'X'))
{
return 'p';
}
if (((board[0][2] == board[1][1]) && (board[1][1] == board[2][0])) && (board[1][1] == 'X'))
{
return 'p';
}
//判断电脑获胜
for (int i = 0; i < ROWS; i++)
{
if (((board[i][0] == board[i][1])) && ((board[i][1]) == (board[i][2])) && (board[i][0] == '0'))
return 'c';
}
for (int i = 0; i < COLS; i++)
{
if (((board[0][i] == board[1][i])) && ((board[1][i]) == (board[2][i])) && (board[0][i] == '0'))
return 'c';
}
if (((board[0][0] == board[1][1]) && (board[1][1] == board[2][2])) && (board[2][2] == '0'))
{
return 'c';
}
if (((board[0][2] == board[1][1]) && (board[1][1] == board[2][0])) && (board[1][1] == '0'))
{
return 'c';
}
}
3.game.h
#define _CRT_SECURE_NO_WARNINGS 1
#include<time.h>
#include<stdlib.h>
#include<stdio.h>
#include<windows.h>
#include<string.h>
#ifndef __GAME_H__
#define __GAME_H__
#define ROWS 3//行
#define COLS 3//列
enum CH
{
PLAY = 1,
EXIT = 0
};
void init_board(char board[ROWS][COLS], int rows, int cols);
void printf_board(char board[ROWS][COLS], int rows, int cols);
void menu();
void player_move(char board[ROWS][COLS]);
void computer_move(char board[ROWS][COLS]);
char check_win(char board[ROWS][COLS]) ;
#endif