<?php
declare(strict_types=1);
namespace Anon\Quiz;
class QuestionException extends \Exception {}
abstract class Question
{
protected $text;
protected $correctAnswer;
public function __construct(string $text, $correctAnswer)
{
$this->text = $text;
$this->correctAnswer = $correctAnswer;
}
public function getQuestionText(): string
{
return $this->text;
}
public function getCorrectAnswer()
{
return $this->correctAnswer;
}
abstract public function getQuestionTips(): string;
abstract public function checkAnswer($userAnswer): bool;
}
class NumericQuestion extends Question
{
private $answerDeviation;
public function __construct(string $text, float $correctAnswer, float $answerDeviation)
{
parent::__construct($text, $correctAnswer);
$this->answerDeviation = $answerDeviation;
}
public function getQuestionTips(): string
{
$output = "Введите вариант ответа. Допустимая погрешность - {$this->answerDeviation}.";
return $output;
}
public function checkAnswer($userAnswer): bool
{
$leftLimit = $this->correctAnswer - $this->answerDeviation;
$rightLimit = $this->correctAnswer + $this->answerDeviation;
return ($userAnswer >= $leftLimit && $userAnswer <= $rightLimit);
}
}
class ChoiceQuestion extends Question
{
private $choices = array();
public function __construct
(string
$text, string
$correctAnswer, array $choices) {
throw new QuestionException('Массив с вариантами ответов пуст.');
}
parent::__construct($text, $correctAnswer);
$this->choices = $choices;
}
public function getQuestionTips(): string
{
$output = "Варианты ответа:\n";
foreach ($this->choices as $choiceIndex => $choiceText) {
$output .= " {$choiceIndex}) {$choiceText}\n";
}
}
public function checkAnswer($userAnswer): bool
{
return $userAnswer == $this->correctAnswer;
}
public function getAvailableChoices
(): array {
return $this->choices;
}
}
class QuestionWriter
{
private $questions = array();
public function addQuestion(Question $question): void
{
$this->questions[] = $question;
}
public function addQuestions
(array $questions): void
{
throw new QuestionException('Переданный массив с вопросами пуст.');
}
foreach ($questions as $question) {
$this->addQuestion($question);
}
}
public function writeQuestions(): void
{
$output = '';
$questionNumber = 1;
foreach ($this->questions as $question) {
$output .= "$questionNumber. {$question->getQuestionText()}\n\n";
$output .= "{$question->getQuestionTips()}\n\n\n";
$questionNumber++;
}
}
public function writeAnswers
(array $userAnswers): void
{
$output = '';
$questionNumber = 1;
foreach ($this->questions as $question) {
$arrayIndex = $questionNumber - 1;
if (!isset($userAnswers[$arrayIndex])) {
throw new QuestionException("Ответ на вопрос не найден (индекс $arrayIndex)");
}
$userAnswer = $userAnswers[$arrayIndex];
$result = $question->checkAnswer($userAnswer);
$output .= "$questionNumber. Ваш ответ - $userAnswer. ";
$output .= $result ? "Верно!" : "Неверно! Правильный ответ - {$question->getCorrectAnswer()}.";
$output .= "\n";
$questionNumber++;
}
}
}
function getQuestions
(): array {
$questions[] = new ChoiceQuestion('В каком фильме Георгия Данелия низшим сословиям предписывалось носить цак?', 'b',
array('a' => 'Новая планета', 'b' => 'Кин-дза-дза!',
'c' => 'Убить Билла',
'd' => 'Не грози Южному Централу, попивая сок у себя в квартале'
));
$questions[] = new ChoiceQuestion('Первый и последний президент Советского Союза?', 'd',
'b' => 'Черненко',
'c' => 'Ельцин',
'd' => 'Горбачев'
));
$questions[] = new NumericQuestion('Чему равняется число Пи?', 3.14, 0.002);
$questions[] = new NumericQuestion('Сколько существует чудес света?', 7, 0);
return $questions;
}
$questions = getQuestions();
$questionWriter = new QuestionWriter();
$questionWriter->addQuestions($questions);
$questionWriter->writeQuestions();
$answers = array('b', 'c', 3.141592, 8);
echo "\n\n\n";
$questionWriter->writeAnswers($answers);