游戏介绍:井字棋(Tic Tac Toe)是由德国人发明的三连棋游戏,要求玩家轮流在一有九格方盘上划加字或圆圈,谁先把三个同一记号排成横线、直线、斜线,,即是胜者!此文章将教初学者如何利用简单的c语句完成井字棋游戏。
框架介绍:在此次完成游戏的过程中我们将游戏的文件分成3个部分。1. game.h 部分为我们存放游戏的头文件,应该将此部分放入编译器的头文件文件夹中。2. test.c 作为第二部分存放我们的游戏主逻辑部分,此部分存入源文件部分,将引用我们的“game.h”文件部分。3. game.c则作为我们实现游戏的源文件部分,将所有头文件中的声明的逐个实现。
游戏逻辑介绍:想实现井字棋游戏首先我们要想常规游戏一样有一个菜单,假设选择1开始0退出,进入游戏后我们得拥有一个3x3的游戏棋盘,类似于一个井字,很容易理解,所以我们首先应该定义一个board[][]数组以便存放之后的字符,所以(1).我们应该定义一个3x3的棋盘。接着我们得将这个棋盘打印出来,但是我们在打印时棋盘中没有存放东西,所以棋盘中先用空格填充。接着我们开始打印棋盘的分割线,所以(2).打印棋盘的分割线。此处分割线如何打印会在游戏中具体介绍。(3).棋盘拥有之后我们实际上就要开始实现人机之间的互动,是实现人间分别下棋的一个过程。将我们可以将下棋的过程实现在棋盘上后,紧接着我们要判断游戏的结果。所以(4).实现人机对战后判断游戏的结果。实现以上逻辑,游戏运行的基本思想及完成。
游戏实现部分:首先实现test.c部分: 首先我们编写一个简单的游戏逻辑,如下图代码所示
int main()
{
int input;
srand((unsigned int)time(NULL)); //**实现电脑生成随机数后面讲解**
do
{
menu();//**游戏进入先打印一个菜单**
scanf("%d",&input);
switch(input)
{
case 1:
game();//**实现游戏的函数**
break;
case 0:
printf("游戏退出\n");
break;
default:
printf("输入有误,请重新输入\n");
break;
}
}while(input);
return 0;
}
——————————————————————————
以下部分放置于主函数之上即可
完成简单逻辑后我们应完成菜单的打印以及game()函数的部分:
void menu()
{
printf("******************\n");
printf("***1.游戏开始*****\n");
printf("***0.游戏退出*****\n");
printf("******************\n");
}
**void game()//**函数部分将在game.c部分进行进一步讲解**
{
char Board[ROW][COL]={0};
char ret;
InitBoard(Board,ROW,COL);
DisplayBoard(Board,ROW,COL);
while(1)
{
Computermove(Board,ROW,COL);
ret=IsWin(Board,ROW,COL);
if(ret !=' ')
break;
DisplayBoard(Board,ROW,COL);
Playermove(Board,ROW,COL);
ret=IsWin(Board,ROW,COL);
if(ret !=' ')
break;
DisplayBoard(Board,ROW,COL);
}**
if(ret=='X')
{
printf("电脑赢\n");
}
else if(ret=='0')
{
printf("玩家赢\n");
}
else if(ret=='Q')
{
printf("平局\n");
}
DisplayBoard(Board,ROW,COL);
}
——————————————————————————————
(2).第二部分则为game.h的头文件部分,完整的头文件部分如下
——————————————————————————————
#include<stdio.h>//**打印函数的头文件**
#include<stdlib.h>
#include<time.h>//**电脑生成随机数的time函数头文件**
#define ROW 3//**此处用define定义3行3列的棋盘**
#define COL 3
void InitBoard(char Board[ROW][COL],int row,int col);//**定义棋盘的函数声明**
void DisplayBoard(char Board[ROW][COL],int row,int col);//**打印棋盘的函数的声明**
void Computermove(char Board[ROW][COL],int row,int col);//**电脑移动的函数声明**
void Playermove(char Board[ROW][COL],int row,int col);//**玩家移动的函数声明**
char IsWin(char Board[ROW][COL],int row,int col);//**判断电脑或者玩家有没有获得游戏胜利的函数声明**
int IsFull(char Board[ROW][COL],int row,int col);//**判断是否平局的函数声明**
——————————————————————————————————————————
以上我们就实现了头文件和游戏大体逻辑部分,接下来我们则要实现最重要的游戏部分,头文件中的自定义函数声明我们都将在game.c中一一实现。
——————————————————————————————————————————————
game.c:
首先来看定义的第一个函数,InitBoard函数,此函数将完成我们九个格子的初始化,我们将格子全部初始化为空格:
void InitBoard(char Board[ROW][COL],int row,int col) //**空型函数,Board[ROW][COL]接受指针,row,col为接受的形式参数**
{
int i=0;//**使用简单的循环语句**
for(i=0; i<row; i++)
{
int j=0;
for(j=0; j<col; j++)
Board[i][j]=' ';
}
}
实际上我们还可以使用更方便的memset函数:
{
memset(&board[0][0],' ',col*row*board[0][0]);//此处不做过多的介绍
}
——————————————————————————————
接着打印我们的棋盘的分割线
——————————————————————————————
void DisplayBoard(char Board[ROW][COL],int row,int col)
//{
// int i=0;
// for(i=0; i<row; i++)
// {
// printf(" %c | %c | %c \n",Board[i][0],Board[i][1],Board[i][2]);
// if(i<row-1)
// printf("---|---|---\n");
// }
//}
/此处打印方式不能满足改变ROW COL数值后的棋盘所以我们出现第二种打印方式
{
int i=0;
for(i=0; i<row; i++)
{
int j=0;
for(j=0; j<col; j++)
{
printf(" %c ",Board[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 Computermove(char Board[ROW][COL],int row,int col)
{
int x=0;
int y=0;
printf("电脑走\n");
while(1)
{
x=rand()%row;//**rand()即为让电脑生成随机数**
y=rand()%col;
if(Board[x][y]==' ')
{
Board[x][y]='X'; break;
}
}
}
玩家移动
——————————————————————————————
void Playermove(char Board[ROW][COL],int row,int col)
{
int x=0;
int y=0;
printf("玩家走\n");//**此处为玩家自行输入坐标完成操作**
while(1)
{
printf("请输入坐标\n");
scanf("%d%d",&x,&y);
if(x>=1&&x<=row&&y>=1&&y<=col)
{
if(Board[x-1][y-1]==' ')
{
Board[x-1][y-1]='0';
break;
}
else
{
printf("坐标被占用请重新输入\n");
}
}
else
{
printf("输入有误请重新输入\n");
}
}
}
——————————————————————————————
到这里我们就完成了人机对战的基本操作,接下来我们得判断游戏的输赢。
————————————————————————————————
char IsWin(char Board[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]!=' ')//**行3个相连**
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]!=' ')//**列3个相连**
return Board[0][i];
}
if(Board[0][0]==Board[1][1]&&Board[1][1]==Board[2][2]&&Board[2][2]!=' ')//**对角线相连**
{
return Board[1][1];
}
if(Board[0][2]==Board[1][1]&&Board[1][1]==Board[2][0]&&Board[2][0]!=' ')
{
return Board[1][1];
}
if(IsFull(Board,row,col))//**这里判断是否出现平局**
{
return 'Q';
}
return ' ';
}
int IsFull(char Board[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(Board[i][j]==' ')
return 0;
}
}
return 1;
}
到这里,我们的井字棋游戏也就结束了,但游戏存在很多不完美的东西,比如在进行游戏时电脑并不会优先生成3个相连的数,他只能随机生成在9个格子里,所以我们只保证了游戏的逻辑但是并没有游戏的可玩性,而且我们的游戏也只能靠玩家输入坐标来完成,还没有达到一个游戏的最终的要求。
ps:代码粘贴过去直接可以进行游戏