Coverage Report

Created: 2025-09-03 03:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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