栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c语言实践项目:三子棋(肯定能看懂)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c语言实践项目:三子棋(肯定能看懂)

今天我们来完成一个项目 用c语言实现三子棋

目录
    • 添加头文件
    • 0.主要函数以及头文件
      • #game.h
      • untili.h
    • 1.显示棋盘
    • 2.电脑下棋
    • 3.检查结果
    • 4.玩家下棋
    • 5.再次检查结果
    • 6.判断胜负以及game.c全局代码
    • 7.登录界面
    • 总结

先说一下代码的基本逻辑

1.显示棋盘
2. 电脑或玩家下棋
3. 检查结果
4. 电脑或玩家下棋
5. 检查结果
6. 判断胜负

下面是代码实操

添加头文件

由于函数较多,写在一起比较乱,首先我们先创建一个头文件命名为game.h 再定义一个源文件 game.c ,为了方便使用,我们再写一个公共的头文件库 untili.h,这样我们在使用的时候通过引用untili就相当于引用全部的头文件了,最后创建一个源文件,是我们的主函数,命名为gamemain.c,这里的操作放出来一个,以此类推


下面我们开始写函数

0.主要函数以及头文件 #game.h
#ifndef _GAME_H_
#define _GAME_H_

#include"untili.h"
void InitGame();
void ShowchessBoard();
void ComputerChoice();
bool IsFull();
char CheckResult();
void gamerchoice();
void startgame();
//int  VictoryJudgment(char winner);


#endif 
untili.h
#ifndef _UTILI_H_
#define _UTILI_H_
#include
#include"time.h"
#include
#include

#endif 

1.显示棋盘
void InitGame()
{
	for (int i = 0; i < ROW; ++i)
	{
		for (int j = 0; j < COL; ++j)
		{
			chess_board[i][j] = ' ';
		}
	}
}
void ShowchessBoard()
{
	for (int i = 0; i < ROW; ++i)
	{
		printf("| %c | %c | %c |n", chess_board[i][0],
			chess_board[i][1],
			chess_board[i][2]);
		if (i + 1 != ROW)
			printf(" --- --- ---n");
	}
}

数组的定义和宏请参考开头的函数表(row和col都是3)
InitGame()的作用是把一个3*3的二维数组全都变成空格,方便落子
ShowchessBoard()的作用则是围成一个棋盘的形状

2.电脑下棋

在这里,我们先让电脑下棋,到全部完成一会是可以选择谁先下的

void ComputerChoice()
{
	int x, y;
	while (1)
	{
		srand(time(0));
		x = rand() % ROW;
		y = rand() % COL;
		if (chess_board[x][y] == ' ')
		{
			chess_board[x][y] = 'x';
			break;
		}
	}
}

ComputerChoice()函数中使用了一个用时间随机种子产生随机数的方法,在使用这个方法之前我们先要引用一个头文件 stdio
**srand(time(0));**就是用时间做随机种子,好处就是没有任何一个时刻的时间是相同的,所以我们可以放心他产生的随机数都是完全随机的。**x = rand() % ROW;**的意思就是产生一个0-ROW之间的随机数(0,1,2)。
在这里我们进行了一个判断,如果随机出来的数组元素里边是空格的话,我们就让他为’x’代表电脑下在了这里。

3.检查结果

在电脑或者我们每次下完棋以后,必须进行一次检查,检查有没有人胜出,或者是和棋,三子棋的规则是横竖斜三个连成一片就算赢,所以我们判断的逻辑就是,判断横着竖着斜着的连着的三个元素是不是一样。代码如下

bool IsFull()
{
	for (int i = 0; i < ROW; ++i)
	{
		for (int j = 0; j < COL; ++j)
		{
			if (chess_board[i][j] == ' ')
			{
				return false;
			}
		}
		
	}
	return true;

}
char CheckResult()
{
	for (int i = 0; i < ROW; ++i)
	{
		if (chess_board[i][0] != ' ' && chess_board[i][0] == chess_board[i][1]
			&& chess_board[i][0] == chess_board[i][2])
		{
			return chess_board[i][0];
		}
		for (int i = 0; i < ROW; ++i)
		{
			if (chess_board[0][i] != ' ' && chess_board[0][i] == chess_board[1][i]
				&& chess_board[0][i] == chess_board[2][i])
			{
				return chess_board[0][i];
			}
		}
		if (chess_board[1][1] != ' '
			&& chess_board[0][0] == chess_board[1][1]
			&& chess_board[0][0] == chess_board[2][2])
			return chess_board[1][1];
		if (chess_board[1][1] != ' '
			&& chess_board[0][2] == chess_board[1][1]
			&& chess_board[0][2] == chess_board[2][0])
			return chess_board[1][1];
	}
	if (IsFull())
		return 'h';
		return 'c';
}

在这里char CheckResult()函数的作用就是刚才说的判断横竖斜,这里不再赘述,我们说一下
IsFull()函数,这个函数的作用是判断有没有产生平局,产生了就返回真,没产生就返回假,他是通过循环遍历数组,看数组中还有没有空格,有,就是还没有和棋。
返回’x’电脑赢
返回’o’玩家赢
返回’c’继续(棋盘没满)
返回’h’和棋(棋盘满了)

4.玩家下棋
 void gamerchoice()
{
	printf("请您落子n");
	int x, y;
	while (1)
	{
		printf("您输入的坐标为:");
		scanf_s("%d %d", &x, &y);
		if (chess_board[x][y] == ' ')
		{
			chess_board[x][y] = 'o';
			break;
		}
		else
		{
			printf("您输入的位置已落子,请重新输入");
		}
	}
}

玩家下棋的方式和电脑区别就在于一个随机产生,一个主动输入,这里不再赘述

5.再次检查结果

和上一次判断完全相同

6.判断胜负以及game.c全局代码

判断胜负我们可以用一个char类型的变量来储存检查结果返回的值

game.c全局代码如下

#include"game.h"

#define ROW 3
#define COL 3
static char chess_board[ROW][COL];
// 基本逻辑
//1.登陆界面
//  (1)显示棋盘
void InitGame()
{
	for (int i = 0; i < ROW; ++i)
	{
		for (int j = 0; j < COL; ++j)
		{
			chess_board[i][j] = ' ';
		}
	}
}
void ShowchessBoard()
{
	for (int i = 0; i < ROW; ++i)
	{
		printf("| %c | %c | %c |n", chess_board[i][0],
			chess_board[i][1],
			chess_board[i][2]);
		if (i + 1 != ROW)
			printf(" --- --- ---n");
	}
}
//2.电脑下棋
void ComputerChoice()
{
	int x, y;
	while (1)
	{
		srand(time(0));
		x = rand() % ROW;
		y = rand() % COL;
		if (chess_board[x][y] == ' ')
		{
			chess_board[x][y] = 'x';
			break;
		}
	}
}
//3.判断输赢
// 返回'x'电脑赢
// 返回'o'玩家赢
// 返回'c'继续(棋盘没满)
// 返回'h'和棋(棋盘满了)
bool IsFull()
{
	for (int i = 0; i < ROW; ++i)
	{
		for (int j = 0; j < COL; ++j)
		{
			if (chess_board[i][j] == ' ')
			{
				return false;
			}
		}
		
	}
	return true;

}

char CheckResult()
{
	for (int i = 0; i < ROW; ++i)
	{
		if (chess_board[i][0] != ' ' && chess_board[i][0] == chess_board[i][1]
			&& chess_board[i][0] == chess_board[i][2])
		{
			return chess_board[i][0];
		}
		for (int i = 0; i < ROW; ++i)
		{
			if (chess_board[0][i] != ' ' && chess_board[0][i] == chess_board[1][i]
				&& chess_board[0][i] == chess_board[2][i])
			{
				return chess_board[0][i];
			}
		}
		if (chess_board[1][1] != ' '
			&& chess_board[0][0] == chess_board[1][1]
			&& chess_board[0][0] == chess_board[2][2])
			return chess_board[1][1];
		if (chess_board[1][1] != ' '
			&& chess_board[0][2] == chess_board[1][1]
			&& chess_board[0][2] == chess_board[2][0])
			return chess_board[1][1];
	}
	if (IsFull())
		return 'h';
		return 'c';
}
//4.玩家下棋
 void gamerchoice()
{
	printf("请您落子n");
	int x, y;
	while (1)
	{
		printf("您输入的坐标为:");
		scanf_s("%d %d", &x, &y);
		if (chess_board[x][y] == ' ')
		{
			chess_board[x][y] = 'o';
			break;
		}
		else
		{
			printf("您输入的位置已落子,请重新输入");
		}
	}
}
//5.判断输赢
//6.游戏界面

 void startgame()
 {
	 InitGame();
	 char winner;
	 int mode;
	 printf("请选择您的游戏模式 :输入 1 您先下,输入 0 电脑先下n"); 
	 scanf_s("%d", &mode);
	 while(1)
	 {
		 if (mode) 
		 {
			 ShowchessBoard();
			 gamerchoice();
			 winner = CheckResult();
			 if (winner != 'c')
				 break;
			 ComputerChoice();
			 winner = CheckResult();
			 if (winner != 'c')
				 break;
		 }
		 else
		 {
			 ComputerChoice();
			 ShowchessBoard();
			 winner = CheckResult();
			 if (winner != 'c')
				 break;
			 gamerchoice();
			 winner = CheckResult();
			 if (winner != 'c')
				 break;
		 }
	 }
	  ShowchessBoard();
	  if (winner == 'x')
	  {
		  printf("很遗憾,您输了,是否再来一局: 输入:1再来,输入:0结束n");
	  }
	  if (winner == 'o')
	  {
		  printf("恭喜您,您赢了,是否再来一局: 输入:1再来,输入:0结束n");
	  }
	  if (winner == 'h')
	  {
		  printf("双方棋逢对手,是否再来一局: 输入:1再来,输入:0结束n");
	  }
	 
 }

在这里我们实现了一个功能就是选择模式,是电脑先下还是玩家先下,但是操作过程比较简陋,希望各位看官能指导一下

7.登录界面

登录界面的操作比较简单.

int main()
{
	int choose;
	int select = 1;
	while (select)
	{
		printf("*******************************n");
		printf("*        简 易 三 子 棋       *n");
		printf("*******************************n");
		printf("*  [1] Play        [0] Exit   *n");
		printf("*******************************n");
		printf("请选择:>");
		scanf_s("%d", &select);
		if (select == 0)
		{
			break;
		}
		if (select != 1)
		{
			printf("error againn");
			continue;
		}
		do {
			startgame();
			scanf_s("%d", &choose);
			system("cls");
		   } while (choose);
	}
	printf("************ GoodBye *********n");
	return 0;
}

在gamemain.c这个主函数中,我们主要实现了几点功能,一个是显示了游戏的登录界面
另一个重要功能就是通过do while循环来控制游戏次数,可以多次进行游戏:

总结

到这里呢,我们的三子棋项目就算完成了,但是还有几点问题
1.发现使用时间做随机种子电脑下的越来越慢了,到最后程序几乎就停住了
2.代码不够简洁
3.还有些功能可以开发出来(比如计分板)
有任何不明白的地方都可以在评论区中提出,还请各位给上珍贵的指导意见。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/832516.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号