# Slots game project - Social iOS App 為例
```flow
st=>start: main
enter=>operation: AppDelegate::applicationDidFinishLaunching()
isLogin=>condition: 曾經登入
login=>operation: Login Scene
lobby=>operation: Lobby Scene
select=>operation: Select Game
e=>end: Enter Game
st->enter->isLogin
isLogin(no)->login->lobby
isLogin(yes)->lobby->select->e
```
## Client 和 Server 之間的溝通
一般來說傳輸資料的兩端會分為 客戶端 ( Client ) 跟 伺服器端 ( Server )
Client: 主要會發送 「 請求 request 」到 Server 端
Server: 收到 request 開始處理資料,完成後會回傳 「回應 response 」到 Client 端
```sequence
Clent->Server: 發送 HttpRequest
Server->Clent: 回傳 HttpResponse
```
### Login Phase
```sequence
Clent->Server: PreConfigurationRequest
Note right of Server: PreConfigurationServlet
Server->Clent: PreConfigurationResponse
Note left of Clent: 畫面導到Login Scene
Clent->Server: LoginRequest
Note right of Server: LoginServlet
Server->Clent: LoginResponse
Clent->Server: GameListRequest
Note right of Server: GameListServlet
Server->Clent: GameListResponse
Note left of Clent: 畫面進入Lobby
```
### Select Game Phase
```sequence
Note left of Clent: 點擊遊戲Icon
Clent->Server: 發送 SelectGameRequest
Note right of Server: SelectGameServlet
Server->Clent: SelectGameResponse
Note left of Clent: 從SelectGameResponse取得PlayerMathData, PaytableData等資料並進入遊戲畫面
```
```c++=
//每次spin都會產生一筆PlayerMathData紀錄.
class PlayerMathData : public Payload {
}
```
```c++=
//賠付表
class PaytableData {
}
```
## Project 架構 - Game Releated
```graphviz
digraph hierarchy {
nodesep=1.0 // increases the separation between nodes
node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
edge [color=Blue, style=dashed] //All the lines look like this
GameFactory->{IntroAnimation OutroAnimation GameBackground GameLayer Paytable GameReels GameIcon}[label="create", fontcolor=darkgreen]
GameReels->{GameReel GameSymbol}[label="create", fontcolor=darkgreen]
}
```
### GameFactory
主要功能為創建遊戲相關的元件和預載資源(圖資/音效).
### GameBackground
設定一般遊戲以及免費遊戲的背景.
### GameIcon
都用Spine產生Icon居多, 故可繼承**SpineIcon** class省去大量的common code
```c++=
class SpineIcon : public GameIcon {
}
```
### GameLayer
```flow
st=>start: GameLayer::load()
enter=>operation: GameLayer::onEnter()
spin=>operation: 玩家按下spin(GameLayer::spin())
spinCallback=>operation: 收到Server回覆後, 通知輪軸停下的符號(stops), 當輪軸停到正確位置後
setEndSpinState=>operation: GameLayer::setEndSpinState()
st->enter->spin->spinCallback->setEndSpinState
```
```c++=
void GameLayer::load() {
//載入資源
//加入Background
//加入Reels
//加入Game Control以及設定相關Callback
}
```
```c++=
void GameLayer::onEnter() {
//SelectGameResponse回傳上次遊戲的PlayerMathData, client根據此PlayerMathData設定遊戲畫面
}
```
```c++=
void GameLayer::spin() {
//通知輪軸開始滾動
reels->spin([=] {
});
//發送SpinRequest to Server
GameManager::spin(_game, _selections, _creditPerSelection, _anteBetLevel, [=] (std::shared_ptr<SlotSpinResponse> response) {
//等到收到Server回覆後通知Reels設定Stops
rls->setStops(mathData->getStops(), mathData, response->getLevelsPassed().size() > 0 || ProgressiveState::getTotalQueuedProgressiveWinTotal() > 0);
});
}
```
```c++=
void GameLayer::setEndSpinState() {
if(_mathData->isTriggeredFreeGamesFromBaseGame()) {
//一般遊戲觸發免費遊戲流程:
//如果有win進行賠付
//顯示Intro Animation
//Intro Animation顯示後, 則開始免費遊戲
} else if(_mathData->isTriggeredBonusPick()) {
//觸發Bonus Pick(小遊戲)流程:
//如果有win進行賠付
//顯示Intro Animation
//Intro Animation顯示後, 則開始小遊戲
} else if(this->isFreeSpin() || _mathData->isLastFreeGame()) {
//免費遊戲流程
} else if(this->isAutoSpin()) {
//一般遊戲且在自動模式下的流程
} else {
//一般遊戲且非自動模式下的流程
}
// 根據以上不同的情境, 有win會進行賠付, 反之則在免費遊戲或自動遊戲時會自行下一場遊戲
}
```
### GameReels, GameReel, GameSymbol

此GameReels上有5個GameReel, 每個GameReel上顯示3個GameSymbol.
```c++=
void NutcrackerReels::setStops(const std::vector<int>& stops, std::shared_ptr<PlayerMathData> mathData, bool jackpotWonOrLevelUp) {
//根據Reel狀態插入Symbol
for(int column = 0; column < NUM_COLUMNS; column++) {
auto reel = getReel(column);
if(reel->getStatus() == Reel::ReelStatus::Stopped) {
// 當Reel為停止狀態
for(int row = 0; row < NUM_ROWS; row++) {
int symbolidx = stops[column + (row * NUM_COLUMNS)];
auto symbol = NutcrackerSymbol::create(symbolidx, mathData);
reel->insertSymbol(symbol, row);
}
} else {
// 當Reel在滾動時
// 設定stops, 並讓Reel控制stops停在正確的位置
reel->setStopSymbols(stopsForReel, bounceForReel);
}
}
}
```
```c++=
void NutcrackerReels::spin(std::function<void()> spinComplete, std::shared_ptr<PlayerMathData> mathData) {
// GameLayer通知Reels開始滾動, 此時Reels會將之前Server提供的Display reel strip隨機取段插入Reel並開始滾動.
// 直到GameLayer收到Server spin response, 並且Reels設定stops後.
// Reel會依序停下. 當全部Reel都停下後會通知GameLayer
}
```
```c++=
void NutcrackerReels::showSelectionWin(int selection, long long symbolMask, int multiplier) {
// 顯示哪條賠付線(組合), 哪個Symbol贏得獎金.
}
```
### GameMultiplier
- in GameReels.cpp
### IntroAnimation and OutroAnimation
- **Intro Animation**: 進入Free game前的動畫, 通知玩家贏得幾場免費遊戲

- **Outro Animation**: Free game結束後的動畫, 通知玩家在免費遊戲期間總共贏得多少獎金

### Paytable
Game Feature, Wild/Scatter敘述, Paytable, Lines等遊戲介紹