足球战术之设计模式篇 (0分)

  • 主题发起人 主题发起人 VRGL
  • 开始时间 开始时间
在快速反击中使用proxy模式,
可以大大提高反击的质量,首先,
得分手总站在前场,不参与防守,
浪费太大,而且容易被防死,所以
可以使用一个速度很快的前卫做
proxy来助攻,截掉对方来球后,
由他来快速带球通过中场,但是
不由他射门得分,而是吸引对方防守,
传给真正的得分手realsubject来完成
射门。好处是减小开销,增大威力:)
代码如下:
class 队员{
public:
virtual ~队员();
virtual void 反击()=0;
protected:
队员();
}
class 得分手:public 队员{
public:
得分手(const char* 号码);
virtual ~得分手();
virtual void 反击();
private:
//...
};
class 助攻队员:public 队员{
public:
助攻队员(const char* 号码);
virtual ~助攻队员();
virtual void 反击();
protected:
得分手* 传给得分手();
private:
得分手* _得分手;
char* _号码;
};
 
排兵布阵时使用interpreter模式,
可以让教练不用去hack,而是简单
的复用就可以完成复杂的战术。
在这个模式中,client是教练,
context是球队,abstractexpression
是基本打法,terminalexpression
是单个队员的打法,nonterminal
expression是一条线的打法,
好处是用类来表示打法,可以用
继承来改变或扩展打法;而且
"抽象打法树"中各节点的类的
实现大体类似,易于实现。缺点是
为每种打法定义一个类,当打法
很复杂时,很难维护。interpreter
和composite(组合进攻)在实现上
有很多相通之处,以下是需要考虑的
特殊问题:
1.抽象打法树的创建。可以使用经典
教科书上的打法,也可以由教练提供。
2.打法的实现可以采用visitor(全攻全守)
来实现。
3.当许多打法都以某个队员作为
最终完成者时,这个队员可以作为
flyweight来共享:)
代码如下:
class 基本打法{
public:
基本打法();
virtual ~基本打法();
virtual bool 组织(球队&)=0;
virtual 基本打法* 进攻(const char*,基本打法&)=0;
virtual 基本打法* 防守(const char*,基本打法&)=0;
};
class 球队{
public:
bool 找寻球员(const char*) const;
void 赋给(球员打法*,bool);
};
class 左后卫打法:public 基本打法{
public:
左后卫打法(const char*);
virtual ~左后卫打法();
virtual bool 组织(球队&);
virtual 基本打法* 进攻(const char*,基本打法&);
virtual 基本打法* 防守(const char*,基本打法&);
private:
char* _左后卫号码;
};
class 双前锋打法:public 基本打法{
public:
双前锋打法(基本打法*,基本打法*);
virtual ~双前锋打法();
virtual bool 组织(球队&);
virtual 基本打法* 进攻(const char*,基本打法&);
virtual 基本打法* 防守(const char*,基本打法&);
private:
基本打法* _前锋甲;
基本打法* _前锋乙;
};
 
向你学习!
 
有时候,复用一条线时会产生问题,
如如果雷布罗夫加入AC milan,他和
其他队员的配合可能会产生问题,
这时利用舍甫琴科和其他队员的
熟练配合和他和雷布罗夫以前的
熟练配合,使用adapter模式,
可能也会组合出不错的配合。
又如Ronaldo很久没和其他队友
配合,这时用全面的vieri做adapter
来跟他做球,也会打出比较好的配合。
这里前锋之间是公有派生,和其他队员
是私有派生,代码如下:
class 被适配前锋{
public:
被适配前锋();
virtual void 射门();
virtual void 跑动();
};
class 其他队员{
public:
其他队员();
void 跑动();
virtual bool 传球();
};
class 适配前锋:public 被适配前锋,private 其他队员{
public:
适配前锋();
virtual void 射门();
virtual void 跑动();

virtual bool 传球();
};

 
使用iterator模式,让每个队员做
iterator,每个位置做aggregate,
有如下几个好处:
1.每个位置支持不同的队员用不同方式遍历。
2.简化了每个位置的接口,使其kiss,不用具有遍历的接口。
3.在同一个位置支持多个队员同时遍历。
代码如下:
template <class Item>
class 位置{
public:
位置(long size=缺省_位置_容量);
long 计数() const;
Item&amp;
Get(long index) const;
//...
};
template <class Item>
class 队员{
public:
virtual void 回到初始位置()=0;
virtual void 下一个位置()=0;
virtual bool 是否到达() const=0;
virtual Item 当前Item() const=0;
protected:
队员();
};
template <class Item>
class 左后卫:public 队员<Item>{
public:
左后卫(const 位置<Item>* 一个位置);
virtual void 回到初始位置;
virtual void 下一个位置();
virtual bool 是否到达() const;
virtual Item 当前Item() const;
private:
const 位置<Item>* _位置;
long _当前;
};
 
这个有什么用呀
 
使用builder模式,来多点进攻,
可以避免abstract factory的
进球方式已经定死的缺点,
因为builder生产的产品差异很大,
以至于无需定义一个抽象的父类,
再就是很多人会把builder和observer
弄混,以为subject就是director,
observer就是builder,其实builder
模式中的director是虚拟的,并
没有该类,实际上只是在builder中
有统一的可以看作是director的接口。
用builder模式有以下几个好处:
1.你可以任意改变进球的方式和过程,
只用新生成一个builder(打某种战术的一个队员)。
2.将进球的过程和其他组织过程分开。
3.可以对进球过程进行更精细的控制。
4.builder的抽象父类并不将生成方法
声明成纯虚拟函数,而是定义成空方法,
可以让教练(client)只定义其需要的方法。
代码如下:
class 射门机器{
public:
virtual void 头球射门(){}
virtual void 脚射门(){}
virtual void 其他射门(){}
virtual 进球* 得到进球(){return 0;}
protected:
射门机器();
};
class 队员:public 射门机器{
public:
队员();
virtual void 头球射门();
virtual void 脚射门();
virtual void 其他射门();
virtual 进球* 得到进球();
private:
//...自己的特性和进攻方式
};

 
使用prototype模式,用其他队员牵制
对手的注意力,然后带球队员通过个人
技术甩脱对方的防守,单刀赴会得分
(clone)。就像皇马在西甲半程时齐达内
进的那个球。好处是在进攻进行时决定
是否射门或改用其他方法;动态控制
射门;改用不同球员来变化射门方式;
减少进攻需要的队员数;动态换人
改变进攻来改变战术。缺点是:需要
每个队员都有单刀赴会的能力,实现
起来比较困难:)
代码如下:
class 牵制队员:public 队员{
public:
牵制队员(中路*,左路*,右路*);
virtual 两路* 中路包抄 const;
virtual 右路* 左路包抄 const;
virtual 左路* 右路包抄 const;
private:
两路* _中路包抄原型;
右路* _左路包抄原型;
左路* _右路包抄原型;
};
左路* 牵制队员::右路包抄 const{
return _右路包抄原型->左路单刀;
}
class 左路带球队员:public 带球队员{
public:
带球队员();
virtual void 启动();
virtual 左路* 左路单刀 const;
private:
/*...自己特性*/
};
左路* 左路带球队员::左路单刀() const{
return new 左路(*this);
}
 
使用工厂方法有以下好处,
球员仅处理进球(product)接口,
但每要产生一种新的进球方式,
就必须让这个队员来学会这种方法,
或者换个队员。球员基类在类中
创建进球,而不是直接创建,
为子类提供一个hook。提供平行
的类层次。
代码如下:
class 球员{
public:
virtual 进球* 创建(进球类型);
};
进球* 球员::创建(进球类型 id){
if (id==高空球) return new 头球进球;
if (id==半高球) return new 抽射破门;
//repeat for remaining products...
return 0;
}
进球* 射门机器::创建(进球类型 id){
if (id==高空球) return new 倒钩;
if (id==半高球) return new 胸部或肩部挡进去;

if (id==低球) return new 鱼跃冲顶;
return 球员::创建(id);//全部其他的失败时调用
}
 
没什么好说的了,以你为目标,努力!
 
接受答案了.
 

Similar threads

D
回复
0
查看
1K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
I
回复
0
查看
691
import
I
后退
顶部