【C语言】三子棋的实现

目录

一、理清逻辑

二、创建文件

三、具体步骤

1.创建菜单和实现方法

2.创建并初始化二维数组

3.打印棋盘

4.双方下棋

1)玩家下棋

2)电脑下棋

5.判断胜负

四、运行结果

五、完整代码展示


一、理清逻辑

首先我们先来理一理三子棋实现的逻辑

1.打印游戏菜单

2.创建并初始化二维数组

3.打印棋盘

4.双方下棋

5.判断胜负

二、创建文件

我创建了三个文件,分别为test.c、game.h和game.c

test.c文件用于实现进入游戏、退出游戏、判断输赢、打印菜单等逻辑

game.c用于编写游戏的主要实现方法

game.h存放头文件和函数的声明

三、具体步骤

1.创建菜单和实现方法

写在test.c文件中

void menu()
{
	printf("********************************n");
	printf("*********   1.play   ***********n");
	printf("*********   0.exit   ***********n");
	printf("********************************n");
}
void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf(":>");
		
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("三子棋游戏开始n");
			game();
			break;
		case 0:
			printf("结束游戏n");
			break;
		default:
			printf("输入错误n");
			break;

		}
	} while (input);
}

2.创建并初始化二维数组

在test.c中创建二维数组并引用初始化数组的方法

void game()
{
	//创建二维数组
	char board[ROW][COL] = { 0 };
	//初始化二维数组
	InitBoard(board, ROW, COL);
}

在game.h中用宏定义定义行列,声明函数,填写需要的头文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3

在game.c中定义初始化数组的方法

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

3.打印棋盘

在game.c中定义打印棋盘的方法,需要注意的是每打印一行后要进行换行

void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	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 < row; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
		}
		printf("n");
	}
}

在test.c中game方法中引用此函数

4.双方下棋

人机双方轮流下棋,所以应该在test.c中将人机下棋的步骤放入循环

//下棋
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		//电脑下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
	}

1)玩家下棋

在game.c中定义实现玩家下棋的方法,要考虑到下棋是否在范围内和位置是否重复落子的情况,

因为我们是通过二维数组来实现的,所以我们输入的坐标x,y所对应的数组下标应该是x-1,y-1

void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:>");
	int x = 0;
	int y = 0;
	
	while (1)
	{
		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");
	}
	

}

2)电脑下棋

在game.c中定义电脑下棋的方法,我用的是比较简单的用rand函数生成随机数来随机建立坐标,当然这个ai算法是可以优化的。

void computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>n");
	while (1)
	{
		x = rand() % ROW;
		y = rand() % COL;
		if (board[x][y]== ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

5.判断胜负

三子棋的结果无非就是三种,玩家赢,电脑赢,平局

我们先在game.c中定义一个实现判断结果的方法

任意一行相同或任意一列相同或对角线相同则视为胜利

//玩家赢:'*'
//电脑赢:'#'
//平局:Q
//继续:C
int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}
char is_win(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	for (i = 0; i < row; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][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 (is_full(board, row, col)==1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

在test.c中实现判断胜负的逻辑

char ret = 0;
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	//判断胜负
	if (ret == '*')
	{
		printf("玩家赢了!n");
	}
	else if (ret == '#')
	{
		printf("电脑赢了!n");
	}
	else
	{
		printf("平局n");
	}
}

四、运行结果

下面就来展示一下我和人工智障的精彩对局吧

 

嗯,看来我创造出来的ai已经强大到可以击败我了,我真厉害!

五、完整代码展示

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.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 player_move(char board[ROW][COL], int row, int col);
void computer_move(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "game.h"
void menu()
{
	printf("********************************n");
	printf("*********   1.play   ***********n");
	printf("*********   0.exit   ***********n");
	printf("********************************n");
}
void game()
{
	//创建二维数组
	char board[ROW][COL] = { 0 };
	//初始化二维数组
	InitBoard(board, ROW, COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
	//下棋
	char ret = 0;
	while (1)
	{
		//玩家下棋
		player_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		computer_move(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	//判断胜负
	if (ret == '*')
	{
		printf("玩家赢了!n");
	}
	else if (ret == '#')
	{
		printf("电脑赢了!n");
	}
	else
	{
		printf("平局n");
	}
}
void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf(":>");
		
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("三子棋游戏开始n");
			game();
			break;
		case 0:
			printf("结束游戏n");
			break;
		default:
			printf("输入错误n");
			break;

		}
	} while (input);
}

int main()
{
	test();
	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 = 0;
	int j = 0;
	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 = 0;
	int j = 0;
	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 < row; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
		}
		printf("n");
	}
}

void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:>");
	int x = 0;
	int y = 0;
	
	while (1)
	{
		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 computer_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋:>n");
	while (1)
	{
		x = rand() % ROW;
		y = rand() % COL;
		if (board[x][y]== ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}


int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}
char is_win(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][1] != ' ')
		{
			return board[i][1];
		}
	}
	for (i = 0; i < row; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][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 (is_full(board, row, col)==1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

当然,随着所学的知识不断增加,这个游戏可以不断的被优化。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>