Completed
Push — master ( a021a5...5bf4c0 )
by Kirill
02:09
created

GameService::checkAnswer()   C

Complexity

Conditions 8
Paths 6

Size

Total Lines 76
Code Lines 46

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 76
rs 6.1941
c 0
b 0
f 0
cc 8
eloc 46
nc 6
nop 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Chrl\AppBundle\Service;
4
5
use Chrl\AppBundle\Entity\Question;
6
use Doctrine\ORM\EntityManager;
7
use Doctrine\ORM\EntityManagerInterface;
8
use Chrl\AppBundle\Entity\Game;
9
use Chrl\AppBundle\Entity\User;
10
use Chrl\AppBundle\BuktopuhaBotApi;
11
12
/**
13
 * Game service
14
 *
15
 * @category Symfony
16
 * @package  Chrl_Buktopuha
17
 * @author   Kirill Kholodilin <[email protected]>
18
 * @license  http://www.gnu.org/copyleft/gpl.html GNU General Public License
19
 * @link     https://take2.ru/
20
 */
21
22
class GameService
23
{
24
    /** @var EntityManager */
25
    public $em;
26
    /** @var BuktopuhaBotApi */
27
    private $botApi;
28
29
	private $config;
30
31
    public function __construct(BuktopuhaBotApi $telegramBotApi, $config, EntityManagerInterface $entityManager)
32
    {
33
        $this->em = $entityManager;
0 ignored issues
show
Documentation Bug introduced by
$entityManager is of type object<Doctrine\ORM\EntityManagerInterface>, but the property $em was declared to be of type object<Doctrine\ORM\EntityManager>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
34
        $this->botApi = $telegramBotApi;
35
		$this->config = $config;
36
    }
37
38
39
    /**
40
     * @return Game
41
     */
42
    public function findGame(array $message)
43
    {
44
        $game = $this->em->getRepository('AppBundle:Game')->findOneBy(['chatId'=>$message['chat']['id']]);
45
        if (!$game) {
46
            // create game
47
            $game = new Game();
48
            $game->status = 0;
49
            $game->chatId = $message['chat']['id'];
50
            $game->title = isset($message['chat']['title'])
51
                ? $message['chat']['title']
52
                : 'No title';
53
54
            $this->em->persist($game);
55
            $this->em->flush();
56
        }
57
        return $game;
58
    }
59
60
61
    public function getCurrentUser(array $message)
62
    {
63
        $user = $this->em->getRepository('AppBundle:User')->findOneBy(['tgId'=>$message['from']['id']]);
64
        if (!$user) {
65
            $user = new User();
66
            $user->setName(
67
                (
68
                    isset($message['from']['first_name'])
69
                    ? $message['from']['first_name']
70
                    : ''
71
                )
72
                .' '.
73
                (
74
                isset($message['from']['last_name'])
75
                    ? $message['from']['last_name']
76
                    : ''
77
                )
78
            );
79
            $user->setAlias($message['from']['username']);
80
            $user->setTgId($message['from']['id']);
81
            $user->setGame($this->findGame($message));
82
            $user->setChatId($message['chat']['id']);
83
            $user->setPoints(0);
84
85
            $this->em->persist($user);
86
            $this->em->flush();
87
        }
88
        return $user;
89
    }
90
91
    public function getActiveGames()
92
    {
93
        $games = $this->em->getRepository('AppBundle:Game')->findBy(['status'=>1]);
94
        return $games;
95
    }
96
    public function getInactiveGames()
97
    {
98
        $games = $this->em->getRepository('AppBundle:Game')->findBy(['status'=>0]);
99
        return $games;
100
    }
101
102
103
	/**
104
	 * Checks if the answer is correct, and asks next question
105
	 *
106
	 * @param array $message
107
	 */
108
    public function checkAnswer($message)
109
    {
110
        $game = $this->findGame($message);
111
        $user = $this->getCurrentUser($message);
112
113
        if ($game->status == 1) {
114
            /** @var Question $question */
115
            $question = $this->em->getRepository('AppBundle:Question')->find($game->lastQuestion);
116
117
            if (!$question) {
118
                return;
119
            }
120
121
            if (mb_strtoupper($question->a1, 'UTF-8') == mb_strtoupper($message['text'], 'UTF-8')) {
122
                // Correct answer!
123
124
                $user->setPoints($user->getPoints()+$question->price);
125
                $this->em->persist($user);
126
127
                $this->botApi->sendMessage(
128
                    $game->chatId,
129
                    'Correct! @'.$user->getAlias().' gets *'.
130
                    $question->price.'* and now has *'.$user->getPoints().'* points!',
131
                    'markdown',
132
                    false,
133
                    $message['message_id']
134
                );
135
136
                $question->correct++;
137
                $this->em->persist($question);
138
139
                $this->askQuestion($game);
140
            } else {
141
                // Incorrect answer
142
                $game->incorrectTries++;
143
				$hint = $game->hint;
144
145
				if (mb_substr_count($hint,'*','UTF-8') >= mb_strlen($hint,'UTF-8')/2) {
146
					//tell hint
147
148
					for($t = 0; $t< mb_strlen($hint);$t++) {
149
						if (mb_substr($hint,$t,1,'UTF-8') == '*') {
150
							if (rand(0,1)==1) {
151
								$hint = mb_substr($hint,0,$t,'UTF-8')
152
										.mb_substr($question->a1,$t,1)
153
										.mb_substr($hint,$t+1);
154
								break;
155
							}
156
						}
157
					}
158
159
					$game->hint = $hint;
160
161
					$this->botApi->sendMessage(
162
						$game->chatId,
163
						'<b>Hint</b>: '.$hint,
164
						'html'
165
					);
166
167
				} else {
168
					$this->botApi->sendMessage(
169
						$game->chatId,
170
						'Noone answered, correct answer was: *'.$question->a1.'*',
171
						'markdown'
172
					);
173
					$this->em->persist($game);
174
					$this->em->flush();
175
					$this->askQuestion($game);
176
				}
177
178
            }
179
180
            $this->em->persist($game);
181
            $this->em->flush();
182
        }
183
    }
184
185
	/**
186
	 * Asks question in the game
187
	 *
188
	 * @param Game $game
189
	 */
190
191
    public function askQuestion(Game $game)
192
    {
193
		$question = $this->getRandomQuestion();
194
195
		$question->played++;
196
197
		$game->lastQuestion = $question->getId();
198
		$game->lastQuestionTime = new \DateTime('now');
199
		$game->incorrectTries = 0;
200
		$game->hint = str_repeat('*',mb_strlen($question->a1,'UTF-8'));
201
202
		$this->em->persist($game);
203
		$this->em->persist($question);
204
		$this->em->flush();
205
206
        $this->botApi->sendMessage($game->chatId, '*[question]* '.$question->text.' _('.mb_strlen($question->a1,'UTF-8').' letters)_', 'markdown');
207
    }
208
209
    /**
210
	 * Gets random question from database
211
	 *
212
     * @return Question
213
     * @throws \Doctrine\ORM\NoResultException
214
     * @throws \Doctrine\ORM\NonUniqueResultException
215
     */
216
    public function getRandomQuestion()
217
    {
218
        $count = $this->em->createQueryBuilder()
219
            ->select('COUNT(u)')->from('AppBundle:Question', 'u')
220
            ->getQuery()
221
            ->getSingleScalarResult();
222
223
        return $this->em->createQuery('SELECT c FROM AppBundle:Question c ORDER BY c.id ASC')
224
            ->setFirstResult(rand(0, $count - 1))
225
            ->setMaxResults(1)
226
            ->getSingleResult();
227
    }
228
}
229