一、背景

马上过春节了,在家闲暇时间,看到了别人php写的一个命令行游戏,直接拿过来用c语音实现了一下哈。

二、相关知识

1、CLI颜色打印方法,使用printf控制就行,以下从网上收录了一些常用的颜色码:

打印格式为:

printf("\033[字背景颜色;字体颜色m字符串\033[0m");

40: 黑 30: 黑

41: 红 31: 红

42: 绿 32: 绿

43: 黄 33: 黄

44: 蓝 34: 蓝

45: 紫 35: 紫

46: 深绿 36: 深绿

47: 白色 37: 白色

2、CLI的控制码

\033[0m 关闭所有属性

\033[1m 设置高亮度

\03[4m 下划线

\033[5m 闪烁

\033[7m 反显

\033[8m 消隐

\033[30m -- \033[37m 设置前景色

\033[40m -- \033[47m 设置背景色

\033[nA 光标上移n行

\03[nB 光标下移n行

\033[nC 光标右移n行

\033[nD 光标左移n行

\033[y;xH设置光标位置

\033[2J 清屏

\033[K 清除从光标到行尾的内容

\033[s 保存光标位置

\033[u 恢复光标位置

\033[?25l 隐藏光标

\33[?25h 显示光标

三、实现

其实这个idea是网上参考的哦,梳理出来思路如下:

1、定义血量HP、魔法MP,勇士发动攻击则需要消耗MP;

2、战斗方式为回合制,勇士和恶龙分别选择攻击方式进行PK;

基础定义:

#include

#include

#include

#include #define HP_MAX 20

#define MP_MAX 20

#define LOGGREEN(fmt, args...)printf("\033[40;32m"fmt"\033[0m", ##args);

#define LOGYELLOW(fmt, args...)printf("\033[40;33m"fmt"\033[0m", ##args);

#define LOGBLUE(fmt, args...)printf("\033[40;36m"fmt"\033[0m", ##args);

#define LOGD(fmt, args...);printf(fmt, ##args);

#define LOGX(fmt, args...);offset += snprintf(msg + offset, 1000 - offset, fmt, ##args);

static char msg[1000] = {0};

static int offset = 0;typedef enum cmd_enum

{

ROLE_YOU = 1,

ROLE_DRAGON = 2,

CMD_ENUM_MIN = '0',

CMD_ENUM_ATTACK = '1',

CMD_ENUM_POWER = '2',

CMD_ENUM_DODGE = '3',

CMD_ENUM_THUMP = '4',

CMD_ENUM_MAX,

} CMD_ENUM;typedef struct instance_t

{

char name[16];

int role;

int dodge;

int hp;

int mp;

struct instance_t *peer;

} INSTANCE_T;

然后定义四个动作对应玩家可选的四个攻击模式:

void dsp_usage()

{

LOGD("\n\n选项:\n");

LOGD("\t1.攻击:使用攻击需消耗1MP 伤害1HP\n");

LOGD("\t2.蓄力:使用蓄力可增加1MP 伤害0HP\n");

LOGD("\t3.闪避:使用躲闪需消耗0MP 伤害0HP 躲避攻击\n");

LOGD("\t4.重击:使用重击需消耗2MP 伤害2HP 防御无效\n");

}

int main(void)

{

char str_opt = 0;

int opt = 0;

int ret = 0;

void (*do_callback)(INSTANCE_T *pinst);INSTANCE_T inst1 = {{0}, 0};

INSTANCE_T inst2 = {{0}, 0};

strcpy(inst1.name, "勇士");

inst1.hp = 10;

inst1.mp = 0;

inst1.peer = &inst2;

inst1.role = ROLE_YOU;

strcpy(inst2.name, "恶龙");

inst2.hp = 20;

inst2.mp = 3;

inst2.peer = &inst1;

inst2.role = ROLE_DRAGON;

srandom((unsigned int)time(NULL));

dsp_usage();

while ( (str_opt = getchar()) != EOF ) {

switch ( str_opt ) {

case CMD_ENUM_ATTACK:

do_attack(&inst1);

break;

case CMD_ENUM_POWER:

do_power(&inst1);

break;

case CMD_ENUM_DODGE:

do_dodge(&inst1);

break;

case CMD_ENUM_THUMP:

do_thump(&inst1);

break;

case 'q':

LOGD("Game over\n");

exit(0);

default:

continue;

}

switch ( (random() & 0x3) + '1' ) {

case CMD_ENUM_ATTACK:

do_attack(&inst2);

break;

case CMD_ENUM_POWER:

do_power(&inst2);

break;

case CMD_ENUM_DODGE:

do_dodge(&inst2);

break;

case CMD_ENUM_THUMP:

do_thump(&inst2);

break;

default:

break;

}

dsp_title(&inst1, &inst2);

dsp_usage();

}

LOGD("Game over\n");

exit(0);

}

四种攻击模式的实现:

void do_attack(INSTANCE_T *pinst)

{

LOGX("%s准备攻击,", pinst->name);

if ( 0 == pinst->mp ) {

LOGX("MP不足!\n");

return;

}

pinst->mp--;

if ( 0 == pinst->peer->dodge ) {

pinst->peer->hp--;

LOGX("发动攻击!造成掉血1点!\n");

}

else {

LOGX("我勒个去!攻击被%s闪避了!\n", pinst->peer->name);

}

pinst->peer->dodge = 0;

}

void do_power(INSTANCE_T *pinst)

{

LOGX("%s准备蓄力,", pinst->name);

pinst->mp++;

LOGX("MP:%d\n", pinst->mp);

}

void do_dodge(INSTANCE_T *pinst)

{

LOGX("%s准备闪避,", pinst->name);

pinst->dodge = 0;

LOGX("下回合生效!\n");

}

void do_thump(INSTANCE_T *pinst)

{

LOGX("%s准备大招,", pinst->name);

if ( pinst->role == ROLE_YOU ) {

if ( pinst->mp < 2 ) {

LOGX("MP不足!\n");

}

else {

if ( 0 == pinst->peer->dodge ) {

pinst->peer->hp -= 2;

LOGX("Avada Kedavra!!!!\n");

}

else {

LOGX("我勒个去!大招你也躲避了!\n");

}

pinst->mp = 0;

}

}

else {

if ( pinst->mp < 3 ) {

LOGX("巨龙在发呆...\n");

}

else {

LOGX("发动火焰吐吸!无法闪避!\n");

pinst->mp = 0;

pinst->peer->hp -= 4;

}

}

pinst->peer->dodge = 0;

}

最后,再做一个屏幕输出的显示。

void dsp_title(INSTANCE_T *pinst1, INSTANCE_T *pinst2)

{

int ix = 0;

printf("\033[2J");

LOGGREEN("+----------------------------------------+");

LOGGREEN("+----------------------------------------+\n");

LOGGREEN("| YOU HP: %2d: ", pinst1->hp);

for ( ix = 1; ix <= HP_MAX; ix++ ) {

if ( ix <= pinst1->hp ) {

LOGGREEN("=");

}

else {

LOGGREEN(" ");

}

}

LOGGREEN(" |");

LOGGREEN("| DRANGON HP: %2d: ", pinst2->hp);

for ( ix = 1; ix <= HP_MAX; ix++ ) {

if ( ix <= pinst2->hp ) {

LOGGREEN("=");

}

else {

LOGGREEN(" ");

}

}

LOGGREEN(" |\n");

LOGGREEN("| MP: %2d: ", pinst1->mp);

for ( ix = 1; ix <= MP_MAX; ix++ ) {

if ( ix <= pinst1->mp ) {

LOGGREEN("=");

}

else {

LOGGREEN(" ");

}

}

LOGGREEN(" |");

LOGGREEN("| MP: %2d: ", pinst2->mp);

for ( ix = 1; ix <= MP_MAX; ix++ ) {

if ( ix <= pinst2->mp ) {

LOGGREEN("=");

}

else {

LOGGREEN(" ");

}

}

LOGGREEN(" |\n");

LOGGREEN("+----------------------------------------+");

LOGGREEN("+----------------------------------------+\n");

LOGYELLOW("%s", msg);

offset = 0;

if ( pinst1->hp <= 0 ) {

exit(0);

LOGD("噢,你挂了!\n");

}

else if ( pinst2->hp <= 0 ) {

exit(0);

LOGD("恭喜勇士,你获得了胜利\n");

}

}

四、总结

巨龙AI明显不太够,玩家太强了哈哈!好吧,这是个有趣的自娱自乐游戏!

大家新村快乐、鸡年吉祥!

勇者游戏C语言,c语言命令行-勇者斗恶龙相关推荐

  1. 使用Dart/Flutter语言开发的命令行文字RPG类型小游戏

    使用Dart/Flutter语言开发的命令行文字RPG类型小游戏 项目源码:https://gitee.com/FantasyWind/word_game 介绍 项目背景 本项目为使用Dart/Flu ...

  2. 【Rust日报】2021-10-05 Mimic: 一款用Rust语言编写的命令行Gameboy模拟器

    Mimic: 一款用Rust语言编写的命令行Gameboy模拟器 Mimic: A Gameboy emulator written in Rust that can be played on the ...

  3. [转载] c语言中检查命令行参数_C中的命令行参数

    参考链接: Java中的命令行参数 c语言中检查命令行参数 Command line argument is a parameter supplied to the program when it i ...

  4. c语言程序命令行,ttyd(C语言编写的命令行程序) v1.3.1 免费版

    ttyd是一个C语言编写的命令行程序,可以把任意命令行程序分享到网页上操作,可以看做是个网页版的远程终端,支持 Linux.macOS 系统,还可以运行在 OpenWrt 之类的嵌入式系统上. 功能特 ...

  5. 计算器四则运算c语言,C语言:基于命令行的四则运算计算器

    题目: C语言:基于命令行的四则运算计算器 功能要求:  四则运算就是包含+.-.*./..(小数点)和数字的运算表达式,例如:3+2.9*(5-6/3)等  能够解释并执行四则运算表达式  能 ...

  6. c语言程序的命令行输入,C程序获取命令行参数

    命令行参数 命令行界面中,可执行文件可以在键入命令的同一行中获取参数用于具体的执行命令.无论是Python.Java还是C等等,这些语言都能够获取命令行参数(Command-line argument ...

  7. Go语言程序的命令行参数

    获取命令行参数是程序功能多样化的必要前提. 这个例子展示Go语言如何获得程序的命令行参数. Go语言程序: // echoarg project main.go package mainimport ...

  8. Go语言的使用命令行程序

    出于如下原因,程序员想创建命令行程序: 1.为创建能够定期自动运行的脚本. 2.为创建与系统中的文件交互的脚本. 3.为创建能够执行系统维护任务的脚本. 4.为避免设计图形用户界面这种无谓的开销. 在 ...

  9. C语言函数指针命令行参数

    我们可以用函数指针实现多态等高端函数,再加上命令行参数让你的程序提高一个档次. 程序如下: #include<stdio.h> #include<stdlib.h> #incl ...

  10. c语言程序的命令行输入输出,C语言入门教程-命令行参数

    命令行参数 在C中,获取用户输入的命令行参数是很方便的.程序的主函数会接受一个argv参数.有许多高级的库函数都会用到argv结构,所以了解此结构对一个C程序员来说将是很有用的. 请录入并编译下面的程 ...

最新文章

  1. 中国网络出版产业盈利模式与投资前景形势研究报告2022版
  2. spark将rdd转为string_大数据技术之SparkCore(三)RDD依赖关系
  3. 如何用SPSS做协方差分析?超详细图文教程
  4. Elasticsearch之批量操作bulk
  5. QT的QIcon类的使用
  6. PHP的Composer install、require、update
  7. wps 模拟分析 规划求解_【图书推荐】金属塑性加工过程有限元数值模拟及软件应用...
  8. 分享一张前端知识点思维导图
  9. java修改默认字符编码_设置默认的Java字符编码?
  10. scikit-klearn之 1.决策树
  11. ios 设置按钮不可见_自定义键盘InputAccessoryView在iOS中不可见11
  12. 第四篇:在MVPArms中报错error: cannot find symbol class DaggerXXXComponent的问题
  13. linux能yum装mcafee吗,Ubuntu安装Mcafee步骤
  14. python 知乎 合并 pdf_有什么比较好的 PDF 分割、合并软件?
  15. 关于anchor的解释
  16. Jena_1 Jena 与 Fuseki部署
  17. win10平板模式_win10电脑投屏到手机
  18. CSS——设置元素边框的bug,当boder-radius比border本身大的时候
  19. APP开发工具Appcan、apicloud、HBuilder 剖析
  20. 软件架构非功能需求——互操作性

热门文章

  1. open 读Txt文件
  2. Python爬取行政区划代码(最新版)
  3. 计算机VFP试题答案,2010全国计算机vfp二级笔试试题及答案
  4. revit2016与2017区别_revit2017下载及新功能介绍
  5. DIP 电源跌落瞬时中断(Voltage dips)
  6. sqlite3数据库报错:“打不开数据库文件”
  7. 这4款甘特图绘制工具,都是老原精心整理
  8. JAVA程序设计基础(第六版)第六章习题 6.13
  9. cad小插件文字刷_必备CAD插件大全,内含最全字体库
  10. 计算机组成原理(LogisimVerilog部分)-笔记