<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SimpleCoding.org &#187; C++</title>
	<atom:link href="http://www.simplecoding.org/category/c/feed" rel="self" type="application/rss+xml" />
	<link>http://www.simplecoding.org</link>
	<description>Блог о программировании</description>
	<lastBuildDate>Fri, 27 Jan 2012 18:27:45 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Программирование логической игры с использованием DirectX. Крестики-нолики.</title>
		<link>http://www.simplecoding.org/krestiki-noliki.html</link>
		<comments>http://www.simplecoding.org/krestiki-noliki.html#comments</comments>
		<pubDate>Sun, 12 Aug 2007 10:49:45 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/krestiki-noliki.html</guid>
		<description><![CDATA[Программирование на С++. Создание игр с помощью DirectX.]]></description>
			<content:encoded><![CDATA[<p>Не так давно я начал изучать библиотеку DirectX, и, естественно, мне тут же захотелось написать свою собственную игрушку. Информации на эту тему масса, начиная от описания базовых алгоритмов, и заканчивая полностью готовыми играми. С выбором темы игры я долго не мучился. Варианты типа DOOM4 и Elder Scroll&#039;s 5:-) я отбросил сразу. Хотелось написать что-то по быстрому, и, в тоже время, полностью самостоятельно (без использования готовых движков, моделей и т.п.). Поэтому выбор пал на простую логическую игрушку &#8211; крестики-нолики. Кроме простоты реализации эта игра обладает ещё одним очень важным достоинством &#8211; никому не нужно рассказывать правила <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':smile:' class='wp-smiley' />  .<br />
<span id="more-24"></span><br />
<a href="#l1">О программе</a><br />
<a href="#l2">Описание программы</a><br />
<a href="#l3">Заключение</a><br />
<a href="#l4">Скачать</a><br />
<a title="l1" name="l1"></a><br />
<strong>О программе</strong></p>
<p>Эта программа существенно отличается от большинства примеров, размещённых на сайте. Во-первых, она написана на С++ с помощью Visual Studio.NET.<br />
Во-вторых, в ней используются две библиотеки: API Windows и DirectX9. Соответственно, для сборки проекта должен быть установлен DirectX SDK девятой версии.<br />
API Windows используется только для создания окна и обработки сообщений мыши. DirectX &#8211; для создания интерфейса пользователя (крестики, нолики, сетка, меню и т.п.).<br />
Кроме того, хочу сразу предупредить, это одна из моих первых программ, написанная с использованием DirectX. Поэтому не стоит использовать ее как образец для ваших собственных разработок, особенно, если они крупные (например, движок). С другой стороны, работает она правильно (именно так, как задумывалось), а не совсем оптимальный код практически не заметен в играх такого масштаба:-). Так что, выбор за вами.<br />
В-третьих, для работы программы кроме файла xzgame.exe необходимы файлы моделей и текстур (если вы используете инсталлятор, то они установятся автоматически).<br />
В-четвертых, я сделал инсталлятор с помощью программы Inno Setup. Конфигурационный файл называется dist.iss.</p>
<p><a title="l2" name="l2"></a><br />
<strong>Описание программы</strong></p>
<p>Программу можно условно разделить на две части:</p>
<ul>
<li>первая &#8211; хранит информацию о расположении крестиков и ноликов, выполняет расчёт очередного хода;</li>
<li>вторая &#8211; рисует игровое поле, выполняет обработку команд пользователя и т.п.</li>
</ul>
<p>Так как игра достаточно простая, то всю работу, связанную с хранением информации об игре и выбором очередных ходов, выполняет всего один класс &#8211; <code>XZField</code>. Его структура показана на рис.1.<br />
<a href="/wp-content/uploads/2007/08/xzfield.jpg" rel="lightbox"><img src="/wp-content/uploads/2007/08/.thumbs/.xzfield.jpg" alt="Нажмите чтобы увеличить рисунок" title="xzfield.jpg" class="center" width="500" border="0" height="275" /></a></p>
<p style="text-align: center">Рис.1. Класс XZField.</p>
<p>Пользоваться им очень просто. С помощью метода <code>setElement</code> можно добавить крестик или нолик в заданную ячейку. Метод <code>getElement</code> возвращает элемент, расположенный в заданной ячейке. Выбор следующего хода осуществляется методом <code>findNextMove</code>. В качестве параметров этому методу передаются ссылки на переменные, в которых нужно сохранить координаты выбранного хода. Если новый ход был найден, метод возвращает <code>true</code>, в противном случае &#8211; <code>false</code>.</p>
<p>Пример:</p>
<pre class="brush: cpp">XZField f; . . . int row, col; //переменные, в которых сохраняются координаты следующего хода
//ищем следующий ход
if(f.findNextMove(row, col)) {
    f.setElement(f.ZERO, row, col); //устанавливаем элемент
}</pre>
<p>Метод <code>isGameOver</code> позволяет определить закончена ли игра, и кто выиграл. Если игра закончена, возвращает <code>true</code>, в противном случае &#8211; <code>false</code>. В параметре winner сохраняются данные о победителе (крестики, нолики или ничья).</p>
<p>Более подробное описание работы методов класса можно почитать в комментариях к исходному коду класса.</p>
<p>Вторая часть программы значительно объёмнее. Она отвечает за прорисовку всех элементов игры (создание окна, меню, крестики, нолики и т.д.), взаимодействие с пользователем (обработка сообщений мыши).</p>
<p>Таким образом, нам нужно несколько объектов с различными свойствами и назначением:</p>
<ul>
<li>объекты игры (крестик, нолик, сетка, прямоугольник выделения) &#8211; каждый из них является 3D моделью и хранится в файле с расширением .х в папке models (cross.x, zero.x, grid.x, selectionPlane.x). Все эти модели должны быть загружены перед началом игры, также необходим метод для прорисовки (желательно один);</li>
<li>меню &#8211; представляет собой квадрат с текстурой, на которой нарисованы изображения кнопок, текстовые сообщения и пр.. Текстуры должны загружаться из файлов при загрузке программы. Нужны методы для изменения текстур и прорисовки меню;</li>
<li>искусственный интеллект (AI) &#8211; это уже рассмотренный класс <code>XZField</code>;</li>
<li>создание окна и обработка ввода пользователя &#8211; нужно создать обычное окно, создать объект и устройство Direct3D, установить обработчики сообщений мыши, также нужен метод для перерисовки окна;</li>
<li>сообщения об ошибках &#8211; даже в самых простых программах, могут возникнуть десятки различных ошибок, поэтому необходим общий подход к их обработке.</li>
</ul>
<p>На рис.2 изображена диаграмма классов игры. На ней прямоугольниками изображены классы, а стрелками показаны связи между ними. Разберём подробнее, что это все означает и как работает.<br />
<a href="/wp-content/uploads/2007/08/main_classes.jpg" rel="lightbox"><img src="/wp-content/uploads/2007/08/.thumbs/.main_classes.jpg" alt="Нажмите чтобы увеличить изображение" title="main_classes.jpg" class="center" width="500" border="0" height="465" /></a></p>
<p style="text-align: center">Рис.2. Диаграмма классов игры</p>
<p>Итак, в этой игре я использовал следующие классы:</p>
<ul>
<li><code>BaseWindowClass</code></li>
<li><code>XZGame</code></li>
<li><code>ExceptionBase</code></li>
<li><code>XZField</code></li>
<li><code>NewGameMenu</code></li>
<li><code>XZMesh</code></li>
</ul>
<p>Теперь посмотрим, что они делают, и как связаны друг с другом.</p>
<p>Класс <code>BaseWindowClass</code> используется для создания пустого окна. Использовать его напрямую нельзя, т.к. он содержит абстрактный метод <code>Render()</code>. Поэтому нам нужно создать дочерний класс, в котором этот метод будет выполнять рендеринг объектов игры. Но об этом чуть позже, а сейчас рассмотрим как пользоваться остальными методами класса <code>BaseWindowClass</code>.</p>
<p>Конструктор &#8211; ничего не делает.<br />
<code>Create</code> &#8211; создает окно. В качестве параметров можно указать:</p>
<ul>
<li><code>hInstance</code> &#8211; идентификатор приложения;</li>
<li><code>szTitle</code> &#8211; название приложения;</li>
<li><code>iStyle</code> &#8211; стиль окна;</li>
<li><code>iWidth</code> &#8211; длина окна;</li>
<li><code>iHeight</code> &#8211; ширина окна.</li>
</ul>
<p>Это обычные параметры, которые указываются при создании оконных приложений, поэтому я не буду их здесь подробно объяснять.<br />
<code>WndProc</code> &#8211; это оконная процедура. Вызывается операционной системой, для передачи сообщений окну.</p>
<p><code>Run</code> &#8211; этот метод запускает цикл обработки сообщений. В каждом цикле есть вызов метода <code>Render()</code>.</p>
<p><code>MessageHandler</code> &#8211; в этом методе выполняется обработка сообщений, отправленных окну. Написан обработчик сообщения <code>WM_DESTROY</code>, которое приложение получает, когда пользователь закрывает приложение. Обработка этого сообщения является одинаковой для большинства приложений (если пользователь нажал кнопку &#034;закрыть&#034;, значит надо завершать работу), поэтому я написал обработчик в базовом классе. Вы, наверное, заметили, что этот метод объявлен виртуальным. Зачем нам это нужно? В первую очередь давайте посмотрим, кто вызывает этот метод. Сообщение окну передаёт операционная система с помощью оконной процедуры, которая в свою очередь вызывает обработчик. Теперь представим, что нам нужно обрабатывать другие сообщения (например, перемещения мыши). Можно, конечно добавить соответствующие обработчики прямо в текст метода, т.е. каждый раз менять код базового класса, а это не правильно. Гораздо удобнее создать в производном классе такой же метод (<code>MessageHandler</code>), и добавить обработчики в него. Т.е. у нас будет два метода MessageHandler, один &#8211; в базовом классе, другой &#8211; в производном. При этом нам нужно, чтобы оконная процедура вызывала метод производного класса (из него, при необходимости, мы можем вызвать метод базового класса). Так вот, объявление метода виртуальным гарантирует, что мы получим именно такое поведение. Тем, кто хочет разобраться подробнее с этим моментом, я советую почитать какую-нибудь книжку по объектно-ориентированному программированию.</p>
<p><code>Render</code> &#8211; объявлен абстрактным. Это значит, что в производном классе нам придется написать его реализацию. Т.е. объявить точно такой же метод, и написать код, который он будет выполнять (в принципе, этот метод можно оставить пустым, если вы не хотите ничего рисовать).</p>
<p>Теперь давайте посмотрим на класс <code>XZGame</code>. Он является потомком <code>BaseWindowClass</code>, и движком игры, т.е. связывает все компоненты игры вместе, выполняет обработку команд пользователя, выводит результаты игры и др.</p>
<p>Работу этого класса в качестве движка мы рассмотрим далее, а сейчас я только покажу какие методы класса <code>BaseWindowClass</code> мы переопределяем и какие добавляем. В первую очередь нам нужен метод <code>initD3DAndGameObjects()</code>. Он выполняет инициализацию DirectX и всех объектов игры. Далее мы метод <code>setMatricesAndRenderStates()</code> в котором настраиваем устройство Direct3D и матрицы (мира, вида и проекционную). Затем мы переопределяем метод <code>MessageHandler</code>, в котором у нас содержатся обработчики сообщений. И последний метод &#8211; <code>Render()</code>. В нем мы будем рисовать объекты игры (крестики, нолики, игровое поле, меню).</p>
<p>Теперь посмотрим как пользоваться этим классом. Все очень просто. В функции <code>WinMain</code> нам нужно написать примерно такой код:</p>
<pre class="brush: cpp">//создаем экземпляр класса
XZGame XZGame game;
//создаем окно
game.Create(hInst, "Крестики-нолики 1.0", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 640, 480); //инициализируем Direct3D и объекты игры
game.initD3DAndGameObjects();
//устанавливаем матрицы и настраиваем параметры отображения сцены game.setMatricesAndRenderStates();
//входим в цикл обработки сообщений
game.Run();</pre>
<p>В результате будет запущена наша игрушка.<br />
Следующий класс &#8211; <code>ExceptionBase</code>. Это сервисный класс. Он используется всеми классами для передачи сообщений об ошибках. Такой подход позволяет создать общую для всей программы систему уведомления об ошибках.<br />
Пользоваться им очень просто. Если возникла ошибка, мы создаём объект этого класса с указанием описания ошибки, и генерируем исключение. Например:</p>
<pre class="brush: cpp">ExceptionBase error(111, "Какая-то ошибка");
throw error;</pre>
<p>Здесь, 111 &#8211; код ошибки, &#034;Какая-то ошибка&#034; &#8211; описание ошибки.<br />
Перехват исключений выполняется как обычно:</p>
<pre class="brush: cpp">try {
    //код программы
}
//обработка исключений типа ExceptionBase
catch(ExceptionBase err) {
    MessageBox(NULL, (const char*)err, "Ошибка", MB_ICONERROR);
}
//обработка исключений других типов
catch(…) { }</pre>
<p>Тут все просто, но я хочу обратить ваше внимание на оператор <code>(const char*)err</code>. Он выполняет преобразование объекта типа <code>ExceptionBase</code> к типу <code>const char*</code>. Используя такое преобразование можно легко получить строку, содержащую описание ошибки. Есть также оператор приведения к типу <code>int</code>, который возвращает код ошибки.<br />
Класс <code>XZMesh</code>.</p>
<p>Как вам известно, практически все объекты в играх представляют собой меши, т.е. наборы связанных между собой вершин. Для их создания удобнее всего воспользоваться каким-нибудь 3D редактором. Например, я пользуюсь Blender&#039;ом (полностью бесплатная программа, причем очень не большого размера). Вы можете воспользоваться любым другим редактором в зависимости от ваших предпочтений, знаний, навыков и т.п., главное чтобы вы могли в нем нарисовать то, что вам хочется:-).<br />
И ещё один важный момент по поводу редакторов. После того, как вы нарисовали красивый объект, вам нужно будет загрузить его в вашу программу, и тут возникает интересный момент. Каждый редактор использует свой собственный формат для хранения файлов, поэтому убедитесь, что у вас есть возможность импортировать файлы в .х формат (это единственный формат, который поддерживается библиотекой DirectX). Для Blender&#039;а я использовал <a href="http://development.mindfloaters.de/">DirectX8ExporterMod</a>, для 3Dmax&#039;a и Maja конвертер есть в DirectX SDK. Впрочем, если вы занимаетесь созданием движка или просто большим проектом, то можно создать загрузчик файлов для нужного формата (процедура очень трудоёмкая, но обычно себя оправдывает: увеличивается скорость загрузки, можно загружать дополнительную информацию и т.д.).<br />
Но вернёмся к нашему классу. Он очень простой (практически всю работу выполняет DirectX). При вызове конструктора нужно указать имя файла, в котором находится mesh. Для того, чтобы нарисовать mesh вызываем метод <code>render()</code>. Например так:</p>
<pre class="brush: cpp">XZMesh cross = new XZMesh(pD3DDevice, "modelscross.x");
...
cross.render();</pre>
<p>И это все. Никаких наворотов, только то, что необходимо.<br />
Следующий класс <code>NewGameMenu</code>. Он создаёт меню, которое видит игрок перед началом и после окончания игры. Итак, что представляет собой меню? Это просто прямоугольник, на который &#034;натянута&#034; текстура с изображение меню. Тут все просто, но сколько нам нужно текстур? Давайте считать. Существует 4 возможных варианта:</p>
<ul>
<li>игрок только что запустил программу, и мы предлагаем начать игру;</li>
<li>игрок выиграл предыдущую партию, мы выводим соответствующее сообщение и предлагаем сыграть ещё раз;</li>
<li>игрок проиграл предыдущую игру;</li>
<li>предыдущая игра закончилась вничью.</li>
</ul>
<p>Кроме этого я решил реализовать подсветку кнопок меню, т.е. нужно по одной дополнительной текстуре для каждой кнопки (каждое меню в игре имеет две кнопки). Таким образом, получается, что нужно по 3 текстуры на каждый вариант меню. Итого, 4 * 3 = 12 текстур.<br />
Посмотрим, как пользоваться нашим классом.<br />
При создании меню нам нужно указать положение центра меню на экране, передать указатель на массив с именами текстур, количество текстур в массиве, длину и ширину меню, прямоугольник в котором нужно нарисовать меню.<br />
Для прорисовки меню, как вы догадались, используется метод <code>render()</code>.<br />
Два дополнительных метода класса &#8211; <code>checkSelectedButtons</code> и <code>setCurrentMenu</code> используются вместе. Зачем они нужны? Помните, я писал, что мы будем подсвечивать кнопки меню, так вот, чтобы включить подсветку мы должны проверить, где находится курсор мыши, и установить соответствующую текстуру. Метод <code>checkSelectedButtons</code> в качестве параметра принимает координаты курсора мыши, и возвращает номер выбранной кнопки, а метод <code>setCurrentMenu</code> устанавливает нужное меню. Таким образом, если вызывать эти методы при в обработчике события <code>WM_MOUSEMOVE</code> (возникает при перемещении курсора мыши), то мы получим обычное меню: навели курсор на кнопку, она подсветилась, убрали &#8211; подсветка исчезла.<br />
Приводить пример использования этого класса я не буду, т.к. он очень тесно связан с остальным кодом проекта (обработкой сообщений, установкой матриц преобразований и т.п.), поэтому будет лучше, если вы посмотрите исходники программы, и почитаете комментарии.<br />
Теперь, как я и обещал, вернёмся к классу <code>XZGame</code>, и рассмотрим, как он осуществляет управление ходом игры (т.е. его работу в качестве движка).<br />
В первую очередь посмотрим на рис.3. На нем изображена диаграмма состояний класса, на которой изображены все возможные варианты хода игры (ситуации, вроде нажатия на кнопку &#034;Reset&#034; или удара молотком по системному блоку <img src='http://www.simplecoding.org/wp-includes/images/smilies/icon_smile.gif' alt=':smile:' class='wp-smiley' />  здесь не учитываются).<br />
<a href="/wp-content/uploads/2007/08/main_classes.jpg" rel="lightbox"><img src="/wp-content/uploads/2007/08/.thumbs/.main_classes.jpg" alt="Нажмите чтобы увеличить изображение" title="main_classes.jpg" class="center" width="500" border="0" height="465" /></a></p>
<p style="text-align: center">Рис.3. Диаграмма состояний класса</p>
<p>Давайте разберем все по порядку. У нас есть шесть основных состояний игры, каждому из которых соответствует своя константа в перечислении states (см. исходный код):</p>
<ul>
<li><code>NEW_GAME_MENU</code> &#8211; начало новой игры, пользователь только что запустил программу;</li>
<li><code>NEW_GAME_MENU_WIN</code> &#8211; начало новой игры, пользователь выиграл предыдущую игру;</li>
<li><code>NEW_GAME_MENU_LOST</code> &#8211; начало новой игры, пользователь проиграл предыдущую игру;</li>
<li><code>NEW_GAME_MENU_DRAW</code> &#8211; начало новой игры, предыдущая игра закончилась вничью;</li>
<li><code>PLAYER_MOVE</code> &#8211; ожидание хода игрока;</li>
<li><code>COMP_MOVE</code> &#8211; ожидание хода компьютера (ждем, пока метод findNextMove класса <code>XZField</code> выберет ход).</li>
</ul>
<p>Итак, игрок только что запустил программу.</p>
<p>Объект класса <code>XZGame</code> находится в состоянии <code>NEW_GAME_MENU</code>, и, соответственно, на экране отображается меню с предложением начать игру. Если игрок нажимает кнопку &#034;нет&#034; &#8211; игра завершается (не понятно &#8211; зачем вообще он ее запускал? От скуки щелкал по всем ярлыкам подряд:-)). А вот если нажата кнопка &#034;да&#034; &#8211; начинаем играть. В первую очередь, программа выбирает, кто первым будет ходить (случайным образом, с помощью функции <code>rand()</code>). Далее, в зависимости от результатов предыдущего этапа, мы попадаем в состояние <code>PLAYER_MOVE</code> или <code>COMP_MOVE</code>. В состоянии <code>PLAYER_MOVE</code> мы просто ждем, пока игрок сделает ход (кстати, игрок всегда играет ноликами). А в состоянии <code>COMP_MOVE</code> мы ждем результатов метода <code>findNextMove</code>.</p>
<p>Затем мы проверяем состояние игры (завершена, не завершена, если завершена, то с каким результатом). Если игра не была завершена, то мы переходим либо в состояние <code>PLAYER_MOVE</code>, либо <code>COMP_MOVE</code>, в зависимости от того, кто ходил перед этим. Если игра завершена, то в зависимости от ее результатов, мы переходим в одно из трех состояний: <code>NEW_GAME_MENU_WIN</code> (если победил игрок), <code>NEW_GAME_MENU_LOST</code> (если победил компьютер), <code>NEW_GAME_MENU_DRAW</code> (если игра закончилась вничью). Эти состояния очень похожи. Все три рисуют меню с предложением начать новую игру. Разница только в текстурах, которые используются для меню (в верхней части текстуры нарисована строка с результатами игры). Дальше все просто, если игрок нажмет кнопку &#034;да&#034; &#8211; переходим в состояние розыгрыша первого хода, и процесс повторяется, если игрок нажал кнопку &#034;нет&#034; &#8211; завершаем работу.</p>
<p><a title="l3" name="l3"></a><br />
<strong>Заключение</strong></p>
<p>Это очень простая игра, но, тем не менее, здесь используются те же приемы, что и в больших проектах. Проблема с большими проектами в том, что в них, как говорится, &#034;за лесом деревьев не видно&#034; (особенно, если вы только начали изучать DirectX и принципы создания игр). Конечно, моя игрушка написана далеко не идеально. К моменту окончания работы над ней, я видел кучу недостатков, и, если бы я делал ее заново, то возможно она получилась бы лучше и красивее. Но игра работает. В нее можно играть. А это все-таки положительный результат.</p>
<p>В общем, надеюсь, эта статья вам поможет.</p>
<p><a title="l4" name="l4"></a><br />
<strong>Скачать:</strong></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/setup.exe" title="Игра крестики-нолики">игру крестики-нолики (setup.exe &#8211; 578кБ);</a></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/xzgame.zip" title="Архив с исходниками программы крестики-нолики">исходный код (xzgame.zip &#8211; 475кБ).</a></p>
<p><strong>Постовой</strong></p>
<p><a href='http://netpeak.net/'>Продвижение сайта</a> сделает ваш товар ближе к потребителю</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/krestiki-noliki.html/feed</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Решение классической задачи программирования на C++. Восемь ферзей.</title>
		<link>http://www.simplecoding.org/vosem-ferzej.html</link>
		<comments>http://www.simplecoding.org/vosem-ferzej.html#comments</comments>
		<pubDate>Sat, 11 Aug 2007 15:39:26 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/vosem-ferzej.html</guid>
		<description><![CDATA[Программирование на С++, восемь ферзей]]></description>
			<content:encoded><![CDATA[<p>Эта задача &#8211; одна из очень интересных шахматных головоломок.<br />
Условие такое: можно ли поставить восемь ферзей на пустой доске таким образом, чтобы ни один из них не &#034;атаковал&#034; другого, т.е. так, чтобы ни какие два ферзя не стояли на одном и том же столбце, или на одной и той же строке, или на одной и той же диагонали шахматной доски.<br />
<span id="more-21"></span><br />
Решение этой задачи, как вы понимаете, существует, причём не одно. На рис.1 я показал один из возможных вариантов расстановки ферзей.</p>
<table style="border: 1px solid #303030; margin: auto; text-align: center; border-collapse: collapse">
<tr>
<td style="width: 20px; background-color: #c0c0c0"></td>
<td style="width: 20px; background-color: #ffffff"></td>
<td style="width: 20px; background-color: #c0c0c0"></td>
<td style="width: 20px; background-color: #ffffff">Ф</td>
<td style="width: 20px; background-color: #c0c0c0"></td>
<td style="width: 20px; background-color: #ffffff"></td>
<td style="width: 20px; background-color: #c0c0c0"></td>
<td style="width: 20px; background-color: #ffffff"></td>
</tr>
<tr>
<td style="background-color: #ffffff">Ф</td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
</tr>
<tr>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0">Ф</td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
</tr>
<tr>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0">Ф</td>
</tr>
<tr>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff">Ф</td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
</tr>
<tr>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff">Ф</td>
<td style="background-color: #c0c0c0"></td>
</tr>
<tr>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0">Ф</td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
</tr>
<tr>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0">Ф</td>
<td style="background-color: #ffffff"></td>
<td style="background-color: #c0c0c0"></td>
</tr>
</table>
<p style="text-align: center">Рис.1</p>
<p>Решение этой задачи на компьютере не представляет большой сложности. В принципе, можно тупо перебрать все возможные варианты расстановки ферзей на доске, а затем определить подходящие. Написать такую программу не сложно, но возникает вопрос: &#034;Сколько существует вариантов и сколько времени нужно для их перебора?&#034; Честно говоря, считать точное количество вариантов мне было лень, но, судя по всему, ждать придется долго.</p>
<p>Поэтому, нужно каким-то образом определить на какую клетку ставить следующего ферзя. Например, ставить несколько ферзей в одну линию бессмысленно (это противоречит условию). Если попробовать решить задача вручную, то становится понятно, что расставить 6 – 7 ферзей не сложно. Но после этого свободных клеток (которые не &#034;бьются&#034; ни одним из ферзей) нет. Следовательно, ферзей нужно расставлять так, чтобы они били как можно меньше клеток. Очень хорошо если несколько разных ферзей &#034;бьют&#034; одни и те же клетки, но при этом не &#034;бьют&#034; друг друга.</p>
<p>Дальше все очень просто. Нужно перебрать по очереди все свободные клетки доски (те, которые не &#034;атакует&#034; ни один ферзь) и посчитать, сколько свободных клеток &#034;будет&#034; бить ферзь из данной.</p>
<p>Для решения задачи нам понадобиться массив <code>accessibility[8][8]</code>. В нем мы будем хранить информацию о том, свободна данная клетка или нет. Таким образом, для того чтобы определить сколько клеток будет &#034;бить&#034; ферзь из заданной, нам нужно перемещать ферзя по всем возможным направлениям (их восемь) и считать свободные клетки. Для перемещения ферзя удобно использовать два одномерных массива, элементы которых указывают на сколько клеток нужно сместить ферзя при движении в выбранном направлении. Я определил их таким образом:</p>
<pre class="brush: cpp">const int vert[] = {0,-1,-1,-1,0,1,1,1};
const int hor[] = {1,1,0,-1,-1,-1,0,1};</pre>
<p>Нулевой элемент соответствует перемещения вправо. Первый – по диагонали вправо и вверх, и т.д. Для перемещения ферзя, например, на одну клетку вниз можно записать</p>
<pre class="brush: cpp">x += hor[6];
y += vert[6];</pre>
<p>Далее нужно выбрать клетку, которой соответствует наименьшее количество &#034;выбитых&#034; свободных клеток. Если таких клеток несколько, то выбираем одну из них случайным образом и ставим на неё ферзя (при этом нужно отметить в массиве <code>accessibility</code>, что соответствующие клетки заняты). Процесс повторяется до тех пор, пока не будут установлены все 8 ферзей.</p>
<p>На этом примере очень хорошо виден главный недостаток эвристического программирования – он не всегда позволяет решить задачу. Программа, работающая по данному алгоритму, находит решение примерно один раз из десяти. Этот результат, конечно, можно улучшить, если, например, выполнять анализ на несколько ходов вперёд. Но, в любом случае, такая программа не сможет гарантировать решение, мы только увеличим вероятность его нахождения.</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/queen.zip" title="Скачать программу (queen.zip - 250kB)">Скачать программу (queen.zip &#8211; 250kB)</a></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/queen_src.zip" title="Скачать исходники (queen_src.zip - 16,4kB)">Скачать исходники (queen_src.zip &#8211; 16,4kB)</a> (Для компиляции необходим Borland C++ Builder 5)</p>
<p><strong>Постовой</strong></p>
<p>Известный интернет-магазин предлагает широкий выбор <a href="http://www.install.in.ua/">кондиционеров</a> в Украине.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/vosem-ferzej.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Классические задачи программирования. Путешествие коня.</title>
		<link>http://www.simplecoding.org/puteshestvie-konya.html</link>
		<comments>http://www.simplecoding.org/puteshestvie-konya.html#comments</comments>
		<pubDate>Fri, 10 Aug 2007 13:22:18 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/puteshestvie-konya.html</guid>
		<description><![CDATA[Программирование на С++, путешествие коня]]></description>
			<content:encoded><![CDATA[<p>Эта интересная головоломка была предложена математиком Эйлером. Задание, на первый взгляд, достаточно простое – нужно шахматным конём, находящимся на произвольной клетке шахматной доски, обойти все остальные клетки доски. При этом на одну клетку можно походить только один раз.<br />
<span id="more-18"></span><br />
Конь, как известно, ходит Г-образно. Т.е. на две клетки в каком-либо направлении (вверх, вниз, вправо, влево) и на одну клетку в перпендикулярном. Таким образом, конем, можно сделать максимум восемь различных ходов из заданной клетки (или меньше, если конь находится у края доски).</p>
<p>Для решения этой задачи на компьютере необходимо разработать правила, в соответствии с которыми компьютер будет выбирать ход. В принципе, очередной ход можно выбирать случайным образом. Но ожидать при этом хороших результатов может только большой оптимист. Интересный вариант выбора ходов предложен в книге &#034;Как программировать на С++&#034; Х.Дейтел, П.Дейтел.</p>
<p>Для его реализации нужны два двумерных массива (размер 8х8). В первый массив (<code>board</code>) записываем данные о том, ходили ли мы на какую-то клетку. Например, в начале все элементы массива равны нулю. Как только мы ставим коня на какую-либо клетку соответствующему элементу массива нужно присвоить единицу. Здесь все просто. Заполнение второго массива (<code>accessibility </code> &#8211; доступность) немного сложнее. Каждый его элемент, также как и в массиве <code>board</code>, соответствует клетке на доске, но здесь мы записываем информацию о том, со скольких клеток можно походить на заданную. Например, на клетку а1 можно походить из двух клеток (с2 и b3). Массив <code>accessibility</code> перед началом решения задачи имеет следующий вид:</p>
<table style="border: 1px solid #303030; margin: auto; text-align: center; border-collapse: collapse">
<tr>
<td style="width: 20px; background-color: #c0c0c0">2</td>
<td style="width: 20px; background-color: #ffffff">3</td>
<td style="width: 20px; background-color: #c0c0c0">4</td>
<td style="width: 20px; background-color: #ffffff">4</td>
<td style="width: 20px; background-color: #c0c0c0">4</td>
<td style="width: 20px; background-color: #ffffff">4</td>
<td style="width: 20px; background-color: #c0c0c0">3</td>
<td style="width: 20px; background-color: #ffffff">2</td>
</tr>
<tr>
<td style="background-color: #ffffff">3</td>
<td style="background-color: #c0c0c0">4</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">3</td>
</tr>
<tr>
<td style="background-color: #c0c0c0">4</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">4</td>
</tr>
<tr>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">4</td>
</tr>
<tr>
<td style="background-color: #c0c0c0">4</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">4</td>
</tr>
<tr>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">8</td>
<td style="background-color: #c0c0c0">8</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">4</td>
</tr>
<tr>
<td style="background-color: #c0c0c0">3</td>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">6</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">4</td>
<td style="background-color: #ffffff">3</td>
</tr>
<tr>
<td style="background-color: #ffffff">2</td>
<td style="background-color: #c0c0c0">3</td>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">4</td>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">4</td>
<td style="background-color: #ffffff">3</td>
<td style="background-color: #c0c0c0">2</td>
</tr>
</table>
<p style="text-align: center">Рис.1</p>
<p>После хода конем на какую-нибудь клетку мы должны будем уменьшить на единицу значения всех элементов массива <code>accessibility</code>, которые соответствуют клеткам, находящимся на расстоянии одного хода от текущей клетки. Изменять значение элемента массива <code>accessibility</code> для текущей клетки не имеет смысла, т.к. соответствующий элемент массива board имеет значение равное единице (на эту клетку ходить нельзя).</p>
<p>Имея эти два массива выбрать ход не сложно. Нужно ходить на те клетки, для которых элементы массива <code>accessibility</code> имеют минимальное значение, а элементы массива board равны нулю.</p>
<p>Можно углубить анализ, т.е. просчитывать несколько ходов вперед. В этом случае нужно выбирать тот ход, который приводит нас к ячейке с минимальным значением элемента в массиве <code>accessibility</code>.</p>
<p>Кроме этого, я хотел бы пояснить, как выполняется ход. Мы уже говорили, что существует восемь возможных ходов. Все они закодированы цифрами от 0 до 7. На рис. 2 показаны все возможные варианты ходов.</p>
<table style="border: 1px solid #303030; margin: auto; text-align: center; border-collapse: collapse">
<tr>
<td style="width: 20px; height: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="width: 20px; background-color: #ffffff">&nbsp;</td>
<td style="width: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="width: 20px; background-color: #ffffff">&nbsp;</td>
<td style="width: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="width: 20px; background-color: #ffffff">&nbsp;</td>
<td style="width: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="width: 20px; background-color: #ffffff">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">2</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">1</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">3</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">0</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">K</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">4</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">7</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">5</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">6</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
</tr>
<tr>
<td style="width: 20px; height: 20px; background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
<td style="background-color: #ffffff">&nbsp;</td>
<td style="background-color: #c0c0c0">&nbsp;</td>
</tr>
</table>
<p style="text-align: center">Рис.2</p>
<p> Каждый ход можно представить как перемещение на заданное количество клеток по горизонтали и по вертикали. Например, нулевому ходу соответствует перемещение на две клетки по горизонтали, и &#034;-1&#034; клетку по вертикали (знак минус указывает на направление перемещения). Для выполнения ходов удобно использовать следующие массивы:</p>
<pre class="brush: cpp">int horizontal[] = {2, 1, -1, -2, -2, -1, 1, 2};
int vertical[] = {-1, -2, -2, -1, 1, 2, 2, 1};</pre>
<p>Значения элементов этих массивов соответствуют перемещению по горизонтали и по вертикали для всех возможных ходов. Например, для выполнения хода 4 нужно выполнить две операции:</p>
<pre class="brush: cpp">X += horizontal[4];
Y += vertical[4];</pre>
<p>где, X и Y – текущие координаты (по горизонтали и вертикали, соответственно).</p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/knight.zip" title="Скачать программу (knight.zip - 250kB)">Скачать программу (knight.zip &#8211; 250kB)</a></p>
<p><a href="http://www.simplecoding.org/wp-content/uploads/2007/08/knight_src.zip" title="Скачать исходники (knight_src.zip - 16,4kB)">Скачать исходники (knight_src.zip &#8211; 16,4kB)</a> (Для компиляции необходим Borland C++ Builder 5)</p>
<p><strong>Постовой</strong></p>
<p>Выбираем надежный <a href="http://hostlex.ru/">платный хостинг</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/puteshestvie-konya.html/feed</wfw:commentRss>
		<slash:comments>32</slash:comments>
		</item>
		<item>
		<title>Простая логическая игрушка. Пример создания игры на C++.</title>
		<link>http://www.simplecoding.org/prostaya-logicheskaya-igrushka.html</link>
		<comments>http://www.simplecoding.org/prostaya-logicheskaya-igrushka.html#comments</comments>
		<pubDate>Fri, 08 Jun 2007 20:00:19 +0000</pubDate>
		<dc:creator>Владимир</dc:creator>
				<category><![CDATA[C++]]></category>

		<guid isPermaLink="false">http://www.simplecoding.org/?p=9</guid>
		<description><![CDATA[Программирование на С++, пример логической игрушки]]></description>
			<content:encoded><![CDATA[<p>С этой игрой я познакомился, когда играл в &#034;Космических рейнджеров&#034; (это было задание в одном из квестов). Игра показалась мне интересной, и я решил написать свою версию. При этом мне захотелось добавить возможность регулирования уровня сложности.</p>
<p><span id="more-9"></span></p>
<p>Правила игры очень простые. Два игрока по очереди кладут в корзину шарики трех цветов (красные, синие и зеленые). Всего нужно положить по три шарика каждого цвета. Каждый игрок за один ход может положить один или несколько шариков только одного цвета. Например, два красных или три синих, или один зеленый и т.д. Выигрывает тот, кто кладет последний шарик.</p>
<p>Давайте разберем подробнее принцип выбора оптимального хода. Если в корзине нет шариков, то можно сделать девять различных ходов, во всех остальных случаях количество возможных ходов будет меньшим. Глубина анализа (т.е. количество просчитываемых ходов) будет задаваться текущим уровнем сложности. Допустим, она равна трем. Это значит, что необходимо проверить все возможные наши ходы, далее просчитать все ходы игрока, а затем снова проанализировать, как мы можем после хода игрока.</p>
<p>Для сохранения всех этих данных я использовал двумерный массив. Количество столбцов соответствует максимально возможному количеству ходов (девяти), а количество строк – глубине анализа (трем). Вы, наверное, заметили, что размер массива не позволяет сохранить информацию обо всех возможных ходах. Но это нам и не требуется, ведь мы хотим выбрать оптимальный ход на данный момент, а на следующем ходу мы проводим новый анализ. В массив мы будем записывать информацию о том, приводит данных ход к победе или нет. При этом в первой строке каждая ячейка соответствует возможному ходу. Если ход возможен и приводит к победе (корзина заполнена) записываем в соответствующую ячейку &#034;1&#034;, если после хода корзина не заполнена – &#034;0&#034;, и &#034;-127&#034; если ход не возможен. Во второй и следующих строках записываем информацию только о лучших ходах. Т.е. просчитываем мы все возможные ходы, но информацию пишем только о лучшем из них.</p>
<table id="ballTable" style="margin: auto; border-collapse: collapse">
<tr>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/red.gif" alt="красный шарик" /></td>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/empty.gif" alt="нет шарика" /></td>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/empty.gif" alt="нет шарика" /></td>
</tr>
<tr>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/blue.gif" alt="синий шарик" /></td>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/empty.gif" alt="нет шарика" /></td>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/empty.gif" alt="нет шарика" /></td>
</tr>
<tr>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/green.gif" alt="зеленый шарик" /></td>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/green.gif" alt="зеленый шарик" /></td>
<td style="border: 1px solid #454545"><img src="http://www.simplecoding.org/wp-content/uploads/2007/07/green.gif" alt="зеленый шарик" /></td>
</tr>
</table>
<p style="text-align: center">Рис.1</p>
<p>Рассмотрим следующий пример. Допустим, корзина заполнена так, как показано на рис.1 (три зеленых шарика, один синий и один красный). В соответствии с приведенными правилами будет составлен следующий массив (первые 3 элемента каждой строки массива соответствуют красному цвету, вторые 3 – синему, третьи 3 – зеленому):</p>
<table class="arrayTable" style="margin: auto; border-collapse: collapse; text-align: center">
<tr>
<td style="border: 1px solid #454545; color: red; width: 40px">1</td>
<td style="border: 1px solid #454545; color: red; width: 40px">2</td>
<td style="border: 1px solid #454545; color: red; width: 40px">3</td>
<td style="border: 1px solid #454545; color: blue; width: 40px">1</td>
<td style="border: 1px solid #454545; color: blue; width: 40px">2</td>
<td style="border: 1px solid #454545; color: blue; width: 40px">3</td>
<td style="border: 1px solid #454545; color: green; width: 40px">1</td>
<td style="border: 1px solid #454545; color: green; width: 40px">2</td>
<td style="border: 1px solid #454545; color: green; width: 40px">3</td>
</tr>
<tr>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">1</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">1</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
</tr>
<tr>
<td style="border: 1px solid #454545">1</td>
<td style="border: 1px solid #454545">1</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">1</td>
<td style="border: 1px solid #454545">1</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
<td style="border: 1px solid #454545">0</td>
</tr>
</table>
<p style="text-align: center">Массив 1</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simplecoding.org/prostaya-logicheskaya-igrushka.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

