zoukankan      html  css  js  c++  java
  • 用 Silverlight 开发围棋在线对弈程序(二)MVC

    Silverlight 开发围棋在线对弈程序

    作者: Neil Chen

    第二部分:MVC

    为了重用代码,并且开始开发围棋程序的界面控制功能,我们考虑用 MVC 架构来对前面的程序进行一点小的修改,这样方便扩展功能。

    首先需要引入几个枚举,以及帮助类:
    wq2.png

    设计完成之后,我们的 Model, View, Controller 的类图如下:
    wq3.png

    程序的执行是从  App.xaml.cs 中开始的:

                  private void Application_Startup(object sender, StartupEventArgs e)

                  {

                         var model = new WeiQiModel();

                         var controller = new WeiQiController(model);

                  }

    这里创建了 Model Controller 对象,然后在 Controller 的构造函数中,将执行 View 的初始化动作,并将生成的 UserControl 对象赋给 Application.Current.RootVisual,从而达到显示 View 的目的。代码如下:

           public class WeiQiController

           {

                  WeiQiView _view;

                  WeiQiModel _model;

     

                  public WeiQiController(WeiQiModel model)

                  {

                         _model = model;

                         _view = new WeiQiView(this, model);

                         _view.CreateView();              

     

                         Application.Current.RootVisual = _view;

     

                         model.Init();

                  }

    }

    再来看一下 View 的构造函数,在其中,我们对 Model 的一个事件进行了注册。这样,当 Model 中的数据有变化时,可以直接通知 UI 进行更新。

           public partial class WeiQiView : UserControl

           {

                  WeiQiController _controller = null;

                  WeiQiModel _model = null;

     

                  public WeiQiView(WeiQiController controller, WeiQiModel model)

                  {

                         _controller = controller;

                         _model = model;

     

                         // 订阅 model 的更新事件以获得 UI 更新的通知

                         _model.BoardUpdated += new EventHandler<BoardUpdateEventArgs>(_model_BoardUpdated);

                  }

           }

    View 在响应鼠标点击事件时,进行必要的坐标转换,然后将请求转发给 Controller 处理:

                  // 棋盘上的鼠标点击事件

                  void canvasBoard_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

                  {

                         var p = e.GetPosition(canvasBoard);

                        

                         // 转换绝对坐标为相对位置信息

                         Position pos;

     

                         pos.X = (int)Math.Round(p.X / cellSize);

                         pos.Y = (int)Math.Round(p.Y / cellSize);

     

                         // 调用 Controller

                         _controller.ClickOnBoard(pos);

                  }

    另一个转发的例子:

                  void btnGo_Click(object sender, RoutedEventArgs e)

                  {

                         // 游戏开始

                         _controller.DealCommand("Start");

                  }

    看一下 Controller 中这两个方法的实现:

                  // 在棋盘上某个位置点击

                  public void ClickOnBoard(Position pos)

                  {

                         if (_model.GameStatus != GameStatus.Started)

                               return;

     

                         _model.SetStone(pos);

                  }

     

                  // 处理命令

                  public void DealCommand(string command)

                  {

                         if (command == "Start")

                         {

                               _model.GameStatus = GameStatus.Started;

                         }

                  }

    可以看到, Controller 调用了 Model 的相应核心逻辑进行处理。而 Model 中目前仅实现了简单的下棋规则判断,还有一些复杂的规则需要继续补充进去。如下列实现:

                  // 判断某个点是否能落子

                  //

                  // 在如下情况下,可能会导致落子失败:

                  //            1. 坐标出界

                  //            2. 该位置已有棋子

                  //            3. 打劫,没有找劫材就提劫。

                  //            4. 属于自杀,并且不能提取对方的棋子。

                  private bool CanMove(Stone stone, int x, int y)

                  {

                         // 1. 坐标出界

                         if (!CheckPosition(x, y))

                               return false;

     

                         // 2. 该位置已有棋子

                         if (GetStone(x, y) != Stone.None)

                               return false;

     

                         // 3. 打劫判断

     

                         // 4. 自杀判断

     

                         // TODO...

     

     

                         return true;

                  }

    到目前为止,程序显示如下:
    wq4.png

    其他实现细节看代码,这里不列举了。

    代码下载:[v0.03]


    未完待续 TO BE CONTINUED】

  • 相关阅读:
    Qt数据库集成应用封装
    Qt个人研究进展
    Qt仿win7自动顶部最大化左侧右侧半屏效果
    Qt编写QUI皮肤生成器
    java定时任务
    进程间通信(java)--队列
    单例设计模式-java
    Java RMI
    远程调用方式概述
    IO模型-java版
  • 原文地址:https://www.cnblogs.com/RChen/p/1425639.html
Copyright © 2011-2022 走看看