手把手教你用C语言实现三子棋

编辑: admin 分类: c#语言 发布时间: 2022-03-15 来源:互联网
目录
  • 1.设计简单菜单
  • 2.创建棋盘
  • 3.下棋过程的实现 
    • 3.1玩家下棋
    •  3.2电脑下棋
    • 3.3判断输赢
  • 4.游戏源码
    • 总结

      1.设计简单菜单

      相信大家在玩游戏时会发现,进入游戏前会有菜单拱你选择,你可以选择你想要的模式,三子棋也是同样的。

      void menu()
      {
      	printf("******************************\n");
      	printf("*********   0.play   *********\n");
      	printf("*********   1.exit   *********\n");
      	printf("******************************\n");
      }
      int main()
      {
      	srand((unsigned)time(NULL));
      	int input = 0;
      	do
      	{
      		menu();
      		printf("请选择:\n");
      		scanf("%d", &input);
      		switch (input)
      		{
      		case 0: game(); break;//game()函数是后续用来实现游戏过程的一个函数
      		case 1:printf("退出游戏\n"); break;
      		default:printf("选择错误,请重新选择\n"); break;
      		}
      	} while (input);//while(input)相当于while(input!=0)只要没进入游戏就会一直循环到进入为止
      
      	return 0;
      }
      

      2.创建棋盘

      在C语言中我们把下棋的棋子存在二维数组里

      char board[ROW][COL];

      在下棋前,我们应该保证棋盘上是没有棋子的,所以我们得先初始化棋盘。

      void InitBoard(char board[ROW][COL], int row, int col)
      {
      	int i, j;
      	for (i = 0; i < row; i++)
      	{
      		for (j = 0; j < col; j++)
      		{
      			board[i][j] = ' ';
      		}
      	}
      }
      

      接下来我们要把棋盘打印出来我们才能下

      void DisplayBoard(char board[ROW][COL], int row, int col)
      {
      	int i, j;
      	//打印棋盘
      	for (i = 0; i < row; i++)
      	{
      		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");
      	}
      }
      

       

      这样一个简易的棋盘就打印出来了。(确实简易)

      3.下棋过程的实现 

      3.1玩家下棋

      void PlayerMove(char board[ROW][COL], int row, int col)
      {
      	printf("玩家走:>\n");
      	int x, y;
      	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] = '*';
      				break;
      			}
      			else
      			{
      				printf("坐标被占用,请重新输入\n");
      			}
      		}
      		else
      		{
      			printf("坐标非法,超出范围\n");
      		}
      	}
      }
      

       3.2电脑下棋

      void ComputerMove(char board[ROW][COL], int row, int col)
      {
      	printf("电脑走:>\n");
      
      	while (1)
      	{
      		int x = rand() % row;//0~2 注意放在循环里,保证每一次进来都会产生一个随机数
      		int y = rand() % col;//0~2
      		if (board[x][y] == ' ')
      		{
      			board[x][y] = '#';
      			break;
      		}
      	}
      }
      

      电脑下棋我就要在这边说明一下了,电脑是通过产生随机数来进行下棋的,那这个随机数怎么产生呢?C语言作为历史比较久的一门语言,早期并没有设计出太多函数,像现在的Python是自带有随机函数的,直接调用就可以产生随机值的,而C语言实现随机数的方式就是时间戳。

      那什么是时间戳呢?

      时间戳是从1970年1月1日(UTC/GMT的午夜)开始到现在所经过的秒数。

      当你单独使用rand函数的时候你会发现产生的数确实是随机的,但这个随机是伪随机,即每次随机都是一样的数,而当你用了时间戳就能实现真正的随机,因为时间是时时刻刻在发生变化的。

      那应该怎么使用呢?

      首先在主函数里你需要这样

      srand((unsigned)time(NULL));

      这样你的rand函数就变成了真正的随机函数了,这边要注意一点,rand函数一定要放在循环里,保证每次循环都能产生一个随机数,若放在循环外面,则每进一次函数才会产生一次随机值。

      到这里整个游戏的实现就圆满完成了。

      真以为这就结束了?想想也没毛病,菜单也设计了,棋盘也打印了,玩家和电脑也实现了,还有什么吗?

      想不到吧,游戏输赢你还没判断吧。

      3.3判断输赢

      在判断游戏输赢前还有一个小细节,我们玩家和电脑在下棋时如果棋盘上有子是不是不能下,所以还需要一个判断棋盘是否满了的函数。

      int IsFull(char board[ROW][COL], int row, int col)
      {
      	int i, j;
      	for (i = 0; i < row; i++)
      	{
      		for (j = 0; j < col; j++)
      		{
      			if (board[i][j] == ' ')
      				return 0;//棋盘还没满
      		}
      	}
      	return 1;//棋盘满了
      }
      

       然后就可以进行判断输赢的实现了

      char IsWin(char board[ROW][COL], int row, int col)
      {
      	//行
      	int i, j;
      	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 (j = 0; j < col; j++)
      	{
      		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
      			return board[0][j];
      	}
      	//对角线
      	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
      		return board[0][0];
      	else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
      		return board[0][2];
      	//平局
      	if (IsFull(board, ROW, COL))
      		return 'd';
      	//游戏继续
      	return 't';
      }
      

      到这里整个游戏的逻辑就完美了。(别慌,这次是真的结束了,没有骗你们)

      接下来附上整个游戏的源码

      4.游戏源码

      test.c文件

      #define _CRT_SECURE_NO_WARNINGS 1
      #include"game.h"
      void game()
      {
      	//三子棋的过程
      	char board[ROW][COL];
      	//初始化棋盘
      	InitBoard(board, ROW, COL);
      	//打印棋盘
      	DisplayBoard(board, ROW, COL);
      	//下棋
      	char ret = IsWin(board, ROW, COL);
      	while (1)
      	{
      		PlayerMove(board, ROW, COL);
      		DisplayBoard(board, ROW, COL);//打印棋盘
      		ret = IsWin(board, ROW, COL);
      		if (ret != 't')
      			break;
      
      		ComputerMove(board, ROW, COL);
      		DisplayBoard(board, ROW, COL);
      		ret = IsWin(board, ROW, COL);
      		if (ret != 't')
      			break;
      	}
      
      	if (ret == 'd')
      		printf("平局");
      	else if (ret == '*')
      		printf("玩家赢");
      	else if (ret == '*')
      		printf("电脑赢");
      
      }
      void menu()
      {
      	printf("******************************\n");
      	printf("*********   0.play   *********\n");
      	printf("*********   1.exit   *********\n");
      	printf("******************************\n");
      }
      int main()
      {
      	srand((unsigned)time(NULL));
      	int input = 0;
      	do
      	{
      		menu();
      		printf("请选择:\n");
      		scanf("%d", &input);
      		switch (input)
      		{
      		case 0: game(); break;
      		case 1:printf("退出游戏\n"); break;
      		default:printf("选择错误,请重新选择\n"); break;
      		}
      	} while (input);
      
      	return 0;
      }
      

       game.c文件

      #define _CRT_SECURE_NO_WARNINGS 1
      #include"game.h"
      void InitBoard(char board[ROW][COL], int row, int col)
      {
      	int i, j;
      	for (i = 0; i < row; i++)
      	{
      		for (j = 0; j < col; j++)
      		{
      			board[i][j] = ' ';
      		}
      	}
      }
      void DisplayBoard(char board[ROW][COL], int row, int col)
      {
      	int i, j;
      	//打印棋盘
      	for (i = 0; i < row; i++)
      	{
      		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 PlayerMove(char board[ROW][COL], int row, int col)
      {
      	printf("玩家走:>\n");
      	int x, y;
      	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] = '*';
      				break;
      			}
      			else
      			{
      				printf("坐标被占用,请重新输入\n");
      			}
      		}
      		else
      		{
      			printf("坐标非法,超出范围\n");
      		}
      	}
      }
      void ComputerMove(char board[ROW][COL], int row, int col)
      {
      	printf("电脑走:>\n");
      
      	while (1)
      	{
      		int x = rand() % row;//0~2 注意放在循环里,保证每一次进来都会产生一个随机数
      		int y = rand() % col;//0~2
      		if (board[x][y] == ' ')
      		{
      			board[x][y] = '#';
      			break;
      		}
      	}
      }
      int IsFull(char board[ROW][COL], int row, int col)
      {
      	int i, j;
      	for (i = 0; i < row; i++)
      	{
      		for (j = 0; j < col; j++)
      		{
      			if (board[i][j] == ' ')
      				return 0;//棋盘还没满
      		}
      	}
      	return 1;//棋盘满了
      }
      char IsWin(char board[ROW][COL], int row, int col)
      {
      	//行
      	int i, j;
      	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 (j = 0; j < col; j++)
      	{
      		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')
      			return board[0][j];
      	}
      	//对角线
      	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')
      		return board[0][0];
      	else if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')
      		return board[0][2];
      	//平局
      	if (IsFull(board, ROW, COL))
      		return 'd';
      	//游戏继续
      	return 't';
      }
      

      game.h

      #pragma once
      #include<stdio.h>
      
      #include<time.h>
      
      #include<stdlib.h>
      
      #define ROW 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 PlayerMove(char board[ROW][COL], int row, int col);
      //电脑下棋
      void ComputerMove(char board[ROW][COL], int row, int col);
      //判断输赢
      char IsWin(char board[ROW][COL], int row, int col);
      
      

      总结

      本篇文章就到这里了,希望能给你带来帮助,也希望您能够多多关注海外IDC网的更多内容!