初阶c语言:实战项目三子棋

前言

大家已经和博主学习有一段时间了,今天讲一个有趣的实战项目------三子棋

目录

前言

制作菜单

构建游戏选择框架

实现游戏功能

模块化编程

初始化棋盘

打印棋盘

玩家下棋

电脑下棋

时间戳:推荐一篇

C语言生成随机数的方法_c语言随机数_杯浅的博客-CSDN博客

判断输赢

游戏逻辑实现


制作菜单

在玩游戏时,我们在进入游戏都会有菜单选项,选择开始游戏,推出游戏等这些指令,说到选择,那么我们可以依据我们所学的循环和分支语句来先完成基本框架的设计。

首先我们进入游戏都是先显示选项,做出选择,并且在玩游戏时玩一局,还想玩怎么办(想一想我们前边的知识哪种结构符合先进入游戏出现菜单再循环这一需求)那肯定是do...while的循环结构更符合,那么我们就先使用函数来打印输出一个菜单选项

cpp 复制代码
void menu()
{
	printf("*****************************\n");
	printf("*****************************\n");
	printf("**********1.play^************\n");
	printf("**********0.exit^************\n");//菜单
	printf("*****************************\n");
	printf("*****************************\n");
}

int main()
{int a = 0;
    do
 {
  menu();
  printf("请选择:");
  scanf("%d",&a);

 
 }while();  
return 0;
}

构建游戏选择框架

游戏菜单已在屏幕上显示完成,现在需要完成选择,并且在玩游戏时玩一局,还想玩怎么办。

这时候需要应用博主之前阐述的switch语句来实现:

cpp 复制代码
int main()
{
	int input = 0;
	do
	{
		menu();
		printf("PLEASE SELECT:");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			game();    //以上为界面的选择
			break;
		case 0:
			printf("Exit\n");
			break;
		default:
			printf("ERRO,PLEASE CHOOSE AGAIN\n");
			break;
		}
	} while (input);//while循环可以利用0为假,其余为来实现用户可反复选择
//直到选到合适为止
	return 0;
}                     

实现游戏功能

模块化编程

这里博主引入一个概念:模块化编程。方便引用,不会显得头重脚轻,而且转为静态库不易被盗用。这里需要创建三个文件:test.c game.c game.h

test.c:是用来实现游戏逻辑 game.c:用来实现游戏功能的函数 game.h:用来申明游戏功能函数(可引用)

传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。

模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等。

传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。

模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等!

总的来说就是:当你代码比较多的时候,就可以采用模块化编程来完成这个程序。

三子棋,我们需要在棋盘中输入要下的位置,相当于是一个三乘三的数组(这里我们就用到了二维数组的知识),那么游戏开始前需要我们先对棋盘初始化(使数组中的元素都为空格),那么就是数组初始化赋值(只用循环遍历每一个元素并赋予空格就ok了)。

注意: 这里设置函数的时候因为用到二维数组,所以函数的形参为数组名,行 ,列

cpp 复制代码
void initboard(char board[row][col], int hang, int lie)
{
	int i = 0;

	int j = 0;

	for (i = 0; i < hang; i++)
	{
		for (j = 0; j <lie; j++)
		{
			board[i][j] =' ';
		}	
		printf("\n");
	}
}

打印棋盘

将置空的二维数组用线隔开

cpp 复制代码
void displayboard(char board[row][col], int hang, int lie) //可以随意控制棋盘大小
{
	int i = 0;
	for (i = 0; i <hang; i++)
	{
		int j = 0;
		for (j = 0; j <lie; j++)
		{
			printf(" %c ",board[i][j]);
			if (j < lie - 1)//为了不让最后一行打印'|'
			printf("|");
		}
		printf("\n");
		if (i < hang - 1)
		{
			int j = 0;
			for (j = 0; j < lie; j++)
			{
				printf("---");
				if (j < lie - 1)
				printf("|");
			}
			printf("\n");
		}
	}
}

++效果图++

玩家下棋

玩家下棋的话使用*标志,利用坐标来将"空格"替换

cpp 复制代码
void player(board[row][col],int hang,int lie)
{
    int x = 0;
    int y = 0;
printf("玩家开始下棋");
scanf("%d %d",&a,&b);
if(x>=1&&x<=3&&y>=1&&y<=3)   
{  
   if(board[x-1][y-1]==' ')
      {board[x-1][y-1]='*';}
    else
{printf("坐标已经被占用,请重新选择");}
    else
{printf("坐标非法请重新输入");}
 }   
}

玩家下完棋需要有对立面,也就是我们的电脑

电脑下棋

时间戳:推荐一篇

C语言生成随机数的方法_c语言随机数_杯浅的博客-CSDN博客

cpp 复制代码
void computer(char board[row][col], int hang, int lie)
{
	printf("电脑下棋\n");
	int x = 0;
	int y = 0;
	while(1)
	{ 
	x = rand() % hang;//0-2//模取余数不会超过这个数
	y = rand() % lie;
	if (board[x][y] ==' ')
	{
		board[x][y] = '#';
		break;
	}
	}
}

判断输赢

输赢情况分析:行三连,列三连,对角线俩条。

cpp 复制代码
char panduan(char board[row][col], int hang, int lie)
{
	int i = 0;
	for (i = 0; i < hang; i++)//行
	{
		if(board[i][0]==board[i][1]&&board[i][1]==board[i][2] && board[i][1] != ' ')
		{
			return board[i][1];//电脑和玩家都可以用这一个判断
		}
	}
	int j = 0;
	for (j = 0; j< lie; j++)//列
{
	if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	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 (isfull(board, hang, lie))
	{
		return 'q';//平局 else
	}	
	return 'c';
}

游戏逻辑实现

创建菜单函数选择 进入游戏 以及 退出游戏。

首先,初始化 棋盘。

然后,再打印棋盘。注意:一定是要先进行 初始化 然后再 打印棋盘。

玩家下棋,并打印出棋盘(玩家输入行、列坐标方式进行落子,'x' = 玩家落子)

判断玩家是否 赢,判断是否 继续游戏。(字符'c'代表 继续游戏、字符'q'代表 游戏平局)

电脑进行落子下棋(随机位置进行落子,'o' = 电脑落子)

判断③种胜负方式!分别是:玩家赢、电脑赢、以及 平局。

然后,再回到步骤①,是否选择 进入游戏 以及 退出游戏。

cpp 复制代码
void game()
{
	int key = 0;
	char board[row][col] = { 0 };   //不直接写成数字,利于改变棋盘大小
	//初始化棋盘的函数
	initboard(board,row,col);
	displayboard(board,row,col);
	while(1)
	{
		player(board, row, col);
		key=panduan(board, row, col);
		if(key!='c')
		{
			break;
		}
		displayboard(board, row, col); 
		computer(board, row, col);
		key = panduan(board, row, col);
		if (key != 'c')
		{
			break;
		}
		displayboard(board, row, col);
	}	
	if (key == '*')
	{
		printf("玩家胜利\n");
	}
	else if(key=='#')
	{
		printf("电脑胜利\n");
	}
	else if(key=='p')
	{
		printf("平局\n");
	}
}

另外我们还需要将game.c以声明的形式放入game.h中:

cpp 复制代码
#pragma once
#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<time.h>//这个全可以调用
#define row 3
#define col 3
//初始化棋盘
void initboard(char board[row][col], int hang, int lie);
//打印棋盘 难点
void displayboard(char board[row][col], int hang, int lie);
//玩家下棋
void player(char board[row][col], int hang, int lie);
//电脑下棋
void computer(char board[row][col], int hang, int lie);
//判断输赢  玩家赢  电脑赢  平  继续/
char panduan(char board[row][col], int hang, int lie);
int isfull(char board[row][col], int hang, int lie);

之后利用test.c来实现游戏逻辑(在编辑的开始需要加上#include''game.h'')

好了今天的文章到这里,希望对大家有帮助!

相关推荐
前端青山14 分钟前
React事件处理机制详解
开发语言·前端·javascript·react.js
black0moonlight1 小时前
ISAAC Gym 7. 使用箭头进行数据可视化
开发语言·python
maknul1 小时前
【学习笔记】AD智能PDF导出(装配文件)
笔记·学习·pdf
时光の尘2 小时前
C语言菜鸟入门·关键字·int的用法
c语言·开发语言·数据结构·c++·单片机·链表·c
坊钰2 小时前
【Java 数据结构】时间和空间复杂度
java·开发语言·数据结构·学习·算法
pq113_62 小时前
ftdi_sio应用学习笔记 4 - I2C
笔记·学习·linux驱动·ftdi_sio
Edward-tan2 小时前
c语言数据结构与算法--简单实现线性表(顺序表+链表)的插入与删除
c语言·开发语言·链表
武昌库里写JAVA2 小时前
一文读懂Redis6的--bigkeys选项源码以及redis-bigkey-online项目介绍
c语言·开发语言·数据结构·算法·二维数组
苹果酱05672 小时前
windows安装redis, 修改自启动的redis服务的密码
java·开发语言·spring boot·mysql·中间件
蒟蒻的贤3 小时前
vue11.22
开发语言·前端·javascript