• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nika3007 / SE_Memory / 21245115618

22 Jan 2026 10:32AM UTC coverage: 54.437% (-0.3%) from 54.778%
21245115618

push

github

web-flow
Enhance README formatting and Docker instructions

Updated README.md to improve formatting and clarify Docker commands.

319 of 586 relevant lines covered (54.44%)

0.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.42
/src/main/scala/controller/controllerComponent/controllerBaseImpl/ControllerImpl.scala
1
package controller.controllerComponent.controllerBaseImpl
2

3
import controller.controllerComponent.{ControllerAPI, GameStatus, Command}
4
import model.*
5
import model.modelComponent.MemoryGameAPI
6
import util.Observable
7

8
import scala.util.Try
9

10
import com.google.inject.Inject
11

12
final class ControllerImpl @Inject() (private val _game: MemoryGameAPI)
13

14
  extends Observable
15
  with ControllerAPI:
16

17
  override def game: MemoryGameAPI = _game
1✔
18

19
  private[controllerComponent] var _gameStatus: GameStatus = GameStatus.Idle
20
  override def gameStatus: GameStatus = _gameStatus
1✔
21

22
  private[controllerComponent] var _currentPlayer: String = "human"
23
  override def currentPlayer: String = _currentPlayer
1✔
24

25
  override def board: Board = game.board
1✔
26

27
  @volatile private[controllerComponent] var cancelThread = false
28

29
  private var undoStack: List[Command] = Nil
30
  private var redoStack: List[Command] = Nil
31

32
  override def aiEnabled: Boolean =
×
33
    !game.ai.isInstanceOf[NoAI]
×
34

35
  private def execute(cmd: Command): Unit =
1✔
36
    cancelThread = false
37
    cmd.doStep()
1✔
38
    undoStack = cmd :: undoStack
1✔
39
    redoStack = Nil
40

41
  override def undo(): Unit =
1✔
42
    cancelThread = true
43
    undoStack match
44
      case cmd :: rest =>
45
        undoStack = rest
×
46
        cmd.undoStep()
×
47
        redoStack = cmd :: redoStack
×
48
      case Nil => ()
1✔
49

50
  override def redo(): Unit =
1✔
51
    redoStack match
52
      case cmd :: rest =>
53
        redoStack = rest
×
54
        cancelThread = false
55
        cmd.doStep()
×
56
        undoStack = cmd :: undoStack
×
57
      case Nil => ()
1✔
58

59
  override def processInput(input: String): Boolean =
1✔
60
    if input == null || input.trim.isEmpty then return false
1✔
61
    if currentPlayer == "ai" then return true
×
62

63
    Try(input.trim.toInt).toOption match
1✔
64
      case Some(i) if i >= 0 && i < board.cards.size =>
1✔
65
        execute(new ChooseCardCommand(this, i))
1✔
66
        true
67
      case _ =>
68
        _gameStatus = GameStatus.InvalidSelection(-1)
1✔
69
        notifyObservers
1✔
70
        true
71

72
  override def aiTurnFirst(): Unit =
×
73
    if currentPlayer == "ai" then
×
74
      execute(new ChooseCardCommand(this, game.ai.chooseCard(board)))
×
75

76
  override def aiTurnSecond(): Unit =
×
77
    if currentPlayer == "ai" then
×
78
      execute(new ChooseCardCommand(this, game.ai.chooseCard(board)))
×
79

80
  private def advanceLevelIfPossible(): Unit =
×
81
    _gameStatus = GameStatus.LevelComplete
82
    notifyObservers
×
83

84
    val hasNext = game.nextLevel()
×
85
    undoStack = Nil
86
    redoStack = Nil
87
    _currentPlayer = "human"
88

89
    if hasNext then
90
      _gameStatus = GameStatus.NextRound
×
91
      notifyObservers
×
92

93
  private[controllerComponent] def handleCardSelection(i: Int): Unit =
1✔
94
    val oldBoard = board
1✔
95
    val (nextBoard, result) = board.choose(i)
1✔
96

97
    if nextBoard.eq(oldBoard) && result.isEmpty then
×
98
      _gameStatus = GameStatus.InvalidSelection(i)
×
99
      notifyObservers
×
100
      return
1✔
101

102
    game.board = nextBoard
1✔
103

104
    result match
105
      case None =>
106
        _gameStatus = GameStatus.FirstCard
1✔
107
        notifyObservers
1✔
108

109
      case Some(true) =>
110
        _gameStatus = GameStatus.Match
1✔
111
        notifyObservers
1✔
112

113
        if game.board.cards.forall(_.isMatched) then
1✔
114
          advanceLevelIfPossible()
×
115

116
      case Some(false) =>
117
        _gameStatus = GameStatus.NoMatch
×
118
        notifyObservers
×
119

120
        new Thread(() =>
×
121
          Thread.sleep(1200)
×
122

123
          if !cancelThread then
124
            game.board = game.board.copy(
×
125
              cards = game.board.cards.map {
×
126
                case c if c.isFaceUp && !c.isMatched => c.flip
×
127
                case c => c
×
128
              }
129
            )
×
130

131
          if !cancelThread then
132
            _currentPlayer =
×
133
              if game.ai.isInstanceOf[NoAI] then "human"
×
134
              else if _currentPlayer == "human" then "ai" else "human"
×
135

136
          _gameStatus = GameStatus.NextRound
137
          notifyObservers
×
138
        ).start()
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc