c语言练习 三子棋

本部分包含数组练习题三子棋。

test.c-三子棋的测试

game.c-三子棋的实现

game.h-三子棋的函数声明

代码部分:

game.h

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define ROW 3
#define COL 3
//初始化二维数组
void InitArr(char arr[ROW][COL],int row,int col);
//打印棋盘
void PrintArr(char arr[ROW][COL], int row, int col);
//玩家走
void PlayerMove(char arr[ROW][COL], int row, int col);
//电脑走
void AiMove(char arr[ROW][COL], int row, int col);
//判断输赢
//玩家赢返回--'x'
//电脑赢返回--'o'
//平局返回--'c'
//继续游戏返回--'g'
char isWin(char arr[ROW][COL], int row, int col);
char isFull(char arr[ROW][COL], int row, int col);

game.c

#include"game.h"
//初始化二维数组
void InitArr(char arr[ROW][COL], int row,int col)
{
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < col;j++)
		{
			arr[i][j] = ' ';
		}
	}
}
//打印棋盘
void PrintArr(char arr[ROW][COL], int row, int col)
{
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < col+1;j++)
		{
			printf("+");
			if(j<col)
			printf("---");
		}
		printf("\n");
		for (int j = 0;j < col+1;j++)
		{
			printf("|");
			if (j < col )
			printf(" %c ", arr[i][j]);
		}
		printf("\n");
	}
	for (int j = 0;j < col + 1;j++)
	{
		printf("+");
		if (j < col)
			printf("---");
	}
	printf("\n");
}
//玩家走
void PlayerMove(char arr[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = 0;
		int y = 0;
		printf("玩家输入:");
		scanf("%d %d", &x, &y);
		if (x > 0 && x <= ROW && y > 0 && y <= COL)
		{
			if (arr[x - 1][y - 1] == ' ')
			{
				arr[x - 1][y - 1] = 'x';
				break;
			}
			else
			{
				printf("已被占用,请重下\n");
			}
		}
		else
		{
			printf("下错了,请重下\n");
		}
	}
}
//电脑走
void AiMove(char arr[ROW][COL], int row, int col)
{
	printf("电脑走\n");

	while (1)
	{
		int x = rand() % ROW;
		int y = rand() % COL;
		if (arr[x][y] == ' ')
		{
			arr[x][y] = 'o';
			break;
		}
	}
}
//判断输赢
char isWin(char arr[ROW][COL], int row, int col)
{
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < col;j++)
		{
			//一行有三个
			if (arr[i][j] == arr[i][j + 1] && arr[i][j + 1] == arr[i][j + 2] && arr[i][j + 1] != ' ')
			{
				return arr[i][j];
			}
			//一列有三个
			else if (arr[i][j] == arr[i + 1][j] && arr[i + 1][j] == arr[i + 2][j] && arr[i + 1][j] != ' ')
			{
				return arr[i+1][j];
			}
			//斜杆有三个
			else if (arr[i][j] == arr[i + 1][j + 1] && arr[i + 1][j + 1] == arr[i + 2][j + 2] && arr[i + 1][j + 1] != ' ')
			{
				return arr[i+1][j+1];
			}
			else if (arr[i][j] == arr[i - 1][j - 1] && arr[i - 1][j - 1] == arr[i - 2][j - 2] && arr[i - 1][j - 1] != ' ')
			{
				return arr[i-1][j-1];
			}
		}
	}
	//平局			
	return isFull(arr, ROW, COL);
}

char isFull(char arr[ROW][COL], int row, int col)
{
	for (int i = 0;i < row;i++)
	{
		for (int j = 0;j < col;j++)
		{
			if (arr[i][j] == ' ')
				return 'g';
		}
	}
	return 'c';
}

test.c

#include"game.h"

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

void game()
{
	//创建二维数组
	char arr[ROW][COL];
	//初始化二维数组
	InitArr(arr,ROW,COL);
	//打印棋盘
	PrintArr(arr,ROW,COL);
	char ret = 0;
	while (1)
	{
		//玩家走
		PlayerMove(arr, ROW, COL);
		PrintArr(arr, ROW, COL);
		ret=isWin(arr, ROW, COL);
		if (ret != 'g')
			break;
		//电脑走
		AiMove(arr, ROW, COL);
		PrintArr(arr, ROW, COL);
		ret=isWin(arr, ROW, COL);
		if (ret != 'g')
			break;
	}
	if (ret == 'x')
		printf("玩家胜利\n");
	else if (ret == 'o')
		printf("电脑胜利\n");
	else if (ret == 'c')
		printf("平局\n");
}

int main()
{
	//数组练习题
	//三子棋
	int input = 0;
	srand((unsigned int)time(NULL));

	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);
	
}

笔记:

  • 数组
    • 5.1 概述
      • 所谓数组,就是一个集合,里面存放了相同类型的数据元素
      • 特点1:数组中的每个数据元素都是相同的数据类型
      • 特点2:数组是由连续的内存位置组成的
      • 例图:

    • 5.2 一维数组
      • 5.2.1 一维数组定义方式
        • 一维数组定义的三种方式:
          • 数据类型 数组名[ 数组长度 ];
          • 数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
          • 数据类型 数组名[ ] = { 值1,值2 ...};
        • 图示:

        • 注意:如果在初始化数据的时候,没有全部填写完,会用0来填补剩余数据+数组长度必须是常量
        • 总结1:数组名的命名规范与变量名命名规范一致,不要和变量重名
        • 总结2:数组中下标是从0开始索引
      • 5.2.2 一维数组数组名
        • 一维数组名称的用途:
          • 1.可以统计整个数组在内存中的长度
          • 2.可以获取数组在内存中的首地址
        • 注意:数组名是常量,因此不可以赋值
        • 总结1:直接打印数组名,可以查看数组所占内存的首地址
        • 总结2:对数组名进行sizeof,可以获取整个数组占内存空间的大小
      • 5.2.3 冒泡排序
        • 作用: 最常用的排序算法,对数组内元素进行排序
          • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
          • 对每一对相邻元素做同样的工作,执行完毕后,找到第一个最大值。
          • 重复以上的步骤,每次比较次数-1,直到不需要比较
    • 5.3 二维数组
      • 二维数组就是在一维数组上,多加一个维度。
      • 5.3.1 二维数组定义方式
        • 二维数组定义的四种方式:
          • 数据类型 数组名[ 行数 ][ 列数 ];
          • 数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
          • 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
          • 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
        • 建议:以上4种定义方式,利用第二种更加直观,提高代码的可读性
        • 总结:在定义二维数组时,如果初始化了数据,可以省略行数
      • 5.3.2 二维数组数组名
        • 二维数组名称的用途:
          • 1.查看二维数组所占内存空间
          • 2.获取二维数组首地址
    • 5.4 数组&函数
      • 传递数组给函数
        • 可以通过指定不带下标(索引)的数组名来传递一个指向数组的指针
        • 传数组给一个函数,数组类型自动转换为指针类型,因而传的实际是地址
        • 数组作为参数的三种方式
          • 1.形式参数是一个指针:void myFunction(int *param)
          • 2.形式参数是一个已定义大小的数组:void myFunction(int param[10])
          • 3.形式参数是一个未定义大小的数组:void myFunction(int param[])
      • 从函数返回数组
        • C++ 不允许返回一个完整的数组作为函数的参数。但是,您可以通过指定不带索引的数组名来返回一个指向数组的指针。
        • 如果您想要从函数返回一个一维数组,您必须声明一个返回指针的函数。
          • 例子:int * myFunction()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ohrkaninchen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值