OTK就是one turn kill,不过这次我们要谈的OTK是自杀,对就是自己把自己给OTK了。

其实程序没有任何错误,只是恰巧碰上了这么个死循环。

ps:文章最后有代码git地址

发动条件及效果:

奥金尼(奥金尼特效是你的回复生命的牌和技能改为造成等量伤害)

痛苦女王(每当该随从造成伤害,为你的英雄回复等量生命值)

奥金尼在场的时候当痛苦女王发动攻击的时候,进行痛苦女王的特效判定,回复生命1,又触发奥金尼的特效,扣自己1点血,再次触发痛苦女王造成伤害的特效,再次回复生命1,又触发奥金尼特效,扣自己1点血,然后造成死循环,直到自己挂掉为止。

当然视频里的猜测是肯定不对的,按照程序员的思路来看应该是进入死循环了。

程序模拟:

我们希望能够模拟一下这个场景,并且尝试去实现一下炉石的战斗逻辑,下面的图就是我们的模拟效果,大致实现了一些卡牌和功能。

基础类设计

首先是baseUnit,这个类实现大部分基础的内容,在这个类基础上衍生了卡片和英雄,然后卡片在衍生出魔法卡片,武器卡片,随从卡片等。

基础类里包含了血量、护甲、圣盾、攻击次数等属性,可以实现一些炉石中的基础攻击,还没有考虑aoe技能的实现和恐狼这样的光环设计。

基本的风怒,actCount可以+1;冲锋,战吼的时候actCount+1,默认的随从上场actCount是0;

不过这些都不是重点,我们的重点是在攻击后的判定如何实现,这里baseUnit里也没有实现随从对拼的逻辑,死亡逻辑,只是搭了个架子。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using HeartStone.Interface;

namespace HeartStone.BaseDomain

{

public class BaseUnit : IUnitAction

{

public BaseUnit(BaseHero pHero)

{

OwnerHero = pHero;

Name = "未知";

Ac = 0;

ActCount = 0;

Ad = 0;

BaseAd = 0;

BaseHP = 0;

this.HeroType = HeroType.None;

this.Hp = 0;

this.Shield = false;

}

public virtual void Dispose()

{

Console.WriteLine("{0}死亡", this.Name);

return;

}

public BaseHero OwnerHero { get; set; }

///

/// 职业类型

///

public HeroType HeroType { get; set; }

public string Name { get; set; }

private int _Hp;

///

/// 血量

///

public int Hp

{

get { return _Hp; }

set

{

//血量最高不得超过基础血量

if (value > BaseHP)

_Hp = BaseHP;

else

_Hp = value;

}

}

///

/// 基础血量

///

public int BaseHP { get; set; }

private int _Ac { get; set; }

///

/// 护甲

///

public int Ac

{

get { return _Ac; }

set

{

//护甲最多不能超过基础血量

if (value > BaseHP)

_Ac = BaseHP;

else

_Ac = value;

}

}

///

/// 攻击

///

public int Ad { get; set; }

///

/// 基本攻击

///

public int BaseAd { get; set; }

///

/// 攻击次数,冲锋上场+1,风怒每回合+1

///

public int ActCount { get; set; }

private bool _Shield = false;

///

/// 圣盾

///

public bool Shield

{

get { return _Shield; }

set { _Shield = value; }

}

public virtual void Attack(BaseUnit targeted, BaseUnit from, int ad)

{

targeted.Defense(targeted, from, ad);

}

public virtual void Defense(BaseUnit targeted, BaseUnit from, int ad)

{

if (Shield)

Shield = false;

else

{

int acDefend = 0;

if (targeted.Ac > 0)

{

acDefend = targeted.Ac - ad;

if (acDefend >= 0)

targeted.Ac -= ad;//攻击5,护甲10,10-5大于等于0,表示护甲比攻击高,只要减护甲即可

else

{

//攻击5,护甲2,2-5=-3,小于0,表示护甲不够,要减

targeted.Ac = 0;

targeted.Hp += acDefend;

}

}

else

targeted.Hp -= ad;

Console.WriteLine("{0}受到{1}的{2}伤害,当前护甲{3},生命{4}", targeted.Name, from.Name, ad, targeted.Ac, targeted.Hp);

from.MakeDamage(targeted, from, ad);

}

}

///

/// 执行治疗

///

///

///

///

public void Treat(BaseUnit targeted, BaseUnit from, int ad)

{

var hero = from as BaseHero;

bool flag = true;

if (hero != null)

flag = hero.treatFlag;

else

flag = from.OwnerHero.treatFlag;

if (flag)

{

targeted.Hp += ad;

Console.WriteLine("{0}受到{1}的{2}治疗", targeted.Name, from.Name, ad);

}

else

{

if (targeted.Hp >= 0)

{

//from制造了伤害

Defense(targeted, from, ad);

}

}

}

public virtual void MakeDamage(BaseUnit targeted, BaseUnit from, int ad)

{

return;

}

}

}

奥金尼的实现

奥金尼的效果是你的治疗变成等量的伤害,所以对手的治疗依然是治疗,所以我给英雄增加了一个属性,treatFlag,用于标记这个英雄的治疗状态。

那么卡片自带的治疗效果,譬如大地之环或者老司机呢,所有卡片在上场的时候,也就是new的时候必须要传递一个owner,来表示这张卡是属于谁的,那么就可以很容易的找到这个英雄的治疗状态了。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using HeartStone.BaseDomain;

namespace HeartStone.Units.UnitCard

{

public class OKinny : BaseCard

{

public OKinny(BaseHero pHero)

: base(pHero)

{

Crystal = 4;

BaseCrystal = 4;

Ad = 3;

BaseAd = 3; BaseHP = 5;

Hp = 5;

Name = "奥金尼";

//牧师职业卡

HeroType = HeroType.Minister;

//奥金尼战场效果

pHero.treatFlag = false;

Console.WriteLine("{0}召唤登场",Name);

}

~OKinny()

{

this.OwnerHero.treatFlag = true;

}

public override void Dispose()

{

//奥金尼死了要重置

this.OwnerHero.treatFlag = true;

base.Dispose();

}

}

}

痛苦女王的实现

痛苦女王的效果是,造成伤害时回复等量的生命,所以痛苦女王需要重写MakeDamage方法,然后给自己英雄回复等量生命。

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using HeartStone.BaseDomain;

namespace HeartStone.Units.UnitCard

{

public class QueenPain : BaseCard

{

public QueenPain(BaseHero pHero)

: base(pHero)

{

Crystal = 2;

BaseCrystal = 2;

Ad = 1;

BaseAd = 1; BaseHP = 4;

Hp = 4;

Name = "痛苦女王";

//牧师职业卡

HeroType = HeroType.Minister;

Console.WriteLine("{0}召唤登场", Name);

}

public override void MakeDamage(BaseUnit targeted, BaseUnit from, int ad)

{

Treat(from.OwnerHero, this, ad);

base.MakeDamage(targeted, from, ad);

}

}

}

治疗的实现

治疗的实现时需要判断treatFlag,如果treatFlag为false的话就变成造成等量的伤害,然后再次调用from.MakeDamage方法,这样就可以循环起痛苦女王制造伤害的效果了,当然为了防止真的死循环,这里需要对目标的生命值进行一个判断,如果目标生命值小于0了则停止继续循环。

///

/// 执行治疗

///

///

///

///

public void Treat(BaseUnit targeted, BaseUnit from, int ad)

{

var hero = from as BaseHero;

bool flag = true;

if (hero != null)

flag = hero.treatFlag;

else

flag = from.OwnerHero.treatFlag;

if (flag)

{

targeted.Hp += ad;

Console.WriteLine("{0}受到{1}的{2}治疗", targeted.Name, from.Name, ad);

}

else

{

if (targeted.Hp >= 0)

{

//from制造了伤害

Defense(targeted, from, ad);

}

}

}

英雄和技能的实现

英雄的技能考虑到战士是瞬发的,法师可以选择目标,当然还会有可以只能选自己随从的技能或者只能选英雄的技能,等等。 所以在这里我们加了一个taregtObject,用于标记这个技能可以指向谁。

然后就是实现每个英雄的代码了,我实现了3个英雄,这里展示一下牧师的实现

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using HeartStone.BaseDomain;

namespace HeartStone.Units.Hero

{

public class HeroMinister : BaseDomain.BaseHero

{

///

/// 构造函数

///

public HeroMinister()

: base()

{

Name = "牧师";

//初始化自己的技能

HeroSkill = new MinisterSkill(this);

}

}

public class MinisterSkill : BaseHeroSkill

{

public MinisterSkill(BaseHero pHero)

: base(pHero)

{

TargetObject = TargetedObject.AllUnit;

}

///

/// 牧师的技能

///

public override void Skill(BaseUnit taregted)

{

Console.WriteLine("{0}使用了技能,目标{1}", thisHero.Name, taregted.Name);

this.thisHero.Treat(taregted, thisHero, 2);

}

}

}

模拟效果

然后我们就可以进行一个简单的模拟了,不考虑水晶,直接模拟环境

static void Main(string[] args)

{

HeroMinister minister = new HeroMinister();

HeroWarrior warrior = new HeroWarrior();

//战士回合,战士使用技能,结束

warrior.HeroSkill.Skill(warrior);

Console.WriteLine("================回合结束================");

//牧师回合,牧师上奥金尼,痛苦女王,用治疗伤害战士

OKinny oKinny = new OKinny(minister);

QueenPain queenPain = new QueenPain(minister);

minister.HeroSkill.Skill(warrior);

Console.WriteLine("================回合结束================");

//战士回合,战士使用技能,结束

warrior.HeroSkill.Skill(warrior);

Console.WriteLine("================回合结束================");

//牧师回合,奥金尼攻击,痛苦女王攻击,牧师卒

oKinny.Attack(warrior, oKinny, oKinny.Ad);

queenPain.Attack(warrior, queenPain, queenPain.Ad);

Console.WriteLine("================回合结束================");

Console.ReadKey();

}

写在最后

平时玩的时候觉得炉石挺简单的一个游戏,模拟一下这个场景应该很容易,但真正去实现的时候发现还是有很多地方缺乏考虑,经过一天的修改才最终出来这个模拟的雏形,还有很多对战逻辑没有实现,譬如aoe的法术还没想到什么好的方法来进行实现。

炉石传说 C# 开发笔记

最近在大连的同事强力推荐我玩 炉石传说,一个卡牌游戏.加上五一放一个很长很长的假期,为了磨练自己,决定尝试开发一个C#的炉石传说. 这件事情有人已经干过了,开发了一个网页版的炉石,但是貌似不能玩... ...

[原创]webapp/css3实战,制作一个《炉石传说》宣传页

在移动网页,尤其是webapp中常需要用到大量的css3动画,来获得良好交互体验 我之前帮朋友做了一个,可惜没帮上忙现在和大家分享一下 目标是要做一个游戏的介绍宣传页面,文字内 ...

炉石传说 C# 开发笔记(6月底小结)

炉石传说的开发,已经有30个工作日了. 关于法术的定义方法,有过一次重大的变更:法术效果是整个炉石的核心,正是因为丰富的法术效果,才造就了炉石的可玩性. 原来构思的时候,对于法术效果没有充分的理解,所 ...

炉石传说 C# 开发笔记 (续)

炉石传说山寨的工作一直在进行着,在开发过程中深深体会到,对于业务的理解和整个程序的架构的整理远比开发难得多. 在开发过程中,如果你的模型不合理,不准确,很有可能造成代码的混乱,冗余,难以维护和扩展性比 ...

炉石传说__multiset

炉石传说  Problem Description GG学长虽然并不打炉石传说,但是由于题面需要他便学会了打炉石传说.但是传统的炉石传说对于刚入门的GG学长来说有点复杂,所以他决定自己开发一个简化版 ...

《炉石传说》建筑设计欣赏(6):卡&在执行数据时,组织能力

上一篇文章我们看到了核心存储卡的数据,今天,我们不断探索卡&身手. 基本的类 通过之前的分析,卡牌&技能涉及到几个类体系:Entity.Actor.Card.S ...

fzu Problem - 2232 炉石传说(二分匹配)

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2232 Description GG学长虽然并不打炉石传说,但是由于题面需要他便学会了打炉石传说.但是传统的炉石 ...

islands打炉石传说<DP>

islands最近在完一款游戏"炉石传说",又名"魔兽英雄传".炉石传说是一款卡牌类对战的游戏.游戏是2人对战,总的来说,里面的卡牌分成2类,一类是法术牌,另一 ...

CCF2016093炉石传说(C语言版)

问题描述 (Hearthstone: Heroes of Warcraft,简称炉石传说)是暴雪娱乐开发的一款集换式卡牌游戏(如下图所示).游戏在一个战斗棋盘上进行 ...

随机推荐

【Unity3d】3d网页游戏场景打包与加载

http://www.cnblogs.com/dosomething/archive/2012/04/07/2436353.html 3d游戏中  一个场景往往比较大  如果游戏的进行需要下载一个10 ...

Do things for others

早上,按照平常的时间去吃早饭,食堂格外的空旷,打饭的员工说今天人很少,我说昨天是有元旦晚会,她说今天是放假,我后来想,还是她说的更有道理.她看的比我清楚更清楚! 幸亏昨晚上记录下了早上要帮别人搜论文的 ...

关于原生JS获取类相关的代码

mysql中的第三范式

※多表操作 (凡是多表,都要用到关联技术(把多表合并成一个新表): 左关联.右关联.内关联.还有一个外(全)关联,MySQL不支持,为考虑软件兼容,我们开发一般不用.) ※表与表之间的关系:1对1,1 ...

Android 百度地图开发之一(Hello BaiDu Map)

之前也接触过百度地图的开发,但那是在网上找的案例或代码,而且是比较老的版本.打算重新学习一下百度地图的开发. 本次使用的百度地图的版本是 Android SDK v3.0.0 本篇文章主要讲述百度地图 ...

使用Git操作GitHub代码入门教程

GitHub除了网页操作外,还可以借助本地客户端git(或github for windows)来增删修改远程代码.使用Git操作来连接GitHub可以通过Https或SSH方式,使用SSH方式可以免 ...

2013 长沙网络赛 B 题 Bizarre Routine

题解 http://blog.csdn.net/u010257508/article/details/11936129 #include #include

hdu 5997 rausen loves cakes(线段数合并+启发式修改)

题目链接:hdu 5997 rausen loves cakes 题意: 给你n个点,每个点有一个颜色,现在有两个操作,第一个操作,将颜色x改为颜色y,第二个操作,询问[x,y]区间有多少颜色段(颜色 ...

deepin 桌面突然卡死

deepin桌面突然卡死 使用快捷键Ctrl+alt+F2 重启systemctl

从0移植uboot(五) _实现串口输出

串口作为一种非常简单的通信方式,才是嵌入式系统调试的王道,通过设置串口输出,我们可以将程序运行的情况直接通过串口线输出到屏幕上,对于这种异常重要的功能,uboot原生就提供了支持,但为此我们需要做一些 ...

android webview 炉石,从炉石传说的一个自杀OTK说起相关推荐

  1. Android WebView清除缓存,总有一个方法适合你

    一,缓存介绍 缓存分为:页面缓存和数据缓存 页面缓存: 指加载一个网页时的html.JS.CSS等页面或者资源数据. 数据缓存 : 数据缓存分为AppCache和DOM Storage两种. 一般清除 ...

  2. Android WebView简要介绍和学习计划

    我们通常会在App的UI中嵌入WebView,用来实现某些功能的动态更新.在4.4版本之前,Android WebView基于WebKit实现.不过,在4.4版本之后,Android WebView就 ...

  3. android 除了webview 浏览器控件,AgentWeb是基于Android WebView一个功能完善小型浏览器库...

    [技巧沙龙]AI开辟者拭魅战营-7分钟打造1个定制技能.7月22号,我们等你一路! Android 端 AgentWeb 介绍 AgentWeb是一个高度封装的 Android WebView ,简单 ...

  4. 如何设计一个优雅健壮的Android WebView?,吊打面试官系列

    }if (mIWebViewClient != null) {mIWebViewClient.onPageFinished(view, newProgress);} } } 可以看到,我们使用了`mP ...

  5. 如何设计一个优雅健壮的Android WebView?(上)

    原文链接 https://kaolamobile.github.io/2017/12/10/design-an-elegant-and-powerful-android-webview-part-on ...

  6. 如何设计一个优雅健壮的Android WebView?(上) 基于考拉电商平台的WebView实践

    前言 Android应用层的开发有几大模块,其中WebView是最重要的模块之一.网上能够搜索到的WebView资料可谓寥寥,Github上的开源项目也不是很多,更别提有一个现成封装好的WebView ...

  7. 如何设计一个优雅健壮的Android WebView?(下

    nativeReady = false; var jsoncommand = JSON.stringify(command); var _temp = prompt(jsoncommand,''); ...

  8. Android WebView使用与JavaScript使用

    WebView基本使用 WebView是View的一个子类,可以让你在activity中显示网页. 可以在布局文件中写入WebView:比如下面这个写了一个填满整个屏幕的WebView: <?x ...

  9. android的webView的教程,Android WebView 应用界面开发教程

    WebView组件本身就是一个浏览器实现,Android5.0增强的WebView基于Chromium M37,直接支持WebRTC.WebAudio.WebGL.开发者可以直接在WebView中使用 ...

最新文章

  1. python学精通要多久-学习Python从入门到精通需要多长时间
  2. AI:Algorithmia《2020 state of enterprise machine learning—2020年企业机器学习状况》翻译与解读
  3. 万字详解,JDK1.8的Lambda、Stream和日期的使用详解
  4. what to do preparing for phd
  5. hdu 4350 Card(递推循环节,3级)
  6. 深度学习-Tensorflow2.2-tf.data输入模块{2}-tf.data基础用法-09
  7. js accordian效果
  8. 获取 子文件夹 后缀_后期制作老司机教你一键批量生成项目文件夹
  9. 韩顺平php视频笔记37 php数据类型(部分)
  10. 一份 Hadoop 面试 【避坑指南】 拍了拍你!
  11. CPU虚拟化的常见技术
  12. Android游戏开发
  13. Linux 2.6内核启动传递命令行的过程分析
  14. python 随机种子 时间_python课堂整理24----时间和随机数模块
  15. ROS学习笔记(一)#ROS系统及RoboWare的安装
  16. charles 的安装和手机配置 (我用的win7系统 ,和 iphone8 的配置)
  17. 各国在计算机视觉领域论文数,计算机视觉论文
  18. Typescript无法导入json的问题
  19. 基于ATT-LSTM的语音情感分类
  20. 科技圈的“三座大山”正在崩塌中。。。

热门文章

  1. setContentView(R.layout.main)在Android里面,这句话是什么意思?
  2. 论文排版2-Latex排版
  3. UGUI-- 图集制作
  4. 沈阳网赛1003 HDU 5894 hannnnah_j’s Biological Test
  5. android输入法架构解析
  6. String转QString,线段相交,四点共面,git相关操作,截图,扩展工具,string乱码,矩阵相乘
  7. java hid_Java和HID通讯
  8. 如何让你的 Python 代码在腾讯云 Linux 中一直运行着
  9. webScoket即时聊天,用户不在线时消息暂存,上线立马收到
  10. ACM知识竞)赛 之 SDUT3034 炸学校(最短路Dijkstra)