动作追踪_追踪对手的动作

本文演示了一种根据过去的表现选择运动状态的技术。 为了使事情尽可能简单,该示例不包括数据的长期持久性(尽管您可以不费吹灰之力地添加此功能)。 我将把本技巧的范围限于代码的高级概述。 如果您想对类和方法进行更详细的说明,请参考源代码注释文档。 完整的源代码可在参考资料中找到

数学实用程序类

通常,机器人会严重依赖一些数学算法。 一个好的做法是为最常用的算法创建一个带有静态方法的实用程序类。

此示例的实用程序类是BotMath类。 此类包含单个方法calculateDamage() ,用于根据子弹的力量来计算由子弹造成的伤害。

扩展AdvancedRobot类以提供发布者/订阅者支持

当我们向机器人添加状态,状态管理器和其他支持类时,他们将需要访问不同的事件。 我们可以将这些事件传递给状态管理器,然后让它们将事件传递给各个状态,但是将仅将相关事件直接传递给需要它们的对象会更有效。

ExtendedRobot类允许对象注册以仅接收其感兴趣的事件。 EventRegistry类包含用于注册不同事件的常量。 抽象的EventListener类定义接收这些事件所需的方法。

除了标准的Robocode事件外, ExtendedRobot类还生成状态管理器和状态所需的三个事件。 enabledisableexecute事件直接传递给任何注册的状态管理器,它们负责将事件传递给活动状态。 在每个回合开始时调用enable()方法; 此方法的实现应初始化变量并注册任何相关的Robocode事件。 在每个回合结束时调用disable()方法。 此方法的实现应释放资源,并取消订阅该类当前已预订的任何Robocode事件。 每次回合都会调用execute()方法,从而允许状态管理器和状态执行基于回合的算法。 任何需要接收这些事件的类都必须实现CommandListener接口。

管理状态

StateManager类负责选择最佳状态。 每转一圈,其execute()方法都会调用当前活动状态的isValid()方法。 如果状态的isValid()方法返回false,则选择新状态(此过程可用于根据对手的数量等切换状态)。

选择新状态涉及的大部分工作由StateManagerselectNewState()方法处理。 此方法从每个候选状态请求统计数据,并对数据进行评估以选择最佳状态。 StateManager使用两阶段方法来选择最佳状态。 首先,它尝试使用赢/输比最高的状态; 如果找不到合适的状态,则StateManager选择损坏/时间比率最低的状态。

状态

抽象的State类定义每个状态实现所需的方法。 它包括标准的enable()disable()execute()方法,以及一些与状态管理器进行通信的专用方法。 getStatistics()方法返回一个Statistics对象,其中包含有关该州过去的表现的数据(在此示例中,该状态管理一个Statistics对象,但是可以很容易地对其进行修改以使用HashMap来查看对手的统计信息)。 getName()方法返回在调试消息中使用的状态的友好名称。 isValid()方法负责确定何时应使用状态-在状态选择期间和选择状态后的每一回合都将调用它。

每个State类负责跟踪其执行情况并将该数据记录到其Statistics对象。

我在源代码中包括了两个简单的示例状态: TrackStateCannonFodderState类提供了抽象State类的示例实现。

统计

Statistics类是用于跟踪状态执行情况的简单容器类。 它包含损坏率(损坏/时间),使用状态的遭遇次数,损失次数和获胜次数的变量。 它还包含用于设置和检索此数据的三种帮助方法。 update()方法提供了一种简单的方法来设置Statistics对象中的变量。 getDamageRatio()getWinLossRatio()方法返回状态的统计数据。

为防止单个不良回合取消潜在有效状态的资格,除非统计状态数据至少在三次遭遇中使用过( Statistics对象在此评估期间返回默认数据值),否则统计数据将不被视为有效。

放在一起

机器人的主要类别承担建立状态管理器和状态的大部分责任。 每轮必须创建状态管理器,将状态添加到状态管理器,将状态管理器注册为命令侦听器,并调用ExtendedRobot enable()方法来激活命令侦听器。 主机器人类还负责每转executeTurn()调用ExtendedRobot executeTurn()方法(此方法调用所有已注册命令侦听器的execute()方法)。 在每个回合结束时,主机械手类必须调用disable()方法以允许命令侦听器正常关闭。

清单1显示了一个多状态机器人的典型run()方法:

清单1.多状态机器人的典型run()方法
public void run() {
        try {
            // Set up and enable the state manager
            StateManager navigation = new StateManager(this);
            navigation.addState(new CannonFodderState(this));
            navigation.addState(new TrackState(this));
            addCommandListener(navigation);
            enable();

            // Set turret to move independent of body
            setAdjustGunForRobotTurn(true);

            // Main bot execution loop
		    while(true) {
                // Spin gun
                setTurnGunRightRadians(Math.PI);
                // Allow StateManager to do it's thing
		    	executeTurn();
                // Finish the turn
                execute();
	    	}
        } finally {
            // Disable the State Manager
            disable();
        }
    }

在那里。 我意识到这实现起来相当复杂,但是它提供了两个巨大的持续优势。 该体系结构非常可扩展-您可以通过添加状态来增强功能。 此外,始终选择最佳状态的优势使机器人更具活力-更不用说击败了。


翻译自: https://www.ibm.com/developerworks/java/library/j-movement/index.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值