2015-09-26 79 views
1

我正在寫一個回合制的紙牌遊戲(線上線上撲克)。我有使用rails的經驗,所以我想將它用於大部分邏輯,如使用硬幣和統計管理用戶,管理房間和遊戲。我打算使用節點js + socket.io + redis來提供實時消息服務器 - >客戶端(基本上使用rails的redis發佈消息,在node.js端監聽它們並通過socket.io發佈到客戶端)以及使用REST API從客戶端 - >服務器進行通信。rails turn based game manager

我堅持的部分是試圖管理軌道內的實際遊戲邏輯。我將需要一款遊戲管理器,用於評估遊戲中發生的所有事情(交易卡,接受投注,通過玩家輪流,評估結果等)。特別是兩件事情,似乎有點不可能給我,這是從我的經驗建設的webapps這種情況下,與軌道至今:

  • 具有遊戲管理器在內存中一個單一的共享對象: 我想這可能是一個redis緩存的對象,並將在每次狀態更改時重新加載,並以新狀態再次保存,這似乎是一個很大的開銷。 我正在考慮的另一件事是持有一個遊戲管理器對象的散列,每個進行中的遊戲都是一個靜態對象,可以從rails應用程序的任何地方訪問。我在這裏失蹤的任何東西?這可以通過某種方式改進,或者採取其他方法來完成這種功能?

  • 有一個計時器在等待玩家進行移動時發出嘀嗒聲 與任何回合制遊戲一樣,我需要等待特定秒數直到玩家反應,如果玩家沒有采取行動讓說20秒,然後服務器應該自動移動到下一個玩家。 我真的不知道如何在rails中做到這一點。我正在考慮的一種方法是延遲任務,它將在20秒後運行,並且如果用戶在其之前採取行動,玩家將轉向或被取消。 (使用sidekiq來完成這些任務)。

編輯

我卡在設計如何實現實際的遊戲邏輯,這就是爲什麼我需要一個遊戲管理員,需要有一個計時器滴答每一個活動的遊戲每隔1秒(至少有2名玩家的遊戲),如果玩家不轉向下一個玩家,則需要在x秒後進行回叫。由於每個請求的無狀態性質,我不明白我該如何在rails中執行此操作,因此我需要將遊戲狀態存儲在內存中並以某種方式運行計時器。 我相信我可以在node.js中的遊戲邏輯中解決這個特定問題,但我寧願使用node.js來管理套接字連接並通過redis pub/sub接收事件。

+0

NICE - 在Rails中製作基於回合的遊戲是一個偉大的項目:) –

回答

2

這將是相當抽象的,我希望你不介意。


遊戲管理器

會是什麼game manager實際上

你說你想讓它在內存中運行 - 爲什麼?應用程序基於輸入/輸出運行。除非你想以某種定時響應格式(發送通知消息等)來使用它,否則遊戲經理的想法實際上是無用的。

你需要的是一種處理系統中個人遊戲的方法。這可能需要大量的JavaScript實現,但從Rails的角度來看,沒有必要在後端過度使用。

請記住,你只是在尋找實時邏輯。這並不意味着您必須在服務器上運行實時應用程序。相反,您可以在後端使用Rails的模型和業務邏輯來處理它。

這只是一個簡單的例子:

#app/models/game.rb 
class Game < ActiveRecord::Base 
    #columns id | name | active (bool) | created_at | updated_at 
    has_many :players 
end 

#app/models/player.rb 
class Player < ActiveRecord::Base 
    #columns id | game_id | user_id | created_at | updated_at 
    belongs_to :game 
    belongs_to :user 

    alias_attribute :joined, :created_at 
end 

#app/models/user.rb 
class User < ActiveRecord::Base 
    has_many :players 
    has_many :games, through: :players 
end 

這是一個非常簡單的例子,但它應該給你如下:

#config/routes.rb 
resources :games, only: [:index, :show] do 
    resources :sessions, path: "", path_names: { new: "join", destroy: "leave" show: "" }, only: [:new, :destroy] #-> url.com/games/:game_id/join 
end 

#app/controllers/games_controller.rb 
class SessionsController < ApplicationController 
    def new 
     @game = Game.find params[:game_id] 
     @session = @game.players.new player_params 
     if @session.save 
     redirect_to @game #-> takes you to url.com/game/23 
     else 
     redirect_to root_url, notice: "Sorry, you cannot join this game" 
     end 
    end 

    private 

    def player_params 
     params.require(:user).permit(:x, :y, :z) 
    end 
end 

我知道這不是嚴格CRUD,但我希望你能理解它的工作原理。

然後,您可以讓你的邏輯你的模型裏面:

#app/models/player.rb 
class Player < ActiveRecord::Base 
    belongs_to :game 
    belongs_to :user 

    alias_attribute :joined, :created_at 

    validates :user, uniqueness: { scope: :game, message: "You're already in this game!" } 
end 

的這個實時方面會從你的服務器如何快速響應的要求。如果你有一個JS前端(爲了讓它看起來很漂亮),你可以用JSON(如API)來ping後端,並在前端處理它們並作出迴應。

-

消息

使用PusherRedis

實時通知的東西將是一個多一點參與的事情來實現,而不是編程方式,但機智。

向連接的客戶端發送推送通知相對簡單 - 只需在Redis中排列消息並使用Pusher將消息發送出去即可。但是,如果你想在沒有輸入的情況下調用消息(如果有時間更新或IE等),你需要在服務器上每運行一個x秒鐘就有一些CRON腳本運行。

這是您可能需要一些單獨功能的地方,但我認爲Rails可以通過一些rake命令來處理它。具有這種類型功能的資源負載是必須理解的。

+0

編輯答案。實際的遊戲管理幾乎與我以爲我會做的一樣。有一個API來調用,後端將管理一切。我正在努力的是在哪裏實施每場比賽的實際時間報價。我不認爲我可以用cron工作來解決問題。 – DArkO

+0

是的,cron可能不是最好的方法。我在想服務器上的應用程序*可以寫成與Rails應用程序一起運行,使用應用程序的數據和服務器上的應用程序的實時數據 –