美文网首页
Flutter从头到尾设计一款简单的五子棋游戏(三) | 具体代

Flutter从头到尾设计一款简单的五子棋游戏(三) | 具体代

作者: 代码我写的怎么 | 来源:发表于2022-12-13 14:52 被阅读0次

前言

在前面两篇文章中,我们已经介绍了设计一款五子棋游戏的所使用的一些思想以及部分的代码,以便我们更好地对设计模式进行理解。这次我们全面把代码铺开来讲,注意,我们这次的设计是完全使用Flutter自带的包进行设计。

正文

1.前情回顾

上一篇文章中,我们对棋子的代码进行了设计。现在我们再进行回顾一下。先放个整个项目所使用到的类图的概览图。

棋子创建——享元模式

对于棋子的创建,我们使用享元模式,因为享元模式的设计思路就是将大量相同的对象进行复用。

在本项目中,棋子创建的类图如下:

在编码上,我们定义了抽象类Chess,他本质上是一个抽象享元。

///棋子的抽象类  
///使用了桥接模式,外观和颜色是两个不同的维度  
abstract class Chess{  

  Color? _color;  

  Color get color => _color!;  

  ChessShape? _chessShape;  

  ChessShape get chessShape => _chessShape!;  

  set chessShape(ChessShape? __chessShape);  
}

随后对具体的两个棋子进行了设计。也就是设计模式中的具体享元进行设计。

而对于具体的黑白棋子,则需要继承自Chess类

class BlackChess extends Chess{  
  BlackChess() {  
    _color = Colors.black;  
  }  

  set chessShape(ChessShape? __chessShape) {  
    super._chessShape = __chessShape;  
  }  
}

白色棋子同理,代码如下:

class WhiteChess extends Chess{  
  WhiteChess() {  
    _color = Colors.*white*;  
  }  

  set chessShape(ChessShape? __chessShape) {  
    super._chessShape = __chessShape;  
  }  
}

而对于享元工厂,我们则可以使用单例模式进行创建。

类图如下:

代码如下:

class ChessFlyweightFactory {  
  ChessFlyweightFactory._();  

  static ChessFlyweightFactory? *_factory*;  

  static ChessFlyweightFactory *getInstance*() {  
    if ( *_factory* == null) {  
      *_factory* = ChessFlyweightFactory._();  
    }  
    return *_factory*!;  
  }  

  HashMap<String, Chess> _hashMap = HashMap<String, Chess>();  

  Chess getChess(String type) {  
    Chess chess;  
    if (_hashMap[type] != null) {  
      chess = _hashMap[type]!;  
    } else {  
      if (type == "white") {  
        chess = WhiteChess();  
      } else {  
        chess = BlackChess();  
      }  
      _hashMap[type] = chess;  
    }  
    return chess;  
  }  
}

至此,我们对基本的棋子编写也已经完成了。

2.其他设计

棋子形状——桥接模式

因为形状主要是用来装饰棋子的,比如玩家根据自身等级可以购买不同的棋子皮肤、形状,因此我们这里抽出来单独设计。这里使用到

在本次的设计中,我们的棋子可以有方棋子和圆棋子。

类图如下:

由于ChessWhiteChessBlackChess已经在上方给出了代码, 因此这里我们只给出剩下的三个类。

abstract class ChessShape{  
  int? _shape;  

  int get shape => _shape!;  

  set shape(int value) {  
    _shape = value;  
  }  
}

ChessShape是一个抽象类,定义了其返回的形状类型。这里我们使用1代表圆,0代表方。具体的类设计如下:

class CircleShape extends ChessShape{  
  CircleShape(){  
    shape = 1;  
  }  
}

class RectShape extends ChessShape{  
  RectShape(){  
    shape = 2;  
  }  
}

玩家状态的切换——状态模式

游戏玩家状态的可以进行切换,如是否可以悔棋等,因此在这里使用了状态模式。

玩家类设计如下:

class UserContext {  

  late State _state;  

  State get state => _state;  

  UserContext(){  
    _state = StartState(this);  
  }  

  play() {  
    _state.play();  
  }  

  //悔棋只能悔棋三次  
  bool regretChess() {  
    return _state.regretChess();  
  }  

  // 认输 10步之内不能认输  
  bool surrender() {  
    return _state.surrender();  
  }  

  setState(State state){  
    _state = state;  
  }  

  void reset() {  
    _state = StartState(this);  
  }  
}

这里对玩家的一些动作进行了限制,比如悔棋只能悔棋三次前10步不能认输。这个玩家类在状态模式中也叫环境类

随后我们设计抽象状态类:

abstract class State {  
  int _step = 0;  

  int get step => _step;  
  int _reg = 0;  

  int get reg => _reg;  
  UserContext _userContext;  

  State(UserContext userContext):_userContext = userContext;  

  // 悔棋只能悔棋三次  
  bool regretChess();  

  // 认输10步之内不能认输  
  bool surrender();  

  play() {  
    _step++;  
  }  

}

随后设计具体的状态类:

class StartState extends State {  

  StartState(UserContext userContext) : super(userContext);  

  //悔棋只能悔棋三次  
  @override  
  bool regretChess(){  
    return false;  
  }  

  @override  
  bool surrender() {  
    return false;  
  }  

  @override  
  play() {  
    super.play();  
    if(_step >= 4) {  
      _userContext.setState(MidState(_userContext).._step = _step.._reg = _reg);  
    }  
  }  

}  

在开始状态中,我们设置不能悔棋,也不能投降。当步数大于4时,我们进行状态转移到MidState。效果图如下:

class MidState extends State {  
  MidState(UserContext userContext) : super(userContext);  

  @override  
  int get _reg{  
    return super._reg;  
  }  

  //悔棋只能悔棋三次  
  @override  
  bool regretChess(){  
    _reg++;  
    if(_reg == 3) {  
      print('切换到白热化阶段');  
      _userContext.setState(EndState(_userContext).._step = _step.._reg = _reg);  
    }  
    return true;  
  }  

  @override  
  bool surrender() {  
    return true;  
  }  

}  

在这个MidState中,我们允许投降,也允许悔棋。当悔棋超过3次,则进入到EndState。效果图如下:

class EndState extends State {  
  EndState(UserContext userContext) : super(userContext);  

  //悔棋只能悔棋三次  
  @override  
  regretChess(){  
    return false;  
  }  

  @override  
  surrender() {  
    return true;  
  }  

}

EndState中,我们只允许投降。效果图如下:

3.总结

今天在复习了原有的享元模式上,再介绍了桥接模式以及状态模式。关于棋子的创建以及玩家的状态我们也就已经设计完成,后续我们将把悔棋、以及App主题变换加上,基本就大功告成了。

作者:Jalor
链接:https://juejin.cn/post/7176111304745156665

相关文章

  • 贝贝五子棋 - 单机双人联机

    贝贝五子棋是一款画风简洁,棋力强大,功能丰富的五子棋游戏。集联网五子棋、单机五子棋于一体,是一款经典小游戏。联网模...

  • 利用C++打造双人对战的五子棋游戏,界面新颖「附源码」

    五子棋游戏的历史可谓源远流长,是一款老少皆宜的两人对弈纯策略游戏,讲究的是有攻有守的五子棋技巧,玩法简单易上手,五...

  • 五子棋AI算法的实现

    五子棋 五子棋五子棋是比较流行的棋类游戏了,玩法简单,基本上人人会玩,在此就不介绍游戏规则了。下面使用 swift...

  • 五子棋

    黑白纵横,五子连珠 古色古香的游戏界面 还等什么,快来挑战五子棋吧 五子棋游戏的历史可谓源远流长,是一款老少皆宜的...

  • 《超越1024》

    《超越1024》是一款简单休闲的益智游戏。 从游戏设计者的角度出发,我们希望开发一款纯粹的游戏,不以点击为目的,不...

  • pygame 欢乐五子棋 (一)

    Hello, 大家好,从本期开始,我们就开始开发我们五子棋小游戏!五子棋游戏,规则简单,比较适合我这种新手~ 我们...

  • 厉害了!神级程序员C++一小时极限开发五子棋游戏!

    一直以来都觉得”五子棋“算是比较简单容易玩的棋牌游戏,于是,小编就觉着用C++开发一款这样的游戏应该也不难,然后就...

  • 策略模式

    实例解析:一款模拟鸭子的游戏,游戏中会出现各种鸭子,一边游泳戏水,一边呱呱叫。设计如下所示: 具体代码 设计原则 ...

  • iOS-五子棋

    导读 五子棋是程序猿比较熟悉的一款小游戏,相信很多人大学时期就用多种语言写过五子棋小游戏.笔者工作闲暇之余,试着用...

  • 用C/C++实现五珠棋游戏,教你开发属于自己的游戏!

    这是一款用C++编写的五珠棋游戏,彩色的珠子,看着真舒服,一听好像是五子棋,不过好像玩法不太一样,具体怎么玩,有空...

网友评论

      本文标题:Flutter从头到尾设计一款简单的五子棋游戏(三) | 具体代

      本文链接:https://www.haomeiwen.com/subject/yaphqdtx.html