/nix/store/i1aar97n7b4yf8rk94p66if25brfvvdx-gqvzl8a5pvrg3xj44q0msrndcripi8dk-source/src/statefunctions/statecontroller.cc
Line | Count | Source |
1 | | #include "statefunctions/statecontroller.h" |
2 | | |
3 | | #include <array> |
4 | | #include <iostream> |
5 | | #include <map> |
6 | | #include <memory> |
7 | | #include <random> |
8 | | #include <thread> |
9 | | #include <utility> |
10 | | #include <vector> |
11 | | |
12 | | #include "controllers/controllermanager.h" |
13 | | #include "statefunctions/router.h" |
14 | | #include "types/gamestate.h" |
15 | | #include "types/settings.h" |
16 | | #include "types/statefunction.h" |
17 | | |
18 | | namespace mahjong { |
19 | | |
20 | | namespace { |
21 | | int thread_index = 1; |
22 | | std::map<int, bool> should_halt; |
23 | | } // namespace |
24 | | |
25 | 0 | int StartGame(const GameSettings& settings, bool async) { |
26 | 0 | if (async) { |
27 | 0 | std::thread gameloop(&StateController, settings); |
28 | 0 | gameloop.detach(); |
29 | 0 | return thread_index; |
30 | 0 | } |
31 | 0 | StateController(settings); |
32 | 0 | return 0; |
33 | 0 | } |
34 | | |
35 | 0 | void ExitGame(int game) { |
36 | 0 | if (should_halt.contains(game)) { |
37 | | // std::cerr << "Halting Game..." << std::endl; |
38 | 0 | should_halt[game] = true; |
39 | 0 | } |
40 | 0 | } |
41 | | |
42 | 7 | std::unique_ptr<GameState> InitGameState(const GameSettings& settings) { |
43 | 7 | auto state = std::make_unique<GameState>(); |
44 | 35 | for (int i = 0; i < 4; i++) { |
45 | 28 | state->players.at(i).controller = |
46 | 28 | ControllerManager::Instance().NewController( |
47 | 28 | settings.seatControllers.at(i)); |
48 | 28 | } |
49 | 7 | if (settings.seed != 0U) { |
50 | 7 | state->seed = settings.seed; |
51 | 7 | } else { |
52 | 0 | std::random_device rd; |
53 | 0 | state->seed = rd(); |
54 | 0 | } |
55 | 7 | state->nextState = StateFunctionType::kGameStart; |
56 | 7 | return state; |
57 | 7 | } |
58 | | |
59 | 48 | std::unique_ptr<GameState> AdvanceGameState(std::unique_ptr<GameState> state) { |
60 | 48 | try { |
61 | 48 | state->prevState = state->currState; |
62 | 48 | state->currState = state->nextState; |
63 | 48 | return Router::Instance().Route(state->nextState)(std::move(state)); |
64 | 48 | } catch (const unsigned int e) { |
65 | 0 | switch (e) { |
66 | 0 | case 0xBAD22222: // Asked for decision too many times. |
67 | 0 | std::cerr << "Asked for decision too many times" << '\n'; |
68 | 0 | state->nextState = StateFunctionType::kError; |
69 | 0 | break; |
70 | 0 | default: |
71 | 0 | throw(e); |
72 | 0 | } |
73 | 0 | } |
74 | 0 | return state; |
75 | 48 | } |
76 | | |
77 | 0 | void StateController(const GameSettings& settings) { |
78 | 0 | const int id = thread_index++; |
79 | 0 | should_halt[id] = false; |
80 | 0 | std::unique_ptr<GameState> state = InitGameState(settings); |
81 | 0 | while (state->nextState != StateFunctionType::kGameEnd && !should_halt[id]) { |
82 | 0 | state = AdvanceGameState(std::move(state)); |
83 | 0 | } |
84 | 0 | if (state->nextState == StateFunctionType::kGameEnd) { |
85 | 0 | Router::Instance().Route(state->nextState)(std::move(state)); |
86 | 0 | } |
87 | 0 | } |
88 | | |
89 | | } // namespace mahjong |