"The Same Game": A Simple Game from Start to Finish

文档视图结构

文档/视图体系结构是一个神奇的架构,通过这个架构,我们可以分离应用程序的数据和显示。文档包含了全部的数据,视图从文档获取数据并且显示给用户。针对这个游戏例子,我们得数据是游戏板和有颜色的砖块以及消耗的时间等信息。视图显示游戏板和有颜色的砖块,并且允许用户点击他们。视图同时与用户交互,并且修改文档中的游戏数据,相应地视图被更新以反应数据的变化,如此循环。

文档: 保有数据

终于来到编码时间. 在显示任何数据到屏幕之前,我们要设计好数据的保存方式,所以我们将先从文档部分开始,然后再考虑如何实现将这些数据显示出来。

首先,我们创建一个游戏板类型,让我们叫它CSameGameBoard。通过在解决方案浏览界面(Solution Explorer)单击鼠标右键,然后选择"Add -> Class..." or "Add Class..." 。

在弹出的Generic C++ Class Wizard界面中,我们填上类名CSameGameBoard。

下面是CSameGameBoard类的头文件:

#pragma once

class CSameGameBoard
{
public:
  /*  Default Constructor */
  CSameGameBoard(void);
  /*  Destructor */
  ~CSameGameBoard(void);
  /*  Function to randomly setup the board */
  void SetupBoard(void);
  /*  Get the color at a particular location */
  COLORREF GetBoardSpace(int row, int col);
  /*  Accessor functions to get board size information */
  int GetWidth(void) const { return m_nWidth; }
  int GetHeight(void) const { return m_nHeight; }
  int GetColumns(void) const { return m_nColumns; }
  int GetRows(void) const { return m_nRows; }
  /*  Function to delete the board and free memory */
  void DeleteBoard(void);
private:
  /*  Function to create the board and allocate memory */
  void CreateBoard(void);
  /*  2D array pointer */
  int** m_arrBoard;
  /*  List of colors, 0 is background and 1-3 are piece colors */
  COLORREF m_arrColors[4];
  /*  Board size information */
  int m_nColumns;
  int m_nRows;
  int m_nHeight;
  int m_nWidth;
};

这个类是十分简单的,它包含了一个指针,叫做m_arrBoard,它是一个二维数组,数组的每一个元素的取值为0或三个颜色之一(1-3),这个变量代表了我们看到的整个彩色砖块的全部。我们也添加了跟踪砖块行数 (m_nRows)和列数(m_nColumns)的变量,砖块宽度 (m_nHeight)和砖块高度 (m_nHeight)的变量,以及管理游戏板的一些函数。

create函数需要给二维数组m_arrBoard分配空间来存储游戏板数据,并且初始化所有的砖块为空。setup函数将reset游戏板,并游戏板上的每一个砖块随机地选择一种颜色。最后delete函数重新分配游戏板内存并释放掉之前的内存以防止内存泄漏。

在游戏板类中,有一个COLORREF类型的数组,COLORREF 存储了一个32位的颜色值。这个数组包含了四种颜色:0代表背景色,以及1-3,代表砖块可能的三种颜色(红黄蓝)。二维数组m_arrBoard的每一个元素中存储着这里的四种颜色索引之一。

以下是CSameGameBoard类的实现,在SameGameBoard.cpp文件中。

#include "StdAfx.h"
#include "SameGameBoard.h"

CSameGameBoard::CSameGameBoard(void)
: m_arrBoard(NULL),
  m_nColumns(15), m_nRows(15),
  m_nHeight(35),  m_nWidth(35)
{
  m_arrColors[0] = RGB(  0,  0,  0);
  m_arrColors[1] = RGB(255,  0,  0);
  m_arrColors[2] = RGB(255,255, 64);
  m_arrColors[3] = RGB(  0,  0,255);
}

CSameGameBoard::~CSameGameBoard(void)
{
  //  Simply delete the board
  DeleteBoard();
}

void CSameGameBoard::SetupBoard(void)
{
  //  Create the board if needed
  if(m_arrBoard == NULL)
    CreateBoard();
  //  Randomly set each square to a color
  for(int row = 0; row < m_nRows; row++)
    for(int col = 0; col < m_nColumns; col++)
      m_arrBoard[row][col] = (rand() % 3) + 1;
}

COLORREF CSameGameBoard::GetBoardSpace(int row, int col)
{
  //  Check the bounds of the array
  if(row < 0 || row >= m_nRows || col < 0 || col >= m_nColumns)
    return m_arrColors[0];
  return m_arrColors[m_arrBoard[row][col]];
}

void CSameGameBoard::DeleteBoard(void)
{
  //  Don‘t delete a NULL board
  if(m_arrBoard != NULL)
  {
    for(int row = 0; row < m_nRows; row++)
    {
      if(m_arrBoard[row] != NULL)
      {
        //  Delete each row first
        delete [] m_arrBoard[row];
        m_arrBoard[row] = NULL;
      }
    }
    //  Finally delete the array of rows
    delete [] m_arrBoard;
    m_arrBoard = NULL;
  }
}

void CSameGameBoard::CreateBoard(void)
{
  //  If there is already a board, delete it
  if(m_arrBoard != NULL)
    DeleteBoard();
  //  Create the array of rows
  m_arrBoard = new int*[m_nRows];
  //  Create each row
  for(int row = 0; row < m_nRows; row++)
  {
    m_arrBoard[row] = new int[m_nColumns];
    //  Set each square to be empty
    for(int col = 0; col < m_nColumns; col++)
      m_arrBoard[row][col] = 0;
  }
}

现在我们已经将游戏板封装成了一个类型,接下来,我们可以在文档类中,创建一个这个类型的实例。需要牢记的是,文档类拥有我们应用的全部数据,它和显示数据的视图类保持分离。下面是文档类的头文件 SameGameDoc.h:

#pragma once

#include "SameGameBoard.h"

class CSameGameDoc : public CDocument
{
protected: // create from serialization only
  CSameGameDoc();
  virtual ~CSameGameDoc();
  DECLARE_DYNCREATE(CSameGameDoc)

// Attributes
public:

  // Operations
public:

  /*  Functions for accessing the game board */
  COLORREF GetBoardSpace(int row, int col)
  { return m_board.GetBoardSpace(row, col); }
  void SetupBoard(void)   { m_board.SetupBoard(); }
  int GetWidth(void)      { return m_board.GetWidth(); }
  int GetHeight(void)     { return m_board.GetHeight(); }
  int GetColumns(void)    { return m_board.GetColumns(); }
  int GetRows(void)       { return m_board.GetRows(); }
  void DeleteBoard(void)  { m_board.DeleteBoard(); }


  // Overrides
public:
  virtual BOOL OnNewDocument();

protected:

  /*  Instance of the game board */
  CSameGameBoard m_board;


  // Generated message map functions
protected:
  DECLARE_MESSAGE_MAP()
};

文档类实际上是一个游戏板类的简单的封装,在后面的文章中我们将增加更多的功能到这里。但是目前它是保持非常简单的,我们增加了一个游戏板类的实例和7个函数,这将允许视图类接入我们的游戏板类的信息经由文档类。文档类所有功能的实现是非常简单的,它们都是间接的调用了游戏板类。

#include "stdafx.h"
#include "SameGame.h"

#include "SameGameDoc.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

// CSameGameDoc
IMPLEMENT_DYNCREATE(CSameGameDoc, CDocument)
BEGIN_MESSAGE_MAP(CSameGameDoc, CDocument)
END_MESSAGE_MAP()

// CSameGameDoc construction/destruction
CSameGameDoc::CSameGameDoc()
{
}

CSameGameDoc::~CSameGameDoc()
{
}

BOOL CSameGameDoc::OnNewDocument()
{
  if (!CDocument::OnNewDocument())
    return FALSE;

  //  Set (or reset) the game board
  m_board.SetupBoard();

  return TRUE;
}

Really all we added was the call to the SetupBoard function in the OnNewDocument handler in the document. All this does is allows the user to start a new game with the built-in accelerator Ctrl+N or from the menu File->New.

As we continue through the series of articles we‘ll be adding new functions to both the game board and the document to implement different features for the game but for now we are done with the document and are ready to display this information in the view.

时间: 2024-10-14 09:29:18

"The Same Game": A Simple Game from Start to Finish的相关文章

在VC工程中添加多语言支持[转]

随着贸易国际化,在软件开发过程中,常会碰到需在现有中文版软件加入多语言支持的情况.由于不同语言版本间的差别通常仅是软件操作界面的不同,为实现多语言支持,使用纯资源DLL是一个不错的解决之道.所谓纯资源DLL是指只包含资源的DLL,譬如:快捷键.对话框.字符串.菜单.工具条.位图.图标.版本信息等等. 具体做法是:利用VC可视化编辑环境为每种语言制作一套资源ID一一对应的资源集并编译生成DLL文件.应用程序初始化时按预设的语言设置选择合适的资源DLL调入,使用资源时依据资源ID进行访问,这样即可实

初译 Support Vector Machines:A Simple Tutorial(一)

从本次开始我将开始尝试着逐章翻译一下 Alexey Nefedov的<Support Vector Machines:A Simple Tutorial>这本教材,这可是我们导师极力推荐的SVM教材,看了好久一直感觉一脸懵逼,索性开坑翻译一下吧,也当是加深理解,毕竟我也是一知半解,如果翻译的有不对的地方还望大佬们斧正,欢迎提意见,欢迎讨论. 嗯,就是这样. (一)Introduction 在本章节中将会介绍一些用于定义支持向量机(SVM)的基础的概念,这些概念对于理解SVM至关重要,假定读者了

ubuntu16.04下安装NS-2.35以及对simple例的理解

本人是在VMWare上安装的ubuntu16.04版本,然后安装NS2.35. 1.下载ns2的安装包,这里我选择的是ns-allinone-2.35.tar.gz压缩格式的all in one安装包,all in one 安装包包含所有的组件,比较方便,另附下载地址: http://www.isi.edu/nsnam/ns/ns-build.html 2.安装前要先进行一些准备工作进行配置环境,输入如下代码: $sudo apt-get install build-essential $sud

[bzoj3489]A simple rmq problem

本题既不是rmq也不会simple(对我这种蒟蒻而言) 一开始只能想到树套树套树TAT然后看了看数据范围果断滚去膜拜题解. 然后才知道预先排序一下可以弄掉一个log.不过得写可持久化线段树套可持久化线段树.. 然后愉悦的开码了...感人的是竟然不用调...更感人的是交上去直接tle了. 然后从网上找了别人的代码(方法一样)发现同样的数据我要跑6s+..标称只要2s+.. 之后各种卡常还是慢了一倍TAT...最后自己写个max函数就和标程一样快了TAT这几天怎么总是出些奇怪的状况QAQ. 本来故事

地理数据可视化:Simple,Not Easy

如果要给2015年的地理信息行业打一个标签,地理大数据一定是其中之一.在信息技术飞速发展的今天,“大数据”作为一种潮流铺天盖地的席卷了各行各业,从央视的春运迁徙图到旅游热点预测,从大数据工程师奇货可居到马云布道“DT”时代,“大数据”被推到了一个前所未有的高度,连国家领导人出访演讲都言必称大数据.地理信息数据天生具有大数据属性,作为整天和地理信息数据打交道的地信人自然不甘落后,地理大数据概念脱颖而出. 地理大数据是什么?大体来说就是把社会经济.自然资源.商业信息等但凡具有一点空间维度的数据一股脑

简单工厂模式( Simple Factory Pattern )

1. 简单工厂模式( Simple Factory Pattern ) 1.1. 模式动机 考虑一个简单的软件应用场景,一个软件系统可以提供多个外观不同的按钮(如圆形按钮.矩形按钮.菱形按钮等), 这些按钮都源自同一个基类,不过在继承基类后不同的子类修改了部分属性从而使得它们可以呈现不同的外观,如果我们希望在使用这些按钮时,不需要知道这些具体按钮类的名字,只需要知道表示该按钮类的一个参数,并提供一个调用方便的方法,把该参数传入方法即可返回一个相应的按钮对象,此时,就可以使用简单工厂模式. 1.2

NYOJ 707 A Simple Problem(结构体排序) 睡前一水~~

链接:click here 题意: A Simple Problem 时间限制:3000 ms  |  内存限制:65535 KB 难度:2 描述 You know, just as the title imply, this is a simple problem. In a contest, given the team-id, solved, penalty of all the teams, tell me the champion.If the numbers of solved pr

hdu 4974 A simple water problem(数学题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4974 Problem Description Dragon is watching competitions on TV. Every competition is held between two competitors, and surely Dragon's favorite. After each competition he will give a score of either 0 or

hdu 4975 A simple Gaussian elimination problem.(网络流,判断矩阵是否存在)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4975 Problem Description Dragon is studying math. One day, he drew a table with several rows and columns, randomly wrote numbers on each elements of the table. Then he counted the sum of each row and col