三子棋的C语言实现(详解)

2023-12-15 15:32:08

三子棋的C语言实现(详解)

第一次见到三子棋好像是猪猪侠和菲菲公主,哈哈。
笔者今天学习并用C语言实现了这个简单的小游戏。
中间犯了许多小错误,比如
在这里插入图片描述
这个粗心直接跳出循环,也不报错,逐语句查了半天。
又比如do while结尾的分号没写,“=”和“==”
同时笔者也学习了两个新知识

如何产生随机数,rand(),srand()函数的用法

rand以种子为基准(种子是一个数),用一个递推公式算出的一系列数,来产生随机数。种子不变,rand函数产生的随机数是一样的。为了产生“真正的随机数”,用srand函数和time函数根据时间不同随机初始化种子。
srand可以根据不同参数初始化不同的随机数种子,比如在srand(1),srand(2)下,rand()产生的随机数是不同的。但为了“随机”,我们用时间戳,不同时间,srand的参数不一样即重置了种子。这样就达到了随机啦。

注意,

srand((unsigned)time(NULL));

放在循环体外面,重置一次种子就可以了,然后在循环中,rand产生第一个,第二个…随机数。

为什么呢?因为电脑运算速度很快,要是放在循环体里面,在很短的时间内,种子没有被重置,每次循环都打印该时间下对应的第一个随机数,也就是说,会打印相同的数。(笔者初学,错误请大佬指正)

memset函数的使用

memset(&board[0][0],' ',ROW*COL*sizeof(board[0][0]);
用在棋盘初始化中,见下面代码

分文件的代码具体实现和详细注释

//game.h
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.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 PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
char JudgingWin(char board[ROW][COL], int row, int col);
//game.c
#include"game.h"
#include<stdio.h>
//实现
void InitBoard(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] = ' ';//先都初始化空格,占个位置,不会让棋盘打印歪
		}
	}
	//memset(&board[0][0],' ',ROW*COL*sizeof(board[0][0]);
	//从首地址开始赋值空格,连续赋值这么多字节
	//包含<string.h>

}
//列固定不能动了
//void DisplayBoard(char board[ROW][COL], int row, int col);
//{
//	int i = 0;
//	int j = 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 DisplayBoard(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("|\n");
//		}
//		if(i<row-1)
//			printf(" ---|---|---\n");
//
//	}
//}
void DisplayBoard(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)
		{
			int j = 0;
			for (j = 0;j < col;j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
		}
		printf("\n");
	}
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;//存放坐标
	printf("请玩家下棋,输入想要下棋的坐标");
	scanf_s("%d %d", &x, &y);//遇到了scanf死循环。。。
	//站在用户角度,可没有什么在第零行下棋
	if (x > 0 && x <= row && y > 0 && y <= col)
	{
		//首先看一下坐标有没有被占用
		if (board[x - 1][y - 1] == ' ')
		{
			board[x-1][y-1] = 'O';//玩家的棋子O
		}
		else
		{
			printf("该处已经下过棋,请重新输入\n");
		}
	}
	else
	{
		printf("输入非法坐标,请重新输入\n");

	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("电脑下棋了\n");
	while (1)
	{
		x = rand() % row;//随机产生0,1,2
		y = rand() % col;
		if (board[x][y] ==' ')
		{
			board[x][y] = 'X';
			break;
		}
	}

}

char JudgingWin(char board[ROW][COL], int row, int col)
{
	//赢有四种情况,谁赢返回谁的棋子字符O或X,平局返回Q,继续返回C
	int i = 0;
	//第i行字符全部相同(但不能全是空),判赢
	for (i = 0;i < row;i++)
	{
		if (board[i][0] == board[i][1] && board[i][0] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	//第i列相同,判赢
	for (i = 0;i < col;i++)
	{
		if (board[0][i] == board[1][i] && board[0][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线同,判赢
	if (board[0][0] == board[1][1] && board[0][0] == board[2][2] && board[0][0] != ' ')
		{
			return board[0][0];
		}
	if (board[0][2] == board[1][1] && board[0][2] == board[2][0] && board[0][2] != ' ')
	{
		return board[0][2];
	}
	//棋盘已满,无赢则判平局,返回Q;棋盘未满,继续下,返回C
	for (i = 0;i < row;i++)
	{
		int j = 0;
		for (j = 0;j < col;j++)
		{
			if (board[i][j] == ' ')
				return 'C';
		}
		
	}
	return 'Q';
}

//test.c
#include<stdio.h>
#include"game.h"
void menu()
{
	printf("****************************************\n");
	printf("*********欢迎来玩三子棋游戏!***********\n");
	printf("***********输入1.开始游戏***************\n");
	printf("***********输入0.退出游戏***************\n");
	printf("****************************************\n");
}
void game()
{
	//用二维数组来存放数据
	char board[ROW][COL] = { 0 };//棋盘board
	//初始化棋盘
	InitBoard(board, ROW, COL);//方便改棋盘大小
	//显示(打印)棋盘
	DisplayBoard(board, ROW, COL);
	//循环 玩家下棋后,打印棋盘,判断输赢
	// 	   电脑下棋后,打印棋盘,判断输赢
	char ret = 0;
	//只要返回ret为C,电脑和人就继续下棋
	//返回ret为其他值时,跳出循环判断结局
	while (1)
	{
		PlayerMove(board, ROW, COL);//这里是调用函数,传参,可不是什么定义,申明,实现
		DisplayBoard(board, ROW, COL);
		ret = JudgingWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		ComputerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
		ret = JudgingWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	
	}
	if (ret == 'Q')
	{
		printf("已达成平局\n");
	}
	if (ret == 'O')
	{
		printf("恭喜!您成功地击溃了电脑\n");
	}
	if (ret == 'X')
	{
		printf("悲哀!您狠狠地输给了电脑\n");
	}
}
	
int main()
{
	int input = 0;//输入
	menu();
	srand((unsigned)time(NULL));//重置随机数种子
	do
	{
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
		default:
			printf("输入错误,请重新输入");
			break;
		}

	} while (input);//do while这个分号可不能丢!

		return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

文章来源:https://blog.csdn.net/m0_70541367/article/details/132719025
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。