三子棋及其拓展N子棋|C语言详解

目录

目录

1.什么是三子棋​​​​​​​

2.模块化和思路

3.各函数具体实现

1初始化数组

2打印棋盘

3玩家下棋

4电脑下棋

5判断输赢是否继续   

4.完整代码和四子棋运行结果


1.什么是三子棋

三子棋是一种民间传统游戏。将正方形对角线连起来,相对两边依次摆上三个双方棋子,只要将自己的三个棋子走成一条线,对方就算输了。但是,有很多时候会出现和棋的情况。

2.模块化和思路

实现三子棋主要可以通过二维数组和循环来实现,可以采用模块化的方式来制作。

 game.h的头文件里存放头文件,函数定义和自定义信息。

test.c 实现大体逻辑和游戏的主体功能。

game.c里面实现所有具体功能的函数。

test.c 大体逻辑:

 

 其中打印菜单和玩游戏封装为两个函数menu()和game(),在game.h声明,在game.c实现。

define的使用:

在三子棋中,可以用3*3二维数组来记录两边下子的情况,对应的四子棋应该是4*4.为了不用改大量代码可以利用#定义行数和列数。如下图:在game.h写上define 相关语句,在相关函数出都用ROW,COL代替3,4,5就可以了。最后只要修改这两处的3即可拓展为N子棋。

注意那game.c里也要进行引用#define"game.h"。

game()函数的大体思路:

主要封装五个函数:

1初始化数组
    init_arr(arr,ROW ,COL);
2打印棋盘
    print_board(arr, ROW, COL);

3玩家下棋
   player_game(arr, ROW, COL);
4电脑下棋
   computer_game(arr, ROW, COL);
5判断输赢是否继续   返回值char四种: *->电脑赢  #->玩家赢    c->继续(continue)  d->平局 (draw)
   judge_winner(arr, ROW, COL);

注:玩家下‘#’  电脑下‘*’

3.各函数具体实现

main函数  of  test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

int main()
{
	srand((unsigned int)time(NULL));//后面有用到随机数后面会回来补
	int flag = 0;
	do
	{
		menu();

		scanf("%d", &flag);

		if (1 == flag)
		{
			system("cls");
			game();
			
		}
		else if (0 == flag)
		{
			printf("退出游戏\n");
		}
		else
		{
			printf("请输入有效数字!\n");
		}

	} while (flag);
	return 0;
}

menu和game函数(封装五个函数)   of game.c

void menu()
{
	printf("---------welcom!---------\n");
	printf("---------1.play ---------\n");
	printf("---------0.exit ---------\n");
	printf("-----请输入你的选择:>----\n");
}
//开始游戏
void game()
{
	//0.创建数组并初始化
	char arr[ROW][COL];
	init_arr(arr,ROW ,COL);
	//1.打印棋盘
	print_board(arr, ROW, COL);
	//2.循环下棋
	char flag = 0;
	do {

		player_game(arr, ROW, COL);
		
		flag = judge_winner(arr, ROW, COL);
		if (flag != 'c')
			break;

		computer_game(arr, ROW, COL);
		
        flag = judge_winner(arr, ROW, COL);
		if (flag != 'c')
			break;

	} while (1);

	if (flag == '*')
		printf(" 很遗憾,你输了。\n\n\n");
	else if (flag == '#')
		printf(" 恭喜你,你赢了! \n\n\n");
	else
	{
		printf(" 平局,游戏结束。\n\n\n");
	}

	/*
	
	//3.玩家下棋
	player_game(arr, ROW, COL);
	//4.电脑下棋
	computer_game(arr, ROW, COL);
	//5.判断输赢   *-电脑赢  #-玩家赢    c-继续 d-平局 
	judge_winner(arr, ROW, COL);
	
	*/

}

封装的五个函数 实现  of  game.c

1初始化数组


    init_arr(arr,ROW ,COL); //函数声明放到game.h

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

注释:全部初始化为字符空格,打印原始棋盘好对齐


2打印棋盘


    print_board(arr, ROW, COL);//函数声明放到game.h

​
void print_board(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//第i行
		int j = 0;
        //打印每组的字符
		for (j = 0; j < col; j++)
		{
			printf(" %c ", arr[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");
	}
}

​

注:每个字符旁边打两个格,每i行下面打一排分隔符,最后一行不要分隔符。

以七子棋棋盘为例:

3玩家下棋


   player_game(arr, ROW, COL);//函数声明放到game.h

void player_game(char arr[ROW][COL], int row, int col)
{
	int i = 0; 
	int j = 0;
	do {
		printf("请输入您要下棋的坐标:>");
		scanf("%d %d", &i, &j);
		if (i > 0 && i < row + 1 && j>0 && j < col +1)
		{
			if (arr[i - 1][j - 1] == ' ')
			{
				arr[i - 1][j - 1] = '#';
				break;
			}
			else
			{
				printf("当前坐标已被占用,请重新输入\n");
			}

		}
		else
		{
			printf("您输入的坐标不合法,请重新输入\n");
		}
		
	} while (1);
	
	print_board(arr, ROW, COL);
}

注:为了防止两种情况,一种已经下过了,一种坐标超过范围了,需要循环输入,直到下成功。

还要注意,玩家以为的坐标范围是1-N,1-N。而我们数组是0-N-1,需要减一。

最后要记得打印出棋盘。


4电脑下棋


   computer_game(arr, ROW, COL);//函数声明放到game.h

​
void computer_game(char arr[ROW][COL], int row, int col)
{
	
	printf("电脑下棋:>");
	Sleep(700);
	
	do {

		int i = rand() % row;
		int j = rand() % row;
		
		if (arr[i][j] == ' ')
		{
			arr[i][j] = '*';
			printf("(%d ,%d)\n", i + 1, j + 1);
			break;
		}
	} while (1);

	print_board(arr, ROW, COL);

}

​

注:用随机数实现产生坐标,为了避免坐标已经下过,用循环实现。最后要记得打印出棋盘。


5判断输赢是否继续   


   judge_winner(arr, ROW, COL);//函数声明放到game.h

char judge_winner(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//检验第i行
		int j = 0;
		int sum = 0;
		for (j = 0; j < col; j++)
		{
			sum += arr[i][j];
		}
		if (sum == 35 * col)
			return '#';
		if (sum == 42 * col)
			return '*';
	}

	 i = 0;
	for (i = 0; i < row; i++)
	{
		//检验第i列
		int j = 0;
		int sum = 0;
		for (j = 0; j < col; j++)
		{
			sum += arr[j][i];
		}
		if (sum == 35 * col)
			return '#';
		if (sum == 42 * col)
			return '*';
	}

	 i = 0;
	int sum = 0;
	for (i = 0; i < row; i++)
	{
		sum += arr[i][i];
	}
	if (sum == 35 * col)
		return '#';
	if (sum == 42 * col)
		return '*';


	 i = 0;
	int j = col - 1;
	 sum = 0;
	for (i = 0, j = col - 1; i < row; i++, j--)
	{
		sum += arr[i][j];
	}
	if (sum == 35 * col)
		return '#';
	if (sum == 42 * col)
		return '*';


	 i = 0;
	 j = 0;
	int flag = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (arr[i][j] == ' ')
				return 'c';

		}
	}
	return 'd';
}

注:为了实现N子棋,可以把值加在一起,# *连了的话就会等于35*col 或者42*col。

分四种:行 列 两条对角线  每一种都需要遍历

4.完整代码和四子棋运行结果

game.h:

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include<time.h>

#define ROW 3
#define COL 3

//菜单打印
void menu();

//开始游戏
void game();

void init_arr(char arr[ROW][COL],int row,int col);

void print_board(char arr[ROW][COL], int row, int col);

void player_game(char arr[ROW][COL], int row, int col);

void computer_game(char arr[ROW][COL], int row, int col);

char judge_winner (char arr[ROW][COL], int row, int col);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

//菜单打印
void menu()
{
	printf("---------welcom!---------\n");
	printf("---------1.play ---------\n");
	printf("---------0.exit ---------\n");
	printf("-----请输入你的选择:>----\n");
}
//开始游戏
void game()
{
	//0.创建数组并初始化
	char arr[ROW][COL];
	init_arr(arr,ROW ,COL);
	//1.打印棋盘
	print_board(arr, ROW, COL);
	//2.循环下棋
	char flag = 0;
	do {

		player_game(arr, ROW, COL);
		
		flag = judge_winner(arr, ROW, COL);
		if (flag != 'c')
			break;

		computer_game(arr, ROW, COL);
		
		flag = judge_winner(arr, ROW, COL);
		if (flag != 'c')
			break;

	} while (1);

	if (flag == '*')
		printf(" 很遗憾,你输了。\n\n\n");
	else if (flag == '#')
		printf(" 恭喜你,你赢了! \n\n\n");
	else
	{
		printf(" 平局,游戏结束。\n\n\n");
	}

	/*
	
	//3.玩家下棋
	player_game(arr, ROW, COL);
	//4.电脑下棋
	computer_game(arr, ROW, COL);
	//5.判断输赢   *-电脑赢  #-玩家赢    c-继续 d-平局 
	judge_winner(arr, ROW, COL);
	
	*/

}


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

void print_board(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//第i行
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", arr[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_game(char arr[ROW][COL], int row, int col)
{
	int i = 0; 
	int j = 0;
	do {
		printf("请输入您要下棋的坐标:>");
		scanf("%d %d", &i, &j);
		if (i > 0 && i < row + 1 && j>0 && j < col +1)
		{
			if (arr[i - 1][j - 1] == ' ')
			{
				arr[i - 1][j - 1] = '#';
				break;
			}
			else
			{
				printf("当前坐标已被占用,请重新输入\n");
			}

		}
		else
		{
			printf("您输入的坐标不合法,请重新输入\n");
		}
		
	} while (1);
	
	print_board(arr, ROW, COL);
}

void computer_game(char arr[ROW][COL], int row, int col)
{
	
	printf("电脑下棋:>");
	Sleep(700);
	
	do {

		int i = rand() % row;
		int j = rand() % col;
		
		if (arr[i][j] == ' ')
		{
			arr[i][j] = '*';
			printf("(%d ,%d)\n", i + 1, j + 1);
			break;
		}
	} while (1);

	print_board(arr, ROW, COL);

}


char judge_winner(char arr[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//检验第i行
		int j = 0;
		int sum = 0;
		for (j = 0; j < col; j++)
		{
			sum += arr[i][j];
		}
		if (sum == 35 * col)
			return '#';
		if (sum == 42 * col)
			return '*';
	}

	 i = 0;
	for (i = 0; i < row; i++)
	{
		//检验第i列
		int j = 0;
		int sum = 0;
		for (j = 0; j < col; j++)
		{
			sum += arr[j][i];
		}
		if (sum == 35 * col)
			return '#';
		if (sum == 42 * col)
			return '*';
	}

	 i = 0;
	int sum = 0;
	for (i = 0; i < row; i++)
	{
		sum += arr[i][i];
	}
	if (sum == 35 * col)
		return '#';
	if (sum == 42 * col)
		return '*';


	 i = 0;
	int j = col - 1;
	 sum = 0;
	for (i = 0, j = col - 1; i < row; i++, j--)
	{
		sum += arr[i][j];
	}
	if (sum == 35 * col)
		return '#';
	if (sum == 42 * col)
		return '*';


	 i = 0;
	 j = 0;
	int flag = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (arr[i][j] == ' ')
				return 'c';

		}
	}
	return 'd';
}

test.c:

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
int main()
{
	srand((unsigned int)time(NULL));
	int flag = 0;
	do
	{
		menu();

		scanf("%d", &flag);

		if (1 == flag)
		{
			system("cls");
			game();
			
		}
		else if (0 == flag)
		{
			printf("退出游戏\n");
		}
		else
		{
			printf("请输入有效数字!\n");
		}

	} while (flag);
	return 0;
}

拓展为四子棋运行结果:

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值