C语言小游戏——三子棋

C语言 -- 三子棋

       本篇主要是用二维数组和多个函数来实现三子棋游戏。

       让我们先来看看这个编写这个游戏的思路:首先要打印三子棋的棋盘,然后是玩家下棋,电脑下棋,最后判断谁赢了,或者看看是否平局。

       我们用一个头文件 game.h ,一个源文件 game.c(主要的代码都在这里面哦!)和一个源文件测试文件 text.c(主要写整个游戏的具体思路)来编写我们的代码。



*首先我们看看头文件(game.h):

#ifndef __GAME_H__
#define __GAME_H__

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 3  //行  自己可以改变棋盘的大小
#define COL 3  //列  同上(不能小于三哦)

void init_board(char board[ROW][COL], int row, int col);
void print_board(char board[ROW][COL], int row, int col);
void player_move(char board[ROW][COL], int row, int col);
void computer_board(char board[ROW][COL], int row, int col);
char is_win(char board[ROW][COL], int row, int col);
//以上是后面源文件中需要调用的函数

enum OPTION
{
	EXIT,
	PLAY
};
//枚举 

#endif // ! __GAME_H__

       

*再来看看测试文件 (test.c):

#include"game.h"

void menu()
{
	printf("             三子棋游戏            \n");
	printf("\n");
	printf("***********************************\n");
	printf("*******       1. play       *******\n");
	printf("*******       0. exit       *******\n");
	printf("***********************************\n");
}

void game()
{
	int row = 0;
	int col = 0;
	char ret = '0';
	char board[ROW][COL] = { '0' };            //创建一个数组(棋盘)
	init_board(board, ROW, COL);               //初始化棋盘,使其都是空格。
	print_board(board, ROW, COL);              //打印棋盘
	while (1)
	{
		player_move(board, ROW, COL);      //玩家下棋
		print_board(board, ROW, COL);  
		ret = is_win(board, ROW, COL);
                //判断输赢平局
		if (ret == 'X')
		{
			printf("恭喜你,赢了!\n");
			break;
		}
		else if (ret == 'Q')
		{
			printf("平局\n");
			break;
		}
		computer_board(board, ROW, COL);     //电脑下棋
		print_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
                //判断
		if (ret == 'O')
		{
			printf("电脑赢了!\n");
			break;
		}
		else if (ret == 'Q')
		{
			printf("平局\n");
			break;
		}
	}
}

int main()
{
	int input = 0;
	srand((unsigned int)(time(NULL)));
	menu();                             //打印菜单
	do
	{
		printf("请选择:");
		scanf_s("%d", &input);
		switch (input)
		{
		case PLAY:
			game();
			break;
		case EXIT:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择!\n");
			break;
		}
	} while (input);

	return 0;
}

        


*最后来看看最重要的 game.c ,让我们分部来看:       

初始化数组,元素都是空格

void init_board(char board[ROW][COL], int row, int col)
{
	memset(board, ' ', sizeof(board[0][0]) * row * col);
}

不知道memset函数的点击这里大笑 ==> 点击打开链接


接下来就要打印棋盘了,如下图(3*3棋盘),我们将它分成后面这个图看看。

                     

看红色的(横着看),发现最后一个红框里面比前面的少一个 ‘ | ’;

再看紫色的,发现最后一行比上面少底下一行;

观察完了,我们来实现代码

void print_board(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;

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


*玩家下棋

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("玩家走\n");
		printf("请输入你要下棋的坐标:");
		scanf_s("%d %d", &x, &y);

		if (((x > 0) && (x <= row)) && ((y > 0) && (y <= col)))   //下棋的坐标要在棋盘内。 
		{
			if (board[x - 1][y - 1] == ' ')                   //:玩家输入的坐标假如是(1 1),写代码的应该知道其实是(0 0)
			{
				board[x - 1][y - 1] = 'X';
				break;
			}
			else
			{
				printf("输入的坐标已有棋子,请重新输入!\n");
			}
		}
		else
		{
			printf("输入棋子的坐标有误,请重新输入!\n");
		}
	}
}


*电脑下棋

void computer_board(char board[ROW][COL], int row, int col)
{
	printf("电脑走\n");
	while (1)
	{
		int x = rand() % row;    //srand((unsigned int)(time(NULL))
		int y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = 'O';
			break;
		}
	}
}


*判断输赢还有平局

char is_win(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	
	for (x = 1; x < row - 1; x++)
	{
		for (y = 0; y < col; y++)
		{
			if ((board[x][y] == board[x - 1][y]) && (board[x][y] == board[x + 1][y]) && board[x][y] != ' ')
			{
				return board[x][y];
			}
		}
	}
	for (x = 0; x < row; x++)
	{
		for (y = 1; y < col - 1; y++)
		{
			if ((board[x][y] == board[x][y - 1]) && (board[x][y] == board[x][y + 1]) && board[x][y] != ' ')
			{
				return board[x][y];
			}
		}
	}

	for (x = 1; x < row - 1; x++)
	{
		for (y = 1; y < col - 1; y++)
		{
			if (((board[x][y] == board[x - 1][y - 1]) && (board[x][y] == board[x + 1][y + 1]) && board[x][y] != ' ')
				|| ((board[x][y] == board[x - 1][y + 1]) && (board[x][y] == board[x + 1][y - 1])) && board[x][y] != ' ')
				return board[x][y];
		}
	}
	if (is_full(board, ROW, COL) == 1)    //判断棋盘是否满了(平局)
	{
		return 'Q';   //表示棋盘满了
	}
}
static int is_full(char board[ROW][COL], int row, int col)   
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

想想上面那段代码可以优化吗?

      我们可以把玩家或者电脑下棋的坐标传过来,以这个坐标为中心判断输赢,就不用重新一个一个的找,一个一个判断。(可以自己试试哦!)



最后我们来看看结果(3*3棋盘)



再来看一个(5*5棋盘)

                     



       好了,这样这个三子棋代码就完成了!学会了吗?大笑




猜你喜欢

转载自blog.csdn.net/hyb_91/article/details/80056661