在服务器端实现游戏转弯超时

时间:2014-01-22 21:58:50

标签: c++ mysql datetime

目前我正在为iOS平台编写一款回合制游戏。客户端使用CocoaTouch在Objective-C中编写,服务器使用C ++编写,用于Ubuntu Server OS。服务器连接到MySQL数据库,在该数据库中存储用户&游戏数据。

现在我希望实现一个时间限制,这必须在服务器端完成。当用户转弯时,下一个用户将有最多24小时的回答,否则我希望游戏跳过此用户并转到下一个玩家。我对如何做到这一点有一些想法,但我不确定它们是否有用。我一直在想的是将最后一个转弯的日期和时间存储为与我的SQL数据库上的Game表相关的实体。然后我想在服务器上启动一个运行直到终止的线程,然后查看当前时间减去每个游戏的最后一个回合,比如每分钟左右。如果从最后一次转弯开始超过24小时,该线程允许队列中的下一个玩家轮到他们,并跳过懒惰的玩家。

听起来过于复杂吗?还有另一种更简单的方法吗?我知道以前在很多游戏中都做过,我只是不知道怎么做。提前谢谢!

3 个答案:

答案 0 :(得分:1)

您可能只想要一个具有“下一步操作”计划的后台进程,这是一种可以在触发事件时可以处理的优先级队列。

如果您正确设计服务器,单个进程可以处理许多独立游戏。该架构将获取一个事件,加载任何相关数据,相应地发送,然后返回等待新事件。

C ++确实有这方面的框架,但你可以很快地在NodeJS或Python的Twisted中对其进行原型设计。

答案 1 :(得分:1)

在这种情况下,我认为你根本不需要任何线程或后台进程。

我在这里看到的是一个简单的算法:

  1. 当用户登录游戏/匹配时 - 检查数据库中的最后回合结束时间
  2. 如果从最后一个回合结束时间开始的经过时间大于24小时,请获取当前时间,从数据库中减去时间(显然您需要将两次转换为小时)并将其除以24,
    • 如果该分区是一个奇数,那就是另一个玩家(玩家A)的转弯
    • 如果分区是一个偶数,那就是玩家B的转弯。
  3. 将数据库时间设置为databaseTime+division*24
  4. 此算法可以跳过多次转弯。当玩家A完成他的移动时,48小时过去了,玩家B就转了。

答案 2 :(得分:1)

请查看reactor模式(boost.asio,ACE)。这些框架是异步的,使用事件驱动的模型并且不需要线程。下面是关于如何解决它的伪代码:

reactor.addTCPListener(acceptSock(), Handler::AcceptSock) // calls AcceptSock when accepting a new TCP connection
rector.addTCPListener(clientSock, Handler::ClientData) // calls ClientData when user is sending the server game stats (its move, status etc)
. 
.
.
later on somewhere
.
.
.
for(set<Game>::Iterator it = games.begin(); it != games.end(); ++it) {
    (it*)->checkTurn() // this call can be responsible for checking the timestamps from the ClientData function
}

要点:

使用reactor模式,您将能够拥有一个非阻塞服务器,可以在不处理IO时执行清理任务。清理可以将时间戳与切换/传递轮次进行比较。