【C语言实现经典小游戏】——“三子棋”【近万字保姆级教学】

        相信大家都玩过三子棋,而看到这篇文章的你大概也想实现自己的小游戏吧,那么跟随我的脚步,一步步实现你的C语言小游戏吧!

目录

1.三子棋的原理

 2.运用的特殊的函数

3.开始前的准备工作

4.游戏菜单的创建

 5.游戏主体核心的实现


1.三子棋的原理

三子棋其实就是应该3*3的九宫格,玩家和电脑每人各下一次,判断谁先将三颗子给连成一条线,则为成功,在编程时我们会先将这九个空格填充为空格,由玩家先行下棋,电脑后下让后进行判断胜负。

 2.运用的特殊的函数

就如同我在猜数字游戏中给出的几个特殊函数一般,三子棋也会用到几个特别的函数,并且所用到的都相像

1.rand()-->来提供随机数

在这里插入图片描述

2.srand配合rand和time的使用

Generates a pseudorandom number:生成一个随机数字

注意:The rand function returns a pseudorandom integer in the range 0 to RAND_MAX

意思是rand的范围是0-RAND_MAX其中RAND_MAX我们可以找的其d定义得知为0x7fff-32767

即rand函数返回的随机数的范围为(0-32767)

单单使用rand() 函数来生成随机数是不行的,因为它每玩一次生成的随机数都是相同的,即随机数不随机,所以要通过srand()函数,种下一个随机种子,来产生随机数。
 

3.库函数,标识在开头

 便于rand的使用

3.开始前的准备工作

由于我们编写代码行数较多,我们可以在game.c里实现我们的函数,在test.c里测试,最后引用game.h的头文件来串联一下。注意引用时要用#include “game.h”

我们需要有三个文件如下:

  1. test.c      ——   测试游戏
  2. game.h   ——  游戏函数的声明
  3. game.c   ——  游戏函数的实现

4.游戏菜单的创建

1)打印菜单栏
我们在test.c的文件里使用创建一个菜单,跟我们上次猜字游戏一样,因为不需要返回,所以使用void menu()来创建一个开始界面,我们想要输入1开始游戏,输入0退出游戏:

//test.c源文件中的代码
void menu()
{
    printf("**********************************\n");
    printf("************  1.play  ************\n");
    printf("************  0.exit  ************\n");
    printf("**********************************\n");
 
}


这里之前要先写一个主函数,去调用这个菜单,(因为是不管怎样都要打印一遍,所以用do whiel 循环)代码如下:

//test.c源文件中的代码
int main()
{
 
    do
    {
        menu();   //菜单栏打印
 
    } while ();
    return 0;
}

调用完菜单之后我们就要选择这两个,既然要选择 ,我们就要输入,我们定义一个变量为 input 代码如下:

//test.c源文件中的代码
int main()
{
    int input = 0;
    
    do
    {
        menu();
 
        printf("请选择:>");
 
        scanf("%d", &input);
 
    } while ();
    return 0;
}


选择完之后我们就要接收进来,根据选择的数字来做出相应的事情,这里就用到switch和case语句实现,代码如下:

//test.c源文件中的代码
int main()
{
    int input = 0;
    
    do
    {
        menu();
        printf("请选择:>");
        scanf("%d", &input);
        switch (input)
        {
        case 1 :
            game();   //选择1,就玩游戏,所以这里提供一个实现游戏代码的函数
            break;
        case 0 :
            printf("退出游戏成功\n");
            break;
        default :
            printf("选择错误,请重新选择>\n");
            break;
        }
    } while (input); //根据输入0和1去判断循不循环
    return 0;

这就是我们的运行截图

 5.游戏主体核心的实现

1)定义字符数组和初始化九宫格

//test.c源文件中的代码
void game()
{
	
	char board[ROW][COL] = { 0 };  //这里代码还是在test.c中
	InitBoard(board,ROW,COL);  //ROW,COL分别表示行和列(定义在头文件)
                               //这样可以让我们随心所欲的设置棋盘的行和列
 
}
//game.h头文件中的代码:
 
#define ROW 3
#define COL 3
 
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);

我需要将九宫格里全部初始化成为空格,在这里编写一下函数:

//game.c源文件中的代码

void init_board(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++)
        {
            board[i][j] = ' ';
        }
    }
}

2)打印棋盘

       初始化填充后,我们可以通过打印---和|来实现我们的棋盘,要注意右边和下边是没有封口的,运用两次循环,外循环打印行,内循环打印列,最终可以实现我们的棋盘。

//test.c源文件中的代码:
void game()
{
	char board[ROW][COL] = { 0 };
 
	InitBoard(board,ROW,COL);
 
	print_board(board, ROW, COL); //打印棋盘
}
//game.h头文件中的代码
 
#define ROW 3
#define COL 3
 
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//game.c源文件中的代码
 
void print_board(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 < col; j++)
			{
				printf("---");
				if(j < col - 1)
				printf("|");
			}
			printf("\n");
		}
	}
}

3)玩家下棋

设为*

//test.c源文件中的代码
 
void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	InitBoard(board,ROW,COL);
	print_board(board, ROW, COL);
	while (1)
	{
		PlayerBoard(board, ROW, COL);
		print_board(board, ROW, COL);  //下完棋就要打印一次棋盘,这样才能看见棋子落在哪里
	}
//game.h头文件中的代码
 
#define ROW 3
#define COL 3
 
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerBoard(char board[ROW][COL], int row, int col);
//game.c源文件中的代码
 
void PlayerBoard(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		printf("玩家请下棋:>");
		scanf("%d%d", &x, &y);
		if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';   //我们定义*为玩家的棋子
				break;
			}
			else
			{
				printf("该坐标已被占用,请重新输入\n");
			}
		}
		else
		{
			printf("非法坐标,请重新输入\n");
		}
	}
}

4)电脑下棋

设为#

//test.c源文件中的代码
 
void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	InitBoard(board,ROW,COL);
	print_board(board, ROW, COL);
	while (1)
	{
		PlayerBoard(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
	
		ComputerBoard(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
    }
	
 
}
//game.h头文件中的代码
 
#define ROW 3
#define COL 3
 
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerBoard(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);
//game.c源文件中的代码
 
void ComputerBoard(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
 
	while (1)
	{
		printf("电脑下棋:>\n");
		x = rand() % row;
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';   //规定#为电脑下的棋子
			break;
		}
	}
}

5)判断部分

        有四种情况就是玩家赢,电脑赢,平局,继续游戏,我们可以有一个返回值,根据返回值来判读,比如,玩家赢我们就返回’*‘,电脑赢我们就返回’#‘,平局就返回’Q‘,还要继续游戏就根据'C'来判断

//test.c源文件中的代码
 
void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	InitBoard(board,ROW,COL);
	print_board(board, ROW, COL);
	while (1)
	{
		PlayerBoard(board, ROW, COL);
		print_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')             //如果等于C了,说明还可以继续玩游戏,不等于了就退出循环
		{
			break;
		}
		ComputerBoard(board, ROW, COL);
		print_board(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");
	}
}

//game.h头文件中的代码
 
#define ROW 3
#define COL 3
 
//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
void print_board(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerBoard(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerBoard(char board[ROW][COL], int row, int col);
 
//判断输赢的情况
//玩家赢  就返回  '*'
//电脑赢  就返回  '#'
//平局    就返回  'Q'
//继续玩  就返回  'C'
char is_win(char board[ROW][COL], int row, int col);

//game.c源文件中的代码
 
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;
}
 
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][0] != ' ')
		{
			return board[i][0];
		}
	}
 
	// 判断竖三列
	for (i = 0; i < col; 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 (1 == is_full(board, ROW, COL))
	{
		return 'Q';           //返回Q说明棋盘已经满了,并且没人输赢,即平局
	}
	else
	{
		return 'C';           //返回C说明棋盘没有满,游戏继续
	}
}

大功告成!

下面看看效果吧

 代码!

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
	printf("*********************************\n");
	printf("***********1.play****************\n");
	printf("***********0.exit****************\n");
	printf("*********************************\n");
}

void game()
{
	char ret = 0;
	char board[ROW][COL];
	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 != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);
		print_board(board, ROW, COL);
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}

	}
	if (ret == '*')
		printf("玩家win\n");
	else if (ret == '#')
		printf("电脑win\n");
	else if (ret == 'Q')
		printf("平局\n");
	
}


//电脑WIN #
//玩家WIN *
//平局 Q
//游戏继续 C



void test()
{
	srand((unsigned int ) time(NULL));
	int input = 0;
	do
	{
		menu();
			printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			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

#include "game.h"

void init_board(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++)
		{
			board[i][j] = ' ';
		}
	}
}


//void print_board(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	for (i = 0; i < row; i++)
//	{
//		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//		if(i<row-1)
//		printf("---|---|---\n");
//	}
//
//}
void print_board(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++)
		{
			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 player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入要下棋的坐标");
		int i = 0, j = 0;
		scanf("%d %d", &i, &j);

		if (i >= 1 && i <= row && j >= 1 && j <= col)
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else
		{
			printf("您输入错误\n");
		}
	}
}


void computer_move(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:\n");
	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;
		if (board[x][y] == ' ');
		{board[x][y] = '#';
		break;
		}
	}
}
//is_full只在is_win用,所以不用声明
static 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][0]!= ' ')
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; 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 (is_full(board, row, col) == 1)
	{
		return 'Q';
	}
		return 'C';
}
//game.h
#pragma once
#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 init_board(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);

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值