Задача «Карточная игра "Go fish"»
Задача
Произвести рефакторинг кода на C, реализующего детскую карточную игру Go Fish.
Исходный код
- fish.c – код программы на одном из старых диалектов C, но, тем не менее, с минимальными модификациями собирается современными компиляторами.
Описание
Поскольку игра мало распространена в России, то приводим краткое описание правил.
- В игре участвуют от 2 до 10 игроков (в данной программе реализовано 2 игрока).
- Игра ведётся стандартной колодой на 52 карты.
- Цель игры – собрать как можно больше стопок с картами одинакового достоинства (все двойки, все тузы, все десятки и т.п.)
- В начале игры игрокам случайно раздаётся по 7 карт (или по 5 карт, если игроков 5 и более).
- Оставшиеся карты складываются в общую стопку рубашкой вверх. Эта стопка называется "ocean" или "pool", т.е. "океан" или "бассейн", т.е. место откуда можно выудить рыбу.
- Игроки ходят по очереди.
- Игрок, к которому перешёл ход, задаёт противнику вопрос о картах определённого достоинства, например "у тебя есть семёрки?"
- У игрока должна быть хотя бы одна карта того достоинства, которое он запрашивает у противника.
- Если у противника запрошенных карт нет, то он отвечает "Go fish" – "сходи поймай", и игрок достаёт себе 1 карту из "океана" – общей колоды.
- Если у противника есть карты запрошенного достоинства, то он отдаёт их задавшему вопрос.
- Если игрок забирает у противника запрошенные карты, то ход остаётся у него, и он может сделать ещё один запрос на карту какого-либо достоинства.
- Если игрок достаёт из общей стопки – "океана" карту запрошенного достоинства, то он получает право взять из общей стопки ещё одну карту. Таким образом возможна ситуация когда игрок подряд достаёт из общей колоды до 4 карт подряд.
- После того, как игрок "выудил" из общей колоды карту не того достоинства которое запрашивал, ход переходит следующему игроку.
- Как только у игрока набралось 4 карты одного достоинства, он их выкладывает рядом с собой в отдельную стопочку лицом вверх. Эти карты "выиграны" игроком, и в дальнейшей игре не участвуют.
- Игра заканчивается после того, как все карты "выиграны" игроками. Побеждает тот, кто "выиграл" больше карт.
В процессе рефакторинга необходимо:
- Переписать код на C++ (объявление переменных не в начале блока, а там где они реально используются, убрать анахронизмы языка C, и т. п.)
- Избавиться от define'ов (объявление констант) и глобальных переменных.
- Избавиться от
goto
.
- Текстовый ввод / вывод производить через
std::cout
и т.п. Выделить текстовый ввод / вывод в отдельный класс / модуль.
- Обработку ошибок перенести на механизм исключений и
std::exception
.
- По возможности заменить примитивные структуры данных наподобие массивов на
std::array
либо std::vector
, std::stack
, std::queue
или другие.
- Выделить класс игрока, который занимается вводом / выводом, передачей указаний пользователя.
- Выделить класс компьютерного игрока, который реализует некоторое AI.
- Реализовать класс игры, который будет реализовывать правила игры, вызов игроков, сообщать игрокам доступную информацию.
- Возможно использование паттерна стратегия для этих классов.
- На дополнительный балл: Подготовить код к возможности игры на 3 и более игроков (1 человек + компьютерные игроки).
Архив с проектами для Visual Studio 2013 и Visual Studio 2015.