c语言小游戏----改版斗兽棋

一、项目背景

       此游戏是笔者大二第一学期时受好友之托,重拾c语言编写的小程序,这篇文章主要介绍Game中的游主体逻辑部分。程序主体多用if-elsewhilefor等关键字,适合c语言初学者阅读,若有疑问或bug或建议可评论指出。

 

二、编程环境

笔者用的是  Visual Studio 2019,调用库有:

#include <iostream>
#include <windows.h>    
#include <conio.h>   

三、规则介绍

四、程序主体

1、chess结构体

struct chess {
    int player;  // 1  A电脑   2  B人类    0   棋盘
    int ani;     // 8方块  7象(E)  6虎(T)  5狮(L)  4狼(W)  3狗(D)  2猫(C)  1鼠(M)  0空  
}Board[Vol * Vol], PlayB;   

PlayB使用户控制可以移动的方块棋子,Board是组成棋盘的各个棋子。

player的值代表这个棋子属于哪一方,ani的值代表这个棋子是空还是动物还是方块(方块的player为0)。

2、主要函数:

       其中关于UI设计的六个函数分别有着隐藏光标定位绘制棋盘绘制方框绘制棋子展示提示的作用;Init部分的三个函数重绘棋盘,让数据初始化,便于重新开始;Game部分的三个函数分别是游戏主体逻辑比较棋子大小游戏结束

3、游戏主体逻辑

(1)结构

       可以观察到,当数据初始化完成后,就进入了循环输入反馈的游戏主体中。而根据输入,有三种反馈,分别是方块棋子的移动空格选中或取消棋子召唤己方动物。在反馈结束后,根据f(判断棋子互动有无的标志)判断是否进行棋子互动。若达到结束条件,则结束游戏。

(2)小键盘移动

// 上下左右移动
if (ch_1 == -32) {
	ch_2 = _getch();
	switch (ch_2) {
	case 72:y == 1 ? y = Vol : y--; break;
	case 75:x == 1 ? x = Vol : x--; break;
	case 80:y == Vol ? y = 1 : y++; break;
	case 77:x == Vol ? x = 1 : x++; break;
	default:break;}

       在用_getch()(在头文件conio.h)获得上下左右键的键值时候,他们是双键值,会返回高八位和低八位的int型数值。经测试,返回的第一个数值为-32,第二个数值上72左75下80右77。这里采用的是碰壁返回另一边的碰壁逻辑。

(3)空格选中棋子

else if (ch_1 == ' ') {
    if (PlayB.player == 0) {//手上无棋子,需拿起棋子
	    if (Board[(x - 1) * Vol + y - 1].player == 2) {
		    PlayB.ani = Board[(x - 1) * Vol + y - 1].ani;
		    PlayB.player = Board[(x - 1) * Vol + y - 1].player;
		    Board[(x - 1) * Vol + y - 1].player = Board[(x - 1) * Vol + y - 1].ani = 0;
		    Chess(x, y, PlayB);
		    tips = 4;
	    }
    }
    else if (PlayB.player == 2) {
	    if (Board[(x - 1) * Vol + y - 1].player == 2)
		    tips = 5;
	    else if (Board[(x - 1) * Vol + y - 1].player == 0) {
		    Board[(x - 1) * Vol + y - 1].ani = PlayB.ani;
	    	Board[(x - 1) * Vol + y - 1].player = PlayB.player;
		    PlayB.ani = 8;
	    	PlayB.player = 0;
	    	Chess(x, y, PlayB);
	    	tips = 6;
	    }
	    else if (Board[(x - 1) * Vol + y - 1].player == 1) {
	    	f = PlayB.ani;
	    	PlayB.ani = 8;
		    PlayB.player = 0;
	    }
    }
}

       首先判断手上是否有棋子,根据方块棋子的player属性判断其为方块还是己方动物,否则不响应。若为方块,则可以拿起棋子,当落点所属玩家为人类时,落点棋盘上的棋子属性变为空(皆0),手上方块属性变为己方动物属性。若为己方动物,则按下空格视为落子,若落子处为,则直接落子,与提子为反逻辑;若落子处为敌方动物,则成功落子并进行棋子互动;若落子处为己方动物,则会提示无法落子

(4)召唤棋子

// 召唤己方棋子
switch (ch_1) {
case 'e':case 'E':Allchess[6] = Allchess[6] > 0 ? Allchess[6] - 1 : -1; f = 7; break;
case 't':case 'T':Allchess[5] = Allchess[5] > 0 ? Allchess[5] - 1 : -1; f = 6; break;
case 'l':case 'L':Allchess[4] = Allchess[4] > 0 ? Allchess[4] - 1 : -1; f = 5; break;
case 'w':case 'W':Allchess[3] = Allchess[3] > 0 ? Allchess[3] - 1 : -1; f = 4; break;
case 'd':case 'D':Allchess[2] = Allchess[2] > 0 ? Allchess[2] - 1 : -1; f = 3; break;
case 'c':case 'C':Allchess[1] = Allchess[1] > 0 ? Allchess[1] - 1 : -1; f = 2; break;
case 'm':case 'M':Allchess[0] = Allchess[0] > 0 ? Allchess[0] - 1 : -1; f = 1; break;
case 'g':case 'G':end = 1; break;
default:break;
}

     召唤棋子即召唤手中动物到棋盘上,因手中动物每种各两只,所以需要进行计数处理,并赋值f,进行棋子互动。其中按下G键游戏提前结束。

(5)棋子互动

if (f) 
{
	if (Allchess[f - 1] > -1) {//手上还有棋子吗?
		if (Board[(x - 1) * Vol + y - 1].player == 1) {//该位置有敌方棋子
			int flag = Compare(f, Board[(x - 1) * Vol + y - 1].ani);
			if (flag == 2) { //两子皆亡
				Achess[Board[(x - 1) * Vol + y - 1].ani - 1]--;
				Bchess[f - 1]--;
				Board[(x - 1) * Vol + y - 1].ani = Board[(x - 1) * Vol + y - 1].player = 0;
				tips = 2;
				sumA--; sumB--;
			}
			else if (flag == 1) {//人类获胜!
				Achess[Board[(x - 1) * Vol + y - 1].ani - 1]--;
				Board[(x - 1) * Vol + y - 1].ani = f;
				Board[(x - 1) * Vol + y - 1].player = 2;
				tips = 3;
				sumA--;
			}
			else {//电脑获胜
				Bchess[f - 1]--;
				tips = 1;
				sumB--;
			}
		}
		else if (Board[(x - 1) * Vol + y - 1].player == 0) { //该地无棋子
			Board[(x - 1) * Vol + y - 1].ani = f;
			Board[(x - 1) * Vol + y - 1].player = 2;
			tips = 6;
		}
		else if (Board[(x - 1) * Vol + y - 1].player == 2) { //该地有己方棋子
			Allchess[f - 1]++;
			tips = 5;
		}
	}
	else
		tips = 9;
	f = 0;
	Chess(x, y, Board[(x - 1) * Vol + y - 1]);
}

        棋子互动首先判定手中是否有棋子,若无则f=0,跳出互动;

       若手中有棋子,则根据落点棋子player属性互动。若落点棋子为,则直接落子;若落点棋子为己方棋子,则因该位置已满,无法放入,棋子回到手中,计数器+1;若落点棋子为敌方棋子,则进行比较,有以下三种结果:被吃,吃,同归于尽。同时相应计数器-1。

4、cheat处理及颜色

if (cheat)
	switch (board.ani) {
	case 7:printf(RED"E " NONE); break;
	case 6:printf(RED"T " NONE); break;
	case 5:printf(RED"L " NONE); break;
	case 4:printf(RED"W " NONE); break;
	case 3:printf(RED"D " NONE); break;
	case 2:printf(RED"C " NONE); break;
	case 1:printf(RED"M " NONE); break;
	default:break;
	}
else
	printf(RED"●" NONE);

若cheat为1,则敌方棋子为已知,否则为未知。(方便测试时用)

加上如下宏定义,可以输出不同颜色的字体:

#define RED  "\033[0;32;31m"                      //字体红色
#define NONE "\033[m"                             //字体无色

五、结语

难度中规中矩,适合c语言初学者新手上路,该题另有复盘要求:

 可作为读者的小练习。代码放在评论区。

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
C语言的词法分析程序主要用于对源程序进行分析,将源程序中的各种单词进行分类提取。根据引用和引用中提供的信息,词法分析程序可以将源程序中的关键字、自定义标识符、整数、界符和运算符进行分析和提取。 关键字包括main、if、else、for、while和int等。自定义标识符是除了关键字之外的标识符。整数是无符号的整数。界符包括大括号{}、小括号()、逗号,和分号;。运算符包括等号=、减号-、乘号*、除号/、小于号<、左移运算符<<、大于等于>=、等于==和不等于!=等。 在编写词法分析程序时,可以使用字符串处理函数,例如gets、strcpy和strcmp等,来从键盘获取源程序输入,并对字符串进行复制和比较操作,以便进行单词的分类和提取。 通过词法分析程序,可以将源程序中的各种单词按照其类型进行分类,并提取出来,从而为后续的语法分析和语义分析提供基础。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [小C语言--词法分析程序](https://blog.csdn.net/wq3699823668/article/details/100599572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [A - 小C语言--词法分析程序](https://blog.csdn.net/Mercury_Lc/article/details/108685127)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [词法分析源程序(c语言编写)](https://download.csdn.net/download/wviyong/1797051)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

XiDelilA

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

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

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

打赏作者

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

抵扣说明:

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

余额充值