1. C++ / Говнокод #27123

    +2

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    ShipType Ship::getShipTypeByLength(int length)
    {
        switch (length) {
            case 1: return BOAT;
            case 2: return CRUISER;
            case 3: return DESTROYER;
            case 4: return BATTLESHIP;
            case 5: return AIRCRAFT_CARRIER;
    
            default:
                std::cout << "No ship meets the given length: " << length << std::endl;
                return ERROR_SHIP;
        }
    }
    
    int Ship::getShipLengthByType(ShipType type)
    {
        switch (type) {
            case BOAT: return 1;
            case CRUISER: return 2;
            case DESTROYER: return 3;
            case BATTLESHIP: return 4;
            case AIRCRAFT_CARRIER: return 5;
    
            default:
                std::cout << "No ship meets the given type: " << type << std::endl;
                return 0;
        }
    }
    
    int Ship::getShipAmountByType(ShipType type)
    {
        switch (type) {
            case BOAT: return 4;
            case CRUISER: return 3;
            case DESTROYER: return 2;
            case BATTLESHIP: return 1;
            case AIRCRAFT_CARRIER: return 1;
    
            default:
                std::cout << "No ship meets the given type: " << type << std::endl;
                return 0;
        }
    }
    
    Coordinates Ship::getFirstBlockCoordinatesByShipData(int x, int y, int length, Orientation orientation)
    {
        Coordinates result;
        if (orientation == HORIZONTAL) {
            result.x = x - (length / 2);
            result.y = y;
        } else {
            result.x = x;
            result.y = y - (length / 2);
        }
        return result;
    }
    
    Coordinates Ship::getLastBlockCoordinatesByShipData(int x, int y, int length, Orientation orientation)
    {
        Coordinates result;
        if (orientation == HORIZONTAL) {
            result.x = x + (length / 2) + (length % 2) - 1;
            result.y = y;
        } else {
            result.x = x;
            result.y = y + (length / 2) + (length % 2) - 1;
        }
        return result;
    }

    Вот некоторые полезные функции из игры «Морской Бой», которую я зачем-то написал.

    Запостил: oaoaoammm, 21 Ноября 2020

    Комментарии (39) RSS

    • любишь все повторять два раза два раза?
      Ответить
    • Кстати, что лучше - сгруппировать в класс ship и сделать коллекцию кораблей или везде, где нужен корабль, доступаться по ID из enum'а? Почему и в каких случаях?
      Ответить
      • Я вообще не хранил корабли, только состояние клеточек... Но видимо тут графоний и надо их правильно рисовать?
        Ответить
        • Графония пока нет, зато его можно будет легко прикрутить, на это и был расчёт. Расширяемость )))

          А ещё мне показалось, что проще оперировать кораблями как объектами.

          Вот захочется тебе удалить корабль, который ты поставил... Придётся проверять какая у него ориентация, потом в обе стороны шагать по полю и стирать клеточки (я обычно всегда проёбываюсь и шагаю слишком далеко)... А так выкидываешь инстанс из вектора и нормально.
          Ответить
          • У меня и ручная расстановка тоже была тупо кликаньем по клеточкам...
            Ответить
        • А если понадобится сделать такое? http://www.youtube.com/watch?v=PnOyK4crkks
          Ответить
          • Да всё равно будет работать... там попадание/потопление определялось чем-то наподобие алгоритма заливки, поэтому форма корабля в общем-то пофиг.

            Но проверка расставленных юзером кораблей станет намного сложнее, да. Придётся форму распознавать а не просто полоски.
            Ответить
            • > Придётся форму распознавать
              понадобится нейронка
              Ответить
              • > нейронка

                И блокчейн!

                На самом деле, он тут даже в тему -- надо посчитать хеш от поля перед началом игры и передать противнику. Тогда переставлять корабли посреди игры уже не выйдет.
                Ответить
                • у меня что-то такое было в какой-то клиент-серверной игрухе, чтобы "клиент" не мухлевал
                  Ответить
          • У меня там, кстати, ещё был impossible mode, в котором комп переставляет "единички" куда-нибудь в другое место если игрок в них попадает. В итоге надо всё поле полностью расстрелять чтобы выиграть. И за это время комп обычно успевал у игрока всё потопить.
            Ответить
            • в том варианте как на видео, было бы чуть сложнее так читовать
              Ответить
            • Была игрушка для DOS (что-то типа битвы за Чёрное море), в которой компьютер подглядывал за расположением твоих кораблей. Если он задевает твой многоклеточный корабль, то следующими ходами его добивает.
              Ответить
              • Если он задевает корабль, то добить его несложно и без подглядывания. обычно двумя ходами, если повезет то и одним, ну а если не повезет, то тремя
                Ответить
              • Эм, у меня и без подглядывания добивало. Просто стреляешь вокруг клетки в которую попал. Ну и потом вдоль линии.

                Или он прям всегда с первого раза добивал, никогда не промахиваясь?
                Ответить
                • Прям всегда с первого раза, никогда не промахиваясь. Если попал в одну из клеток корабля, следующими выстрелами точно топит остальные клетки, не трогая незанятые. Т. е. после ранения никогда не было перехода хода.
                  Ответить
                  • Зачем? Зачем? Там честный то алгоритм не сильно дольше работает.
                    Ответить
                    • Ну чтобы человеку обыграть компьютер было труднее.
                      Ответить
                      • А он даёт человеку иногда выиграть, чтобы тот не расстроился и не свалил?
                        Ответить
                        • Первый выстрел робот делал рандомно, т. е. теоретический шанс у человека был.

                          Мне после той игры было непривычно играть в другие реализации морского боя. Я удивлялся возросшей вероятности победы.
                          Ответить
                          • > Первый выстрел робот делал рандомно

                            Какой анскилл )))

                            Можно же псевдорандомом по диагоналям чтобы по-быстрому найти длинные корабли и отбросить как можно больше пустых клеток.
                            Ответить
                            • Или собирать статистику в облаке (возможно, персонализированную) по частоте использования клеток пользователями.
                              Ответить
                              • Можно попробовать нейросеть обучить, кстати. Вдруг у людей какие-то бессознательные паттерны есть.
                                Ответить
                                • Я когда-то видел эксперимент, где людям предлагали оценить количество питушни в каком-то ящике.

                                  В итоге получилось так, что половина назвала число меньшее, чем там было, а половина – большее, а среднее арифметическое было очень близко к фактическому количеству питушни, так что вполне возможно )))
                                  Ответить
                                  • Ну да, если ты попросишь юзера придумать пароль или ещё какую-то случайную последовательность, то символы, скорее всего, не будут повторяться т.к. это "выглядит не случайно".

                                    Возможно и тут человек будет раскидывать единички подальше друг от друга "чтобы случайно не попали" и т.п.
                                    Ответить
                                    • Кстати, а ещё в фильмах про отмывание денег, где придумывают цифр для отчетности «из воздуха», постоянно фигурируют фразы типа: «смотрите, видите? Вот здесь каждое третье число заканчивается на начётную цифру!»

                                      Думаю, если ИИ будет подстраиваться под каждого игрока, то ИИ будет побеждать.
                                      Ответить
            • Мой морской бой на бейсике решал проблему троллинга пользователя иначе: все крупные корабли он группировал в по краям, так что их было относительно легко убить, но при этом карта почти не открывалась. А на оставшемся широком морском просторе он раскидывал четыре единички, которые можно было убить, только методично прокликивая все клетки. Какая честность )))
              Ответить
              • Ну это даже не чит, а вполне честная тактика...
                Ответить
      • Я бы сделал корабь, и в конструктор ему передавал кол-во клеточек.
        Это на крестах.

        На джавке или C# я бы взял enum, на котлине sealed classes
        Ответить
        • Какие классы )))

          Я тогда писал в стиле ротоёба олимпиадников из вк.
          Ответить
          • Я, когда это всё затевал, подумал: «так, я делаю какую-то дичь, крестов толком не знаю, пусть хотя бы будет рахитектура и ООП, а то стану как кое-кто».

            В итоге у меня получился класс GameEngine (синглтон), который общается с гуём. Сам GameEngine использует NetworkingEngine (тоже синглтон), где я сру каждые 500 миллисекунд данными о курсоре оппонента и статусе хода (кликнули ли по полю).

            Ещё есть два wxBoard, которые берут указатели на классы Board и отрисовывают доски с кораблями и отметками (попал/ не попал): одна доска для своей питушни, а другая – для чужой.

            Всё это я пытался обернуть в RAII, но, т.к. это была лаба в конце семестра, по достижении более или менее нормального результата (в визуальном плане) я всё это забросил.
            Ответить
            • > каждые 500 миллисекунд

              Какой киберспорт )))
              Ответить
              • Я ещё и по TCP сру, хотя надо бы по UDP такое делать )))
                Ответить
                • Ну для пошаговой игры tcp наверное норм. А доску противника клиент заранее знает, получается?
                  Ответить
                  • Неет, тут я дал реверс-инженерам и владельцам исходного кода возможность всегда выигрывать.

                    Клиент ждёт, пока не придёт true и два индекса, по которым стреляет противник, а затем отправляет success_code: промахнулся, ранил или убил (если убил, то начинается передача данных корабля другому игроку, чтобы он его себе нарисовал).

                    Вот такой вот багор )))
                    Ответить
          • так я про сейчас


            "тогда" у меня тоже noname01.pas был
            Ответить
            • Тадам! Обнаружен уёбок!

              Не беспокойтесь. Попытайтесь следовать нашим советам и ссылкам. Если компьютер является частью локальной сети, отсоедините сетевой кабель, чтобы избежать дальнейшего распространения уёбка.
              Ответить

    Добавить комментарий