Программирование игры в крестики-нолики в Visual Basic

программирование компьютерные игры может быть самая технически сложная (и, возможно, самая высокооплачиваемая) работа, которую программист могу иметь. Игры высшего уровня требуют как от программистов, так и от компьютеров.

Visual Basic 6 теперь полностью обойдена как платформа для программирования игр. (Это никогда не было таковым. Даже в «старые добрые времена» серьезные программисты игр никогда не использовали бы язык высокого уровня, такой как VB 6, потому что вы просто не могли получить нарезку Максимальная производительность, которая требуется большинству игр.) Но простая игра «Tic Tac Toe» - отличное введение в программирование, которое немного более продвинуто чем "Привет, мир!"

Это отличное введение во многие фундаментальные концепции программирования, поскольку в нем сочетаются следующие методы:

  • Использование массивы. Маркеры X и O хранятся в отдельных массивах, а целые массивы передаются между функциями для отслеживания хода игры.
  • Использование графики уровня VB 6: VB 6 не предлагает отличных графических возможностей, но игра является хорошим введением в то, что доступно. Большая часть этой серии статей посвящена исследованию того, как GDI +, следующее поколение графики Microsoft, заменяет графику уровня VB 6.
    instagram viewer
  • Использование математических вычислений для управления программой: в программе используются умные по модулю (Mod) и целые числа расчеты деления с использованием двухкомпонентных маркерных массивов, чтобы определить, когда выигрыш из трех элементов произошло.

Класс программирования в этой статье, пожалуй, немного прошел начальный уровень, но он должен быть хорош для «промежуточных» программистов. Но давайте начнем с начального уровня, чтобы проиллюстрировать некоторые концепции и начать Visual Basic программирование игровой карьеры. Даже более продвинутые ученики могут обнаружить, что немного сложно получить правильную форму объектов.

Как играть в крестики-нолики

Если ты никогда не играл Крестики-ноликивот правила. Два игрока чередуются при размещении X и Os на игровом поле 3 х 3.

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

Перед началом любого реального кодирования всегда полезно изменить имена любых компонентов, которые вы используете. Как только вы начнете кодированиеимя будет автоматически использоваться Visual Basic, поэтому вы хотите, чтобы оно было правильным. Мы будем использовать имя формы frmTicTacToe и мы также изменим заголовок на «О Tic Tac Toe».

С установленной формой, используйте элемент управления панели инструментов линии, чтобы нарисовать сетку 3 x 3. Нажмите на инструмент «Линия», затем нарисуйте линию там, где вы хотите. Вы должны будете создать четыре линии таким образом и отрегулировать их длину и положение, чтобы они выглядели правильно. Visual Basic также имеет несколько удобных инструментов в меню «Формат», которые помогут. Это отличный шанс попрактиковаться с ними.

В дополнение к игровой сетке нам понадобятся некоторые объекты для символов X и O, которые будут размещены в сетке. Поскольку в сетке девять пробелов, мы создадим массив объектов с девятью пробелами, которые в Visual Basic называются элементами.

Есть несколько способов сделать практически все в среде разработки Visual Basic, и создание массивов элементов управления не является исключением. Вероятно, самый простой способ - создать первую метку (щелкнуть и нарисовать так же, как инструмент линии), назвать ее, задать все атрибуты (например, Font и ForeColor), а затем сделать ее копию. VB 6 спросит, хотите ли вы создать управляющий массив. Используйте имя lblPlayGround для первой метки.

Чтобы создать остальные восемь элементов сетки, выберите первый объект метки, установите свойство Index на ноль и нажмите CTRL + C (копия). Теперь вы можете нажать CTRL + V (вставить), чтобы создать еще один объект метки. Когда вы копируете объекты подобным образом, каждая копия наследует все свойства, кроме Index, от первой. Индекс будет увеличиваться на одну для каждой копии. Это контрольный массив, потому что все они имеют одинаковые имена, но разные значения индекса.

Если вы создадите массив таким способом, все копии будут размещены друг над другом в верхнем левом углу формы. Перетащите каждый ярлык на одну из позиций игровой сетки. Убедитесь, что значения индекса являются последовательными в сетке. Логика программы зависит от этого. Объект метки со значением индекса 0 должен находиться в верхнем левом углу, а нижняя правая метка должна иметь индекс 8. Если метки закрывают игровую сетку, выберите каждую метку, щелкните правой кнопкой мыши и выберите «Отправить назад».

Поскольку существует восемь возможных способов выиграть игру, нам понадобится восемь разных линий, чтобы показать выигрыш в игровой сетке. Вы будете использовать ту же технику для создания другого массива управления. Сначала нарисуйте линию, назовите ее linWin и установите свойство Index на ноль. Затем используйте технику копирования-вставки, чтобы создать еще семь строк. На следующем рисунке показано, как правильно установить номера индексов.

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

Две кнопки объекты:

  • cmdNewGame
  • cmdResetScore

Объект Frame FraPlayFirst, содержащий две кнопки выбора:

  • optXPlayer
  • optOPlayer

Кадр объекта fraScoreBoard, содержащий шесть меток. Только lblXScore и lblOScore изменяются в коде программы.

  • lblX
  • lblXScore
  • lblO
  • lblOScore
  • lblMinus
  • lblColon

Наконец, вам также нужен объект метки lblStartMsg, чтобы «замаскировать» кнопку cmdNewGame, когда на нее не нужно нажимать. Это не видно на рисунке ниже, потому что он занимает то же место в форме, что и кнопка команды. Возможно, вам придется временно переместить командную кнопку, чтобы нарисовать этот ярлык на форме.

Пока что никакого VB-кодирования не было сделано, но мы наконец готовы к этому.

инициализация

Теперь вы наконец-то начали писать код программы. Если вы этого еще не сделали, вы можете загрузить исходный код, чтобы следовать за ним, как объясняется работа программы.

Одно из первых дизайнерских решений - как отслеживать текущее «состояние» игры. Другими словами, каковы текущие значения X и Os в игровой сетке и кто будет следующим. Понятие «состояние» имеет решающее значение во многих областях программирования, и, в частности, оно важно при программировании ASP и ASP.NET для Интернета.

Это можно сделать несколькими способами, поэтому это важный шаг в анализе. Если вы решали эту проблему самостоятельно, возможно, вы захотите нарисовать блок-схему и попробовать разные варианты с «бумажкой» перед началом любого кодирования.

Наше решение использует два «двумерных массива», потому что это помогает отслеживать «состояние», просто изменяя индексы массива в циклах программы. Состояние верхнего левого угла будет в элементе массива с индексом (1, 1), верхний правый угол будет в (1, 3), нижний правый в (3,3) и т. Д., Два массива, которые делают это:

iXPos (x, y)

и

iOPos (x, y)

Есть много разных способов сделать это, и окончательное решение VB.NET из этой серии покажет вам, как сделать это с помощью всего одного одномерного массива.

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

Вам также необходимо несколько глобальных переменных следующим образом. Обратите внимание, что они находятся в общем коде и коде объявлений для формы. Это делает их «уровень модуля» переменные, на которые можно ссылаться в любом месте кода для этой формы. Дополнительные сведения об этом см. В разделе «Общие сведения о диапазоне переменных» в справке Visual Basic.

Есть две области, где переменные инициализируются в нашей программе. Во-первых, несколько переменных инициализируются во время загрузки формы frmTicTacToe.

Частный Sub Form_Load ()

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

Sub InitPlayGround ()

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

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

  • Переход по коду с помощью клавиши F8
  • Установка наблюдения за ключевыми переменными, такими как sPlaySign или iMove
    Установка точки останова и запрос значения переменных. Например, во внутреннем цикле инициализации:
lblPlayGround ((i - 1) * 3 + j - 1) .Caption = ""

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

Line0.Visible = False
Line1.Visible = False
Line2.Visible = False
Line3.Visible = False
Line4.Visible = False
Line5.Visible = False
Line6.Visible = False
Line7.Visible = False

вместо этого:

Для я = 0 до 7
linWin (i) .Visible = False
Далее я

Делать ход

Если какую-то часть системы можно считать «сердцем», это подпрограмма lblPlayGround_Click. Эта подпрограмма вызывается каждый раз, когда игрок нажимает игровую сетку. (Клики должны быть внутри одного из девяти элементов lblPlayGround.) Обратите внимание, что у этой подпрограммы есть аргумент: (индекс как целое число). Большинство других «подпрограмм обработки событий», таких как cmdNewGame_Click (), этого не делают. Индекс указывает, какой объект метки был нажат. Например, индекс будет содержать нулевое значение для верхнего левого угла сетки и значение восемь для нижнего правого угла.

После того, как игрок щелкает квадрат в игровой сетке, командная кнопка для запуска другой игры, cmdNewGame, «включается», делая ее видимой. Состояние этой командной кнопки выполняет двойную функцию, потому что она также используется в качестве логической переменной принятия решения позже в программе. Использование значения свойства в качестве переменной решения обычно не рекомендуется, потому что если когда-либо возникает необходимость изменить программу (скажем, например, чтобы сделать командная кнопка cmdNewGame видна постоянно), тогда программа неожиданно завершится сбоем, потому что вы можете не помнить, что она также используется как часть программы логика. По этой причине всегда полезно искать код программы и проверять использование всего, что вы меняете при обслуживании программы, даже значений свойств. Эта программа нарушает правило частично, чтобы подчеркнуть это, и частично потому, что это относительно простой кусок кода, в котором легче увидеть, что делается, и избежать проблем позже.

Выбор игрока игрового поля обрабатывается путем вызова подпрограммы GamePlay с Index в качестве аргумента.

Обработка хода

Сначала вы проверяете, нажали ли на незанятый квадрат.

Если lblPlayGround (xo_Move) .Caption = "" Тогда

Если мы уверены, что это законный ход, счетчик ходов (iMove) увеличивается. Следующие две строки очень интересны, поскольку они переводят координаты из одномерной Если lblPlayGround компонент массива для двумерных индексов, которые вы можете использовать в iXPos или iOPos. Мод и целочисленное деление («обратный слеш») - это математические операции, которые вы не используете каждый день, но вот отличный пример, показывающий, как они могут быть очень полезны.

Если lblPlayGround (xo_Move) .Caption = "" Тогда
iMove = iMove + 1
x = Int (xo_Move / 3) + 1
y = (xo_Move Mod 3) + 1

Значение xo_Move 0 будет преобразовано в (1, 1), 1 в (1, 2)... От 3 до (2, 1)... С 8 по (3, 3).

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

Если sPlaySign = "O", то
iOPos (x, y) = 1
iWin = CheckWin (iOPos ())
еще
iXPos (x, y) = 1
iWin = CheckWin (iXPos ())
End If
lblPlayGround (xo_Move) .Caption = sPlaySign

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

На экране пользователя отображается только X в верхнем левом поле, в то время как iXPos имеет 1 в верхнем левом поле и 0 во всех остальных. У iOPos есть 0 в каждой коробке.

Значения изменяются, когда игрок O нажимает на центральный квадрат сетки. Теперь iOPos показывает 1 в центре окна, в то время как пользовательский экран показывает X в левом верхнем углу и O в центре окна. На iXPos в верхнем левом углу отображается только 1, а во всех остальных полях - 0.

Теперь, когда вы знаете, где игрок нажал, и какой игрок нажал (используя значение в sPlaySign), все, что вам нужно сделать, это выяснить, выиграл ли кто-то игру, и выяснить, как это показать в отобразить.

В поисках победителя

После каждого хода функция CheckWin проверяет наличие выигрышной комбинации. CheckWin работает путем сложения каждой строки, каждого столбца и каждой диагонали. Отслеживание шагов через CheckWin с помощью функции отладки в Visual Basic может быть очень познавательным. Сначала нужно найти выигрыш, проверить, были ли найдены три единицы в каждой отдельной проверке в переменной iScore, а затем возвращает уникальное значение «подписи» в Checkwin, которое используется в качестве индекса массива для изменения свойства Visible одного элемента в linWin компонентный массив. Если победителя нет, CheckWin будет содержать значение -1. Если есть победитель, отображение обновляется, табло меняется, отображается сообщение с поздравлением, и игра перезапускается.

Давайте подробно рассмотрим одну из проверок, чтобы увидеть, как она работает. Остальные похожи.

Проверьте строки на 3
Для я = 1 до 3
iScore = 0
CheckWin = CheckWin + 1
Для j = 1 до 3
iScore = iScore + iPos (i, j)
Следующее j
Если iScore = 3, то
Функция выхода
End If
Далее я

Первое, на что нужно обратить внимание, это то, что первый индексный счетчик i отсчитывает строки, а второй j - по столбцам. Внешний цикл затем просто перемещается из одного ряда в другой. Внутренний цикл считает 1 в текущем ряду. Если их три, значит, у вас есть победитель.

Обратите внимание, что вы также отслеживаете общее количество квадратов, протестированных в переменной CheckWin, которая является значением, возвращаемым после завершения этой функции. Каждая выигрышная комбинация будет иметь уникальное значение в CheckWin от 0 до 7, которое используется для выбора одного из элементов в массиве компонентов linWin (). Это делает порядок кода в функции CheckWin также важным! Если вы переехали один из блоков код цикла (как показано выше), когда кто-то выигрывает, на игровой сетке будет проведена неправильная линия. Попробуйте и посмотрите!

Отделочные детали

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

instagram story viewer