Игра Угадай число: правила, алгоритм и реализации

Отгадать номер – это классическая логическая игра, в которой один игрок (или компьютер) загадывает целое число из заданного диапазона, а второй пытается его угадать, получая подсказки «меньше», «больше» или «угадано»․ В статье мы разберём:

  • правила и варианты игры;
  • математический фундамент – бинарный поиск;
  • алгоритм реализации на разных языках (C, C++, Python, Java);
  • советы по оптимизации и интересные варианты․

Правила классической версии

Самая простая форма выглядит так:

  1. Загадать целое число n в диапазоне [L, R] (обычно от 1 до 100)․
  2. Игрок делает предположение x․
  3. Ведущий отвечает:
    • «меньше», если x > n;
    • «больше», если x < n;
    • «угадано», если x = n․
  4. Игра продолжается, пока число не будет отгадано․

Вариации правил

  • Ограничение по попыткам․ Часто задают максимум 7–10 попыток․
  • Разные диапазоны․ Можно использовать от 0 до 99, от 1 до 1000 и т․д․
  • Мультиплеер․ Два игрока поочерёдно загадывают числа․
  • Автоматический помощник․ Бот, который сам угадывает число, используя бинарный поиск․

Математический фундамент: бинарный поиск

Бинарный поиск – это оптимальный алгоритм для угадывания числа, когда каждый ответ «меньше/больше» позволяет исключать ровно половину оставшегося диапазона․ За ⌈log₂(N)⌉ попыток можно найти любое число из диапазона из N значений․

Пример: диапазон 1‑100․ За 7 попыток (⌈log₂100⌉ = 7) можно гарантированно отгадать число․

Псевдокод бинарного поиска


left = L
right = R
while left <= right:
 mid = (left + right) // 2
 print("Ваше число:", mid)
 answer = input("Больше (b), меньше (m) или угадано (y)? ")
 if answer == 'y':
 break
 elif answer == 'b':
 left = mid + 1
 else:
 right = mid ‒ 1

 

Реализация игры «Угадай число»

3․1 На языке C

Код ниже генерирует случайное число в диапазоне 1‑100 и позволяет пользователю угадывать, пока он не справится․


#include <stdio․h>
#include <stdlib․h>
#include <time․h>

int main(void) {
 int left = 1, right = 100;
 int secret, guess;
 int attempts = 0;

 srand((unsigned)time(NULL));
 secret = left + rand % (right ‒ left + 1);
 printf("Я загадал число от %d до %d․ Попробуйте отгадать!
", left, right);

 while (1) {
 printf("Введите ваш вариант: ");
 if (scanf("%d", &guess) != 1) {
 printf("Ошибка ввода!
");
 return 1;
 }
 attempts++;

 if (guess == secret) {
 printf("Поздравляю! Вы угадали число %d за %d попыток․
", secret, attempts);
 break;
 } else if (guess < secret) {
 printf("Загаданное число больше․
"); } else {
 printf("Загаданное число меньше․
");
 }
 }
 return 0;
}

 

3․2 На языке C++ (с использованием бинарного поиска)


#include <iostream>
using namespace std;

int main {
 int left = 1, right = 100, mid, attempts = 0;
 char reply;
 cout << "Загадайте число от 1 до 100, а я попробую его отгадать․
";
 while (left <= right) {
 mid = (left + right) / 2;
 attempts++;
 cout << "Мой вариант: " << mid << "․ Правильно? (y=да, b=больше, m=меньше): ";
 cin >> reply;
 if (reply == 'y') {
 cout << "Ура! Я отгадал за " << attempts << " попыток․
"; break;
 } else if (reply == 'b') {
 left = mid + 1;
 } else {
 right = mid — 1;
 }
 }
 return 0;
}

 

3․3 На языке Python

Python позволяет написать игру в несколько строк благодаря функции random․randint и простому вводу․


import random

LEFT, RIGHT = 1, 100
secret = random․randint(LEFT, RIGHT)
attempts = 0

print(f"Я загадал число от {LEFT} до {RIGHT}․ Попробуйте отгадать!")

while True:
 try:
 guess = int(input("Ваш вариант: "))
 except ValueError:
 print("Введите целое число!")
 continue

 attempts += 1
 if guess == secret:
 print(f"Поздравляю! Вы угадали число {secret} за {attempts} попыток․")
 break
 elif guess < secret:
 print("Загаданное число больше․")
 else:
 print("Загаданное число меньше․")

 

3․4 На языке Java


import java․util․Random;
import java․util․Scanner;

public class GuessNumber {
 public static void main(String[] args) {
 final int LEFT = 1;
 final int RIGHT = 100;
 Random rnd = new Random;
 int secret = LEFT + rnd․nextInt(RIGHT — LEFT + 1);
 Scanner sc = new Scanner(System․in);
 int attempts = 0;

 System․out․println("Я загадал число от " + LEFT + " до " + RIGHT + "․ Попробуйте отгадать!");
 while (true) {
 System․out․print("Ваш вариант: ");
 int guess = sc․nextInt;
 attempts++;

 if (guess == secret) {
 System․out․println("Поздравляю! Вы угадали число " + secret + " за " + attempts + " попыток․");
 break;
 } else if (guess < secret) {
 System․out․println("Загаданное число больше․");
 } else {
 System․out․println("Загаданное число меньше․");
 }
 } sc․close;
 }}

 

Как выиграть в «Угадай число» (для игрока)

Если вы играете против компьютера, используйте тот же принцип бинарного поиска:

  1. Установите границы L и R․
  2. Сделайте первую догадку mid = (L+R)//2․
  3. В зависимости от ответа сдвигайте границу:
    • Если сказали «меньше», то R = mid-1․
    • Если сказали «больше», то L = mid+1․
  4. Повторяйте, пока не угадаете․

Эта стратегия гарантирует победу за ⌈log₂(N)⌉ попыток․

Расширенные варианты игры

5․1 Игра с ограничением по времени

Можно добавить таймер (например, 30 секунд)․ В C# или Python с модулем threading это делается легко․

5․2 Многопользовательская онлайн‑версия

<html lang="ru">
<head>
 <meta charset="UTF-8">
 <>Угадай число</>
</head>
<body>
 <h2>Игра «Угадай число»</h2>
 <input type="number" id="guess" placeholder="Введите число">
 <button onclick="check">Проверить</button>
 <p id="msg"></p>

 <script>
 const LEFT = 1, RIGHT = 100;
 const secret = Math․floor(Math․random * (RIGHT ‒ LEFT + 1)) + LEFT;
 let attempts = 0;

 function check {
 const g = Number(document․getElementById('guess')․value);
 attempts++;
 if (g === secret) { } else if (g < secret) { } else { }
 }
 </script>
</body>
 

5․3 Игра с «подсказками» (например, «горячо‑холодно»)

Каждая попытка может возвращать расстояние до загаданного числа, что делает игру более интерактивной․

Ошибки, которых следует избегать

  • Неправильный диапазон․ Убедитесь, что случайное число генерируется в том же диапазоне, что и проверка ввода․
  • Необработанные вводы․ Пользователь может ввести нечисло – всегда проверяйте scanf, try/except и т․п․
  • Бесконечный цикл․ При использовании while всегда проверяйте условие выхода․
  • Переполнение при вычислении средней точки․ В C/C++ лучше писать mid = left + (right, left) / 2, чтобы избежать overflow․

Игра «Отгадать номер» – отличный способ отточить навыки логического мышления, изучить базовые алгоритмы (особенно бинарный поиск) и попрактиковаться в программировании․ Мы рассмотрели правила, математическую основу, привели готовые примеры кода на популярных языках и обсудили стратегии победы․

Попробуйте реализовать свою версию, добавьте новые правила, сделайте её многопользовательской или превратите в веб‑приложение – возможности безграничны!


Дата генерации статьи: 03:51:39 ()