Игры
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 очков или вынудивший противника превысить это число.