我正在为 iOS 开发 BlackJack 游戏。跟踪当前状态和需要做的事情变得越来越困难。例如,我有一个跟踪当前游戏的 C++ 类:
class Game {
queue<Player> playerQueue;
void hit();
void stand();
}
目前我正在使用事件(方法 A)实现它:
- (void)hitButtonPress:(id)sender {
game->hit();
}
void Game::hit() {
dealCard(playerQueue.top());
}
void Game::stand() {
playerQueue.pop();
goToNextPlayersTurn();
}
随着越来越多的选项被添加到游戏中,为每个选项创建事件变得乏味且难以跟踪。
我想到的另一种实现方式是这样的(方法B):
void Game::playersTurn(Player *player) {
dealCards(player);
while (true) {
string choice = waitForUserChoice();
if (choice == "stand") break;
if (choice == "hit")
dealCard(player);
// etc.
}
playerQueue.pop();
goToNextPlayersTurn();
}
其中 waitForUserChoice 是一个特殊函数,它让用户与 UIViewController 交互,一旦用户按下按钮,然后才将控制返回给 playersTurn 功能。换句话说,它会暂停程序,直到用户点击按钮。
使用方法 A,我需要在每次需要用户交互时拆分我的功能。方法 B 让一切都更加可控。 方法 A 和 B 之间的本质区别如下:
答:
function A() {
initialize();
// now wait for user interaction by waiting for a call to CompleteA
}
function CompleteA() {
finalize();
}
乙:
function B() {
initialize();
waitForUserInteraction();
finalize();
}
注意 B 如何使代码更有条理。甚至有办法用 Objective-C 做到这一点吗?或者是否有我没有提到的其他推荐方法?
我能想到的第三种选择是使用有限状态机。我听说过一些关于它们的信息,但我确定在这种情况下这是否对我有帮助。
针对我的问题推荐的设计模式是什么?
最佳答案
我理解您遇到的困境。当我第一次使用 iOS 时,我很难集中精力放弃对操作系统的控制权。
通常 iOS 会鼓励您使用方法 A。通常您的 ViewController 中有变量,这些变量是在方法 A() 中设置的,然后在 CompleteA() 中检查它们以验证 A() 是否先运行等。
关于您关于有限状态机的问题,我认为它可以帮助您解决问题。我在 iOS 中写的第一件事是 FSM(这是非常糟糕的代码)但是你可以在这里看看(靠近 FlipsideViewController.m 的底部:
https://github.com/esromneb/ios-finite-state-machine
一般的想法是将它放在@interface block 内的 .h 文件中
static int state = 0;
static int running = 0;
在你的 .m 中你有这个:
- (void) tick {
switch (state) {
case 0:
//this case only runs once for the fsm, so setup one time initializations
// next state
state = 1;
break;
case 1:
navBarStatus.topItem.title = @"Connecting...";
state = 2;
break;
case 2:
// if something happend we move on, if not we wait in the connecting stage
if( something )
state = 3;
else
state = 1;
break;
case 3:
// respond to something
// next state
state = 4;
break;
case 4:
// wait for user interaction
navBarStatus.topItem.title = @"Press a button!";
state = 4;
globalCommand = userInput;
// if user did something
if( globalCommand != 0 )
{
// go to state to consume user interaction
state = 5;
}
break;
case 5:
if( globalCommand == 6 )
{
// respond to command #6
}
if( globalCommand == 7 )
{
// respond to command #7
}
// go back and wait for user input
state = 4;
break;
default:
state = 0;
break;
}
if( running )
{
[self performSelector:@selector(tick) withObject:nil afterDelay:0.1];
}
}
在这个例子中(从 github 上的那个修改而来)globalCommand 是一个代表用户输入的 int。如果 globalCommand 为 0,则 FSM 仅在状态 4 中旋转,直到 globalCommand 不为零。
要启动 FSM,只需将 running 设置为 1 并从 viewController 调用 [self tick]。 FSM 将每 0.1 秒“滴答”一次,直到运行设置为 0。
在我最初的 FSM 设计中,我必须响应用户输入和来自运行其自身软件的 Windows 计算机的网络输入。在我的设计中,Windows PC 也运行类似但不同的 FSM。对于此设计,我使用 NSMutuableArray 构建了两个命令的 FIFO 队列对象。用户交互和网络数据包会将命令排入队列,而 FSM 会将项目出列并对其做出响应。我最终使用了 https://github.com/esromneb/ios-queue-object对于队列。
如果您需要任何说明,请发表评论。
关于ios - 在 iOS 中等待用户交互的设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14995611/
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
这可能是个愚蠢的问题。但是,我是一个新手......你怎么能在交互式rubyshell中有多行代码?好像你只能有一条长线。按回车键运行代码。无论如何我可以在不运行代码的情况下跳到下一行吗?再次抱歉,如果这是一个愚蠢的问题。谢谢。 最佳答案 这是一个例子:2.1.2:053>a=1=>12.1.2:054>b=2=>22.1.2:055>a+b=>32.1.2:056>ifa>b#Thecode‘if..."startsthedefinitionoftheconditionalstatement.2.1.2:057?>puts"f
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下
我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的
给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称