Игры
14.3. Игра "Отгадай числа"
"Отгадай числа" — это игра для двух участников, которая состоит в следующем. Игроки загадывают по n целых чисел в пределах от 0 до 9 включительно, числа не повторяются. Цель игры — найти набор чисел, который загадал противник. Порядок чисел в наборе значения не имеет. Участник называет n чисел. Если среди них более половины совпадают с числами, загаданными противником, то право хода остается за ним. В противном случае ход переходит к другому игроку. Побеждает игрок, который первым правильно назовет весь набор чисел, загаданный противником. Данная игра является одним из вариантов игры "Быки и коровы" [9], в котором имеются только "коровы".
Приведенная ниже программа — это реализация игры человека с компьютером. Значение n запрашивается у пользователя. Компьютер загадывает набор n попарно-различных случайных чисел. Пользователь вводит числа через пробел. Первым ходит компьютер.
open core, console, list constants diglist : unsigned* = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]. class facts num: (unsigned, unsigned*, positive). digs : unsigned* := []. n : positive := 0. class predicates readDigits: (positive) -> unsigned*. add: (unsigned, unsigned*, unsigned* [out], positive, positive [out]). gen: (positive, unsigned) -> unsigned*. gen: (positive, unsigned, unsigned*) -> unsigned*. count: (unsigned*, unsigned*) -> positive. f: (positive) -> string. clauses readDigits(N) = reverse(digs):- writef("Введите % % от 0 до 9 через пробел: > ", N, f(N)), digs := [], n := N, std::repeat(), try hasDomain(unsigned, X), X = read() catch _ do clearInput(), write("\nПовторите попытку: > "), fail end try, add(X, digs, L, n, N1), digs := L, n := N1, n = 0, clearInput(), !. readDigits(_) = []. f(N) = "чисел":- N > 4, !. f(_) = "числа". gen(N, R) = reverse(gen(N, R, [])). gen(N, R, L) = gen(N1, R, L1):- N > 0, !, add(math::random(R), L, L1, N, N1). gen(_, _, L) = L. add(X, L, [X | L], N, N - 1):- X < 10, not(isMember(X, L)), !. add(_, L, L, N, N). count(L, L1) = length(filter(L, {(X):- isMember(X, L1)})). class predicates game: (positive). game: (positive, unsigned, unsigned*, unsigned*). game: (positive, unsigned, unsigned*, unsigned*, positive). move: (unsigned, positive) -> unsigned*. writeMessage: (unsigned, unsigned*, unsigned*). writeVariants: (unsigned). subset: (positive, unsigned*) -> unsigned* nondeterm. candidate: (positive) -> unsigned* nondeterm. isBad: (unsigned*) determ. toStr: (unsigned) -> string. clauses subset(0, _) = []:- !. subset(N, [X | L]) = [X | subset(N - 1, L)]. subset(N, [_ | L]) = subset(N, L). candidate(N) = L:- L = subset(N, diglist), not(isBad(L)). isBad(L):- num(0, L1, N), N <> count(L, L1), !. writeVariants(X):- num(X, L, N), write(L, " - ", N), nl, fail; succeed(). game(N):- writef("Загадайте % различных чисел от 0 до 9\n", N), L = readDigits(N), write("\nНачинается игра\n"), game(N, 0, gen(N, length(diglist) + 0), L). game(N, X, L, L1):- L2 = move(X, N), K = count(L1, L2), write(L2, " - ", K), nl, assert(num(X, L2, K)), game(N, X, L, L1, K). game(N, X, L, L1, N):- !, writeMessage(X, L, L1). game(N, X, L, L1, K):- K > N div 2, !, game(N, X, L, L1). game(N, X, L, L1, _):- game(N, 1 - X, L1, L). move(0, N) = L:- write("\nХод компьютера\n"), L = candidate(N), !. move(_, N) = readDigits(N):- write("\nВаш ход\n"), writeVariants(1). toStr(0) = "компьютер":- !. toStr(_) = "человек". writeMessage(X, L, L1):- Player1 = toStr(X), Player2 = toStr(1 - X), writef("Выиграл %!\n% задумал %, % задумал %.\n", Player1, Player1, L, Player2, L1). run():- write("Количество угадываемых чисел: "), N = read(), clearInput(), game(N), _ = readLine().Пример 14.3. Игра "Отгадай все числа"
Упражнения
- Реализуйте вариант топологической игры "Ползунок", в котором игрок, замкнувший траекторию, проигрывает, а не выигрывает.
- Реализуйте игру "Поле чудес" в режиме "пользователь загадывает, компьютер отгадывает".
-
Реализуйте игру "Быки о коровы" в режимах
- пользователь загадывает, компьютер отгадывает;
- компьютер загадывает, пользователь отгадывает;
- загадывают оба, выигрывает тот, кто отгадает первым.
- Реализуйте игру "Крестики-нолики" пользователя с компьютером.
- Реализуйте игру в камни пользователя с компьютером. Имеется груда камней. За один ход можно взять от одного до трех камней. Игроки ходят по очереди. Проигрывает тот, кто берет последний камень.
-
Игра "Ним" заключается в следующем. Имеется n кучек, в которых лежат камни. Игроки ходят по очереди. За один ход игрок может взять любое ненулевое число камней из произвольной кучки. Напишите программу для игры пользователя с компьютером, в которой игрок, взявший последний камень
- выигрывает;
- проигрывает.
- Реализуйте игру в баллы пользователя с компьютером. Компьютер запрашивает число n баллов, которые нужно набрать (например 20), а также несколько чисел, которые можно называть (например 2, 5, 6) и имя игрока, который ходит первым. Игроки по очереди называют одно из разрешенных чисел. Названные числа суммируются. Выигрывает участник, после хода которого сумма становится равной n или вынудивший противника превысить это число.
- Реализуйте игру в 37 пользователя с компьютером. Игроки по очереди называют одно из чисел от 1 до 5, названные числа суммируются. Нельзя повторять число, которое назвал противник на предыдущем ходе. Выигрывает участник, получивший ровно 37 очков или вынудивший противника превысить это число.