diff --git a/manual/add-note.php b/manual/add-note.php index 1398e5d006..ef9d63d509 100644 --- a/manual/add-note.php +++ b/manual/add-note.php @@ -1,11 +1,15 @@ :
- ? + question; ?>? (Example: nine) - - - + + + diff --git a/manual/spam_challenge.php b/manual/spam_challenge.php deleted file mode 100644 index 15bf6a5dd7..0000000000 --- a/manual/spam_challenge.php +++ /dev/null @@ -1,66 +0,0 @@ -
-

: ?
+

: question; ?>?
(Example: nine)

- - - + + +
@@ -158,13 +162,13 @@
-

: ?
+

: question; ?>?
(Example: nine)

- - - + + +
diff --git a/src/Spam/Challenge.php b/src/Spam/Challenge.php new file mode 100644 index 0000000000..3a3466990e --- /dev/null +++ b/src/Spam/Challenge.php @@ -0,0 +1,160 @@ + 'zero', + 1 => 'one', + 2 => 'two', + 3 => 'three', + 4 => 'four', + 5 => 'five', + 6 => 'six', + 7 => 'seven', + 8 => 'eight', + 9 => 'nine', + ]; + + private const CHALLENGES = [ + // name, print, generator + 'max' => [ + 'max', + [ + self::class, + 'print_prefix', + ], + ], + 'min' => [ + 'min', + [ + self::class, + 'print_prefix', + ], + ], + 'minus' => [ + [ + self::class, + 'minus', + ], + [ + self::class, + 'print_infix', + ], + [ + self::class, + 'gen_minus', + ], + ], + 'plus' => [ + [ + self::class, + 'plus', + ], + [ + self::class, + 'print_infix', + ], + [ + self::class, + 'gen_plus', + ], + ], + ]; + + private function __construct( + public string $function, + public string $argumentOne, + public string $argumentTwo, + public string $question, + ) { + } + + public static function create(): self + { + $function = array_rand(self::CHALLENGES); + + $challenge = self::CHALLENGES[$function]; + + $a = mt_rand(0, 9); + $argumentOne = self::NUMBERS[$a]; + + $b = isset($challenge[2]) ? $challenge[2]($a) : mt_rand(0, 9); + $argumentTwo = self::NUMBERS[$b]; + + $question = $challenge[1]( + $function, + $argumentOne, + $argumentTwo, + ); + + return new self( + $function, + $argumentOne, + $argumentTwo, + $question, + ); + } + + public static function isValidAnswer( + string $function, + string $argumentOne, + string $argumentTwo, + string $answer, + ): bool { + if (!array_key_exists($function, self::CHALLENGES)) { + return false; + } + + $challenge = self::CHALLENGES[$function]; + + $a = array_search($argumentOne, self::NUMBERS, true); + + if (!is_int($a)) { + return false; + } + + $b = array_search($argumentTwo, self::NUMBERS, true); + + if (!is_int($b)) { + return false; + } + + $expected = self::NUMBERS[$challenge[0]($a, $b)]; + + return $expected === $answer; + } + + private static function plus(int $a, int $b): int + { + return $a + $b; + } + + private static function gen_plus(int $a): int + { + return mt_rand(0, 9 - $a); + } + + private static function minus(int $a, int $b): int + { + return $a - $b; + } + + private static function gen_minus(int $a): int + { + return mt_rand(0, $a); + } + + private static function print_infix(string $name, string $a, string $b): string + { + return "$a $name $b"; + } + + private static function print_prefix(string $name, string $a, string $b): string + { + return "$name($a, $b)"; + } +} diff --git a/tests/test-answer.phpt b/tests/Spam/Challenge/is-valid-answer.phpt similarity index 94% rename from tests/test-answer.phpt rename to tests/Spam/Challenge/is-valid-answer.phpt index 235d68cd76..e948e166be 100644 --- a/tests/test-answer.phpt +++ b/tests/Spam/Challenge/is-valid-answer.phpt @@ -1,9 +1,13 @@ --TEST-- -test_answer() returns true when answer to spam challenge is valid +Challenge::isValidAnswer() returns true when answer to spam challenge is valid --FILE-- $function, - 'argumentOne' => $argumentOne, - 'argumentTwo' => $argumentTwo, - 'question' => $question, + 'function' => $challenge->function, + 'argumentOne' => $challenge->argumentOne, + 'argumentTwo' => $challenge->argumentTwo, + 'question' => $challenge->question, ]; }, range(1, 20));