我正在编写自己的“魔方”应用程序。主要班级Cube
有18种旋转方式:
是的,它们可以通过参数 Direction 成对连接(例如RotateFrontFace(Direction direction)
)但目前看来这似乎是合适的。
我想实现撤消/重做功能,并且因为所有方法都具有相同的签名(没有输入参数,无效返回类型),所以它们可以保存在 LinkedList 数据结构中。因此,每次调用其中一种旋转方法时,都会将其添加到链表中。
如果我们从 LinkedList 的开头开始(虽然还没有尝试过)并向结尾前进,那么这将非常有效,因此每次旋转都将完全按照最初的方式执行。
但是撤消呢?如果我从末尾到开头遍历列表,那么应该调用相反的方法(例如,而不是RotateFrontFaceClockWise
, RotateFrontFaceAntiClockWise
应该调用)。有什么想法如何实施吗?优雅? :)
我不会使用委托引用作为旋转建模的方式,如果主要目的之一是能够执行重做/撤消。我会考虑为每次轮换创建一个数据模型,并存储这些轮换步骤的列表。然后,每个步骤都可以有其自己关联的重做/撤消委托,这允许某人(从任一端)遍历列表以了解发生了哪些操作,并重复或反转它们。
使用面向数据的方法对此类转换进行建模的另一个好处是,它可能会减少类似(但略有不同)版本的数量。RotateXXX( )
方法。
编辑:解决您关于这种解决方案可能采取什么形式的问题。
最简单的事情可能是存储Tuple<Action,Action>
将每对旋转/取消旋转操作表示为成对的委托。但是,我会考虑使用显式数据结构来描述旋转操作,也许最终包括描述性名称、方向/面属性等。我也会改变你的RotateXXX
方法,以便它们是静态方法Cube
,并接受一个立方体实例作为参数。这将允许在实例外部对旋转操作进行建模Cube
.
public sealed class Rotation
{
private readonly Action<Cube> _RotateAction;
private readonly Action<Cube> _UnrotateAction; // used for undo or backtracking
private Rotation( Action<Cube> rotateAction, Action<Cube> unrotateAction )
{
_RotateAction = rotateAction;
_UnrotateAction = unrotateAction;
}
public void Rotate( Cube cube ) { _RotateAction( cube ); }
public void Unrotate( Cube cube ) { _Unrotate( cube ); }
public static readonly RotateFrontFaceClockswise =
new Rotation( Cube.RotateFrontFaceClockwise
Cube.RotateFrontFaceCounterClockwise );
public static readonly RotateFrontFaceCounterClockwise =
new Rotation( Cube.RotateFrontFaceCounterClockwise,
Cube.RotateFrontFaceClockwise );
public static readonly RotateLeftFaceClockwise =
new Rotation( Cube.RotateLeftFaceClockwise,
Cube.RotateLeftFaceCounterClockwise );
public static readonly RotateLeftFaceCounterClockwise =
new Rotation( Cube.RotateLeftFaceCounterClockwise,
Cube.RotateLeftFaceClockwise );
// etc..
}
// now we can keep track of the state changes of a cube using:
List<Rotation> cubeRotations = new List<Rotation>();
cubeRotations.Add( Rotation.RotateFrontFaceCounterClockwise );
cubeRotations.Add( Rotation.RotateBackFaceClockwise );
cubeRotations.Add( Rotation.RotateLeftFaceCounterClockwise );
// to apply the rotations to a cube, you simple walk through the data structure
// calling the Rotate( ) method on each:
Cube someCube = new Cube( ... )
foreach( Rotation r in cubeRotations )
{
r.Rotate( someCube );
}
// to undo these rotations you can walk the like in reverse:
foreach( Rotation r in cubeRotations.Reverse() )
{
r.Unrotate( someCube );
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)