Как создать программу через консоль

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

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

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

Идея написать подобное приложение пришла мне в голову после прочтения замечательной книги Мирана Липовача «Изучай Haskell во имя добра!», которую я начал читать просто ради интереса и познания дао функционального программирования. В этом нескучном учебнике приводился исходный код программы для ведения списка задач (далее для краткости, я буду именовать список задач словом todo) на Haskell и предлагалось в качестве упражнения написать несколько функций, неописанных автором. Что сказать, мне бросили вызов.

C# ВВОД ДАННЫХ В КОНСОЛЬ | C# ОТ НОВИЧКА К ПРОФЕССИОНАЛУ | Урок # 5

Суть программы предельно проста. Есть обычный текстовый файл (расширение — *.txt, хотя это и не принципиально) и в нем хранится набор записей, разделенных новой строкой. Программа имеет ряд команд add, remove, view, bump с помощью которых пользователь может добавлять, удалять, просматривать и поднимать на вершину списка записи из файла. При этом все команды отдаются исключительно из командной строки.

Cинтаксис команд очень прост:

todo add . todo remove todo view todo bump

На Haskell программа, которая реализует все эти команды, с учетом возможного некорректного ввода и с рядом некоторых моих правок выглядит примерно так (не спрашивайте меня, когда и как я учил язык):

import Control.Exception import Data.List import System.Directory import System.Environment import System.IO — Доступные команды dispatch :: String -> [String] -> IO() dispatch command | command == «add» = add | command == «view» = view | command == «remove» = remove | command == «bump» = bump | otherwise = doesntExist command — Обработка неправильной команды doesntExist :: String -> [String] -> IO() doesntExist command _ = if command == «» then putStrLn «Empty command !» else putStrLn $ «Command » ++ command ++ » isn’t exist» —Программа действует только, если файл действительно существует withCorrectFile :: String -> IO() -> IO() withCorrectFile fileName fileAction = do fileExists IO() add [fileName, todoItem] = appendFile fileName (todoItem ++ «n») add _ = putStrLn «Command add has exactly two arguments» — Просмотреть задачи из текущего списка view :: [String] -> IO() view [fileName] = withCorrectFile fileName (do contents show n ++ » — » ++ line) [0..] todoTasks putStr $ unlines numberedTasks) view _ = putStrLn «Command view has exactly one argument» — Вспомогательная функция для манипулирования файлами — нужна в том случае, если файл обновляется fileManipulate :: String -> String -> IO() fileManipulate fileName todoItems = withCorrectFile fileName (bracketOnError (openTempFile «.» «temp») ((temporaryFileName, temporaryFile) -> do hClose temporaryFile removeFile temporaryFileName) ((temporaryFileName, temporaryFile) -> do hPutStr temporaryFile todoItems hClose temporaryFile removeFile fileName renameFile temporaryFileName fileName)) — Удаление задачи из списка remove :: [String] -> IO() remove [fileName, numberOfString] = do contents IO() bump [fileName, numberOfString] = do contents [arguments]» else do (command : argumentsList)

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

Написал 3D Игру в Консоли!

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

Однако, вернемся в D.

Для интереса, я изменил некоторые команды в приложении (ну и кое-что добавил) и сделал цветной вывод на экран. Команду bump я заменил на команду head, а также ввел команду tail, которая по синтаксису совпадает с bump, но совершенно противоположна по результату действия (tail переносит задачу в самый низ списка задач).

Для работы над программой нам потребуется скачанные библиотеки QtE5 и arsd, а именно, файлы asc1251.d (из QtE5) и terminal.d (из arsd): asc1251 содержит набор процедур, которые умеют работать с кодировкой в командной строке Windows, а terminal.d — содержит набор процедур, для работы с командной строкой.

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

Все сказанное описывается так:

import std.algorithm; import std.conv; import std.file; import std.path; import std.range; import std.stdio; import std.string; import asc1251; import terminal; void main(string[] arguments) < auto parsedArguments = arguments.drop(1); auto terminal = Terminal(ConsoleOutputType.linear); if (parsedArguments.empty) < terminal.color(Color.red, Color.black); terminal.writeln(«nNot enough arguments!»); >else < auto command = parsedArguments.front; auto commandArguments = parsedArguments.drop(1).array; executeCommand(terminal, command, commandArguments); >>

Что тут происходит? Аргумент arguments процедуры main содержит в себе список всех строк переданных в командной строке приложению плюс имя самого приложения, поэтому с помощью алгоритма drop мы избавляемся от нулевого элемента массива arguments (drop возвращает диапазон, который получается путем пропуска n первых элементов переданного в нее диапазона). Далее создаем структуру, через которую будем манипулировать терминалом и помещаем ее в переменную terminal.

Если, список аргументов, обработанный drop, оказывается пустым, то это значит, что программе в командной строке не были переданы аргументы. В этом случае, мы устанавливаем в качестве фонового цвета командной строки черный, а в качестве цвета сообщения — красный, используя метод color и ряд описанных в arsd типов Color.red и Color.black. Само сообщение выводится в командную строку с помощью метода writeln, который аналогичен функции writeln из std.stdio. Таким образом, в случае запуска программы todo без аргументов, пользователю красным шрифтом будет выведена надпись «Not enough arguments!» («Недостаточно аргументов!»).

Если, список аргументов после drop оказался не пустым, то в переменную command с помощью метода front выделяем первый элемент обработанного списка, а в commandArguments — с помощью drop помещаем аргументы команды манипуляции todo. Далее с помощью алгоритма array мы переводим диапазон в массив, который наряду с другими аргументами (структура терминала и сама команда) передается в исполнитель executeCommand.

Читайте также:
Программа для Айфон чтобы передавать файлы на Андроид

Исполнитель выглядит достаточно просто:

void executeCommand(ref Terminal terminal, string command, string[] arguments) < switch (command.toLower.strip) < case «add»: addTodo(terminal, arguments); break; case «view»: viewTodo(terminal, arguments); break; case «remove»: removeTodo(terminal, arguments); break; case «head»: moveTodoUp(terminal, arguments); break; case «tail»: moveTodoDown(terminal, arguments); break; case «»: terminal.color(Color.red, Color.black); terminal.writeln(«nEmpty command !»); break; default: with (terminal) < terminal.color(Color.red, Color.black); terminal.write(«nUnknown command «); terminal.color(Color.yellow, Color.black); terminal.write(command); terminal.color(Color.red, Color.black); terminal.writeln(» !»); >break; > >

Довольно простой код, который позволяет выбрать нужную функцию для исполнения, а также позволяет правильно обработать ситуации, когда команда манипуляции todo представляет собой пустую строку или неизвестную команду. При этом, перед попаданием в исполнитель строка приводится к нижнему регистру (toLower) и из нее вырезаются конечные и начальные пробелы (strip).

Теперь остается реализовать отдельные функции, которые будут выполнять все действия команд манипуляции списком задач.

Функция addTodo выглядит следующим образом:

void addTodo(ref Terminal terminal, string[] arguments) < if (arguments.length < 2) < terminal.color(Color.red, Color.black); terminal.writeln(«nCommand «add» has 2 arguments»); >else < auto fileName = arguments.front; File file; file.open(fileName, «a+»); arguments .drop(1) .filter!(a =>(a != «») ? true : false) .map!(a => toCON(a)) .each!(a => file.writeln(a)); auto numberOfTodo = arguments.drop(1).length; terminal.color(Color.green, Color.black); terminal.writefln(«n%d» ~ » todo(s) was been added in file %s.», numberOfTodo, fileName ); > >

Работает это следующим образом: если длина аргументов команды add меньше 2, то значит, что пользователь где-то ошибся и ему будет выведено сообщение «Command add has 2 arguments» («Команда add имеет 2 аргумента»), в противном случае — переданный список аргументов add содержит имя файла для обработки и список записей для внесения в файл. После извлечения имени файла происходит его открытие в режиме добавления данных, после чего идет некоторая хитрая обработка содержимого arguments.

Сначала из arguments удаляется первый элемент (drop), после чего выделяются только непустые строки (с помощью алгоритма filter и анонимной функции a => (a != «») ? true : false, которая описывает условие фильтрации), производится перевод в кодировку консоли (toCON из asc1251.d) и соответственно запись результата в файл (с помощью алгоритма each и анонимной функции a => file.writeln(a)).

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

Функция removeTodo выглядит так и имеет несколько параллелей с уже рассматривавшейся addTodo:

void removeTodo(ref Terminal terminal, string[] arguments) < if (arguments.length < 2) < terminal.color(Color.red, Color.black); terminal.writeln(«nCommand «remove» has 2 arguments»); >else < auto fileName = arguments.front; if (fileName.exists) < auto contents = (cast(string) std.file.read(fileName)) .splitLines; try < int index = to!size_t(arguments[1].strip); File temporaryFile; temporaryFile.open(fileName ~ `.temp`,`w`); contents .removeNth(index) .each!(a =>temporaryFile.writeln(a)); temporaryFile.close; remove(fileName); rename(fileName ~ `.temp`, fileName); terminal.color(Color.green, Color.black); terminal.writefln(«nTodo with number %d was been removed from file %s.», index, fileName ); > catch (Exception e) < terminal.color(Color.red, Color.black); terminal.writeln(«nSecond argument must be a positive integer!»); >> else < terminal.color(Color.red, Color.black); terminal.writeln(«nFile » ~ fileName ~ » doesn’t exists!»); >> >

Также, как и в предыдущей функции, проверяется длина списка переданных аргументов, и в случае если она меньше 2, то выдается предупреждение; в противном случае — происходит дальнейшая обработка аргументов.

Функция removeTodo считает, что первый переданный ей аргумент — это имя файла, а второй — номер записи в файле (к номерам записей файла я еще вернусь). В программе этот факт используется на всю катушку: извлекая имя файла из списка аргументов, тут же проверяется его существование (exists из стандартной библиотеки) и сразу же производится извлечение с последующим приведением к size_t (предварительно из строки, содержащей второй аргумент, вырезаются лишние терминирующие символы: пробелы и им подобные). Если нужный файл не существует, то будет выведено сообщение «File doesn’t exists!» (Файл не существует). Если по каким-то причинам не удалось проделать преобразование, то возникнет исключение, которое будет перехвачено с помощью try/catch блока и пользователь увидит сообщение «Second argument must be a positive integer!» (Второй аргумент должен быть положительным целым).

Если все переданные аргументы корректны, то для осуществления удаления записи из файла необходимо считать весь файл в массив строк, удалить из этого массива элемент с нужным индексом (removeNth), перенести массив строк во временный файл (each и writeln), удалить исходный файл (remove) и переименовать временный файл, используя имя исходного файла (rename). Именно это и происходит внутри блока обработки исключения, в котором для удаления элемента из массива используется вспомогательная функция removeNth, которая описывается следующим образом:

T[] removeNth(T, U)(T[] array, U index) < auto newIndex = cast(size_t) index; if (array.length < 0) < return array; >else < if (newIndex < array.length) < return array[0..newIndex] ~ array[newIndex+1..$]; >> return array; >

В случае успешного удаления записи программа выдаст написанное зеленым цветом сообщение «Todo with number %d was been removed from file %s.» (Запись с номером %d была удалена из файла %s), которое легко и просто формируется с помощью функции format.

Функции moveTodoUp и moveTodoDown, с учетом рассмотренных фрагментов, реализуются достаточно просто и также используют массив-накопитель и временный файл:

void moveTodoUp(ref Terminal terminal, string[] arguments) < if (arguments.length < 2) < terminal.color(Color.red, Color.black); terminal.writeln(«nCommand «head» has 2 arguments»); >else < auto fileName = arguments.front; if (fileName.exists) < auto contents = (cast(string) std.file.read(fileName)) .splitLines; try < int index = to!size_t(arguments[1].strip); string element = contents[index]; File temporaryFile; temporaryFile.open(fileName ~ `.temp`,`w`); (element ~ contents.removeNth(index)) .each!(a =>temporaryFile.writeln(a)); temporaryFile.close; remove(fileName); rename(fileName ~ `.temp`, fileName); terminal.color(Color.green, Color.black); terminal.writefln(«nTodo with number %d was been moved to the top of list in file %s.», index, fileName ); > catch (Exception e) < terminal.color(Color.red, Color.black); terminal.writeln(«nSecond argument must be a positive integer!»); >> else < terminal.color(Color.red, Color.black); terminal.writeln(«nFile » ~ fileName ~ » doesn’t exists !»); >> > void moveTodoDown(ref Terminal terminal, string[] arguments) < if (arguments.length < 2) < terminal.color(Color.red, Color.black); terminal.writeln(«nCommand «tail» has 2 argument»); >else < auto fileName = arguments.front; if (fileName.exists) < auto contents = (cast(string) std.file.read(fileName)) .splitLines; try < int index = to!size_t(arguments[1].strip); string element = contents[index]; File temporaryFile; temporaryFile.open(fileName ~ `.temp`,`w`); (contents.removeNth(index) ~ element) .each!(a =>temporaryFile.writeln(a)); temporaryFile.close; remove(fileName); rename(fileName ~ `.temp`, fileName); terminal.color(Color.red, Color.black); terminal.writefln(`Todo with number %d was been moved to the bottom of list in file %s.`, index, fileName ); > catch (Exception e) < terminal.color(Color.red, Color.black); terminal.writeln(«nSecond argument must be a positive integer!»); >> else < terminal.color(Color.red, Color.black); terminal.writeln(«nFile » ~ fileName ~ » doesn’t exists!»); >> >

Читайте также:
Mac OS как установить программу на другой диск

Теперь можно рассмотреть одну из самых интересных функций программы todo — viewTodo. Работает она с использованием весьма простого алгоритма: в случае успешного прохождения всех предварительных проверок (количество аргументов, существование файла и т.д.) происходит считывание всего файла в массив строк, который затем нумеруется, начиная с нуля (при помощи алгоритма enumerate), а затем выводится в командную строку с помощью алгоритма each:

void viewTodo(ref Terminal terminal, string[] arguments) < if (arguments.empty) < terminal.color(Color.red, Color.black); terminal.writeln(«nCommand «view» has 1 argument»); >else < auto fileName = arguments.front; if (fileName.exists) < terminal.color(Color.cyan, Color.black); writeln; auto contents = (cast(string) std.file.read(fileName)) .splitLines; contents .enumerate(0) .each!(a =>writefln(«%d — %s», a[0], a[1])); terminal.color(Color.green, Color.black); terminal.writefln(«nYou have %d todo(s) now in file %s.», contents.length, fileName ); > else < terminal.color(Color.red, Color.black); terminal.writeln(«nFile » ~ fileName ~ » doesn’t exists!»); >> >

Естественно, перед выводом в командную строку производится окрашивание строк в голубой цвет (при этом, сам файл будет выведен в формате » номер_записи — запись»), а затем зеленым цветом будет выведена надпись «You have %d todo(s) now in file %s.» (В файле %s находится %d заметок).

Копируем все функции в один файл (не забываем про main) и компилируем командой:

dmd todo.d asc1251.d terminal

kartinka-namber-van

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

Конечно, на одной конкретной ситуации не покажешь всех нюансов функционального программирования в D, поэтому я советую читателям внимательнее познакомится со стандартной библиотекой D (в частности, разделы std.algorithm, std.functional, std.range) и немного попрактиковаться в каком-нибудь чисто функциональном языке (Haskell, Scheme, Clojure и т.д).

P.S: Автор статьи от всего сердца благодарит создателей языка Haskell, Мирана Липовача, Мохова Геннадия Владимировича за прекрасную библиотеку QtE5 и Адама Руппа за превосходную коллекцию готовых программных решений arsd.

Источник: lhs-blog.info

Как создать сервер CS 1.6: 4 способа

Как создать сервер CS 1.6

Counter-Strike 1.6 – один из старейших и популярнейших онлайн-шутеров. Официальные серверы игры все еще функционируют, а также активно создаются новые.

Сегодня я расскажу о том, как создать сервер CS 1.6 самостоятельно. Затронем разные методы создания, чтобы каждый игрок нашел вариант для себя.

Как создать сервер CS 1.6 с помощью SteamCMD

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

Что касается процедуры создания сервера, то на компьютере под управлением Windows она выглядит следующим образом:

  1. Перейдите на официальный сайтValve, чтобы загрузить последнюю версию установщика SteamCMD для Windows. Обладателям Linux нужно ознакомиться с командами для установки. Скачивание программы для создания сервера в CS 1.6 через SteamCMD
  2. Запустите извлечение в любую созданную ранее папку, куда хотите поместить все файлы утилиты. Распаковка программы для создания сервера в CS 1.6 через SteamCMD
  3. По завершении выполните авторизацию как анонимус, введя логин anonymous, или через существующую учетную запись в Steam, указав свой логин после объявления команды. Авторизация в программе для создания сервера в CS 1.6 через SteamCMD
  4. Авторизуйтесь при помощи SteamGuard и переходите к следующему шагу. Успешная авторизация в программе для создания сервера в CS 1.6 через SteamCMD
  5. Создайте еще одну пустую папку, куда хотите поместить файлы создаваемого сервера. Скопируйте ее путь через Проводник или запомните, чтобы в дальнейшем использовать в консоли. Копирование пути к папке для создания сервера в CS 1.6 через SteamCMD
  6. В запущенной консоли SteamCMD введите force_install_dir+ путь к созданной только что папке, чтобы установить файлы сервера. Установка файлов сервера для создания сервера в CS 1.6 через SteamCMD
  7. Получите обновления для КС 1.6 через команду app_update 90 validate. Команда для обновления файлов для создания сервера в CS 1.6 через SteamCMD
  8. Если появляется ошибка, введите эту команду еще раз, пока не получите уведомление об успешной инсталляции файлов. Успешное обновление файлов для создания сервера в CS 1.6 через SteamCMD
  9. В целевой папке появится файл под названием hlds.exe, который и отвечает за запуск сервера на локальном компьютере. Запуск исполняемого файла для создания сервера в CS 1.6 через SteamCMD
  10. В качестве игры в новом окне выберите Counter-Strike, а остальные параметры задайте на свое усмотрение. Выбор названия сервера для создания сервера в CS 1.6 через SteamCMD
  11. Не забудьте про пароль RCON и активируйте стандартный античит VAC, если хотите защитить свой сервер. Установка защиты для создания сервера в CS 1.6 через SteamCMD
  12. После запуска появится новое графическое окно, в котором вы можете менять конфигурацию сервера и управлять игроками. Окно управления сервером для создания сервера в CS 1.6 через SteamCMD

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

То же самое можно сделать и через консоль на приобретенном VDS, используя инструкцию по применению SteamCMD на Linux. Детальнее об этом и других командах взаимодействия с данным инструментом читайте в официальной документации от разработчиков.

Игровой хостинг

Комьюнити теперь в Телеграм
Подпишитесь и будьте в курсе последних IT-новостей

Пробуем бесплатные серверы

Ранее была популярна тема временных серверов для Контры 1.6, когда любой пользователь мог открыть специальный сайт, заказать там сервер, получить готовый IP-адрес и учетную запись администратора. Так проводились некоторые клановые игры и тренировки с друзьями. Сейчас большинство таких ресурсов закрылись, поскольку Counter-Strike 1.6 теряет свою популярность, а содержать подобные проекты очень дорого. Однако остались бесплатные хостинги с длительным тестовым периодом и другими привилегиями, позволяющими получить сервер бесплатно на определенное количество времени.

Использование бесплатного сервера в CS 1.6

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

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

Создание сервера CS 1.6 на VDS

Вы можете создать сервер Counter-Strike 1.6 на игровом VDS. Такой вариант используют большинство игроков, желающих открыть собственный проект. Вам не нужно держать локальную машину постоянно включенной, появляется значительно больше возможностей в плане установки плагинов и других нововведений, значительно увеличивается скорость работы сервера как с аппаратной части, так и со стороны соединения (пинг у игроков будет меньше).

Читайте также:
Как установить антивирусную программу на данный компьютер

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

  1. Перейдите на главную страницу сервиса. Сервер CS 1.6
  2. После регистрации можно сразу же создать новый сервер. Создание нового сервера на сайте для создания сервера в CS 1.6
  3. Дайте ему любое название и добавьте комментарий, если это требуется. Ввод имени для сервера на сайте для создания сервера в CS 1.6
  4. В качестве операционной системы рекомендуется выбирать Debian 10, поскольку на нее вы сможете сразу же поставить готовую сборку сервера. Выбор операционной системы для создания сервера в CS 1.6
  5. В списке с дополнительным программным обеспечением обязательно выбирайте EngineGP, поскольку этот инструмент и отвечает за работу с сервером CS 1.6. Выбор дополнительного ПО для создания сервера в CS 1.6
  6. Нажмите на кнопку «Далее» для перехода к следующему шагу, предварительно подключив дополнительные функции, если это требуется. Продолжение установки сервера для создания сервера в CS 1.6
  7. Вы найдете готовые конфигурации сервера или сможете настроить свою в зависимости от требований и подходящей цены. Выбор конфигурации сервера на сайте для создания сервера в CS 1.6
  8. По завершении создания сервера его необходимо включить. Запуск выделенного сервера для создания сервера в CS 1.6
  9. Опуститесь к блоку со списком используемых IP, скопируйте в адресную строку браузера IPv4 и перейдите по нему. Переход по адресу для создания сервера в CS 1.6
  10. Приступите к выбору сервера для Counter-Strike 1.6. Выбор варианта аренды для создания сервера в CS 1.6
  11. Заполните форму аренды игрового сервера в зависимости от ваших предпочтений. Заполнение формы аренды для создания сервера в CS 1.6
  12. Теперь у вас есть свой игровой сервер, который можно включить и перейти к его управлению. Запуск арендованного сервера CS 1.6

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

Панель управления арендованным сервером CS 1.6

Создание консольного приложения

Консольное приложение создается следующим образом. Сначала нужно из меню File выбрать команду New | Other Application и на вкладке New появившегося диалогового окна New Items щелкнуть на значке Console Wizard (рис. 7.1). В результате этих действий на экране появится окно Console Wizard (рис. 7.2). В этом окне можно выбрать язык программирования и указать, будет ли использоваться та или иная библиотека.

После того как будут заданы параметры создаваемого консольного приложения, надо щелкнуть на кнопке ОК. В результате C++ Builder создаст проект консольного .приложения и на экране появится окно редактора кода, в котором находится шаблон консольного приложения — функция main (рис. 7.3).

Рис. 7.1. Чтобы приступить к созданию консольного приложения, надо щелкнуть на значке Console Wizard

Рис. 7.2. В окне Console Wizard надо задать характеристики консольного приложение

Начинается консольное приложение директивой #pragma hdrstop, которая запрещает выполнение предварительной компиляции подключаемых файлов. После этой директивы надо вставить директивы #inciude, обеспечивающие подключение необходимых библиотек (например, #include ). Директива #pragma argsused отключает предупреждение компилятора о том, что аргументы, указанные в заголовке функции, не используются.

Рис. 7.3. Шаблон консольного приложения

Следует обратить внимание на то, что консольное приложение разрабатывается в Windows, а выполняется как программа DOS. В DOS и Windows буквы русского алфавита имеют разные коды (в DOS используется кодировка ASCII, а в Windows — ANSI). Это приводит к тому, что консольное приложение вместо сообщений на русском языке выводит «абракадабру».

Проблему вывода сообщений на русском языке консольными приложениями можно решить, разработав функцию перекодировки ANSI-строки в строку ASCII. Если эту функцию назвать rus, то инструкция вывода сообщения может выглядеть, например, так:

printf( rus(«Скорость: %3.2f км/час»), v);

В качестве примера консольного приложения в листинге 7.1 приведена программа «Угадай число», которая для вывода сообщений использует функцию RUS. Значение функции rus — строка символов в кодировке ASCII, соответствующая строке, полученной в качестве параметра.

Листинг 7.1. Пример консольного приложения

#pragma hdrstop
#include
#include // для доступа к getch()
#include // для доступа к srandf), rand()
linclude // для доступа к time_t и time О
char* rus(char* st);

// преобразует ANSI-строку в строку ASCII tpragma argsused
int main(int argc, char* argv[])
int comp,
// число, «задуманное» компьютером igrok,
// вариант игрока n=0; // число попыток
// ГСЧ — генератор случайных чисел
time_t t; // текущее время (для инициализации ГСЧ)
srandf (unsigned)time( // инициализация ГСЧ
comp = rand() % 10 + 1;
puts( rus(«ХпКомпыотер «задумал» число от 1 до 10.»));

puts( rus(«Вы должны его угадать за три попытки.»));
printf(«->»);
scanf(«%i», Sigrok);
n++; > while ( igrok != comp n < 3);
if (igrok == comp)

printf( rus(«ВЫ ВЫИГРАЛИ!»));
else
puts( rus(«Вы проиграли.»));
printf( rus(«Компьютер «задумал» число %d»), comp); >
printf( гиз(«Для завершения нажмите любую клавишу. «));
getch();
return 0; >
/*Функция rus преобразует ANSI-строку в строку ASCII

и может использоваться для вывода сообщений
на русском языке в консольных программах.
Пример использования:
printf( rus(«Скорость: %3.2f км/час»), v);
printf( rus(«У лукоморья дуб зеленыйп»)); */
char* rus(char* st)
unsigned char* p = st;
/* при объявлении символов как char русские буквы

кодируются отрицательными числами */ while ( *р)
if (*p >= 192) // здесь русская буква
if (*р
*р -= 64; else // p . я
*р -= 16;
Р++; > return st;

Компиляция консольного приложения выполняется обычным образом, т. е. выбором из меню Project команды Compile.

После успешной компиляции программа может быть запущена выбором из меню Run команды Run. При запуске консольного приложения на экране появляется стандартное окно командной строки. На рис. 7.4 приведен вид окна командной строки, в котором работает консольное приложение, созданное в C++ Builder.

Процесс сохранения проекта консольного приложения стандартный. В результате выбора из меню File команды Save Project на экране сначала появляется окно Save Project, в котором нужно ввести имя проекта, а затем — окно Save Utit, в котором надо задать имя модуля.

Получить доступ к модулю консольного приложения (тексту программы) для того, чтобы внести изменения в программу, несколько сложнее. Сначала, выбрав в меню File команду Open Project, нужно открыть файл проекта. Затем надо открыть окно Project Manager (команда View | Project Manager), раскрыть список файлов, выбрать срр-файл и из контекстного меню выбрать команду Open (или сделать двойной щелчок на имени срр-файла) (рис. 7.5).

Рис. 7.4. Окно командной строки, в котором работает консольное приложение

Рис. 7.5. Чтобы внести изменения в программу, надо в окне Project Manager выбрать срр-файл и из контекстного меню выбрать команду Open

Fore kc .ru
Рефераты, дипломы, курсовые, выпускные и квалификационные работы, диссертации, учебники, учебные пособия, лекции, методические пособия и рекомендации, программы и курсы обучения, публикации из профильных изданий

Источник: www.ci-builder.ru

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru