|
31 / 31 / 12
Регистрация: 25.07.2015
Сообщений: 120
|
|||||||||||||||||||||
Карточная игра 21. Оптимизация и проверка14.08.2016, 14:15. Показов 13540. Ответов 10
Метки нет (Все метки)
Всем привет. Изучаю java меньше месяца. Только закончил 4 главу Хортсманна. Надоело писать программки с процедурным подходом. Для понятия ООП, поставил себе задачу сделать карточную игру 21 (пока что вариант для 2 игроков). Правила в интернете не стал читать (лень
), а поставил свои: 1) Игра начинается с раздачи каждому 2 карт. 2) Туз - 1; 2 - 2 ... Король - 13. 3) Если у обоих сумма равна - ничья. Иначе выигрывает тот, у кого сумма 21 или, при отсутствие такого варианта, тот, у кого ближе к 21.Класс Card: Кликните здесь для просмотра всего текста
Класс Deck: Кликните здесь для просмотра всего текста
Класс Hand: Кликните здесь для просмотра всего текста
Класс Game: Кликните здесь для просмотра всего текста
К вам у меня есть несколько вопросов: 1) Стоит ли упрощать метод getAdditionalCards() в классе Hand? Я хотел создать сканер для класса и использовать его для вызова рекурсивного метода запроса ответа от игрока. Но меня "испугала" сама идея создания сканера вне метода. 2) Самый сильно-интересующий меня вопрос . В методе compareHands() я постоянно вызываю метод getValueOfHand(). Не перегружаю ли я процессор лишней "фигней"? Возможно стоит использовать поле value для каждого объекта Hand?3) Есть ли какие-нибудь недочеты по инкапсуляции? Кому-то вопросы покажутся глупыми, но я просто не хочу быть дилетантом в том, чему учусь. Всем, кто обратит внимание и ответит, большое спасибо.
0
|
|||||||||||||||||||||
| 14.08.2016, 14:15 | |
|
Ответы с готовыми решениями:
10
Карточная игра 50 Карточная игра Карточная игра на C# |
|
155 / 154 / 53
Регистрация: 30.04.2016
Сообщений: 321
|
||||||
| 14.08.2016, 15:13 | ||||||
|
Для вещей которые ты сделал с помощью
Переменные ты сделал private, а методы нет, делай их все private или public которые нужны. По логике - getAdditionalCards не должен этого всего делать, метод должен просто доставать карту из колоды, а уже управлять этим процессом, спрашивать игрока и тп. уже другой метод/класс. Если ты например захочешь сделать режим игры игрока против компьютера, этот метод ты не сможешь использовать для обоих, придется писать еще один для npc. this.getValueOfHand вызывать много раз нет смысла да, один раз вызываешь и сохраняешь в переменную и потом сравниваешь уже с ней. И писать this.methodName лишнее, methodName достаточно. this - это ссылка на текущий экземпляр объекта. И правила почитай, они посложнее чем твои и больше возможностей в игре - будет сложней реализовывать
1
|
||||||
|
31 / 31 / 12
Регистрация: 25.07.2015
Сообщений: 120
|
|
| 14.08.2016, 17:05 [ТС] | |
|
ninjacut, А чем плохо, что я использовал не enum'ы, а массив стрингов? Я что-то совсем забыл про перечисления, не пользовался ими ни разу.
Как я понимаю, методы у меня сейчас default. Я собираюсь потом все это в один пакет поместить и сделал так, чтобы они были доступны в том пакете. Или в данном виде они используются только своим классом и их можно делать private? Просто я "пришел" с Паскаля, поэтому еще каша в голове ![]() Насчет метода добавления карты игроку. Я так понимаю, что мне лучше отдельно сделать метод, который будет запрашивать ответ от игрока и там уже будет вызывать метод добавления карты, если ответ был "Y". А метод добавления карты отдельно создать в пару строчек. И для NPC вызывать уже чисто его, без запроса? А вот this это пока что моя "головная боль". Не могу полностью въехать в её смысл. Применять применяю, но не все знаю об этом. По идее метод у меня не статичный, то есть я должен применять его к объекту. Причем (в моем случае) к объекту, который его и вызвал. Поэтому я пишу this. Или конкретно в классе Hand, где определен этот метод, я могу обойтись без this? Как доберусь до своего компа, буду пробовать. Спасибо за ответ.
0
|
|
|
155 / 154 / 53
Регистрация: 30.04.2016
Сообщений: 321
|
||
| 14.08.2016, 18:33 | ||
|
striker24, Если допустим ты захочешь за туза давать одно очко если > 11, и 11 если меньше (как в блэкджке) то варианты сравнивать card.getRank().equals(ranks[0]) или card.getRank() == Ranks.ACE.
Делай все методы и переменные - либо private, либо public. Позднее, когда достаточно разберешься, будешь решать где можно делать default или protected доступ. Это совет, расписывать почему - долго. Про this, метод не статичный и значит он вызывается как раз в контексте экземпляра объекта, this писать - это лишнее.
1
|
||
|
31 / 31 / 12
Регистрация: 25.07.2015
Сообщений: 120
|
|||||||||||
| 14.08.2016, 20:28 [ТС] | |||||||||||
|
ninjacut, буду пробовать тогда с enum'ами. Запрос карты переписал вот так:
Кликните здесь для просмотра всего текста
Не сказал бы, что прям конкретно что-то изменилось. Такой подход считается более логичным? И по поводу this. Вы хотите сказать, что если я применяю метод класса Hand внутри другого метода ЭТОГО ЖЕ класса, то компилятор сам "понимает", что метод относится к объекту, который его вызвал? И соответственно this употреблять необязательно. Так ли это? И насчет удобочитаемости. Этот кусок оставил так: Кликните здесь для просмотра всего текста
Мне кажется наличие this здесь делает код более удобочитаемым. Так как в качестве параметра выступает другой экземпляр этого же класса. Явно видно где нужно поле/метод вызвавшего объекта, а где - объекта, который передается в качестве параметра. Вы так не думаете?
0
|
|||||||||||
|
155 / 154 / 53
Регистрация: 30.04.2016
Сообщений: 321
|
|
| 14.08.2016, 21:05 | |
|
striker24, По первому вопросу, я имел в виду что класс Hand по логике не должен заниматься тем чтобы спрашивать нужны ли карты игроку еще или нет. Этим уже бы занимался какой-нибудь GameManager, или Dealer. Вот он уже спрашивает нужны ли карты, и если да, то вызывает метод из Hand, или сам берет карту, и уже ее передает в Hand в метод например dealCard(Card card).
По второму, да, нестатичный метод по-другому нельзя же вызвать, только из объекта. И this в этом случае, по-моему это просто в глаза бросается, никакой ясности не добавляет.
1
|
|
|
31 / 31 / 12
Регистрация: 25.07.2015
Сообщений: 120
|
|
| 15.08.2016, 00:00 [ТС] | |
|
ninjacut, хмм... получается ваши слова можно интерпретировать как "методы в классе должны выполнять действия ОТ ИМЕНИ класса"? Ну то есть как бы Hand берет Card, Dealer спрашивает у Hand ответа и т.д. Получается по такой логике я должен метод drawFromDeck() перенести в класс Hand. Ведь рука "вытягивает" карту. И метод getRank() перенести в Hand, ведь узнает масть и значение карты рука (к примеру, мы можем не переворачивать карту рубашкой вниз и тем самым не узнать этих данных).
Я же создавал все методы по принципу "метод в классе должны выполнять действия НАД этим классом". То есть вытянуть карту из колоды, получить масть от карты, спросить игрока(руку) о взятии еще карты и т.д. Вышел уже за пределы темы, но все-таки хочется знать истину. Возможно, надо перечитывать основы ООП.
0
|
|
|
155 / 154 / 53
Регистрация: 30.04.2016
Сообщений: 321
|
|
| 15.08.2016, 20:58 | |
|
striker24, Не все так догматично. Я лишь покажу свой ход мыслей - ситуация: нужно организовать сдачу карты из колоды в руку. Значит в руку приходит карта, ок, в классе Hand будет метод insertCard(Card card). Из колоды след. карту надо получить, ок, в классе Deck будет метод Card getNextCard(). Все. Использование этих методов уже не этих классов дело.
1
|
|
|
31 / 31 / 12
Регистрация: 25.07.2015
Сообщений: 120
|
|
| 16.08.2016, 23:26 [ТС] | |
|
ninjacut, вроде понятно. Значит буду почаще читать чужой код и пытаться понять логику там. Думаю, что под это дело хорошо подойдет стандартная библиотека java.
0
|
|
|
2 / 2 / 1
Регистрация: 06.06.2013
Сообщений: 4
|
||||||||||||||||||||||||||
| 18.08.2016, 19:42 | ||||||||||||||||||||||||||
|
Тоже не так давно изучаю Java, решил написать свой вариант. Очень похож на вариант автора, но ближе к реальным правилам и сразу на множество игроков, которое вводиться с клавиатуры.
Класс Card: Кликните здесь для просмотра всего текста
Класс Deck: Кликните здесь для просмотра всего текста
Класс Hand: Кликните здесь для просмотра всего текста
Класс Game: Кликните здесь для просмотра всего текста
Класс Run (main): Кликните здесь для просмотра всего текста
Буду очень рад увидеть обоснованную критику.
1
|
||||||||||||||||||||||||||
|
2399 / 2224 / 565
Регистрация: 28.12.2010
Сообщений: 8,672
|
|
| 18.08.2016, 21:17 | |
|
Mr_MaZa, написать всю игру в конструкторе класса это конечно тоже попадает под ваше определение "зато работает", но вопрос какая ваша цель. Если писать "лишь бы работало", тогда нет смысла выкладывать и спрашивать мнение. Если хотите сделать хорошо, то вы сами видите что что-то написано плохо. Зачем ждать пока вам это скажут другие (это я про лейбл).
В целом код как код. Все начинающие такой пишут, что тут критиковать.
0
|
|
| 18.08.2016, 21:17 | |
|
Помогаю со студенческими работами здесь
11
Карточная игра Карточная игра Карточная игра 21 в Delphi Карточная игра Девятка
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога
Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
|
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога
Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
|
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога
Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
|
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
|
|
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога
В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
|
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога
Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
|
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога
Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
|
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога
Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
|