Учебник: создайте карточную игру с Golang (Go)

создайте карточную игру с Golang (Go) Программирование и разработка

Golang или Go — популярный язык программирования, используемый многими ведущими технологическими компаниями. Если вы мечтаете работать в одной из этих ведущих компаний, важно иметь опыт работы с языками программирования, которые они используют. Лучший способ выучить любой язык программирования — это погрузиться прямо в него и получить реальный практический опыт. Солидное портфолио с проектами программирования может помочь продемонстрировать ваши навыки и опыт работы с языком программирования. Сегодня мы собираемся познакомить вас с реальным портфолио-проектом Go.

Давайте начнем!

Описание проекта

Карточные игры популярны во всем мире, и люди всех возрастов играют в разные их вариации. Допустим, вы работаете в стартапе, который хочет создать веб-приложение для различных карточных игр. Они хотят разрабатывать обычные игры, такие как покер и пасьянсы, а также создавать свои собственные уникальные игры. Во все игры можно играть как в одиночном, так и в многопользовательском режиме. Поскольку будет вариант для одного игрока, вашей команде необходимо создать «противника», чтобы играть против пользователей.

Первая часть проекта включает в себя реализацию функции, которая помогает пользователю играть в разновидность покера. Вам нужно будет разработать функцию так, чтобы она могла определять, является ли данная комбинация карт комбинацией стритов или нет. Вторая часть проекта включает создание функции для пользовательской карточной игры под названием Fizzle. Вам нужно будет разработать функцию так, чтобы пользователь мог найти максимальное количество очков, которое можно получить, выбирая карты из набора из десяти случайных карт.

Функции

  • Особенность 1 : Определите, возможна ли раздача стритов.
  • Особенность 2 : Найдите максимальное количество очков, которое можно получить из набора из десяти случайных карт. Теперь, когда вы знаете предысторию, давайте приступим к работе над первой функцией!

Строительная особенность 1

Что касается функции № 1, мы работаем над разновидностью покерной игры с комбинацией стритов. В традиционном покере у игроков есть наборы из пяти карт (так называемые руки ). Обычно комбинация стритов состоит из пяти карт последовательных рангов, таких как 9, 8, 7, 6 и 5.

Читайте также:  Как изучить Node.js: руководство по началу работы

В нашей новой разновидности покера число k будет определяться броском игральных костей. Если на кубике выпадает 1, его нужно бросить снова. Таким образом, k всегда будет в диапазоне 2-6. Рука прямых возможна только тогда, когда K наборы карт могут быть сформированы с использованием всех карт в данной руке.

Пример

В приведенном выше примере мы видим, что нам раздали девять карт

В приведенном выше примере мы видим, что нам раздали девять карт. На кубике выпало 3, поэтому k равно 3. Затем карточки были разделены на три группы. Каждая группа состоит из трех карт в последовательном порядке. В процессе реализации мы будем получать эти карты в виде массива, например {10, 3, 6, 2, 13, 12, 5, 4, 7}. Карты валета, короля и дамы обозначены цифрами 11, 12 и 13 соответственно. Число после броска кубиков дается целым числом. Модуль должен вернуться, trueесли может быть сформирована рука стритов. Если рука стритов не может быть сформирована, она должна вернуться false.

Решение

Обычная интуиция, стоящая за решением, состоит в том, чтобы попытаться сформировать группы размера k, начиная с самой младшей карты. Как только самая младшая карта определена, комбинация стритов возможна только в том случае, если самая младшая карта находится в нижней части группы размера k. Например, если k равно 4, а младшая карта — 2, мы знаем, что группа будет 2, 3, 4, 5. Если мы не можем найти эту группу, значит, рука не стрит.

Приступим к написанию этой функции! Мы разделим решение на несколько этапов. Прежде чем мы начнем, нам нужно импортировать соответствующие пакеты, чтобы мы могли протестировать наш код в конце.

package main
import (
  «fmt»
  «sort»
)

Шаг 1 : Настройте функцию.

func isHandOfStraights(hand []int, k int) bool{

Шаг 2 : Проверьте, делится ли количество карт в руке на k. В противном случае мы не можем создавать группы, поэтому возвращайтесь false.

if len(hand) % k != 0{
        return false
    }

Шаг 3 : Подсчитайте количество появлений каждой карты в данной руке.

    count := make(map[int]int)
    for _, i := range hand{
        count[i] = count[i] + 1
    }

Шаг 4 : отсортируйте список и начните перемещаться по нему с карты с самым низким рейтингом. Мы можем использовать хэш-карту, сохраняя номера карт как ключи и вхождения как значения.

    sort.Ints(hand)
    i := 0
    n := len(hand)

Шаг 5 : Используйте вложенный цикл, который выполняется k раз.

        for i < n {
                current := hand[i]
                for j := 0; j < k; j++ {

Шаг 5.1 : Проверьте, есть ли на карте текущая карта и следующие k-1 карты (в возрастающем рейтинге) count. Если какой-либо из них не существует, вернитесь false.

            if _, ok := count[current + j]; !ok || count[current + j] == 0 {
                return false
            }

Шаг 5.2 : Когда каждая из требуемых карточек найдена, уменьшите количество ее появлений в count.

            count[current + j]—
        }

Шаг 5.3 : После того, как будет найдена полная группа, используйте цикл while, чтобы найти самую маленькую карту следующей группы и определить, у какой из следующих карт countосталось больше нуля вхождений.

        for i < n && count[hand[i]] == 0{
            i++
        }
    }

Шаг 6 : Вернитесь, trueесли все карточки отсортированы по группам.

   return true
}

Теперь давайте протестируем нашу функцию на двух примерах рук.

package main
import (
  «fmt»
  «sort»
)
func isHandOfStraights(hand []int, k int) bool{
    if len(hand) % k != 0{
        return false
    }
    count := make(map[int]int)
    for _, i := range hand{
        count[i] = count[i] + 1
    }
    sort.Ints(hand)
    i := 0
    n := len(hand)
    for i < n {
        current := hand[i]
        for j := 0; j < k; j++ {
            if _, ok := count[current + j]; !ok || count[current + j] == 0 {
                return false
            }
            count[current + j]—
        }
        for i < n && count[hand[i]] == 0{
            i++
        }
    }
    return true
}
func main() {
    hand := []int{5,2,4,4,1,3,5,6,3}
    k := 3
    fmt.Println(isHandOfStraights(hand, k))
    hand2 := []int{1,9,3,5,7,4,2,9,11}
    k = 2
    fmt.Println(isHandOfStraights(hand2, k))
}

Строительный элемент 2

Для функции № 2 мы работаем над специальной карточной игрой под названием Fizzle. В этой игре дилер тасует колоду карт, а затем линейно раскладывает все карты вверх. Затем игроки по очереди бросают кости. Выпало k. Затем игроки по очереди удаляют k карт из колоды, но они могут выбирать карты только с левой или правой стороны карт. Цель состоит в том, чтобы выбрать карты с максимальным количеством очков. Каждая карта имеет количество очков, соответствующее ее номеру, а лицевые карты: валет, дама, король и туз имеют 11, 12, 13 и 14 очков соответственно.

Мы хотим создать для игроков Fizzle функцию, которая анализирует текущее состояние колоды и число, которое выпало игроку, и определяет максимальное количество очков, которое игрок может получить за этот ход.

Пример

В приведенном выше примере, игрок выбрал карты 5, 3, 6, и, 3 чтобы

В приведенном выше примере, игрок выбрал карты 5, 3, 6, и, 3 чтобы получить максимальное количество баллов возможных. В процессе реализации мы получим колоду карт в виде массива, например {5, 3, 4, 4, 2, 3, 4, 6, 3}. Число, которое мы получим после броска кости, будет целым числом. Модуль должен возвращать максимальное количество точек в виде целого числа.

Решение

Чтобы реализовать эту функцию, нам нужно протестировать все возможные комбинации, в которых k карт можно выбрать из колоды слева или справа. Мы не можем выбрать n- ю карту справа (или слева), если не будет выбрана ( n — 1) -я карта справа (или слева). Если мы выберем k — 1 карту справа, то 1 карта будет выбрана с левой стороны и так далее. Мы можем найти все возможные комбинации, если предположим, что скользящее окно размером k перемещается справа налево. Результатом будет максимальная сумма, найденная при попытке всех возможных комбинаций.

Приступим к написанию этой функции! Разобьем это на шаги. Прежде чем мы начнем, нам нужно импортировать соответствующие пакеты, чтобы мы могли протестировать наш код в конце.

package main
import (
  «fmt»
  «math»
)

Шаг 1 : Настройте функцию.

func maxPoints(deck []int, k int) int{
    left := 0;
    right := len(deck) — k
    var total, best int
    total = 0

Шаг 2 : Предположим, что k карточек справа дают нам максимальное количество очков.

    for i := right; i < len(deck); i++ {
        total += deck[i]
    }
    best = total

Шаг 3. Используйте цикл, который выполняется k раз, и проверьте все комбинации.

    for i := 0; i < k; i++ {

Шаг 4 : Удалите точки карты с правой стороны и добавьте точки с левой стороны.

        total += deck[left] — deck[right]

Шаг 5 : Сравните totalточки с текущими bestточками и сохраните максимум.

        best = int(math.Max(float64(best), float64(total)))
        left++
        right++
    }
    return best
}

Теперь давайте протестируем нашу функцию на примере колоды.

package main
import (
  «fmt»
  «math»
)
func maxPoints(deck []int, k int) int{
    left := 0;
    right := len(deck) — k
    var total, best int
    total = 0
    for i := right; i < len(deck); i++ {
        total += deck[i]
    }
    best = total
    for i := 0; i < k; i++ {
        total += deck[left] — deck[right]
        best = int(math.Max(float64(best), float64(total)))
        left++
        right++
    }
    return best
}
func main() {
    deck := []int{5,3,4,4,2,3,2,6,3}
    k := 4
    fmt.Println(maxPoints(deck, k))
}

Подведение итогов проекта и соответствующие вопросы собеседования

Поздравляю! Вы добрались до конца проекта. В ходе этого проекта мы узнали, как:

  • Создайте функцию, которая может идентифицировать руку стритов, группируя карты в последовательном порядке.
  • Используйте технику скользящего окна, чтобы создать функцию для поиска карточек с максимальными баллами.

Проблемы, которые мы решили сегодня, также часто задают вопросы собеседований в ведущих технологических компаниях. После нашего опыта создания проекта вы теперь можете определять проблемы с помощью тех же шаблонов и решать эти проблемы, используя методы, которые мы внедрили сегодня. Давайте взглянем на пару связанных вопросов на собеседовании, которые мы можем решить, используя аналогичный подход:

  • Разделите массив на наборы из K последовательных чисел
  • Найдите максимальную сумму с любого конца массива

Следующие шаги

Создание сильного портфеля кодов дает вам практические навыки решения реальных проблем разработки программного обеспечения. Сильное портфолио — отличный способ выделиться среди конкурентов как Go-разработчик. Сегодня мы завершили только один проект, но есть еще много реальных проектов, над которыми вы могли бы работать, чтобы больше узнать о мире разработки программного обеспечения и помочь вам лучше подготовиться к собеседованию на Go. Еще несколько идей проекта включают в себя:

  • Улучшение пользовательского опыта при поиске контента для просмотра на Netflix
  • Внедрение функций повышения производительности для Календаря Google
  • Оптимизация клиентских функций на Amazon
Оцените статью
bestprogrammer.ru
Добавить комментарий