c语言实现简易三子棋

在这里插入图片描述

前言

实现一个简易的三子棋游戏,玩家能够和电脑进行对战,分出高下。
在这里插入图片描述

一、整体流程

  1. 创建三个文件,test.c用来放测试三子棋功能,game.c里放置游戏各个功能的实现代码,game.h用来放置需要用到的所有头文件及函数的声明。
  2. 在test.c中写一个菜单打印函数,用来每次游戏时打印菜单。在主函数中实现选择进入游戏,退出游戏等功能。当选择进入游戏,游戏具体操作的代码放在一个game()函数中。
  3. 书写game()函数,创建一个棋盘,并且完成棋盘的初始化,打印棋盘,玩家下棋,电脑下棋,判断输赢等功能。将这些功能包装成函数放在game.c中,并在game.h中声明。
  4. 完善代码并测试功能,进行修改完善。

二、具体代码实现

1、制作游戏菜单

void menu()
{
    
    
	printf("************************\n");
	printf("******1 开始游戏 *******\n");
	printf("******0 退出游戏 *******\n");
	printf("************************\n");
}

在这里插入图片描述

2、制作出主函数框架

int main()
{
    
    
	int input = 0;
	srand((unsigned int)time(NULL));//这里是后面电脑下棋需要用到的
	do {
    
    
		menu();
		printf("请输入你的选择>\n");
		scanf("%d", &input);//输入选择
		switch (input) 
		{
    
    
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入非法,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

3、接下来完善game()函数,将游戏各个功能写在game.c中。用二维数组放置棋盘,棋盘的行和列长度可以放在头文件中定义,方便整体的修改。

void game()
{
    
    
	char board[ROW][COL] = {
    
     0 };//棋盘
	InitBoard(board, ROW, COL);//置空初始化棋盘
	DisplayBoard(board, ROW, COL);//打印棋盘
	char ret = ' ';
	while (1)
	{
    
    
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'B')
		{
    
    
			break;
		}
		printf("---------------------\n");
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'B')
		{
    
    
			break;
		}
	}

代码中的一些属性会在后续具体函数的代码中出现

4、棋盘中的元素都为0,需要进行初始化

void InitBoard(char board[ROW][COL], int row, int col)
{
    
    
	for (int i = 0; i < row; i++) 
	{
    
    
		for (int j = 0; j < col; j++) 
		{
    
    
			board[i][j] = ' ';//将数组中所有元素置为空格
		}
	}
}

5、将棋盘打印出来,加上一些线区分每个棋子位置

void DisplayBoard(char board[ROW][COL], int row, int col)
{
    
    
	for (int i = 0; i < row; i++) 
	{
    
    
		for (int j = 0; j < col; j++) 
		{
    
    
			printf(" %c ", board[i][j]);
			if (j < col - 1) 
			{
    
    
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1) 
		{
    
    
			for (int j = 0; j < col; j++) 
			{
    
    
				printf("---");
				if (j < col - 1) 
				{
    
    
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

在这里插入图片描述

6、实现玩家下棋的功能

void PlayerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("该你下了(以空格隔开):\n");
		scanf("%d %d", &x, &y);//输入想要下的坐标(从1开始)
		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");
		}
	}
}

7、实现电脑下棋功能

void ComputerMove(char board[ROW][COL], int row, int col)
{
    
    
	printf("轮到电脑了:\n");
	while (1)
	{
    
    
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] == ' ')
		{
    
    
			board[x][y] = '#';
			break;
		}
	}
}

~srand((unsigned int)time(NULL));已经在主函数中写上,利用时间戳返回一个随机数
~int x = rand() % row ;可以得到0 ~ row-1的随机数,整体加一便可得到1~row的随机数
~对col也是一样

8、判断是否胜利
这里需要用到一个判断棋盘是否已满的函数

int IsFull(char board[ROW][COL], int row, int col)
{
    
    
	for (int i = 0; i < row; i++)
	{
    
    
		for (int j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == ' ')
			{
    
    
				return 0;
			}
		}
	}
	//如果一个空格都没有,走出了循环,说明已经满了
	return 1;
}

判断是否胜利,返回不同的字符,在game()函数中进行判断,得出谁获得胜利
该判断只适用于3*3棋盘的三子棋

char IsWin(char board[ROW][COL], int row, int col)
{
    
    
	//行
	for (int 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 (int i = 0; i < row; i++)
	{
    
    
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
    
    
			return board[0][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
    
    
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
    
    
		return board[1][1];
	}
	//平局
	if (IsFull(board, row, col))
	{
    
    
		return 'A';
	}
	return 'B';
}

9、记得将需要的头文件函数等在game.h中进行声明,并在test.c中引用该头文件
以下是头文件中的内容

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <time.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);
int IsFull(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

三、整体代码

game.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <time.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);
int IsFull(char board[ROW][COL], int row, int col);
char IsWin(char board[ROW][COL], int row, int col);

game.c

#include "game.h"

//数组置空
void InitBoard(char board[ROW][COL], int row, int col)
{
    
    
	for (int i = 0; i < row; i++) 
	{
    
    
		for (int j = 0; j < col; j++) 
		{
    
    
			board[i][j] = ' ';
		}
	}
}
//打印数组
void DisplayBoard(char board[ROW][COL], int row, int col)
{
    
    
	for (int i = 0; i < row; i++) 
	{
    
    
		for (int j = 0; j < col; j++) 
		{
    
    
			printf(" %c ", board[i][j]);
			if (j < col - 1) 
			{
    
    
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1) 
		{
    
    
			for (int j = 0; j < col; j++) 
			{
    
    
				printf("---");
				if (j < col - 1) 
				{
    
    
					printf("|");
				}
			}
			printf("\n");
		}
	}
}
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
    
    
	int x = 0;
	int y = 0;
	while (1)
	{
    
    
		printf("该你下了(以空格隔开):\n");
		scanf("%d %d", &x, &y);//输入想要下的坐标(从1开始)
		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 + 1;
		int y = rand() % col + 1;
		if (board[x][y] == ' ')
		{
    
    
			board[x][y] = '#';
			break;
		}
	}
}
//判断是否满了
int IsFull(char board[ROW][COL], int row, int col)
{
    
    
	for (int i = 0; i < row; i++)
	{
    
    
		for (int j = 0; j < col; j++)
		{
    
    
			if (board[i][j] == ' ')
			{
    
    
				return 0;
			}
		}
	}
	return 1;
}
//判断是否胜利
char IsWin(char board[ROW][COL], int row, int col)
{
    
    
	//行
	for (int 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 (int i = 0; i < row; i++)
	{
    
    
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
    
    
			return board[0][i];
		}
	}
	//判断对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
    
    
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
    
    
		return board[1][1];
	}
	//平局
	if (IsFull(board, row, col))
	{
    
    
		return 'A';
	}
	return 'B';
}

test.c

#include "game.h"

//游戏菜单
void menu()
{
    
    
	printf("************************\n");
	printf("******1 开始游戏 *******\n");
	printf("******0 退出游戏 *******\n");
	printf("************************\n");
}

//三子棋游戏
void game()
{
    
    
	char board[ROW][COL] = {
    
     0 };//棋盘
	InitBoard(board, ROW, COL);//置空
	DisplayBoard(board, ROW, COL);//打印棋盘
	char ret = ' ';
	while (1)
	{
    
    
		//玩家下棋
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'B')
		{
    
    
			break;
		}
		printf("---------------------\n");
		//电脑下棋
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = IsWin(board, ROW, COL);
		if (ret != 'B')
		{
    
    
			break;
		}
	}
	if (ret == '*')
	{
    
    
		printf("恭喜你取得胜利\n");
	}
	else if (ret == '#')
	{
    
    
		printf("很遗憾,你输了\n");
	}
	else
	{
    
    
		printf("你与电脑势均力敌\n");
	}
}
int main()
{
    
    
	int input = 0;
	srand((unsigned int)time(NULL));
	do {
    
    
		menu();
		printf("请输入你的选择>\n");
		scanf("%d", &input);//输入选择
		switch (input) 
		{
    
    
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入非法,请重新输入\n");
			break;
		}
	} while (input);
	return 0;
}

四、效果测试

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zcxyywd/article/details/130587339
今日推荐