C语言小游戏(1)—三子棋

本文详细介绍了如何使用C语言实现一个简单的三子棋游戏,包括项目设置、源文件结构、头文件管理以及关键代码模块如棋盘操作、玩家与电脑走棋和胜负判断。通过一步步的代码演示,展示了游戏开发的基本流程和技术要点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

1.创建项目、源文件、头文件

首先,在编译器中创建一个新项目,然后,添加源文件和头文件。

源文件一般创建两个:test.c和game.c,test.c用于测试,在编写程序过程中,可以不断对当前代码块进行测试,避免程序全部完成之后再测试,编译器报出一堆错误,难以对错误进行定位。

头文件创建一个:game.h,将函数的声明和头文件等放在game.h中,这样对于在test.c和game.c中都需要引的头文件,只需要在game.h中引一次就可以了。

2.代码实现三子棋小游戏

首先创建三个文件

game.h //后面在代码编写过程中,不断丰富该文件内容,存放函数实现过程中所需的头文件、函数声明等
#include <stdio.h>
void game();//声明game函数(不要忘了函数声明后面有;)
test.c//每编写一个功能模块可进行一次测试,确定当前代码没有问题时再继续写
#include "game.h"
void menu()//打印菜单
{
	printf("*************************\n");
	printf("*****0.exit***1.play*****\n");
	printf("*************************\n");
}
int main()
{
	int input=0;
	srand((unsigned int)time(NULL));//随机数的生成起点,用于后面电脑下棋时位置的随机生成
	do
	{
	 menu();
	 printf("请选择\n");
	 scanf("%d",&input);
	 switch(input)
	 {
	 case 0:
		printf("退出\n");
		break;
     case 1:
	    game();
		break;
     default:
	   printf("选择错误,请重新选择\n");
	   break;
	 }
	}while(input);
	return 0;
}

在有了上面两个模块之后,剩下的就是实现游戏的具体过程了,放在game.c中

这里简单分析一下实现游戏过程的几个问题(更加具体、细节的问题见代码备注):

(1)棋盘上的坐标用一个 二维数组存起来,本文所创建的二维数组比实际棋盘大,行、列分别比实际棋盘多2。以棋盘大小3*3为例

为什么这样做呢?

因为后面每走一步都要判断玩家/电脑是否赢了,因此要判断当前棋盘中是否有满足行/列/对角线三个连续的位置同时为玩家/电脑所下棋子的情况,但对于棋盘边缘一圈位置的判断会超出棋盘,如果对于边缘位置都单独判断会比较麻烦,因此,实际创建的数组大小比棋盘的实际大小要大,且多出的部分不会被下棋。

(2)本文打印的棋盘格式(以3*3的棋盘为例)

game.c
#include "game.h"
void game()
{
	char ret='C';
	char Board[ROWS][COLS]={0};
	InitBoard(Board,ROWS,COLS);//用于初始化棋盘
	DisplayBoard(Board,ROW,COL);//打印棋盘
	while(ret=='C')
	{
		printf("玩家走\n");
	    PlayerMove(Board,ROW,COL);//玩家放置棋子
	    DisplayBoard(Board,ROW,COL);
		if((ret=Iswin(Board,ROWS,COLS))!='C')//判断玩家是否赢了,没赢游戏继续,电脑走
			break;
		else
		{
			printf("电脑走\n");
	        ComputerMove(Board,ROW,COL);
	        DisplayBoard(Board,ROW,COL);
		    ret=Iswin(Board,ROWS,COLS);
		} 
	}
	if(ret=='#')
		printf("电脑赢\n");
	else if(ret=='*')
		printf("玩家赢\n");
	else
		printf("平局\n");
}
void InitBoard(char(*Board)[COLS],int rows,int cols)
{
	int i,j=0;
	for(i=0;i<rows;i++)
	{
		for(j=0;j<cols;j++)
		{
			Board[i][j]=' ';//用' '初始化棋盘,初始的棋盘大小是ROWS*COLS
		}
	}
  }
void DisplayBoard(char(*Board)[COLS],int row,int col)//打印棋盘只需要打印大小为:ROW*COL
{
	int i,j=0;
	for(i=1;i<=row;i++)
	{
		for(j=1;j<=col;j++)
		{
			printf(" %c ",Board[i][j]);
			if(j!=col)
				printf("|");
			else
				printf("\n");
		}
		if(i!=row)
		{
			for(j=1;j<=col;j++)
		   {
			printf("---");
			if(j!=col)
				printf("|");
			else
				printf("\n");
		   }
		}
	}
}
void PlayerMove(char(*Board)[COLS],int row,int col)
{
	int x,y=0;
	while(1)//只有当输入的坐标在合法范围(ROW*COL里),并且没有被占用,棋子才成功放置
	{
		printf("请输入坐标:\n");
	    scanf("%d%d",&x,&y);
		if(x<1||x>row||y<1||y>row)
		{
			printf("坐标非法,重新输入\n");
		}
		else if(Board[x][y]!=' ')
        {
			printf("坐标被占用,重新输入\n");
		}
		else
		{
			Board[x][y]='*';//用‘*’代表用户所下棋子
			break;
		}
	}
}
void ComputerMove(char(*Board)[COLS],int row,int col)
  {
	  int x,y=0;
	  while(1)
	  {
		  x=rand()%row+1;
		  y=rand()%col+1;//随机产生x:1-ROW,y:1-COL
		if(Board[x][y]==' ')
        {
			Board[x][y]='#';//用‘#’代表电脑所下棋子
			break;
		}
	  }
  }
char Iswin(char(*Board)[COLS],int rows,int cols)
{
	int i,j=0;
	for(i=1;i<rows-1;i++)
	{
		for(j=1;j<cols-1;j++)
		{
			if((Board[i][j]!=' '))
			{
				if(((Board[i][j]==Board[i][j-1])&&(Board[i][j]==Board[i][j+1]))||
				((Board[i-1][j]==Board[i][j])&&(Board[i][j]==Board[i+1][j]))||
				((Board[i-1][j-1]==Board[i][j])&&(Board[i][j]==Board[i+1][j+1]))||
				((Board[i+1][j-1]==Board[i][j])&&(Board[i][j]==Board[i-1][j+1])))
				return Board[i][j];	//当电脑/用户赢了时,返回Board[i][j]('#'或'*')
			}
		}
	}
	for(i=1;i<rows-1;i++)
	{
		for(j=1;j<cols-1;j++)
		{
			if(Board[i][j]==' ')
				return 'C';//电脑/用户都没有赢,并且棋盘有空格时,游戏继续,返回‘C’
		}
	}
	return 'E';//电脑/用户都没有赢,但是棋盘没有空格了,平局,返回'E'
}

根据在编写game.c过程中,game.h已完善至如下代码所示:

game.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#define ROW 3
#define COL 3
#define ROWS ROW+2
#define COLS COL+2
void game();
void InitBoard(char(*Board)[COLS],int rows,int cols);
void DisplayBoard(char(*Board)[COLS],int row,int col);
void PlayerMove(char(*Board)[COLS],int row,int col);
void ComputerMove(char(*Board)[COLS],int row,int col);
char Iswin(char(*Board)[COLS],int rows,int cols);

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值