Организация рабочих мест

290366
знаков
23
таблицы
7
изображений

4.1.2.1 Организация рабочих мест

Высота рабочего стола составляет 720 мм. Размеры столешницы составляют 1400 х 800 мм, что соответствует оптимальному размеру. Под столешницей рабочего стола есть свободное пространство для ног с размерами по высоте не менее 600 мм, по ширине не менее 500 мм, по глубине - 650 мм, что соответствует [2].

Конструкция одноместного стола для работы с ПЭВМ и ВДТ должна предусматривает две раздельные поверхности: одна - горизонтальная для размещения ПЭВМ или ВДТ и вторая - для клавиатуры. Отсутствуют ящики.

Корпус ВДТ и ПЭВМ, клавиатура и другие блоки и устройства ПЭВМ имеют матовую поверхность одного цвета, не имеет блестящих деталей, способных создавать блики. В конструкции ВДТ предусмотрены кнопки регулировки яркости и контраста. Они обеспечивают возможность регулировки этих параметров от минимальных до максимальных значений.

Размер экрана должен быть не менее 17 дюймов по диагонали, при этом расстояние от глаз до экрана должно быть в пределах 40 – 80 см.

Клавиатура исполнена в виде отдельного устройства с возможностью свободного перемещения. Конструкция клавиатуры предусматривает опорное приспособление, позволяющее изменять угол наклона поверхности клавиатуры в пределах от 5 до 15 градусов. Высоту среднего ряда клавиш не более 30 мм.

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

Все описанные параметры и характеристики соответствуют [2].

4.1.2.2 Освещенность рабочего места

В рабочем кабинете инженера структурного подразделения «Шахматный клуб» ГОУ ВПО «СибГИУ» предусмотрено естественное и искусственное освещение. Естественное освещение в соответствии с требованиями [5] осуществляется через светопроемы, ориентированные на север и северо-восток. Освещенность на поверхности стола и клавиатуре должна быть не менее 300 люкс, а вертикальная освещенность экрана - всего 100-250 люкс.

В качестве источников света при искусственном освещении применяются люминесцентные лампы типа ЛБ – 40 в количестве 3 штук. Светильники располагаются локализовано над рабочим столом ближе к его переднему краю, обращенному к оператору.

4.1.2.3 Расчет освещенности рабочего кабинета инженера структурного подразделения «Шахматный клуб» ГОУ ВПО «СибГИУ».

Высота – 4 м, длина – 4 м, ширина – 3 м

Потолок и стены рабочего кабинета инженера структурного подразделения «Шахматный клуб» ГОУ ВПО «СибГИУ» побелены. Используются лампы ЛБ-40.

Рассчитаем количество светильников, необходимое в рабочем кабинете инженера структурного подразделения «Шахматный клуб» ГОУ ВПО «СибГИУ», по методу коэффициента использования светового потока [5].

Ен = 300 лк

S = 4* 3 = 12

Z = 1.1

k = 1.3

F = 3000 лм

n = 2

I = (4*3)/(2.78*(4+3))= 0,62

h = 4 – 0.5 – 0.72 = 2.78 м

hc = 0.5 м (высота светильника)

hр = 0.72 м (высота рабочего стола)

η = 0,29

 (шт)

Для освещения рабочего кабинета инженера структурного подразделения «Шахматный клуб» ГОУ ВПО «СибГИУ» размерами 4м х 3м х 4 м потребуется 3 светильника с люминесцентными лампами типа ЛБ – 40. В рабочем кабинете инженера установлено 3 светильника, что соответствует [5].

  4.2 Чрезвычайные ситуации 4.2.1 Электробезопасность

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

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

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

Во избежание повреждения изоляции проводов и возникновения коротких замыканий не разрешается:

·          вешать что-либо на провода;

·          закрашивать и белить шнуры и провода;

·          закладывать провода и шнуры за газовые и водопроводные трубы, за батареи отопительной системы;

·          выдергивать штепсельную вилку из розетки за шнур, усилие должно быть приложено к корпусу вилки.

Для исключения поражения электрическим током запрещается:

·          часто включать и выключать компьютер без необходимости;

·          прикасаться к экрану и к тыльной стороне блоков компьютера;

·          работать на средствах вычислительной техники и периферийном оборудовании мокрыми руками;

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

·          класть на средства вычислительной техники и периферийное оборудование посторонние предметы.

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

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

Ремонт электроаппаратуры производится только специалистами-техниками с соблюдением необходимых технических требований.

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

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

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

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

Спасение пострадавшего при поражении электрическим током главным образом зависит от быстроты освобождения его от действия током.

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

Необходимо немедленно начать производить искусственное дыхание, наиболее эффективным из которых является метод “рот в рот”, а также наружный массаж сердца.

Искусственное дыхание пораженному электрическим током производится вплоть до прибытия врача.


4.2.2 Пожарная безопасность

В соответствии с [8] кабинеты с ВДТ по пожарной опасности относятся к категории “В”, т.к. в помещении находятся электронная аппаратура, офисная техника и бумага.

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

·          перегрузки электрических сетей;

·          неисправность электропроводки, электрооборудования и неумелое их использование;

·          самовозгораемость некоторых веществ;

·          несоблюдение правил техники безопасности;

·          курение и применение открытого огня в неположенном месте;

·          короткое замыкание в электрооборудовании;

·          диверсионно-террористические акции.

Порядок и последовательность действий:

·          сообщение о пожаре;

·          эвакуация студентов из горящих помещений;

·          сверка списочного состава с фактическим наличием эвакуированных;

·          тушение возникшего пожара.

Необходимо знать, что:

·          при обнаружении пожара, загорании или задымлении немедленно звонить по телефону 01;

·          при возникновении пожара эвакуация производится через запасные выходы корпуса, столовой и здания главного корпуса «СибГИУ»;

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

·          все эвакуированные пересчитываются и сверяются по списку;

·          тушение загорания производится немедленно с момента его обнаружения.

Исполнители:

·          первый заметивший дым и дежурный по корпусу;

·          дежурный помещений и преподаватели, проводившие занятия;

·          преподаватели и старосты групп;

·          члены ДПД.

В СибГИУ имеется и успешно функционирует собственная противопожарная система, которая состоит из противопожарной службы, средств пожаротушения и организационно-технических мероприятий.

Противопожарная служба состоит из штатных работников отдела обеспечения порядка, которые своими силами способны тушить пожар любой степени сложности. Численность работников отдела обеспечения порядка 30 человек. Главное в их работе – предотвратить пожар. Если возгорание произошло, то основная задача – остановить его, не дать перерасти в пожар. Основной причиной возгорания в здании университета является незатушенная сигарета. Повреждение электропроводки также может привести к возгоранию, а затем и к пожару.

К средствам пожаротушения относятся средства коллективной и индивидуальной защиты.

Средства коллективной защиты:

·          огнетушители порошковые ОП-3;

·          гидранты;

·          пожарные рукава.

Средства индивидуальной защиты:

·          противогазы ГП5;

·          респираторы.

Все виды средств защиты в достаточном количестве имеются на постах службы обеспечения порядка.

В главном корпусе СибГИУ располагается пожарный пост №1, где находятся первичные средства пожаротушения (на начальной стадии развития пожара): огнетушители, песок, войлок, кошма, асбестовое полотно, ведра, лопаты и др. Там же находится и форма.

Источники водоснабжения:

·          пожарные гидранты;

·          пожарные краны – 58 шт.

Пожарные краны размещены в шкафчиках, на дверцы которых нанесен буквенный индекс “ПК” и порядковый номер крана. Каждый пожарный кран оборудован рукавом длиной 20 м и пожарным стволом со спрыском. Пожарные рукава бывают всасывающие и напорные. При помощи всасывающих рукавов забирают воду из водоисточников пожарным насосом. Напорные рукава применяют для подачи воды к месту пожара от водоисточника или водопроводного крана.

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

·          дымовых датчиков;

·          термических датчиков.

Основным мероприятием по защите людей при пожаре является полная экстренная эвакуация. Планы эвакуации висят на всех этажах во всех корпусах университета.

4.2.3 Организационно-штатная структура по ГО и ЧС.

В руководящий состав входят начальник ГОЧС (Кулагин Николай Михайлович), начальник штаба ГОЧС (Герасимова Анна Алексеевна), председатель эвакуационной комиссии (Галевский Геннадий Владиславович) и начальник СЭП (Рябцев Вадим Олегович).

Силы ГОЧС составляют спасательная команда (105 человек), группы оповещения и связи (30 человек), команда охраны общественного порядка (45 человек), санитарные дружины (72 человека) и звенья пожаротушения (20 человек).

4.2.4 Чрезвычайные ситуации, которые могут возникнуть на территории ГОУ ВПО «СибГИУ».

Чрезвычайные ситуации, которые могут возникнуть на территории ГОУ ВПО «СибГИУ», связанные с опасностью для здоровья, гибелью и увечьем студентов и персонала:

·          пожаро-взрывоопасная ситуация;

·          утечка хлора в плавательном бассейне спорткомплекса университета;

·          производственные аварии на Левобережном водозаборе, на его технологических линиях и емкостях с хлором, при неблагоприятных метеоусловиях и направлении ветра от места аварии в сторону университета;

·          аварии на железной дороге, пролегающей в непосредственной близости к ГОУ ВПО «СибГИУ» с разливом АХОВ или взрывом особо опасного груза;

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

·          ураганный ветер, землетрясения, наводнения и другие стихийные бедствия.

4.2.5 Способы оповещения при ЧС

Звучание сирен, прерывистые гудки предприятий и транспортных средств означает подачу предупредительного сигнала “Внимание всем!”.

Услышав его, следует немедленно включить громкоговоритель, радио и телеприемник (в любое время суток), прослушайте экстренное сообщение управления по делам ГО и ЧС.

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

В рабочее время можно получить информацию о передаче сигнала “Внимание всем!” от руководителей университета (ГО и ЧС). Действовать необходимо согласно их указаниям.

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

4.2.6 Действия по видам сообщения при передачи сигнала «Внимание всем!»

При аварии с выбросом АХОВ и неблагоприятных метеоусловиях необходимо:

·          провести герметизацию помещений;

·          отключить вентиляционные устройства, электронагревательные приборы, перекрыть воду, газ;

·          подготовить и проверить средства индивидуальной защиты органов дыхания и кожи, при их отсутствии изготовить простейшие средства индивидуальной защиты;

·          взять с собой документы, деньги, продукты;

·          покинуть свое местонахождение и выйти по кратчайшему пути в направлении, указанном ГОЧС.

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

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

Время выхода из очага заражения весьма ограничено и не должно превышать 15-20 минут с момента аварии, расстояние выхода около 200 – 300 метров. Выход осуществлять, дыша через смоченную в воде матерчатую повязку.

При возникновении “Воздушной опасности” (при военном положении) необходимо:

·          отключить свет, газ, воду;

·          взять средства индивидуальной защиты, документы, запас питания и воды;

·          помочь больному выйти на улицу;

·          как можно быстрее дойти до защитного сооружения или укрыться в складках местности.

При отбое действия по сигналам ГО по указанию ГОЧС или представителя охраны общественного порядка выйти из укрытий и возвратиться к месту работы. Снимать средства индивидуальной защиты – по особому распоряжению. В дальнейшем действовать по указанию управления ГОЧС или старшего на рабочем месте.

При других ЧС действовать применительно к случившейся ЧС.

4.2.7 Организация защиты сотрудников и студентов СибГИУ при возникновении ЧС мирного и военного времени

Инженерная защита: студенты и персонал университета укрываются в защитных сооружениях – подвальных помещениях корпусов, спорткомплексе, столовой.

Обеспечение средствами индивидуальной защиты:

·          в экстренных случаях (при авариях с АХОВ) изготавливаются простейшие средства защиты органов дыхания (матерчатые повязки) из подручного материала, могут быть использованы промышленные респираторы или ватно-марлевые повязки, имеющиеся на рабочем месте;

·          при поступлении распоряжения управления ГО и ЧС на получение средств индивидуальной защиты (СИЗ) из запасов объекта (или централизованного) в помещениях главного корпуса, блока поточных аудиторий, горно-технологического корпуса разворачиваются “Пункты выдачи СИЗ”.

Выдача СИЗ осуществляется поочередно для всех структурных подразделений по графику, составленному штабом ГОЧС университета.

Организация эвакуации университета:

·          в мирное время (экстренная эвакуация):

o     при авариях на предприятиях города (района) или ж/д с выбросом АХОВ – в места, указанные при получении сигнала “Внимание всем!” в направлении, перпендикулярном движению зараженного облака (с учетом особенностей АХОВ);

o     при повышении радиационного фона свыше 60 мкр/час – по распоряжению управления ГОЧС района или руководителя объектов в места, определенные администрацией области;

·          в военное время (плановая эвакуация):

o     с получением распоряжения управления ГОЧС эвакуацию осуществляет эвакуационная комиссия университета. Эвакуация работников и студентов СибГИУ и членов их семей осуществляется по железной дороге в населенный пункт г. Гурьевск Кемеровской области в том числе: железнодорожным транспортом, через СЭП №20, разворачиваемый в помещении блока поточных аудиторий;

o     в загородных зонах размещение происходит в помещениях 3-х автохозяйств и жилых домах (подселением) согласно плану управления ГОЧС.


4.3 Экологичность проекта

С точки зрения энергоснабжения мониторы, используемые в рабочем процессе, имеют встроенную систему экономии электроэнергии – PowerSaver. Эта система сохраняет электроэнергию посредством переключения монитора в режим с низким потреблением энергии, когда он не используется в течение определенного периода времени.

Возможные режимы работы – рабочий, Stand-by, Suspend, выключен. Данная система успешно работает с VESA DPMS – совместимой видеокартой, установленной в компьютере. Более детальная информация сведена в таблице 3.

Таблица 17 – Характеристики режимов сохранения электроэнергии [10].

Состояние Рабочее Режим сохранения электроэнергии EPA/NUTEK
Режим Stand-by Режим Suspend Режим Power-off
Горизонтальная синхр. Активный Неактивный Активный Неактивный
Вертикальная синхр. Активный Активный Неактивный Неактивный
Видео Активный Темный экран Темный экран Темный экран
Потребляемая мощность

73 Вт (макс)

55 Вт (номин)

50 Вт (номин) Менее 15 Вт Менее 5 Вт

Монитор автоматически возвращается к режиму нормального функционирования при восстановлении горизонтальной и вертикальной развертки.


Заключение

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

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

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


Список использованных источников

1.                  Санитарные нормы и правила: СНиП 41.01-03. Отопление, вентиляция и кондиционирование. - Введен 01.01 2004. Технорматив: информационная система. – 58 с.

2.                  Санитарные правила и нормы: СанПиН 2.2.2/2.4.1340-03. Гигиенические требования к персональным электронно-вычислительным машинам и организация работы. – Введен 30.06.2003. Технорматив: информационная система – 26 с.

3.                  Система стандартов безопасности труда: ГОСТ 12.0.003-74. Опасные и вредные факторы. – Введен 18.11.1974. М.: - Госстандарт СССР, 1974г., - 55с.

4.                  Система стандартов безопасности труда: ГОСТ 12.005-88. Общие санитарно-гигиенические требования к воздуху рабочей зоны. – Введен 29.09.1988. М.: - Государственный комитет СССР по стандартам, 1988г. - 28с

5.                  Санитарные правила и нормы: СанПиН 2.2.1/2.2.2.1278-03. Гигиенические требования к естественному, искусственному и совмещенному освещению жилых и общественных зданий. – Введен 15.06.2003.Технорматив: информационная система. – 27 с.

6.                  Санитарные нормы: СН 2.2.4/2.1.8.562-96. Шум на рабочих местах, в помещениях жилых, общественных зданий и на территории жилой застройки. – Введен 31.10.1996. М.: - Госкомсанэпиднадзора России , 1996г. - 34с.

7.                  Санитарные правила и нормы: СанПиН 2.2.4.1191-03 Электромагнитные поля в производственных условиях - Введен 01.05.2003.СПб.: Минздрав РФ, 2003г. - 17 с.

8.                  Нормы пожарной безопасности: НПБ 105-2003. Определение категорий помещений, зданий и наружных установок по взрывопожарной и пожарной опасности. - Введен 18.06.2003. М.: МЧС РФ, 2003г. - 26с.

9.                  Санитарные нормы и правила: СНиП 21.01-97. Пожарная безопасность зданий и сооружений. - Введен 01.01.1998. Технорматив: информационная система. – 23 с.

10.                Система стандартов безопасности труда: ГОСТ Р50949-96. Средства отображения информации индивидуального пользования. Методы измерений и оценки эргономических параметров и параметров безопасности. – Введен 01.07.1997. М: Госстандарт России, 1996 – 27 с.

11.                Фултон Х. Программирование на языке Ruby. Идеалогия языка, теория и практика приминения. / Х.Фултон – М.: ДМК-Пресс, 2007. – 688 с.

12.                Томас Д. Гибкая разработка веб-приложений в среде Rails. / Томас Д., Хэнссон Д.Х. – СПб.:Питер, 2008. – 716 с.

13.                Монахов В.В. Язык программирования Java и среда NetBeans. / Монахов В.В. – СПб.: БХВ-Петербург, 2008. – 640 с.

14.                Шильдт Х. Java. Методики программирования Шилдта. / Шильдт Х. – М.: Вильямс, 2008. – 512 с.

15.                Гудман Д. JavaScript. Библия пользователя. Издание 5-е. / Гудман Д., Моррисон М. – М.: Вильямс, 2006. – 1184 с.

16.                Флэнаган Д. JavaScript. Подробное руководтство. Издание 4-е. / Флэнаган Д. – М.: Символ-плюс, 2004. – 960 с.

17.                Муссиано Ч. HTML и XHTML. Подробное руководство. Издание 6-е. / Муссиано Ч., Кеннеди Б. – М.: Символ-плюс, 2008. – 752 с.

18.                Лазаро И.К. Полный справочник по HTML, CSS и JavaScript. Справочник профессионала. / Лазаро И.К. – М.: Третий Рим, 2007. – 1168 с.

19.                Бобко Т.В. Методические указания к выполнению экономической части дипломных проектов. / Бобко Т.В. – Новокузнецк: СибГИУ, 2007. – 47 с.

20.                Бек К. Экстремальное программирование. / Бек К. – СПб.:Питер, 2002. -224с.

21.                Избачков Ю.С. Информационные системы: Учебник для вузов. 2-е издание. / Избачков Ю.С., Петров В.Н. – СПб.: Питер, 2005. – 656 с.

Приложение А

Календарный план работ по созданию системы

Наименование этапа Сроки исполнения Исполнитель
1 Разработка ТЗ на ИС «Шахматный клуб» по пунктам 1,2

01.08.2007 –

01.09.2007

Ширяев А.С.
2 Разработка ТЗ на ИС «Шахматный клуб» по пунктам 3-5

 01.09.2007 –

 01.11.2007

Ширяев А.С.
3 Разработка ТЗ на ИС «Шахматный клуб» по пунктам 6-9

 01.11.2007 –

 01.12.2007

Ширяев А.С.
4 Закупка оборудования, создание системы, разработка необходимой документации на систему

 01.12.2007 –

 01.02.2008

Персонал шахматного клуба ГОУ ВПО «СибГИУ», персонал МУДОД «СДЮСШОР по шахматам им. Б. А. Кустова»
5 Предварительные испытания системы

 02.02.2008 –

 03.02.2008

Персонал шахматного клуба ГОУ ВПО «СибГИУ», персонал МУДОД «СДЮСШОР по шахматам им. Б. А. Кустова»,

Ширяев А.С.

6 Опытная эксплуатация

 03.02.2008 –

 03.03.2008

Персонал шахматного клуба ГОУ ВПО «СибГИУ», персонал МУДОД «СДЮСШОР по шахматам им. Б. А. Кустова»

Приложение Б

Комплектность документации на систему

Наименование документации

Документация по общесистемным решениям:

 Схема функциональной структуры

Описание автоматизируемых функций и функций по представлению информации

 Общее описание системы

Документация по организационному обеспечению:

Описание организационной структуры

Организационно-техническая инструкция

Документация по техническому обеспечению:

Описание комплекса технических средств

Структурная схема комплекса технических средств

Документация на технические средства

Документация по информационному обеспечению:

Перечень входных сигналов и данных

Перечень выходных сигналов и данных

Описание информационного обеспечения системы

Описание организации информационной базы

Документация по программному обеспечению:

Описание программного обеспечения

Документация на программное обеспечение


Приложение В

Листинг программы-транслятора шахматных партий

Контроллеры (controller)

main_controller.rb

---

# Основной контроллер портала

class MainController < ApplicationController

 

 # Редирект на главную страницу

 def index

 render :action => 'logo'

 end

 

 # Главная страница

 def logo

 end

 # Старая страница

 def main

 render :action => 'logo'

 end

 

 # Показ партий в онлайн режиме (трансляции)

 def online

 @online_games = CurrentGame.find :all

 end

 

 # Показ партий в оффлайн режиме (уже закончившиеся)

 def offline

 

 end

 

 # Напоминание при потере пароля или логина

 def remind

 

 end

 

 # Вход в личный кабинет пользователя

 def enter

 unless session[:user_id].nil?

 redirect_to "/users/room/#{session[:user_id]}"

 end

 end

 

 # Показ трансляции

 def game

 unless params[:id].nil?

 @game = Game.find params[:id]

 else

 render :action => 'logo'

 end

 end

 

 # Возвращает текст партии в условленном формате

 def game_moves

 @game = Game.find(params[:id])

 render_text @game.moves

 end

 # Авторизация

 def login

 session[:user_id] = nil

 user = User.authenticate(params[:login], params[:password])

 if user.nil?

 redirect_to :action => 'enter'

 else

 session[:user_id] = user.id

 redirect_to "/users/room/#{user.id}"

 end

 end

 

 # Выход пользователя

 def unlogin

 session[:user_id] = nil

 redirect_to :action => 'logo'

 end

 

 # Переход к регистрации

 def register

 redirect_to '/users/new'

 end

end

cities_controller.rb

---

class CitiesController < ApplicationController

 layout 'main'

 scaffold :cities

end

clock_reglaments_controller.rb

---

class ClockReglamentsController < ApplicationController

 layout 'main'

 scaffold :clock_reglament

end

countries_controller.rb

---

class CountriesController < ApplicationController

 layout 'main'

 scaffold :countries

end

game_infos_controller.rb

---

class GameInfosController < ApplicationController

 layout 'main'

 scaffold :game_info

end

games_controller.rb

---

class GamesController < ApplicationController

 layout 'main'

 scaffold :game

end

moves_controller.rb

---

class MovesController < ApplicationController

 layout 'main'

 scaffold :move

end

players_controller.rb

---

class PlayersController < ApplicationController

 layout 'main'

 scaffold :player

end

tournament_views_controller.rb

---

class TournamentViewsController < ApplicationController

 layout 'main'

 scaffold :tournament_view

end

tournaments_controller.rb

---

class TournamentsController < ApplicationController

 layout 'main'

 scaffold :tournament

 

 def index

 render :action => 'list'

 end

end

users_controller.rb

---

class UsersController < ApplicationController

 layout 'main'

 scaffold :users

 

 def index

 render :action => 'room'

 end

 

 def room

 

 end

end

Помощники (helper)

main_helper.rb

---

module MainHelper

 

 def print_current_tournament

 html = ""

 Tournament.find_all_by_status('open').each do |tournament|

 city = tournament.city_id.nil? ? nil : City.find(tournament.city_id)

 html << "<tr>"

 html << "<td></td>"

 html << "<td>" + tournament.name + "</td>"

 html << "<td>" + (city.nil? ? "" : city.name) + "</td>"

 html << "</tr>"

 end

 html

 end

 

 def render_game_info

 "Тестовая партия из тестового турнира"

 end

 

 def render_moves

 moves = "<div id=\"moves\"></div>"

 moves = "<table width='100%' align='center'>"

 moves += "<tr><th width='2%'></th><th width='45%'></th><th ></th><th width='45%'></th><th width='2%'></th></tr>"

 moves += "<tr><td>1.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>2.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>3.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>4.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>5.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>6.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>7.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>8.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>9.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>10.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>11.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>12.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>13.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>14.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>15.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>16.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>17.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>18.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>19.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td>20.</td><td>b</td><td>c</td><td>d</td><td>e</td></tr>"

 moves += "<tr><td colspan='5' align='center'>"

 moves += image_tag('go_begin.jpg', :id => 'go_begin', :onclick => 'goBegin();'), :onmouseover => 'new Effect.Scale("go_begin", 110)'), :onmouseout => 'new Effect.Scale("go_begin", 90)') + '&nbsp;'

 moves += image_tag('go_prev.jpg', :id => 'go_prev', :onclick => 'goPrev();') :onmouseover => 'new Effect.Scale("go_prev", 110)', :onmouseout => 'new Effect.Scale("go_prev", 90)') + '&nbsp;'

 moves += image_tag('go_refresh.jpg', :id => 'go_refresh', :onclick => 'goRefresh();') :onmouseover => 'new Effect.Scale("go_refresh", 110)', :onmouseout => 'new Effect.Scale("go_refresh", 90)') + '&nbsp;'

 moves += image_tag('go_next.jpg', :id => 'go_next', :onclick => 'goNext();'):onmouseover => 'new Effect.Scale("go_next", 110)', :onmouseout => 'new Effect.Scale("go_next", 90)') + '&nbsp;'

 moves += image_tag('go_end.jpg', :id => 'go_end', :onclick => 'goEnd();')#:onmouseover => 'new Effect.Scale("go_end", 110)', :onmouseout => 'new Effect.Scale("go_end", 90)') + '&nbsp;'

 moves += "</td></tr>"

 moves += "</table>";

 moves

 end

 

 def render_board

 return "<table class=\"board\" id=\"board\">

 <tr>

 <td class=\"board_label_digit\">8</td>

 <td class=\"board_white_field\" id=\"fieldA8\"></td>

 <td class=\"board_black_field\" id=\"fieldB8\"></td>

 <td class=\"board_white_field\" id=\"fieldC8\"></td>

 <td class=\"board_black_field\" id=\"fieldD8\"></td>

 <td class=\"board_white_field\" id=\"fieldE8\"></td>

 <td class=\"board_black_field\" id=\"fieldF8\"></td>

 <td class=\"board_white_field\" id=\"fieldG8\"></td>

 <td class=\"board_black_field\" id=\"fieldH8\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">7</td>

 <td class=\"board_black_field\" id=\"fieldA7\"></td>

 <td class=\"board_white_field\" id=\"fieldB7\"></td>

 <td class=\"board_black_field\" id=\"fieldC7\"></td>

 <td class=\"board_white_field\" id=\"fieldD7\"></td>

 <td class=\"board_black_field\" id=\"fieldE7\"></td>

 <td class=\"board_white_field\" id=\"fieldF7\"></td>

 <td class=\"board_black_field\" id=\"fieldG7\"></td>

 <td class=\"board_white_field\" id=\"fieldH7\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">6</td>

 <td class=\"board_white_field\" id=\"fieldA6\"></td>

 <td class=\"board_black_field\" id=\"fieldB6\"></td>

 <td class=\"board_white_field\" id=\"fieldC6\"></td>

 <td class=\"board_black_field\" id=\"fieldD6\"></td>

 <td class=\"board_white_field\" id=\"fieldE6\"></td>

 <td class=\"board_black_field\" id=\"fieldF6\"></td>

 <td class=\"board_white_field\" id=\"fieldG6\"></td>

 <td class=\"board_black_field\" id=\"fieldH6\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">5</td>

 <td nowrap class=\"board_black_field\" id=\"fieldA5\"></td>

 <td nowrap class=\"board_white_field\" id=\"fieldB5\"></td>

 <td nowrap class=\"board_black_field\" id=\"fieldC5\"></td>

 <td nowrap class=\"board_white_field\" id=\"fieldD5\"></td>

 <td nowrap class=\"board_black_field\" id=\"fieldE5\"></td>

 <td nowrap class=\"board_white_field\" id=\"fieldF5\"></td>

 <td nowrap class=\"board_black_field\" id=\"fieldG5\"></td>

 <td nowrap class=\"board_white_field\" id=\"fieldH5\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">4</td>

 <td class=\"board_white_field\" id=\"fieldA4\"></td>

 <td class=\"board_black_field\" id=\"fieldB4\"></td>

 <td class=\"board_white_field\" id=\"fieldC4\"></td>

 <td class=\"board_black_field\" id=\"fieldD4\"></td>

 <td class=\"board_white_field\" id=\"fieldE4\"></td>

 <td class=\"board_black_field\" id=\"fieldF4\"></td>

 <td class=\"board_white_field\" id=\"fieldG4\"></td>

 <td class=\"board_black_field\" id=\"fieldH4\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">3</td>

 <td class=\"board_black_field\" id=\"fieldA3\"></td>

 <td class=\"board_white_field\" id=\"fieldB3\"></td>

 <td class=\"board_black_field\" id=\"fieldC3\"></td>

 <td class=\"board_white_field\" id=\"fieldD3\"></td>

 <td class=\"board_black_field\" id=\"fieldE3\"></td>

 <td class=\"board_white_field\" id=\"fieldF3\"></td>

 <td class=\"board_black_field\" id=\"fieldG3\"></td>

 <td class=\"board_white_field\" id=\"fieldH3\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">2</td>

 <td class=\"board_white_field\" id=\"fieldA2\"></td>

 <td class=\"board_black_field\" id=\"fieldB2\"></td>

 <td class=\"board_white_field\" id=\"fieldC2\"></td>

 <td class=\"board_black_field\" id=\"fieldD2\"></td>

 <td class=\"board_white_field\" id=\"fieldE2\"></td>

 <td class=\"board_black_field\" id=\"fieldF2\"></td>

 <td class=\"board_white_field\" id=\"fieldG2\"></td>

 <td class=\"board_black_field\" id=\"fieldH2\"></td>

 </tr>

 <tr>

 <td class=\"board_label_digit\">1</td>

 <td class=\"board_black_field\" id=\"fieldA1\"></td>

 <td class=\"board_white_field\" id=\"fieldB1\"></td>

 <td class=\"board_black_field\" id=\"fieldC1\"></td>

 <td class=\"board_white_field\" id=\"fieldD1\"></td>

 <td class=\"board_black_field\" id=\"fieldE1\"></td>

 <td class=\"board_white_field\" id=\"fieldF1\"></td>

 <td class=\"board_black_field\" id=\"fieldG1\"></td>

 <td class=\"board_white_field\" id=\"fieldH1\"></td>

 </tr>

 <tr>

 <td class=\"board_lebel_letter\">&nbsp;</td>

 <td class=\"board_lebel_letter\">A</td>

 <td class=\"board_lebel_letter\">B</td>

 <td class=\"board_lebel_letter\">C</td>

 <td class=\"board_lebel_letter\">D</td>

 <td class=\"board_lebel_letter\">E</td>

 <td class=\"board_lebel_letter\">F</td>

 <td class=\"board_lebel_letter\">G</td>

 <td class=\"board_lebel_letter\">H</td>

 </tr>

 </table>"

 end

 def render_result

 "1/2 - 1/2"

 end

 

 def render_black_time

 "-:--:--"

 end

 

 def render_white_time

 "-:--:--"

 end

end

Представление (view)

layout/main.rhtml

---

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

 <head>

 <meta http-equiv="content-type" content="text/html;charset=UTF-8" />

 <title>Стартовая страница: <%= controller.action_name %></title>

 <%= stylesheet_link_tag 'scaffold' %>

 <%= stylesheet_link_tag 'main' %>

 <%= stylesheet_link_tag 'game' %>

 <%= javascript_include_tag :defaults %>

 <%= javascript_include_tag 'game' %>

 </head>

 <body style='background-color: #000000'>

 <table bgcolor="#f4f4f4" border="0" width="80%" align="center" cellpadding="0" cellspacing="0" >

 <tr>

 <td width='3%'></td>

 <td>

 <h1><%= link_to(image_tag('dgt.gif', :size => '42x25', :border => 0, :alt => 'http://dgtprojects.com'), 'http://dgtprojects.com') %>&nbsp;&nbsp;&nbsp;

 Сервер трансляции шахматных партий <%= link_to 'rDGT', 'http://rdgt.org' %>&nbsp;&nbsp;&nbsp;

 <%= link_to(image_tag('home.gif', :size => '12x12', :border => 0), '/main/index') %>

 <%= link_to(image_tag('email.gif', :size => '12x12', :border => 0), '') %>

 <%= link_to(image_tag('search.gif', :size => '12x12', :border => 0), '')%>

 </h1><hr />

 </td>

 <td width='3%'></td>

 </tr>

 <tr>

 <td></td>

 <td>

 <p style="color: green"><%= flash[:notice] %></p>

 <%= yield %>

 </td>

 <td></td>

 </tr>

 <tr>

 <td></td>

 <td align="right"><br /><hr />

 <%= mail_to 'zarstudio@gmail.com', '[ Разработчики ]' %><br />&nbsp;

 </td>

 <td></td>

 </tr>

 </table>

 </body>

</html>

main/enter.rhtml

---

<% form_tag '/main/login' do %>

 <table align='center' width='100%'>

 <tr>

 <td width='41%' align="right"><strong>Имя:&nbsp;<strong></td>

 <td align="left"><%= text_field_tag :login, params[:login] %></td>

 </tr>

 <tr>

 <td align="right"><strong>Пароль:&nbsp;</strong></td>

 <td align="left"><%= password_field_tag :password, params[:password] %></td>

 </tr>

 <tr>

 <td align="center" colspan="2"><%= submit_tag 'Войти' %></td>

 </tr>

 <tr>

 <td align="center" colspan="2"><%= link_to '[ Регистрация ]', { :action => 'register' }%></td>

 </tr>

 <tr>

 <td align="center" colspan="2"><%= link_to '[ Забыли логин или пароль? ]', { :action => 'remind' }%></td>

 </tr>

 </table>

<% end %>

<br />

main/game.rhtml

---

<%= render_game_info %>

<br />

<br />

<table width='100%' cellspacing="0" cellpadding="0" border="0" id='table_board'>

 <tr align="center">

 <td width='1%'></td>

 <td width='50%' align="left"><%= image_tag 'seek_black.png', :size => '16x16' %></td>

 <td></td>

 <td width='45%'><%= link_to @game.black_player.to_s, { :controller => 'players', :action => 'show', :id => @game.black_player.id } %></td>

 <td width='1%'></td>

 </tr>

 <tr align="center">

 <td></td>

 <td></td>

 <td></td>

 <td><%= render_black_time %></td>

 <td></td>

 </tr>

 <tr>

 <td></td>

 <td><%= render_board %></td>

 <td></td>

 <td style="background-color: #dadada"><%= render_moves %></td>

 <td></td>

 </tr>

 <tr align="center">

 <td></td>

 <td></td>

 <td></td>

 <td><%= render_white_time%></td>

 <td></td>

 </tr>

 <tr align="center">

 <td></td>

 <td align="left"><%= image_tag 'seek_white.png', :size => '16x16' %></td>

 <td></td>

 <td><%= link_to @game.white_player.to_s, { :controller => 'players', :action => 'show', :id => @game.white_player.id} %></td>

 <td></td>

 </tr>

 <tr align="center">

 <td></td>

 <td></td>

 <td></td>

 <td><%= render_result %></td>

 <td></td>

 </tr>

 <tr>

 <td colspan="5"></td>

 </tr>

</table>

<%= link_to_remote 'Обновить', :update => 'moves', :url => { :action => 'game_moves', :id => @game.id } %>

<div id='debug'></div>

main/logo.rhtml

---

<table align='center'><tr><td align='center'>

<%= image_tag 'logo.jpg', :alt => 'Шахматный портал rDGT', :width => '400px', :height => '280px' %>

<br />

<br /><%= link_to '[ Трансляции ]', { :action => 'online' }%>

<br /><%= link_to '[ Турниры ]' , { :action => 'offline' }%>

<br /><%= link_to '[ Кабинет ]', { :action => 'enter' } %>

</td></tr></table>

main/online.rhtml

---

<!-- <%= link_to '[ Просмотр ]', { :action => 'game' }%>-->

<table width='80%' align='center'>

 <tr>

 <th></th>

 <th width='10%'>Начало</th>

 <th width='25%'>Турнир</th>

 <th width='30%'>Белые</th>

 <th width='30%'>Черные</th>

 </tr>

 <% @online_games.each do |game| %>

 <tr align='center'>

 <td class='td_info'><%= link_to(image_tag('eye.gif', :size => '16x16', :onclick => '', :alt => 'Просмотр трансляции'), { :action => 'game', :id => game.id }) %></td>

 <td class='td_info'><%= game.begin.to_s %></td>

 <td class='td_info'><%= link_to game.tournament.to_s, { :controller => 'tournaments', :action => 'show', :id => game.tournament.id } %></td>

 <td class='td_info'><%= link_to game.white.to_s, { :controller => 'players', :action => 'show', :id => game.white.id } %></td>

 <td class='td_info'><%= link_to game.black.to_s, { :controller => 'players', :action => 'show', :id => game.black.id } %></td>

 </tr>

 <% end %>

</table>

Модель (model)

---

class Cities < ActiveRecord::Base

end

class City < ActiveRecord::Base

end

class ClockReglament < ActiveRecord::Base

end

class Country < ActiveRecord::Base

end

class CurrentGame < ActiveRecord::Base

 def init

 @game = Game.find(self.game_id) if @game.nil?

 end

 

 def tournament

 init

 @game.tournament

 end

 

 def white

 init

 @game.white_player

 end

 

 def black

 init

 @game.black_player

 end

end

class Game < ActiveRecord::Base

 def moves

 result = ""

 @moves = Move.find_all_by_game_id self.id

 @moves.sort { |movea, moveb| movea.number <=> moveb.number }.each do |move|

 result += move.to_s + "|"

 end

 result

 end

 def tournament

 info = GameInfo.find self.game_info_id unless self.game_info_id.nil?

 t = Tournament.find info.tournament_id

 end

 

 def white_player

 player = Player.new

 player.id= 1

 player.first_name = "Иван"

 player.second_name = "Рыков"

 player

 end

 

 def black_player

 player = Player.new

 player.id= 1

 player.first_name = "Сергей"

 player.second_name = "Бедарев"

 player

 end

end

class GameInfo < ActiveRecord::Base

end

class LastMove < ActiveRecord::Base

end

class Move < ActiveRecord::Base

 

 def to_s

 ((self.white_move.nil? or self.white_move == "") ? "******" : self.white_move) +

 ((self.black_move.nil? or self.black_move == "") ? "******" : self.black_move) + ":" +

 (self.white_clock.nil? ? "" : self.white_clock) + "-" + (self.black_clock.nil? ? "" : self.black_clock)

 end

end

class Player < ActiveRecord::Base

 

 def full_name

 return self.second_name + " " + self.first_name

 end

 

 def to_s

 full_name

 end

end

class Tournament < ActiveRecord::Base

 

 def to_s

 self.name

 end

end

class TournamentView < ActiveRecord::Base

end

require 'digest/md5'

class User < ActiveRecord::Base

 validates_presence_of :login

 validates_uniqueness_of :login

 

 def self.authenticate(login, password)

 user = User.find_by_name(login)

 if user

 expected_password = encrypted_password(password)

 if user.password != expected_password

 user = nil

 end

 end

 user

 end

 

 def self.encrypted_password(password)

 Digest::MD5.hexdigest("sdjkvkjeho2ijij2o3d2kn3dl2kn3dn23dkn2ld3n" + password)

 end

end

Миграция (db migration)

---

ActiveRecord::Schema.define(:version => 12) do

 create_table "cities", :force => true do |t|

 t.column "name", :string, :limit => 30

 t.column "country_id", :integer

 t.column "description", :text

 t.column "image", :binary

 end

 create_table "clock_reglaments", :force => true do |t|

 t.column "title", :string, :limit => 30

 t.column "total_time", :integer

 t.column "add", :boolean, :limit => nil, :default => false

 t.column "add_time", :integer, :default => 0

 t.column "desciprion", :text

 end

 create_table "countries", :force => true do |t|

 t.column "name", :string, :limit => 30

 t.column "code", :string, :limit => 30

 t.column "image", :binary

 t.column "description", :text

 end

 create_table "current_games", :force => true do |t|

 t.column "game_id", :integer

 t.column "begin", :datetime

 t.column "end", :datetime

 t.column "description", :text

 end

 create_table "game_infos", :force => true do |t|

 t.column "game_id", :integer

 t.column "white_id", :integer

 t.column "black_id", :integer

 t.column "tournament_id", :integer

 t.column "result", :integer

 t.column "clock_reglament_id", :integer

 t.column "round", :integer

 t.column "debut_code", :string, :limit => 30

 t.column "description", :text

 t.column "status", :string, :limit => 30

 end

 create_table "games", :force => true do |t|

 t.column "game_info_id", :integer

 t.column "begin", :datetime

 t.column "end", :datetime

 t.column "desciption", :text

 end

 create_table "last_moves", :force => true do |t|

 t.column "move_id", :integer

 t.column "move_time", :datetime

 end

 create_table "moves", :force => true do |t|

 t.column "number", :integer

 t.column "game_id", :integer

 t.column "white_move", :string, :limit => 6

 t.column "black_move", :string, :limit => 6

 t.column "white_clock", :float

 t.column "black_clock", :float

 t.column "white_comment", :text

 t.column "black_comment", :text

 end

 create_table "players", :force => true do |t|

 t.column "first_name", :string, :limit => 30

 t.column "second_name", :string, :limit => 30

 t.column "country_id", :integer

 t.column "burn_date", :datetime

 t.column "fide_rating", :integer

 t.column "photo", :binary

 t.column "description", :text

 end

 create_table "tournament_views", :force => true do |t|

 t.column "name", :string, :limit => 30

 t.column "system", :string, :limit => 30

 t.column "is_match", :boolean, :limit => nil, :default => false

 t.column "is_command", :boolean, :limit => nil, :default => false

 t.column "total_games", :integer, :default => 0

 t.column "total_rounds", :integer, :default => 0

 t.column "description", :text

 end

 create_table "tournaments", :force => true do |t|

 t.column "name", :string, :limit => 30

 t.column "category", :integer

 t.column "city_id", :integer

 t.column "begin_date", :datetime

 t.column "end_date", :datetime

 t.column "tournament_view_id", :integer

 t.column "status", :string, :limit => 30

 t.column "description", :text

 end

 create_table "users", :force => true do |t|

 t.column "login", :string, :limit => 30

 t.column "password", :string, :limit => 50

 t.column "name", :string, :limit => 30

 t.column "is_admin", :boolean, :limit => nil, :default => false

 t.column "email", :string, :limit => 30

 t.column "webpage", :string, :limit => 30

 t.column "desciption", :text

 end

end

Javascript (javascript) – осуществляют демонстрацию шахматной партии, при помощи технологии AJAX обращаясь за обновлениями позиции на rDGT сервер.

game.js

---

var images = 'http://localhost:3000/images/classic/';

var moves_url = '/main/game_moves/1';

// Фигура

function figure(id, color, type, current_field, last_field, alive, board) {

 this.id = id;

 this.color = color;

 this.type = type;

 this.current_field = current_field;

 this.last_field = last_field;

 this.alive = alive;

 this.set_field = set_field;

 this.do_move = do_move;

 this.reload = reload;

 this.img = document.createElement('img');

 this.img.id = this.id;

 this.board = board;

 

 this.reload();

 //trace('create figure [' + this.id + ']');

}

// Поле

function field(id, color, vertical, horizontal, figure, board) {

 this.id = id;

 this.color = color;

 this.vertical = vertical;

 this.horizontal = horizontal;

 this.figure = figure;

 this.board = board;

 this.repaint = repaint;

 

 //trace('create field [' + this.id + ']');

}

// Ход

function move(number, color, from_field, to_field, figure, alive_figure, is_short_castling, is_long_castling, prev_move, next_move, board, time) {

 this.number = number;

 this.color = color;

 this.from_field = from_field;

 this.to_field = to_field;

 this.figure = figure;

 this.alive_figure = alive_figure;

 this.forward = forward;

 this.backward = backward;

 this.is_short_castling = is_short_castling;

 this.is_long_castling = is_long_castling;

 this.prev_move = prev_move;

 this.next_move = next_move;

 this.board = board;

 this.white_time = white_time;

 this.black_time = black_time;

}

// Коллекция ходов

function move_collection(board) {

 this.board = board;

 this.get_move = function(color, number) {

 return color == 'white' ? this.moves[(number * 2) - 1] : this.moves[number * 2];

 }

 this.exists_move = function(color, number) {

 return get_move(color, number) != null;

 }

 this.get_current_move = function() {

 return this.current_move;

 }

 this.add_move = function(move) {

 trace('add move: ' + move.number + " " + moveBy.color);

 if(current_move == null) {

 this.first_move = move;

 this.current_move = move;

 } else {

 move.prev_move = this.current_move;

 this.current_move.next_move = move;

 this.current_move = move;

 }

 this.moves.push(move);

}

this.first_move = null;

this.current_move = null;

this.moves = new Array();

}

// Коллекция фигур

function figure_collection(board) {

 this.board = board;

 

 this.wpA = new figure('wpA', 'white', 'pawn', null, null, true, board);

 this.wpB = new figure('wpB', 'white', 'pawn', null, null, true, board);

 this.wpC = new figure('wpC', 'white', 'pawn', null, null, true, board);

 this.wpD = new figure('wpD', 'white', 'pawn', null, null, true, board);

 this.wpE = new figure('wpE', 'white', 'pawn', null, null, true, board);

 this.wpF = new figure('wpF', 'white', 'pawn', null, null, true, board);

 this.wpG = new figure('wpG', 'white', 'pawn', null, null, true, board);

 this.wpH = new figure('wpH', 'white', 'pawn', null, null, true, board);

 this.wrA = new figure('wrA', 'white', 'rook', null, null, true, board);

 this.wrH = new figure('wrH', 'white', 'rook', null, null, true, board);

 this.whB = new figure('whB', 'white', 'horse', null, null, true, board);

 this.whG = new figure('whG', 'white', 'horse', null, null, true, board);

 this.wbC = new figure('wbC', 'white', 'bishop', null, null, true, board);

 this.wbF = new figure('wbF', 'white', 'bishop', null, null, true, board);

 this.wq = new figure('wq', 'white', 'queen', null, null, true, board);

 this.wk = new figure('wk', 'white', 'king', null, null, true, board);

 

 this.bpA = new figure('bpA', 'black', 'pawn', null, null, true, board);

 this.bpB = new figure('bpB', 'black', 'pawn', null, null, true, board);

 this.bpC = new figure('bpC', 'black', 'pawn', null, null, true, board);

 this.bpD = new figure('bpD', 'black', 'pawn', null, null, true, board);

 this.bpE = new figure('bpE', 'black', 'pawn', null, null, true, board);

 this.bpF = new figure('bpF', 'black', 'pawn', null, null, true, board);

 this.bpG = new figure('bpG', 'black', 'pawn', null, null, true, board);

 this.bpH = new figure('bpH', 'black', 'pawn', null, null, true, board);

 this.brA = new figure('brA', 'black', 'rook', null, null, true, board);

 this.brH = new figure('brH', 'black', 'rook', null, null, true, board);

 this.bhB = new figure('bhB', 'black', 'horse', null, null, true, board);

 this.bhG = new figure('bhG', 'black', 'horse', null, null, true, board);

 this.bbC = new figure('bbC', 'black', 'bishop', null, null, true, board);

 this.bbF = new figure('bbF', 'black', 'bishop', null, null, true, board);

 this.bq = new figure('bq', 'black', 'queen', null, null, true, board);

 this.bk = new figure('bk', 'black', 'king', null, null, true, board);

}

// Коллекция полей шахматной доски

function field_collection(board) {

 this.get_field = get_field;

 this.board = board;

 this.toArray = function() {

 return [this.A1, this.A2, this.A3, this.A4, this.A5, this.A6, this.A7, this.A8,

 this.B1, this.B2, this.B3, this.B4, this.B5, this.B6, this.B7, this.B8,

 this.C1, this.C2, this.C3, this.C4, this.C5, this.C6, this.C7, this.C8,

 this.D1, this.D2, this.D3, this.D4, this.D5, this.D6, this.D7, this.D8,

 this.E1, this.E2, this.E3, this.E4, this.E5, this.E6, this.E7, this.E8,

 this.F1, this.F2, this.F3, this.F4, this.F5, this.F6, this.F7, this.F8,

 this.G1, this.G2, this.G3, this.G4, this.G5, this.G6, this.G7, this.G8,

 this.H1, this.H2, this.H3, this.H4, this.H5, this.H6, this.H7, this.H8];

 }

 

 this.A1 = new field('fieldA1', 'black', 'A', '1', null, board);

 this.B1 = new field('fieldB1', 'white', 'B', '1', null, board);

 this.C1 = new field('fieldC1', 'black', 'C', '1', null, board);

 this.D1 = new field('fieldD1', 'white', 'D', '1', null, board);

 this.E1 = new field('fieldE1', 'black', 'E', '1', null, board);

 this.F1 = new field('fieldF1', 'white', 'F', '1', null, board);

 this.G1 = new field('fieldG1', 'black', 'G', '1', null, board);

 this.H1 = new field('fieldH1', 'white', 'H', '1', null, board);

 

 this.A2 = new field('fieldA2', 'white', 'A', '2', null, board);

 this.B2 = new field('fieldB2', 'black', 'B', '2', null, board);

 this.C2 = new field('fieldC2', 'white', 'C', '2', null, board);

 this.D2 = new field('fieldD2', 'black', 'D', '2', null, board);

 this.E2 = new field('fieldE2', 'white', 'E', '2', null, board);

 this.F2 = new field('fieldF2', 'black', 'F', '2', null, board);

 this.G2 = new field('fieldG2', 'white', 'G', '2', null, board);

 this.H2 = new field('fieldH2', 'black', 'H', '2', null, board);

 

 this.A3 = new field('fieldA3', 'black', 'A', '3', null, board);

 this.B3 = new field('fieldB3', 'white', 'B', '3', null, board);

 this.C3 = new field('fieldC3', 'black', 'C', '3', null, board);

 this.D3 = new field('fieldD3', 'white', 'D', '3', null, board);

 this.E3 = new field('fieldE3', 'black', 'E', '3', null, board);

 this.F3 = new field('fieldF3', 'white', 'F', '3', null, board);

 this.G3 = new field('fieldG3', 'black', 'G', '3', null, board);

 this.H3 = new field('fieldH3', 'white', 'H', '3', null, board);

 

 this.A4 = new field('fieldA4', 'white', 'A', '4', null, board);

 this.B4 = new field('fieldA4', 'black', 'B', '4', null, board);

 this.C4 = new field('fieldC4', 'white', 'C', '4', null, board);

 this.D4 = new field('fieldD4', 'black', 'D', '4', null, board);

 this.E4 = new field('fieldE4', 'white', 'E', '4', null, board);

 this.F4 = new field('fieldF4', 'black', 'F', '4', null, board);

 this.G4 = new field('fieldG4', 'white', 'G', '4', null, board);

 this.H4 = new field('fieldH4', 'black', 'H', '4', null, board);

 

 this.A5 = new field('fieldA5', 'black', 'A', '5', null, board);

 this.B5 = new field('fieldB5', 'white', 'B', '5', null, board);

 this.C5 = new field('fieldC5', 'black', 'C', '5', null, board);

 this.D5 = new field('fieldD5', 'white', 'D', '5', null, board);

 this.E5 = new field('fieldE5', 'black', 'E', '5', null, board);

 this.F5 = new field('fieldF5', 'white', 'F', '5', null, board);

 this.G5 = new field('fieldG5', 'black', 'G', '5', null, board);

 this.H5 = new field('fieldH5', 'white', 'H', '5', null, board);

 

 this.A6 = new field('fieldA6', 'white', 'A', '6', null, board);

 this.B6 = new field('fieldB6', 'black', 'B', '6', null, board);

 this.C6 = new field('fieldC6', 'white', 'C', '6', null, board);

 this.D6 = new field('fieldD6', 'black', 'D', '6', null, board);

 this.E6 = new field('fieldE6', 'white', 'E', '6', null, board);

 this.F6 = new field('fieldF6', 'black', 'F', '6', null, board);

 this.G6 = new field('fieldG6', 'white', 'G', '6', null, board);

 this.H6 = new field('fieldH6', 'black', 'H', '6', null, board);

 

 this.A7 = new field('fieldA7', 'black', 'A', '7', null, board);

 this.B7 = new field('fieldB7', 'white', 'B', '7', null, board);

 this.C7 = new field('fieldC7', 'black', 'C', '7', null, board);

 this.D7 = new field('fieldD7', 'white', 'D', '7', null, board);

 this.E7 = new field('fieldE7', 'black', 'E', '7', null, board);

 this.F7 = new field('fieldF7', 'white', 'F', '7', null, board);

 this.G7 = new field('fieldG7', 'black', 'G', '7', null, board);

 this.H7 = new field('fieldH7', 'white', 'H', '7', null, board);

 

 this.A8 = new field('fieldA8', 'white', 'A', '8', null, board);

 this.B8 = new field('fieldB8', 'black', 'B', '8', null, board);

 this.C8 = new field('fieldC8', 'white', 'C', '8', null, board);

 this.D8 = new field('fieldD8', 'black', 'D', '8', null, board);

 this.E8 = new field('fieldE8', 'white', 'E', '8', null, board);

 this.F8 = new field('fieldF8', 'black', 'F', '8', null, board);

 this.G8 = new field('fieldG8', 'white', 'G', '8', null, board);

 this.H8 = new field('fieldH8', 'black', 'H', '8', null, board);

}

function board() {

 this.moves = new move_collection(this);

 this.figures = new figure_collection(this);

 this.fields = new field_collection(this);

 this.init = init;

 this.last_move = null;

 // Обновляет позицию

 this.refresh_moves = function() {

 // Ajax запрос к серверу

 new Ajax.Request(moves_url, {

 method: 'get',

 onSuccess: function(transport) {

 all_moves = transport.responseText;

 trace('ajax: ' + all_moves);

 }

 });

 

 trace('call => parse_moves(' + all_moves + ')')

 

 function existsWhite(move) {

 return getWhiteMove(move) != "******";

 }

 function existsBlack(move) {

 return getBlackMove(move) != "******";

 }

 function getWhiteMove(move) {

 return move.substring(0,6);

 }

 function getWhiteTime(move) {

 return move.substring(13, 19);

 }

 function getBlackMove(move) {

 return move.substring(6,12);

 }

 function getBlackTime(move) {

 return move.substring(20, 26);

 }

 function getFrom(color, move) {

 }

 function getTo(color, move) {

 }

 function isShortCastling(color, move) {

 }

 function isLongCastling(color, move) {

 }

 

 moves_split = all_moves.split('|');

 moves_strip = new Array();

 for(i = 0; i < moves_split.length; i++) {

 if(moves_split[i] != "") {

 moves_strip.push(moves_split[i]);

 trace('split: ' + moves_split[i]);

 }

 }

 

 var number = moves_strip.length;

 trace('number = ' + number);

 var current_move = this.moves.get_current_move();

 trace('current_move = ' + current_move);

 var current_number = current_move != null ? current_move.number : 0;

 trace('current_number = ' + current_number);

 

 if(number == current_number) {

 if((current_move.color == 'white') && existsBlack(moves_strip[number - 1])) {

 var move_annotation = getBlackMove(moves_strip[number - 1]);

 var move_time = getBlackTime(moves_strip[number - 1]);

 var fieldFrom = getFrom('black', move_annotation);

 var fieldTo = getTo('black', move_annotation);

 var move = new move(number, 'black', fieldFrom, fieldTo, fieldFrom.figure, fieldTo.figure, isShortCastling('black', move_annotation), isLongCastling('black', move_annotation), current_move, null, this, move_time);

 this.moves.add_move(move);

 }

 }

 

 if(number > current_number){

 for(iMove = current_move; iMove < number; iMove++) {

 var move_annotation = getWhiteMove(moves_strip[number - 1]);

 if(existsWhite(move_annotation)) {

 var move_time = getWhiteTime(moves_strip[number - 1]);

 var fieldFrom = getFrom('white', move_annotation);

 var fieldTo = getTo('white', move_annotation);

 var move = new move(iMove + 1, 'white', fieldFrom, fieldTo, fieldFrom.figure, fieldTo.figure, isShortCastling('white', move_annotation), isLongCastling('white', move_annotation), current_move, null, this, move_time);

 this.moves.add_move(move);

 }

 

 move_annotation = getBlackMove(moves_strip[number - 1]);

 if(existsBlack(move_annotation)) {

 var move_time = getBlackTime(moves_strip[number - 1]);

 var fieldFrom = getFrom('black', move_annotation);

 var fieldTo = getTo('black', move_annotation);

 var move = new move(iMove + 1, 'black', fieldFrom, fieldTo, fieldFrom.figure, fieldTo.figure, isShortCastling('black', move_annotation), isLongCastling('black', move_annotation), current_move, null, this, move_time);

 this.moves.add_move(move);

 }

 }

 }

 }

 this.refresh_figures = refresh_figures;

 this.go_begin = go_begin;

 this.go_end = go_end;

 this.go_next = go_next;

 this.go_preview = go_preview;

 this.go_custom = go_custom;

 this.repaint = function() {

 }

 

 // Парсит данные пришедшие от сервера

 this.parse_moves = function() {

 var moves = this.all_moves;

 trace('call => parse_moves(' + moves + ')')

 

 function existsWhite(move) {

 return getWhiteMove(move) != "******";

 }

 function existsBlack(move) {

 return getBlackMove(move) != "******";

 }

 function getWhiteMove(move) {

 return move.substring(0,6);

 }

 function getWhiteTime(move) {

 return move.substring(13, 19);

 }

 function getBlackMove(move) {

 return move.substring(6,12);

 }

 function getBlackTime(move) {

 return move.substring(20, 26);

 }

 function getFrom(color, move) {

 }

 function getTo(color, move) {

 }

 function isShortCastling(color, move) {

 }

 function isLongCastling(color, move) {

 }

 

 moves_split = moves.split('|');

 moves_strip = new Array();

 for(i = 0; i < moves_split.length; i++) {

 if(moves_split[i] != null) {

 moves_strip.push(moves_split[i]);

 }

 }

 

 var number = moves_strip.length;

 var current_move = this.moves.get_current_move;

 var current_number = current_move != null ? current_move.number : 0;

 if(number == current_number) {

 if((current_move.color == 'white') && existsBlack(moves_strip[number - 1])) {

 var move_annotation = getBlackMove(moves_strip[number - 1]);

 var move_time = getBlackTime(moves_strip[number - 1]);

 var fieldFrom = getFrom('black', move_annotation);

 var fieldTo = getTo('black', move_annotation);

 var move = new move(number, 'black', fieldFrom, fieldTo, fieldFrom.figure, fieldTo.figure, isShortCastling('black', move_annotation), isLongCastling('black', move_annotation), current_move, null, this, move_time);

 this.moves.add_move(move);

 }

 }

 

 if(number > current_number){

 for(iMove = current_move; iMove < number; iMove++) {

 var move_annotation = getWhiteMove(moves_strip[number - 1]);

 if(existsWhite(move_annotation)) {

 var move_time = getWhiteTime(moves_strip[number - 1]);

 var fieldFrom = getFrom('white', move_annotation);

 var fieldTo = getTo('white', move_annotation);

 var move = new move(iMove + 1, 'white', fieldFrom, fieldTo, fieldFrom.figure, fieldTo.figure, isShortCastling('white', move_annotation), isLongCastling('white', move_annotation), current_move, null, this, move_time);

 this.moves.add_move(move);

 }

 

 move_annotation = getBlackMove(moves_strip[number - 1]);

 if(existsBlack(move_annotation)) {

 var move_time = getBlackTime(moves_strip[number - 1]);

 var fieldFrom = getFrom('black', move_annotation);

 var fieldTo = getTo('black', move_annotation);

 var move = new move(iMove + 1, 'black', fieldFrom, fieldTo, fieldFrom.figure, fieldTo.figure, isShortCastling('black', move_annotation), isLongCastling('black', move_annotation), current_move, null, this, move_time);

 this.moves.add_move(move);

 }

 }

 }

 }

 

 // Настройки

 this.all_moves = "";

 this.moves_delay = 3;

 this.moves_url = '/main/game_moves/1';

 this.figures_delay = 2;

}

// Инициализация доски

function init() {

 trace('call => init()');

 // Расставляем шахматы в начальную позицию

 // белые пешки

 this.figures.wpA.set_field(this.fields.A2);

 this.figures.wpB.set_field(this.fields.B2);

 this.figures.wpC.set_field(this.fields.C2);

 this.figures.wpD.set_field(this.fields.D2);

 this.figures.wpE.set_field(this.fields.E2);

 this.figures.wpF.set_field(this.fields.F2);

 this.figures.wpG.set_field(this.fields.G2);

 this.figures.wpH.set_field(this.fields.H2);

 // белые фигуры

 this.figures.wrA.set_field(this.fields.A1);

 this.figures.wrH.set_field(this.fields.H1);

 this.figures.whB.set_field(this.fields.B1);

 this.figures.whG.set_field(this.fields.G1);

 this.figures.wbC.set_field(this.fields.C1);

 this.figures.wbF.set_field(this.fields.F1);

 this.figures.wq.set_field(this.fields.D1);

 this.figures.wk.set_field(this.fields.E1);

 // черные пешки

 this.figures.bpA.set_field(this.fields.A7);

 this.figures.bpB.set_field(this.fields.B7);

 this.figures.bpC.set_field(this.fields.C7);

 this.figures.bpD.set_field(this.fields.D7);

 this.figures.bpE.set_field(this.fields.E7);

 this.figures.bpF.set_field(this.fields.F7);

 this.figures.bpG.set_field(this.fields.G7);

 this.figures.bpH.set_field(this.fields.H7);

 // черные фигуры

 this.figures.brA.set_field(this.fields.A8);

 this.figures.brH.set_field(this.fields.H8);

 this.figures.bhB.set_field(this.fields.B8);

 this.figures.bhG.set_field(this.fields.G8);

 this.figures.bbC.set_field(this.fields.C8);

 this.figures.bbF.set_field(this.fields.F8);

 this.figures.bq.set_field(this.fields.D8);

 this.figures.bk.set_field(this.fields.E8);

 // Создаем Ajax опрашиватель сервера

 new PeriodicalExecuter(this.refresh_moves, this.moves_delay);

 new PeriodicalExecuter(this.refresh_figures, this.figures_delay);

}

// Перерисовка позиции (делает один ход)

function refresh_figures() {

 //trace('call => refresh_figures');

 

 if(this.exists_move) {

 this.current_move = this.moves.get_current_move();

 this.current_move.forward();

 }

}

// Перейти к началу

function go_begin() {

}

// Перейти к концу

function go_end() {

}

// Следующий ход

function go_next() {

}

// Предыдущий ход

function go_preview() {

}

// Перейти к произвольному ходу

function go_custom(number, color) {

}

// сделать ход

function do_move(from_field, to_field) {

 }

// Возвращает поле

function get_field(vertical, horizontal) {

}

// Установить фигуру на поле

function set_field(field_to_set) {

 this.last_field = field_to_set;

 field_to_set.figure = this;

 field_to_set.repaint();

}

// Возвращает ход по номеру и цвету

function get_move(number, color) {

 

}

// Возвращает текуший ход

function get_current_move() {

 return this.current_move;

}

// Возвращает true если есть ход который нужно совершить

function exists_move() {

}

function repaint() {

 $(this.id).innerHTML = '';

 if(this.figure != null) {

 $(this.id).appendChild(this.figure.img);

 }

}

function reload() {

 this.img.src = images + this.color[0] + this.type[0] + '.gif';

 //trace('reload figure [' + this.id + '].src = \"' + this.img.src + '\"');

}

// Ход вперед !! предыдущую фигуру удалить

function forward(){

 if(this.to_field.figure != null) {

 }

 this.figure.do_move(this.from_field, this.to_field);

}

// Ход назад

function backward() {

 this.figure.do_move(this.to_field, this.from_field);

 this.alive_figure.set_field(this.to_field);

}

function trace(message) {

 $("debug").innerHTML += message + '<br />';

}

window.onload=function() {

 // Запуск

 var main_board = new board();

 main_board.init();

 // setBeginingPosition();

 // refreshGame();

 // new PeriodicalExecuter(refreshGame, periodicalDelay);

 // new PeriodicalExecuter(refreshBoard, 1);

}


Приложение Г

Листинг программы-регистратора шахматных партий

rdgtChess.java

---

public class rdgtChess implements Runnable

static boolean debug = false;

String comport = "COM1";

public static void main(String[] args) {

rdgtChess t;

if(args.length > 0)

 t = new rdgtChess(args[0]);

 else

 t = new rdgtChess();

}

public rdgtChess() {

(new Thread(this)).start();

}

public rdgtChess(String comport) {

this.comport = comport;

(new Thread(this)).start();

}

// Destructor

public void finalize()

{

rdgtMysql.disconnect();

}

// This is the main loop. It samples all boards and tries at regular intervals

// to find new boards and to mark non-answering boards as, well, non-answering.

 Это головная часть. Она опрашивает все доски с регулярным интервалом времени,

 чтобы найти новые доски и отметить неотвечающие доски как неотвечающие

public void run() {

rdgtController c = new rdgtController();

if (c.connect(comport) == false) return;

 System.out.println(rdgtMysql.connect());

int i = 0;

while (true) {

if ((i==0) || (c.db.count_alive()==0)) {

while (c.find_all_boards()==0) {} c.dump_all_active_boards();

i = 15;

} else {

try {Thread.sleep(1000);} catch(Throwable t) {}}

c.poll_all_active_boards();

i--;

}

}

}

rdgtChessboard.java

---

class rdgtChessboard {

 Integer address;

 rdgtHistory history = new rdgtHistory(this);

 rdgtSnapshot snapshot = new rdgtSnapshot(this);

 rdgtFenhax myFenhax = new rdgtFenhax();

 boolean alive;

 boolean dumped;

 boolean updated;

 rdgtDatabase db;

 rdgtChessBoardForm board = null;

 

 public rdgtChessboard(Integer _address, rdgtDatabase _db) {

 address = _address;

 db = _db;

 alive = true;

 dumped = false;

 updated = false;

 update_html();

 board = new rdgtChessBoardForm();

 

 new Thread(new Runnable() {

 public void run() {

 board.setVisible(true);

 }

 }).start();

 }

 rdgtSnapshot get_snapshot() {

 return snapshot;

 }

 int get_address() {

 return address.intValue();

 }

 public void print_position() {

 board.printPosition(snapshot.debugprint());

 board.printClock(snapshot.debugprint_clock());

 }

 

 String print_figure(int figure) {

 if(figure == rdgtProtocol.EMPTY) {

 return " ";

 } else if (figure == rdgtProtocol.WPAWN) {

 return "P";

 } else if(figure == rdgtProtocol.WROOK) {

 return "R";

 } else if(figure == rdgtProtocol.WKNIGHT) {

 return "N";

 } else if(figure == rdgtProtocol.WBISHOP) {

 return "B";

 } else if(figure == rdgtProtocol.WQUEEN) {

 return "Q";

 } else if(figure == rdgtProtocol.WKING) {

 return "K";

 } else if (figure == rdgtProtocol.BPAWN) {

 return "p";

 } else if(figure == rdgtProtocol.BROOK) {

 return "r";

 } else if(figure == rdgtProtocol.BKNIGHT) {

 return "n";

 } else if(figure == rdgtProtocol.BBISHOP) {

 return "b";

 } else if(figure == rdgtProtocol.BQUEEN) {

 return "q";

 } else if(figure == rdgtProtocol.BKING) {

 return "k";

 } else {

 return " ";

 }

 }

 void set_alive(boolean x) {

 alive = x;

 update_html();

 }

 void set_dumped(boolean x) {

 dumped = x;

 }

 void set_updated(boolean x) {

 updated = x;

 history.append(snapshot);

 }

 boolean get_alive() {

 return alive;

 }

 boolean get_dumped() {

 return dumped;

 }

 boolean get_updated() {

 return updated;

 }

 void set_clockdata(boolean running, boolean batteryLow, boolean frontViewLeftSideHigh, boolean blacksTurn, boolean whitesTurn, int secW, int secB) {

 snapshot.set_clockdata(running, batteryLow, frontViewLeftSideHigh, blacksTurn, whitesTurn, secW, secB);

 snapshot.debugprint_clock();

 }

 void update_html() {

 rdgtMysql.update_snapshot(snapshot);

 String fen = rdgtMysql.snapshot2fen(snapshot);

 myFenhax.add(fen);

 rdgtMysql.update_moves(rdgtFenhax.getMoves(true, false), rdgtFenhax.getMoves(true, true), address.intValue());

}

 void set_emptyboard() {

 snapshot.set_emptyboard();

 history.append(snapshot);

 }

 void set_boarddump(int[] all64, int startpos) {

 snapshot.set_boarddump(all64, startpos);

 dumped = true;

 history.append(snapshot);

 }

 void set_fieldupdate(int piece, int pos) {

 snapshot.set_fieldupdate(piece, pos);

 updated = true;

 history.append(snapshot);

 }

}

rdgtConfig.java

---

class rdgtConfig {

 String getDbServer() { return server; }

 String getDbUser() { return user; }

 String getDbPass() { return pass; }

 String getDbBase() { return dbase; }

 boolean useDbServer() { return mysql; }

 boolean usePgnWriter() { return pgn; }

 String getPgnFileName() { return pgnfile; }

 String server= "localhost";

 String user= "root";

 String pass= "zar1562";

 String dbase= "rdgt_development";

 boolean mysql = true;

 boolean pgn = false;

 String pgnfile = "default.pgn";

}

rdgtController.java

---

class rdgtController extends rdgtProtocol {

rdgtDatabase db;

rdgtInterpreter ipr;

rdgtReceiver rec;

rdgtSerialport ser;

rdgtSender snd;

public rdgtController() {

db = new rdgtDatabase();

ipr = new rdgtInterpreter(db);

rec = new rdgtReceiver(ipr);

ser = new rdgtSerialport(rec);

snd = new rdgtSender(ser);

}

boolean connect(String comport) {

if (ser.open(comport)==false) {

System.out.println("Could not open "+comport);

return false;

}

System.out.println("COM port opened: "+comport);

return true;

}

int find_all_boards() {

System.out.println("Scanning for boards...");

db.unalive_all();

int alive = 0;

while (true) {

try {Thread.sleep(300);} catch(Throwable t) {}

snd.send(DGT_BUS_PING, 0);

try {Thread.sleep(1100);} catch(Throwable t) {}

int alivenow = db.count_alive();

if (alivenow == alive) break;

alive = alivenow;

for (Enumeration e = db.get_boards() ; e.hasMoreElements() ;) {

rdgtChessboard b = (rdgtChessboard)(e.nextElement());

if (b.get_alive()==true) {

snd.send(DGT_BUS_IGNORE_NEXT_BUS_PING, b.get_address());

}

}

}

System.out.println("Scanning completed, found "+Integer.toString(alive)+" boards.\n");

return alive;

}

void dump_all_active_boards() {

for (Enumeration e = db.get_boards() ; e.hasMoreElements() ;) {

rdgtChessboard b = (rdgtChessboard)(e.nextElement());

if (b.get_alive()==true) {

b.set_dumped(false);

for (int i=0; i<3; i++) { if (b.get_dumped()==true) break;

snd.send(DGT_BUS_SEND_BRD, b.get_address());

try {Thread.sleep(200);} catch(Throwable t) {}

}

if (b.get_dumped()==false) {

System.out.println("Board "+Integer.toString(b.get_address())+" does not reply to dump_board.");

b.set_alive(false);

}

}

}

}

void poll_all_active_boards() {

int TIMEOUT = 100;

for (Enumeration e = db.get_boards() ; e.hasMoreElements() ;) {

rdgtChessboard b = (rdgtChessboard)(e.nextElement());

if (b.get_alive()==true) {

snd.send(DGT_BUS_SEND_CLK, b.get_address());

try {Thread.sleep(TIMEOUT);} catch(Throwable t) {}

b.set_updated(false);

snd.send(DGT_BUS_SEND_CHANGES, b.get_address());

try {Thread.sleep(TIMEOUT);} catch(Throwable t) {}

for (int i=0; i<2; i=i+1) {

if (b.get_updated()==true) break;

snd.send(DGT_BUS_REPEAT_CHANGES, b.get_address());

try {Thread.sleep(TIMEOUT);} catch(Throwable t) {}}

if (b.get_updated()==false) {

System.out.println("Board "+Integer.toString(b.get_address())+" does not reply anymore.");

b.set_alive(false);

} else {

 b.print_position();

 }

}

}

}

}

rdgtDatabase.java

---

class rdgtDatabase {

Hashtable boards;

public rdgtDatabase() {

boards = new Hashtable();

}

rdgtChessboard get_board(int address) {

Integer _address = new Integer(address);

rdgtChessboard b = (rdgtChessboard)(boards.get(_address));

if (b==null) {

System.out.println("New board found: ID="+_address.toString());

b = new rdgtChessboard(_address, this);

boards.put(_address, b);

}

return b;

}

int get_boardcount() {

return boards.size();

}

Enumeration get_boards() {

return boards.elements();

}

void unalive_all() {

for (Enumeration e = boards.elements() ; e.hasMoreElements() ;) {

((rdgtChessboard)(e.nextElement())).set_alive(false);

}

}

int count_alive() {

int x = 0;

for (Enumeration e = boards.elements() ; e.hasMoreElements() ;) {

if (((rdgtChessboard)(e.nextElement())).get_alive()==true) x++;

}

return x;

}

}

rdgtFenboard.java

---

class rdgtFenboard {

 int[] itsBoard;

 String itsFen;

 public rdgtFenboard(){

itsBoard = new int[64];

for(int i=0;i<64;i++)

 itsBoard[i]='.';

itsFen="";

 }

 public rdgtFenboard(String fen){ setBoard(fen); }

 public rdgtFenboard(int[] board) { setBoard(board); }

 public boolean setBoard(String fen){

if(!validateFen(fen))

 return false;

itsBoard=fen2board(fen);

itsFen=fen;

return true;

 }

 public int getPieceAt(int x, int y){

if(x<0 || x>7 || y<0 || y>7) return 0;

return itsBoard[y*8+x];

 }

public boolean setBoard(int[] board){

if(board.length != 64)

 return false;

itsBoard=board;

return true;

 }

 public void print(){

printBoard(itsBoard);

 }

 public int[] getBoard() { return itsBoard; }

 public rdgtFenboard mask(rdgtFenboard b){

rdgtFenboard output;

output=new rdgtFenboard(mask(getBoard(),b.getBoard()));

return output;

 }

 public int diffCount(rdgtFenboard b){

rdgtFenboard m = mask(b);

int[] table=m.getBoard();

int output=0;

for(int i=0;i<64;i++){

 if(table[i]!='.')

output++;

}

return output;

 }

 int[] fen2board(String aFen){

 int[] board = new int[64];

 int square=0;

 int chr=0;

 while(square<64){

 char c = aFen.charAt(chr);

if(c=='r'||c=='R'||c=='n'||c=='N'||c=='b'||c=='B'||c=='q'||c=='Q'||c=='k'||c=='K'||c=='p'||c=='P'){

 board[square]=c;

 square++;

 }

 if(c>='1' && c<='8'){

 for(int i=0;i<c-'1'+1;i++){

 board[square]='.';

 square++;

 }

 }

 chr++;

 }

 return board;

 }

 String[] outputBoard(int[] board){

 String s="";

 String[] out = new String[8];

 for(int chr=0;chr<64;chr++){

 if(board[chr]<0)

 s += "-" + (char)(Math.abs(board[chr]));

 else if(board[chr]==0)

 s += ", ";

 else

 s += (char)board[chr] + " ";

 if((chr+1)%8==0){

 out[chr/8]=s;

 s="";

 }

 }

 return out;

 }

 void printBoard(int[] board){

 String[] out = outputBoard(board);

 for(int i=0;i<8;i++){

 System.out.println(out[i]);

 }

 System.out.println();

 }

 int[] mask(int[] b1, int[] b2){

 int[] output=new int[64];

 for(int i=0;i<64;i++){

 if(b2[i]!=b1[i]){

 if(b2[i]=='.')

 output[i]=-b1[i];

 else

 output[i]=b2[i];

 }

 else

 output[i] = '.';//b2[i]-b1[i];

 }

 return output;

 }

 boolean validateFen(String aFen){

 /* Only check board part of FEN */

 if(aFen.indexOf(' ')>0){

 aFen = aFen.substring(0,aFen.indexOf(' '));

 }

 int s=0;

 for(int c=0;c<aFen.length();c++){

 if(aFen.charAt(c) == '/') s++;

 }

 if(s!=7) return false;

 int x=0;

 for(int c=0;c<aFen.length();c++){

 if(aFen.charAt(c) == '/'){

 if(x!=8) return false;

 else x=0;

 }

 else

 {

if(aFen.charAt(c) >= '1' && aFen.charAt(c)<= '8')

 x+= aFen.charAt(c)-'1' ;

x++;

 }

 }

 if(x!=8) return false;

 return true;

 }

}

rdgtFendiff.java

---

class rdgtFendiff {

 char piece;

 boolean added;

 int square;

 rdgtFenboard before;

 rdgtFenboard after;

 public rdgtFenboard getBefore() { return before; }

 public rdgtFenboard getAfter() { return after; }

 public char getPiece() { return piece; }

 public boolean isAdded() { return added; }

 public int getSquare() { return square; }

 public boolean isWhite(){

if(piece>'A' && piece < 'Z')

 return true;

else

 return false;

 }

 public boolean equals(rdgtFendiff other){

if(getPiece() != other.getPiece()) return false;

if(getSquare() != other.getSquare()) return false;

if(isAdded() != other.isAdded()) return false;

return true;

 }

 public rdgtFendiff() {

secured=false;

 }

 public rdgtFendiff(char piece, boolean added, int square){

set(piece,added,square);

 }

 public rdgtFendiff(int piece, int square){

if(piece<0){

 this.piece = (char)(-piece);

 added=false;

}

else {

 this.piece=(char)piece;

 added=true;

}

this.square=square;

 }

public rdgtFendiff(int piece,int square, rdgtFenboard before, rdgtFenboard after){

this.before=before;

this.after=after;

if(piece<0){

 this.piece = (char)(-piece);

 added=false;

}

else {

 this.piece=(char)piece;

 added=true;

}

this.square=square;

 }

 public void set(char piece, boolean added, int square){

this.piece=piece;

this.added=added;

this.square=square;

 }

 public String toString() {

String output = ""+piece;

if(added) output += "@";

else output += "&";

output += (char)((square)%8+'a') + "" + (8-square/8);

return output;

 }

}

rdgtFenhax.java

---

public class rdgtFenhax {

 static boolean debug=false;

 static boolean rotated=false;

 public rdgtFenhax(){

boards=new ArrayList();

moves=new movelist();

diffTable=new ArrayList();

result="?-?";

plyCount=0;

 }

 static String getMoves(boolean shortNotation, boolean nice) {

calcMoves();

return moves.getAll(shortNotation,nice);

 }

 static String getMoves(){

return getMoves(false,false);

 }

 static int getPlyCount(){

calcMoves();

return moves.size();

 }

 static void clear(){

boards.clear();

moves.clear();

diffTable.clear();

result="?-?";

 }

 static String getResult() { return result; }

 static boolean add(String aFen){

rdgtFenboard f = new rdgtFenboard();

if(!f.setBoard(aFen))

 return false;

boards.add(f);

if(aFen.indexOf("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR")>=0){

 clear();

 boards.add(f);

}

if((aFen.indexOf("rnbq1bnr/pppppppp") >=0 && aFen.indexOf("PPPPPPPP/RNBQ1BNR") >= 0)||

 (aFen.indexOf("rnbqkbnr/pppppppp") >=0 && aFen.indexOf("PPPPPPPP/RNBQ1BNR") >= 0)||

 (aFen.indexOf("rnbq1bnr/pppppppp") >=0 && aFen.indexOf("PPPPPPPP/RNBQKBNR") >= 0)){

 int[] b=f.getBoard();

 boolean black=false;

 boolean white=false;

 for(int i=16;i<=47;i++){

if(b[i] == 'k') black=true;

if(b[i] == 'K') white=true;

 }

 if(black && white) result="1/2-1/2";

 else if(black) result="0-1";

 else if(white) result="1-0";

}

if(boards.size()>=2){

 rdgtFenboard last = (rdgtFenboard)boards.get(boards.size()-1);

 rdgtFenboard nextlast = (rdgtFenboard)boards.get(boards.size()-2);

 if(last.diffCount(nextlast) < 5){

rdgtFenboard m=nextlast.mask(last);

int[] mask = m.getBoard();

 for(int i=0;i<64;i++){

 if(mask[i] != '.' && mask[i]<0){

diffTable.add(new rdgtFendiff(mask[i],i,nextlast,last));

 }

}

 for(int i=0;i<64;i++){

 if(mask[i] != '.' && mask[i]>0){

diffTable.add(new rdgtFendiff(mask[i],i,nextlast,last));

 }

}

 }

 else {

clear();

boards.add(f);

 }

}

return true;

 }

 static void calcMoves(){

moves.clear();

if(debug){

 for(int i=0;i<diffTable.size();i++){

System.out.print(i + ":" + ((rdgtFendiff)diffTable.get(i)).toString() + " ");

 }

 System.out.print("\n");

}

int offset=0;

int length=diffTable.size();

while(offset<length){

 int start=offset;

 int end=-1;

boolean turn = isWhite( ((rdgtFendiff)diffTable.get(offset)).getPiece() );

 int i=start;

 while(end==-1){

rdgtFendiff test = (rdgtFendiff)diffTable.get(i);

if(turn != isWhite(test.getPiece()) && test.isAdded()){

 end=i-1;

}

else{

 i++;

 if(i>=length)

end=length-1;

}

if(turn==isWhite(test.getPiece()) && test.isAdded()){

 offset=i;

}

 }

 if(offset==start) offset++;

 if(debug) System.out.print(start + "-"+end+" ");

 movelist chunkMoves = new movelist(true,true);

 for(int s=start;s<end;s++){

rdgtFendiff a = (rdgtFendiff)diffTable.get(s);

for(int e=s+1;e<=end;e++){

 rdgtFendiff b = (rdgtFendiff)diffTable.get(e);

 if(a.getPiece() == b.getPiece() && a.getSquare() != b.getSquare()){

if(!a.isAdded() && b.isAdded()){

 String special="";

 if(b.getPiece()=='P' && b.getSquare()/8==0){

for(int j=e+1;j<=end;j++){

 rdgtFendiff prom = (rdgtFendiff)diffTable.get(j);

 if(prom.isAdded() && prom.isWhite()){

if(a.getSquare()%8 != b.getSquare()%8)

 special+=pos2xy(a.getSquare()).substring(0,1)+"x";

special+=pos2xy(b.getSquare())+"="+prom.getPiece();

b=prom;

 }

}

 }

 if(b.getPiece()=='p' && b.getSquare()/8==7){

for(int j=e+1;j<=end;j++){

 rdgtFendiff prom = (rdgtFendiff)diffTable.get(j);

 if(prom.isAdded() && prom.isWhite()){

if(a.getSquare()%8 != b.getSquare()%8)

 special+=pos2xy(a.getSquare()).substring(0,1)+"x";

special+=pos2xy(b.getSquare())+"="+prom.getPiece();

b=prom;

 }

}

 }

 chunkMoves.add(new move(a,b,special));

}

 }

}

 }

 if(chunkMoves.size()==0){

rdgtFendiff a = (rdgtFendiff)diffTable.get(start);

for(int s=start;s<=end;s++){

 rdgtFendiff b = (rdgtFendiff)diffTable.get(s);

 if(b.isAdded()){

if(a.getPiece()=='P' && a.getSquare()/8==1 && !a.isAdded()){

 String special="";

 if(a.getSquare()%8 != b.getSquare()%8)

special+=pos2xy(a.getSquare()).substring(0,1)+"x";

 special+=pos2xy(b.getSquare())+"="+b.getPiece();

 chunkMoves.add(new move(a,b,special));

}

else if(a.getPiece()=='p' && a.getSquare()/8==6 && !a.isAdded()){

 String special="";

 if(a.getSquare()%8 != b.getSquare()%8)

special+=pos2xy(a.getSquare()).substring(0,1)+"x";

 special+=pos2xy(b.getSquare())+"="+b.getPiece();

 chunkMoves.add(new move(a,b,special));

}

else

 chunkMoves.add(new move(a,b,""+a.getPiece()+"@"+pos2xy(a.getSquare())));

 }

}

 }

 for(int j=0;j<chunkMoves.size();j++){

if(debug) System.out.print( (chunkMoves.get(j)).toString() + " ");

moves.add(chunkMoves.get(j));

 }

 if(debug) System.out.print("\n");

}

 }

 static String pos2xy(int pos){

String s = "" + (char)((pos)%8+'a') + "" + (8-pos/8);

return s;

 }

 static boolean isWhite(char piece){

if(piece>'A' && piece < 'Z')

 return true;

else

 return false;

 }

 static movelist moves;

 static ArrayList boards;

 static ArrayList diffTable;

 static String result;

 static int plyCount;

}

class move {

 rdgtFendiff from;

 rdgtFendiff to;

 boolean take;

 String special;

 public move(rdgtFendiff from, rdgtFendiff to){

this.from=from;

this.to=to;

take=false;

special="";

 }

 public move(rdgtFendiff from, rdgtFendiff to, String special){

this.from=from;

this.to=to;

take=false;

this.special=special;

 }

 public rdgtFendiff getFrom(){ return from; }

 public rdgtFendiff getTo(){ return to; }

 public char getPiece(){ return from.getPiece(); }

 public int getFromSquare() { return from.getSquare(); }

 public int getToSquare() { return to.getSquare(); }

 public String getFromCor() { return pos2xy(getFromSquare()); }

 public String getToCor() { return pos2xy(getToSquare()); }

 public boolean isWhite() { return from.isWhite(); }

 public String longNotation() { return moveString(false); }

 public String shortNotation() { return moveString(true); }

 public void setTake(boolean take){ this.take=take; }

 public boolean getTake() { return take; }

String moveString(boolean shortNotation){

if(!special.equals("")) {

 if(isCheck(isWhite()))

return special + "+";

 else

return special;

}

 

boolean ep=false;

char takeBit='-';

if(take) takeBit='x';

String s="";

if(getPiece()!='p' && getPiece()!='P')

 s+=new String(""+getPiece()).toUpperCase();

if(!shortNotation)

 s+=getFromCor()+takeBit;

else {

 if(getPiece()=='R' || getPiece()=='r')

if(findRookLength(getToSquare()%8,getToSquare()/8,getPiece()))

 s+=getFromCor()+takeBit;

 if(getPiece()=='N' || getPiece()=='n')

if(findNightLength(getToSquare()%8,getToSquare()/8,getPiece()))

 s+=getFromCor()+takeBit;

 if(getPiece()=='B' || getPiece()=='b')

if(findBishopLength(getToSquare()%8,getToSquare()/8,getPiece()))

 s+=getFromCor()+takeBit;

 if(getPiece()=='Q' || getPiece()=='q')

if(findQueenLength(getToSquare()%8,getToSquare()/8,getPiece()))

 s+=getFromCor()+takeBit;

 if(getPiece()=='P' || getPiece()=='p')

if( !getFromCor().substring(0,1).equals( getToCor().substring(0,1) ) ) {

 s+=getFromCor().substring(0,1)+"x";

 if(!take) ep=true;

}

 if(take && s.length()>=1){

if(s.charAt(s.length()-1) != 'x')

 s+="x";

 }

}

s+=getToCor();

if(ep)

 s+=" ep.";

/** Is it a check? **/

if(isCheck(isWhite())) s+='+';

return s;

 }

 boolean isCheck(boolean white){

int k=-1;

int K=-1;

for(int i=0;i<64;i++){

 if(to.getAfter().getPieceAt(i%8,i/8) == 'k') k=i;

 if(to.getAfter().getPieceAt(i%8,i/8) == 'K') K=i;

}

boolean check=false;

if(white){

 if(findQueenLength(k%8,k/8,'Q')) check=true;

 if(findRookLength(k%8,k/8,'R')) check=true;

 if(findBishopLength(k%8,k/8,'B')) check=true;

 if(findNightLength(k%8,k/8,'N')) check=true;

 if(findPawnLength(k%8,k/8,'P')) check=true;

}

else{

 if(findQueenLength(K%8,K/8,'q')) check=true;

 if(findRookLength(K%8,K/8,'r')) check=true;

 if(findBishopLength(K%8,K/8,'b')) check=true;

 if(findNightLength(K%8,K/8,'n')) check=true;

 if(findPawnLength(K%8,K/8,'p')) check=true;

}

return check;

 }

 /** Is there a night on a night-distance from square? **/

 boolean findNightLength(int x, int y,char n){

rdgtFenboard b = to.getAfter();

if(b.getPieceAt(x-1,y-2) == n) return true;

if(b.getPieceAt(x+1,y-2) == n) return true;

if(b.getPieceAt(x-2,y-1) == n) return true;

if(b.getPieceAt(x+2,y-1) == n) return true;

if(b.getPieceAt(x-2,y+1) == n) return true;

if(b.getPieceAt(x+2,y+1) == n) return true;

if(b.getPieceAt(x-1,y+2) == n) return true;

if(b.getPieceAt(x+1,y+2) == n) return true;

return false;

 }

 boolean findRookLength(int x, int y, char r){

rdgtFenboard b = to.getAfter();

int xx=0;

int yy=0;

do{

 xx++;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

xx=0;

do{

 xx--;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

xx=0;

do{

 yy--;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

yy=0;

do{

 yy++;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

return false;

 }

 boolean findBishopLength(int x, int y, char r){

rdgtFenboard b = to.getAfter();

int xx=0;

int yy=0;

do{

 xx++;

 yy++;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

xx=0;

yy=0;

do{

 xx--;

 yy--;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

xx=0;

yy=0;

do{

 yy--;

 xx++;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

yy=0;

xx=0;

do{

 yy++;

 xx--;

 if(b.getPieceAt(x+xx,y+yy) == r) return true;

}while(b.getPieceAt(x+xx,y+yy) == '.');

return false;

 }

 boolean findQueenLength(int x, int y, char q){

if(findRookLength(x,y,q)) return true;

if(findBishopLength(x,y,q)) return true;

return false;

 }

 boolean findPawnLength(int x, int y, char p){

rdgtFenboard b = to.getAfter();

if(p=='P'){

 if(b.getPieceAt(x-1,y-1)==p) return true;

 if(b.getPieceAt(x+1,y-1)==p) return true;

}

else {

 if(b.getPieceAt(x-1,y-1)==p) return true;

 if(b.getPieceAt(x+1,y-1)==p) return true;

}

return false;

 }

 public String toString(){

return ""+from.toString() + "-" + to.toString();

 }

 public boolean equals(move other){

if(!from.equals( other.getFrom() )) return false;

if(!to.equals( other.getTo() )) return false;

return true;

 }

 String pos2xy(int pos){

 String s = "" + (char)((pos)%8+'a') + "" + (8-pos/8);

 return s;

 }

}

class movelist {

 ArrayList moves;

 boolean unique;

 boolean noSmooth;

public void clear(){moves.clear(); }

public void remove(int n) { moves.remove(n); }

public movelist(){ moves=new ArrayList(); unique=false; }

public movelist(boolean unique, boolean noSmooth) {

moves=new ArrayList();

this.unique=unique;

this.noSmooth=noSmooth;

 }

 public move get(int n){ return (move)moves.get(n); }

 public int size() { return moves.size(); }

 public String toString() { return getAll(false,false); }

 public void print(boolean shortNotation) {

System.out.println("Moves");

System.out.print(getAll(shortNotation,true));

 }

 void fixTakes(){

for(int i=1;i<moves.size();i++){

 int toSquare = ((move)moves.get(i)).getToSquare();

 char p = (char) ((move)moves.get(i-1)).getTo().getAfter().getBoard()[toSquare];

 if(p!='.'){

move m=(move)moves.get(i);

m.setTake(true);

moves.set(i,m);

 }

}

 }

 

 public String getAll(boolean shortNotation,boolean nice){

fixTakes();

String output="";

boolean lastColor=false;

int n=1;

for(int i=0;i<moves.size();i++){

 move m=(move)moves.get(i);

 if(m.isWhite() && lastColor==false){

if(nice)

 output += n+".\t";

else

 output += n+". ";

n++;

 }

 if(n==1 && !m.isWhite()) {

if(nice)

 output += "1.\t...\t\t";

else

 output += "1. ... ";

 }

 lastColor=m.isWhite();

 int length=output.length();

 if(shortNotation)

output += m.shortNotation()+" ";

 else

output += m.longNotation()+" ";

 if(nice){

if(!m.isWhite())

 output += "\n";

else{

 if(output.length()-length < 8) output += "\t";

 if(output.length()-length < 12) output += "\t";

}

 }

}

return output;

 }

public void add(move aMove){

if(!unique){

 moves.add(aMove);

 return;

}

for(int i=0;i<moves.size();i++){

 if( ((move)moves.get(i)).equals(aMove))

return;

}

if(moves.size()>=1){

 move m=(move)moves.get(moves.size()-1);

 // O-O

 if(m.moveString(false).equals("Ke1-g1") && aMove.moveString(false).equals("Rh1-f1")){

moves.remove(moves.size()-1);

moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O"));

return;

 }

 // O-O-O

 if(m.moveString(false).equals("Ke1-c1") && aMove.moveString(false).equals("Ra1-d1")){

moves.remove(moves.size()-1);

moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O-O"));

return;

 }

 // O-O

 if(m.moveString(false).equals("Ke8-g8") && aMove.moveString(false).equals("Rh8-f8")){

moves.remove(moves.size()-1);

moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O"));

return;

 }

 // O-O-O

 if(m.moveString(false).equals("Ke8-c8") && aMove.moveString(false).equals("Ra8-d8")){

moves.remove(moves.size()-1);

moves.add(new move(aMove.getFrom(),aMove.getTo(),"O-O-O"));

return;

 }

}

moves.add(aMove);

 }

 public void removeSmooth(){

for(int a=0;a<moves.size();a++){

 move aMove=(move)moves.get(a);

 for(int i=0;i<moves.size();i++){

move test = (move)moves.get(i);

if( test.getPiece() == aMove.getPiece()){

 if( aMove.getFrom().getSquare() == test.getTo().getSquare() ||

 aMove.getTo().getSquare() == test.getFrom().getSquare() ){

if(a==i){

 moves.remove(i);

 i=moves.size();

 a=0;

}

else if(i>a){

 moves.remove(i);

 moves.remove(a);

 i=moves.size();

 a=0;

}

else {

 moves.remove(a);

 moves.remove(i);

 i=moves.size();

 a=0;

}

 }

}

 }

 }

 }

}

rdgtHistory.java

---

class rdgtHistory {

Vector history = new Vector();

rdgtSnapshot lastadded = null;

rdgtSnapshot last = null;

rdgtChessboard board;

public rdgtHistory(rdgtChessboard _board) {

board = _board;

}

void append(rdgtSnapshot x) {

if(history.size()==0){

history.addElement(x.copy());

board.update_html();

}

else if(x.sameas((rdgtSnapshot)history.lastElement())==false ){

history.addElement(x.copy());

board.update_html();

}

}

void debugprint() {

System.out.println("======= History for board: "+board.address.toString());

for (Enumeration e = history.elements(); e.hasMoreElements() ;) {

((rdgtSnapshot)(e.nextElement())).debugprint();

}

}

}

rdgtHtml.java

---

class rdgtHtml extends rdgtProtocol {

static String extension = ".html";

static String indexfilename = "board_index";

static String historyprefix = "boardhistory_";

static String snapshotprefix = "boardsnapshot_";

static void print_index(rdgtDatabase db) {

StringBuffer s = new StringBuffer(2000);

s.append("<html>\n<head>\n <meta http-equiv=refresh content=3>\n</head>\n");

s.append("<body><h1>Chessboards</h1>\n<table border=1 cellspacing=0 cellpadding=10>\n");

s.append("<tr><th>Board id<th>Status<th>Time of last move<th>Snapshot<th>History\n");

for (Enumeration e = db.get_boards() ; e.hasMoreElements() ;) {

rdgtChessboard b = (rdgtChessboard)(e.nextElement());

s.append("<tr>\n<td valign=top>");

s.append(Integer.toString(b.get_address()));

s.append("\n<td>");

if (b.get_alive()==true) s.append("Online"); else s.append("Offline");

s.append("<td>");

s.append(b.get_snapshot().get_time().toString());

s.append("\n<td><a href=\"");

s.append(snapshotprefix);

s.append(Integer.toString(b.get_address()));

s.append(extension);

s.append("\">Link</a><td><a href=\"");

s.append(historyprefix);

s.append(Integer.toString(b.get_address()));

s.append(extension);

s.append("\">Link</a>\n");

}

s.append("</table>\n</body>\n</html>\n");

if (writefile(indexfilename+extension, s.toString()) == false) {

System.err.println("Error: Failed to write indexfile.");

return;

}

}

static void print_history(rdgtHistory h) {

StringBuffer s = new StringBuffer(2000);

s.append("<html>\n<head></head>\n");

s.append("<body><h1>History for Chessboard: ");

s.append(Integer.toString(h.board.get_address()));

s.append("</h1>\n");

int i = 0;

for (Enumeration e = h.history.elements() ; e.hasMoreElements() ;) {

rdgtSnapshot ss = (rdgtSnapshot)(e.nextElement());

i=i+1;

s.append("<p><hr size=1><p><h3>Move: ");

s.append(Integer.toString(i));

s.append(" &nbsp; &nbsp;");

s.append(ss.get_time().toString());

s.append(boardview(ss));

s.append("\n");

}

s.append("</body>\n</html>\n");

if (writefile(historyprefix + Integer.toString(h.board.get_address()) + extension, s.toString()) == false) {

System.err.println("Error: Failed to write historyfile.");

return;

}

}

static String boardview(rdgtSnapshot b) {

StringBuffer s = new StringBuffer(1000);

s.append("<table border=0 cellpadding=0 cellspacing=0>\n");

boolean filled = true;

for (int i=0; i<8; i=i+1) {

s.append("<tr>");

for (int j=0; j<8; j=j+1) {

s.append("<td><img src=\"images/");

int p = b.pieces[(i*8)+j];

if (p==EMPTY ) s.append("empty");

else if (p==WPAWN ) s.append("w_pawn");

else if (p==WROOK ) s.append("w_rook");

else if (p==WKNIGHT) s.append("w_knight");

else if (p==WBISHOP) s.append("w_bishop");

else if (p==WKING ) s.append("w_king");

else if (p==WQUEEN ) s.append("w_queen");

else if (p==BPAWN ) s.append("b_pawn");

else if (p==BROOK ) s.append("b_rook");

else if (p==BKNIGHT) s.append("b_knight");

else if (p==BBISHOP) s.append("b_bishop");

else if (p==BKING ) s.append("b_king");

else if (p==BQUEEN ) s.append("b_queen");

if (filled) s.append("1"); else s.append("2");

filled = !filled;

s.append(".gif\">");

}

filled = !filled;

s.append("</tr>\n");

}

s.append("\n</table>");

return s.toString();

}

static void print_snapshot(rdgtSnapshot ss) {

StringBuffer s = new StringBuffer(2000);

s.append("<html>\n<head>\n <meta http-equiv=refresh content=4>\n</head>\n");

s.append("<body><h1>Snapshot of Chessboard: ");

s.append(Integer.toString(ss.board.get_address()));

s.append("</h1>\n<h3>");

s.append(ss.get_time().toString());

s.append("</h3>\n");

s.append(boardview(ss));

s.append("\n</body>\n</html>\n");

if (writefile(snapshotprefix + Integer.toString(ss.board.get_address()) + extension, s.toString()) == false) {

System.err.println("Error: Failed to write snapshotfile.");

return;

}

}

static boolean writefile(String filename, String content) {

FileWriter f = null;

for (int i=0; i<10; i=i+1) {

try {

f = new FileWriter(filename);

break;

}

catch (Throwable t) {

System.err.println("Error opening "+filename+" for writing. Retrying...");

}

}

if (f==null) {

System.out.println("Failed to open file "+filename);

return false;

}

try {

f.write(content);

f.close();

}

catch (Exception e) {

System.out.println("Error writing file "+filename+". ("+e.toString()+")");

return false;

}

return true;

}

}

rdgtInterpreter.java

---

class rdgtInterpreter extends rdgtProtocol {

 rdgtDatabase db;

 public rdgtInterpreter(rdgtDatabase _db) {

 db = _db;

 }

 public boolean interpret(int[] data) {

 int len = ((int) data[1] * 0x80) + (int) data[2];

 int address = ((int) data[3] * 0x80) + (int) data[4];

 String tmp = "Len:" + Integer.toString(len) + " Address:" + Integer.toString(address);

 if (data[0] == DGT_BUS_PING) {

 System.out.println("Received message: PING " + tmp);

 } else if (data[0] == DGT_BUS_UPDATE) {

 System.out.println("Received message: UPDATE " + tmp);

 } else if (data[0] == DGT_BUS_BWTIME) {

 System.out.println("Received message: BWTIME " + tmp);

 } else {

 System.out.println("Received message: (some other message) " + tmp);

 }

 if (check_checksum(data) == false) {

 System.out.println("Message failed checksum test");

 return false;

 }

 if (data[0] == DGT_BUS_PING) {

 if (data.length != 6) { // address+data

 System.out.println("Illegal: Got a BUS_PING with wrong size");

 return false;

 }

 db.get_board(address).set_alive(true);

 return true;

 } else if (data[0] == DGT_BUS_BRD_DUMP) {

 if (data.length != (6 + 64)) {

 System.out.println("Illegal: Got a BUS_BRD_DUMP with wrong size");

 return false;

 }

 rdgtChessboard c = db.get_board(address);

 c.set_boarddump(data, 5);

 return true;

 } else if (data[0] == DGT_BUS_UPDATE) {

 byte pr[] = new byte[data.length - 5];

 for (int i = 5; i < data.length; i++) {

 pr[i - 5] = (byte) data[i];

 }

System.out.println(new String(pr));

 rdgtChessboard c = db.get_board(address);

 for (int i = 5; i < data.length - 1; i++) {

 if (data[i] == EE_POWERUP) {

 }

 else if (data[i] == EE_EOF) {

 }

 else if (data[i] == EE_FOURROWS) {

 }

 else if (data[i] == EE_EMPTYBOARD) {

 c.set_emptyboard();

 } else if (data[i] == EE_DOWNLOADED) {

 }

 else if (data[i] == EE_BEGINPOS) {

 }

 else if (data[i] == EE_BEGINPOS_ROT) {

 }

 else if (data[i] == EE_START_TAG) {

 }

 else if (data[i] == EE_WATCHDOG_ACTION) {

 }

 else if (data[i] == EE_NOP) {

 }

 else if (data[i] >= 0x40 && data[i] <= 0x5F) { // 2-byte piece update

 c.set_fieldupdate(data[i] & 0x0F, data[i + 1]);

 i++;

 } else if ((data[i] >= 0x60 && data[i] <= 0x69) || (data[i] >= 0x70 && data[i] <= 0x79)) {

 i += 2;

 } else {

 System.out.println("Unknown data in DGT_BUS_UPDATE command.");

 return false;

 }

 }

 c.set_updated(true);

 return true;

 }

 else if (data[0] == DGT_BUS_BWTIME) {

 if (data.length != 13) {

 System.out.println("Illegal: Got a DGT_BUS_BWTIME with wrong size (!=10)");

 return false;

 }

 if ((data[11] & 0x20) != 0) {

 System.out.println("(No clock connected)");

 return true;

 }

 boolean running = (data[11] & 0x01) != 0;

 boolean batteryLow = (data[11] & 0x04) != 0;

 boolean frontViewLeftSideHigh = (data[11] & 0x02) != 0;

 boolean blackPlayersTurn = (data[11] & 0x08) != 0;

 boolean whitePlayersTurn = (data[11] & 0x10) != 0;

 int hoursW = data[5] & 0x0F;

 int minutesW = (data[6] & 0x0F) + ((data[6] >> 4) * 10);

 int secondsW = (data[7] & 0x0F) + ((data[7] >> 4) * 10);

 int hoursB = data[8] & 0x0F;

 int minutesB = (data[9] & 0x0F) + ((data[9] >> 4) * 10);

 int secondsB = (data[10] & 0x0F) + ((data[10] >> 4) * 10);

 secondsW = (((hoursW * 60) + minutesW) * 60) + secondsW;

 secondsB = (((hoursB * 60) + minutesB) * 60) + secondsB;

 db.get_board(address).set_clockdata(running, batteryLow, frontViewLeftSideHigh,

 blackPlayersTurn, whitePlayersTurn, secondsW, secondsB);

 return true;

 } else if (data[0] == DGT_BUS_FROM_START) {

 } else if (data[0] == DGT_BUS_START_GAME_WRITTEN) {

 } else if (data[0] == DGT_BUS_VERSION) {

 }

 System.err.println("Unknown message (checksum was ok).");

 return true;

 }

 boolean check_checksum(int[] data) {

 int sum = 0;

 for (int i = 0; i < (data.length - 1); i = i + 1) {

 sum = (sum + data[i]) & 0x7F;

 }

 if (sum == data[data.length - 1]) {

 return true;

 }

 return false;

 }

}

rdgtMysql.java

---

class rdgtMysql extends rdgtProtocol {

static String server= "localhost";

static String user= "root";

static String pass= "zar1562";

static String dbase= "rdgt_development";

static String update_table= "games";

 static Connection conn = null;

 static Statement stmt = null;

 static boolean rotated=false;

 static String connect()

{

try

{

Class.forName("com.mysql.jdbc.Driver").newInstance();

conn = DriverManager.getConnection("jdbc:mysql://"+server+"/"+dbase+"?user="+user+"&password="+pass);

return "";

}

catch (SQLException e)

{

return e.getSQLState();

}

catch (Exception e)

{

return "0";

}

}

static boolean disconnect()

{

if (conn != null) {

try

{

conn.close();

return true;

}

catch (SQLException SQLE)

{

return false;

}

}

else

return false;

}

static String execute(String expr)

{

try

{

stmt = null;

stmt = conn.createStatement();

stmt.executeUpdate(expr);

return "";

}

catch (SQLException e)

{

return e.getSQLState();

}

catch (Exception e)

{

return "0";

}

finally

{

if (stmt != null) {

try

{

stmt.close();

}

catch (SQLException SQLE)

{

;

}

}

}

}

static String snapshot2fen (rdgtSnapshot b)

{

StringBuffer s = new StringBuffer(100);

int counter = 0;

for (int i=0; i<8; i++)

{

for (int j=0; j<8; j++)

{

if ((counter != 0) && (b.pieces[(i*8)+j] != EMPTY))

{

s.append(counter);

counter = 0;

}

switch(b.pieces[(i*8)+j])

{

case WPAWN:s.append("P"); break;

case WROOK: s.append("R"); break;

case WKNIGHT: s.append("N"); break;

case WBISHOP: s.append("B"); break;

case WKING: s.append("K"); break;

case WQUEEN: s.append("Q"); break;

case BPAWN: s.append("p"); break;

case BROOK: s.append("r"); break;

case BKNIGHT: s.append("n"); break;

case BBISHOP: s.append("b"); break;

case BKING: s.append("k"); break;

case BQUEEN: s.append("q"); break;

default: counter++; break;

}

}

if (counter != 0)

s.append(counter);

s.append("/");

counter = 0;

}

String outfen= s.toString().substring(0,s.toString().length()-1);

switch(b.board.address.intValue()){

case 3737:

case 3811:

case 2896:

case 3740:

case 3588:

case 2897:

default:

 rotated=false; break;

}

if(rotated){

 String newFen="";

 for(int i=outfen.length()-1;i>=0;i--){

newFen += outfen.charAt(i);

 }

 outfen=newFen;

}

return outfen;

}

static void update_snapshot(rdgtSnapshot b)

{

if (conn != null)

{

String fen = snapshot2fen(b);

String turn;

if(rotated){

 if(b.isWhiteTurn()) turn="Black";

 else turn="White";

}

else{

 if(b.isWhiteTurn()) turn="White";

 else turn="Black";

}

String sql_command = "UPDATE "+update_table+" SET fen = '"+fen+"',wtime='"+b.getTimeWhite()+"',btime='"+b.getTimeBlack()+"',turn='"+turn+"' WHERE dgt_active like '%Fen%' AND dgt_board = "+b.board.address;

execute(sql_command);

System.out.println(b.board.address+" "+fen+" "+b.getTimeWhite()+" "+b.getTimeBlack()+" "+turn.substring(0,1));

}

}

static void update_moves(String moves, String movestable, int board_id)

{

if (conn != null)

{

 int t=0;

 if(moves.length()>20) t=moves.length()-20;

 System.out.println(board_id + " Moves: " + moves.substring(t));

String sql_command = "UPDATE games SET moves = '"+moves+"' WHERE dgt_active like '%Moves%' AND dgt_board = "+board_id;

execute(sql_command);

}

}

}

rdgtProtocol.java

---

class rdgtProtocol {

static int DGT_TO_BUSMODE = 0x4a;

static int DGT_BUS_SEND_CLK = 0x01 | 0x80;

static int DGT_BUS_SEND_BRD = 0x02 | 0x80;

static int DGT_BUS_SEND_CHANGES = 0x03 | 0x80;

static int DGT_BUS_REPEAT_CHANGES = 0x04 | 0x80;

static int DGT_BUS_SET_START_GAME = 0x05 | 0x80;

static int DGT_BUS_SEND_FROM_START = 0x06 | 0x80;

static int DGT_BUS_PING = 0x07 | 0x80;

static int DGT_BUS_END_BUSMODE = 0x08 | 0x80;

static int DGT_BUS_RESET = 0x09 | 0x80;

static int DGT_BUS_IGNORE_NEXT_BUS_PING = 0x0a | 0x80;

static int DGT_BUS_SEND_VERSION = 0x0b | 0x80;

static int DGT_BUS_BRD_DUMP = 0x03 | 0x80;

static int DGT_BUS_BWTIME = 0x04 | 0x80;

static int DGT_BUS_UPDATE = 0x05 | 0x80;

static int DGT_BUS_FROM_START = 0x06 | 0x80;

static int DGT_BUS_START_GAME_WRITTEN = 0x08 | 0x80;

static int DGT_BUS_VERSION = 0x09 | 0x80;

static boolean is_busmessage(int m) {

return (m== DGT_BUS_BRD_DUMP || m == DGT_BUS_BWTIME ||

m == DGT_BUS_UPDATE || m == DGT_BUS_FROM_START || m == DGT_BUS_PING ||

m == DGT_BUS_START_GAME_WRITTEN || m == DGT_BUS_VERSION);

}

static final int EMPTY = 0x00;

static final int WPAWN = 0x01;

static final int WROOK = 0x02;

static final int WKNIGHT = 0x03;

static final int WBISHOP = 0x04;

static final int WKING = 0x05;

static final int WQUEEN = 0x06;

static final int BPAWN = 0x07;

static final int BROOK = 0x08;

static final int BKNIGHT = 0x09;

static final int BBISHOP = 0x0a;

static final int BKING = 0x0b;

static final int BQUEEN = 0x0c;

boolean is_piece(int p) {

return (p==EMPTY || p==WPAWN || p==WROOK ||

 p==WKNIGHT || p==WBISHOP || p==WKING ||

 p==WQUEEN || p==BPAWN || p==BROOK ||

 p==BKNIGHT || p==BBISHOP || p==BKING ||

 p==BQUEEN);

}

static int EE_POWERUP = 0x6a;

static int EE_EOF = 0x6b;

static int EE_FOURROWS = 0x6c;

static int EE_EMPTYBOARD = 0x6d;

static int EE_DOWNLOADED = 0x6e;

static int EE_BEGINPOS = 0x6f;

static int EE_BEGINPOS_ROT = 0x7a;

static int EE_START_TAG = 0x7b;

static int EE_WATCHDOG_ACTION = 0x7c;

static int EE_NOP = 0x7f;

}

rdgtReceiver.java

---

class rdgtReceiver extends rdgtProtocol {

int messagetype;

int messagelen_msb;

int messagelen_lsb;

int[] data;

int useddata;

int state;

rdgtInterpreter interpreter;

public rdgtReceiver(rdgtInterpreter _interpreter) {

state = 0;

interpreter = _interpreter;

}

void receive(int[] d) {

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

StringBuffer x = new StringBuffer("Received: ");

for (int i=0; i<d.length; i=i+1) {

x.append(c[d[i]>>4]).append(c[d[i] & 0x0F]).append(" ");

}

if (rdgtChess.debug) System.out.println(x.toString());

_receive (d, 0);

}

void _receive(int[] d, int start) {

if (start == d.length) return;

if (state == 0) { // Find a known messageid.

while (start<d.length) {

if (is_busmessage(d[start])) {

messagetype = d[start];

state = 1;

_receive(d,start+1);

return;

}

System.err.println("Did not understand 1 byte of incoming data.");

start = start + 1;

}

return;

}

if (state == 1) {

if ((d[start] & 0x80) > 0) {

System.err.println("Did not understand 2 bytes of incoming data.");

state = 0;

_receive(d, start);

return;

}

messagelen_msb = d[start];

state = 2;

start = start + 1;

}

if (start == d.length) return;

if (state == 2) {

if ((d[start] & 0x80) > 0) {System.err.println("Did not understand 3 bytes of incoming data.");

state = 0;

_receive(d, start);

return;

}

messagelen_lsb = d[start];

state = 3;

start = start + 1;

int newlen = ((int)messagelen_msb * 0x80) + (int)messagelen_lsb;

if (newlen <5) {

System.out.println("Too small message length: " + Integer.toString(newlen));

state = 0;

_receive(d, start);

return;

}

data = new int[newlen];

data[0] = messagetype;

data[1] = messagelen_msb;

data[2] = messagelen_lsb;

useddata = 3;

}

if (start == d.length) return;

if (state == 3) {

while (start<d.length && useddata<data.length) {

data[useddata]=d[start];

start = start + 1;

useddata = useddata + 1;

}

if (useddata == data.length) {

interpreter.interpret(data);

start = start + 1;

data = null;

state = 0;}

}

_receive(d, start);

}

}

rdgtSender.java

---

class rdgtSender extends rdgtProtocol {

rdgtSerialport com;

public rdgtSender(rdgtSerialport _com) {

com = _com;

}

void send(int message, int address) {

String tmp = "Address:"+Integer.toString(address);

System.out.println();

if (message==DGT_TO_BUSMODE) System.out.println("Sending message: SWITCH TO BUSMODE "+tmp);

else if (message==DGT_BUS_SEND_BRD) System.out.println("Sending message: SEND BOARD "+tmp);

else if (message==DGT_BUS_SEND_CHANGES) System.out.println("Sending message: SEND CHANGES "+tmp);

else if (message==DGT_BUS_REPEAT_CHANGES) System.out.println("Sending message: REPEAT CHANGES "+tmp);

else if (message==DGT_BUS_PING) System.out.println("Sending message: PING "+tmp);

else if (message==DGT_BUS_IGNORE_NEXT_BUS_PING) System.out.println("Sending message: IGNORE NEXT PING "+tmp);

else System.out.println("Sending message: (some other message)");

byte x[] = new byte[4];

x[0] = (byte)message;

x[1] = (byte)((address>>7) & 0x7F);

x[2] = (byte)(address & 0x7F);

x[3] = (byte)(((int)x[0]+(int)x[1]+(int)x[2]) & 0x7F);

 com.write(x);

}

}

rdgtSerialport.java

---

class rdgtSerialport implements SerialPortEventListener {

static CommPortIdentifier portid;

InputStream inStream;

OutputStream outStream;

SerialPort serialPort;

rdgtReceiver receiver;

public rdgtSerialport(rdgtReceiver r) {

receiver = r;

}

public boolean open(String portname) {

CommPortIdentifier id = null;

Enumeration portList;

portList = CommPortIdentifier.getPortIdentifiers();

System.out.println(portList.toString());

while (portList.hasMoreElements()) {

System.out.println("2");

id = (CommPortIdentifier) portList.nextElement();

if (id.getPortType() == CommPortIdentifier.PORT_SERIAL) {

System.out.println("Ports: "+id.getName());

if (id.getName().equals(portname)) break; // found

}

id = null;

}

if (id == null) return false; // not found

try {

serialPort = (SerialPort) id.open("ttchess", 2000);

inStream = serialPort.getInputStream();

outStream = serialPort.getOutputStream();

serialPort.addEventListener(this);

serialPort.notifyOnDataAvailable(true);

serialPort.setSerialPortParams(9600, SerialPort.DATABITS_8,

SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);

serialPort.setDTR(false);

serialPort.setRTS(false);

} catch (Exception e) { return false; }

return true;

}

public boolean write(byte[] data) {

char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

StringBuffer x = new StringBuffer(" Sending: ");

for (int i=0; i<data.length; i=i+1) {

int d = data[i];

if (d<0) d=256+d;

x.append(c[d>>4]).append(c[d & 0x0F]).append(" ");

}

if (rdgtChess.debug) System.out.println(x.toString());

try {

outStream.write(data);

} catch (IOException e) { return false; }

return true;

}

public void serialEvent(SerialPortEvent event) {

switch(event.getEventType()) {

case SerialPortEvent.OUTPUT_BUFFER_EMPTY:

break;

case SerialPortEvent.DATA_AVAILABLE:

byte[] readBuffer = new byte[200];

try {

while (inStream.available() > 0) {

int numBytes = inStream.read(readBuffer);

if (numBytes>0) {

int[] buf = new int[numBytes];

for (int i=0; i<numBytes; i=i+1) {

int tmp = readBuffer[i];

if (tmp<0) tmp=256+tmp;

buf[i]=tmp;

}

receiver.receive(buf);

}

}

} catch (IOException e) {}

break;

}

}

}

rdgtSnapshot.java

---

class rdgtSnapshot extends rdgtProtocol {

int[] pieces = new int[64];

Date time;

rdgtChessboard board;

boolean clkRunning, clkBatteryLow, clkFrontViewLeftSideHigh, clkBlackTurn, clkWhiteTurn;

int clkSecWhite, clkSecBlack;

public rdgtSnapshot(rdgtChessboard _board) {

time = new Date();

board = _board;

set_emptyboard();

}

public rdgtSnapshot(rdgtSnapshot x) {

for (int i=0; i<64; i=i+1) pieces[i] = x.pieces[i];

time = x.time;

board = x.board;

clkRunning = x.clkRunning;

clkBatteryLow = x.clkBatteryLow;

clkFrontViewLeftSideHigh = x.clkFrontViewLeftSideHigh;

clkBlackTurn = x.clkBlackTurn;

clkWhiteTurn = x.clkWhiteTurn;

clkSecWhite = x.clkSecWhite;

clkSecBlack = x.clkSecBlack;

}

rdgtSnapshot copy() {

return new rdgtSnapshot(this);

}

void set_clockdata(boolean running, boolean batteryLow, boolean frontViewLeftSideHigh,

boolean blackTurn, boolean whiteTurn, int secW, int secB) {

clkRunning = running;

clkBatteryLow = batteryLow;

clkFrontViewLeftSideHigh = frontViewLeftSideHigh;

clkBlackTurn = blackTurn;

clkWhiteTurn = whiteTurn;

clkSecWhite = secW;

clkSecBlack = secB;

}

public boolean sameas(rdgtSnapshot x) {

for (int i=0; i<64; i=i+1) if (pieces[i] != x.pieces[i]) return false;

return true;

}

Date get_time() { return time; }

void set_emptyboard() {

time = new Date();

for (int i=0; i<64; i=i+1) pieces[i]=EMPTY;

}

void set_boarddump(int[] all64, int startpos) {

time = new Date();

for (int i=0; i<64; i=i+1) {

int p = all64[i+startpos];

if (is_piece(p)==false) {

System.out.println("Confused: Boarddump contained an unknown piece");

pieces[i]=EMPTY;

} else {

pieces[i]=p;

}

}

}

void set_fieldupdate(int piece, int pos) {

time = new Date();

if (pos <0 || pos > 63) {

System.out.println("Confused: Fieldupdate for pos outside 0..63");

return;

}

if (is_piece(piece)==false) {

System.out.println("Confused: Fieldupdate with an unknown piece");

return;

}

pieces[pos]=piece;

}

String seconds2hms(int s) {

return Integer.toString(s/36000)+Integer.toString((s%36000)/3600)+":"+

Integer.toString((s%3600)/600)+Integer.toString((s%360)/60)+":"+

Integer.toString((s%60)/10)+Integer.toString(s%10);

}

String debugprint_clock() {

StringBuffer s = new StringBuffer(50);

s.append("Clock: White "); s.append(seconds2hms(clkSecWhite));

s.append(" Black "); s.append(seconds2hms(clkSecBlack));

System.out.println(s);

 return s.toString();

}

String getTimeWhite(){

return seconds2hms(clkSecWhite);

}

String getTimeBlack(){

return seconds2hms(clkSecBlack);

}

boolean isWhiteTurn(){

return clkFrontViewLeftSideHigh;

}

String debugprint() {

debugprint_clock();

StringBuffer s = new StringBuffer(300);

for (int i=0; i<8; i=i+1) {

for (int j=0; j<8; j=j+1) {

int p = pieces[(i*8)+j];

if (p==EMPTY ) s.append(".");

if (p==WPAWN ) s.append("P");

if (p==WROOK ) s.append("R");

if (p==WKNIGHT) s.append("N");

if (p==WBISHOP) s.append("B");

if (p==WKING ) s.append("K");

if (p==WQUEEN ) s.append("Q");

if (p==BPAWN ) s.append("p");

if (p==BROOK ) s.append("r");

if (p==BKNIGHT) s.append("n");

if (p==BBISHOP) s.append("b");

if (p==BKING ) s.append("k");

if (p==BQUEEN ) s.append("q");

}

s.append("\n");

}

System.out.println(s);

 return s.toString();

}

}


Приложение Д

Снимки экрана

Д.1 Снимок экрана главной страницы сервера трансляции шахматных партий rDGT

 

Д.2 Снимок экрана страницы авторизации пользователя

Д.3 Снимок экрана страницы просмотра текущих online трансляций

Д.4 Снимок экрана страницы просмотра шахматной партии


Приложение Е

Протокол DGT

#ifndef dgtbrd13

#define dgtbrd13

/*

Protocol description for DGT chess board.

Copyright 1998 DGT Projects B.V

Version: 1.03 Single computer and bus support in one .h file

*********************************************************

This protocol is protected under trade mark registration and copyrights.

It may not be used commercially without written permission

of DGT Projects B.V. It is illegal to transfer any registered trade mark

identifications by means of this protocol between any chessboard or other

application and any computer.

*********************************************************

Main functionality of the DGT Electronic Chess Board

----------------------------------------------------

The DGT board is basically a sensor which senses the presense of the special

chess set pieces on the squares of the board. The situation on the board is

measured and can be communicated with an average maximum time delay of

200 mS.

Besides this detection function, the board communicates with an optional

DGT TopMatch Chess Clock, to give the data of the clock available to the

general interface.

Finally the board is equipped with an internal storage of the measured

piece positions.

The board supports two methods of communication: for single-board situations

a protocol for communication between one board and one computer is available.

For situations with many boards a network communications protocol is

available, where many boards can be connected in a bus structure. A separate

communication protocol is available for this bus structure.

The communication protocol for single board connections is described

in the following paragraph "Single board communication protocol". This

paragraph describes much more than only the communication protocol. All

developers should read this paragraph, even if they would only use bus

communication.

The special bus communication protocol is derived from the single board

communication and functionality, where the main added feature is the

possibility to address a specific board on a shared communication bus.

The commands and data contens are described in the paragraph "Bus

Communication Protocol", Note however that the contens can not be understood

without reading the single board communication paragraph.

Paragraph: Single board communication protocol

----------------------------------------------

The main function of the board is to transfer piece position information.

For this, three modes are available:

1. IDLE mode. This cancelles any of the two UPDATE modes. No automatic

transfer of moves.

2. UPDATE_BOARD mode. On the moment that the board detects a removal, change

or placing of a piece, it outputs a DGT_SEND_UPDATE message

3. UPDATE mode. As UPDATE_BOARD mode, where additional the clock data are send

regularly (at least every second)

The board accepts command codes from the computer RS232. The commands are

1-byte codes, sometimes followed by data (see code definition)

The board can send data to the computer. Data always carries a message header.

The message header contains a message code and the total message size in bytes.

The start of the incoming message can be recognised by the MSB of the message

identifier set to 1 (see definition).

Board to computer communication interfaces:

RS232 for communication with computer, receiving commands, sending data

- 9600 Baud, 1 stopbit, 1 startbit, no parity

- No use of handshaking, neither software nor hardware

Connection between Digital Game Timer TopMatch Clock and the board:

Based on NEC SBI protocol. Adaption of the definition given in

the DGT TopMatch documentation.

Connector assignments for DGT Electronic Board: See User

and Programmers Manual

Related to the before mentioned modes, and to piece position information

transfer, the following commands to the board are available:

1. DGT_SEND_RESET

puts the DGT Board in IDLE mode

2. DGT_SEND_CLK

on which the DGT board responds with a DGT_MSG_BWTIME message containing clock

information

3. DGT_SEND_BRD

on which the DGT Board responds with a DGT_MSG_BOARD_DUMP message containing

the actual piece exising of all fields

4. DGT_SEND_UPDATE puts the DGT Board in the UPDATE mode, FRITZ5 compatible

5. DGT_SEND_UPDATE_BRD puts the DGT Board in the UPDATE_BOARD mode

6. DGT_SEND_UPDATE_NICE puts the board in UPDATE mode, however transferring only clocktimes when any time info changed.

The DGT_SEND_CLK command and the DGT_SEND_BOARD command do not affect the current board

mode: i.e. when in UPDATE mode, it continues sending DGT_SEND_UPDATE messages.

Board Identification:

Each DGT Electronic Board carries a unique serial number,

a EEPROM configuration version number and a embedded program version number.

These data are unalterable by the users.

Current identification is:

"DGT Projects - This DGT board is produced by DGT Projects.\n

DGT Projects is a registered trade mark.\n


Информация о работе «Обеспечение всемирной трансляции спортивных шахматных соревнований с применением разработанного в ходе проекта законченного программного продукта»
Раздел: Информатика, программирование
Количество знаков с пробелами: 290366
Количество таблиц: 23
Количество изображений: 7

Похожие работы

Скачать
524386
0
0

... развития с деспотической властью, облеченную лишь в новую одежду. Преодолеть свойственный для страны традиционализм, развиваться по демократическому пути не удалось. Подтвердилось выдвинутое историками положение об истории России как движении по кругу вместо линейного развития. Контрольные вопросы: 1. Объясните сущность двоевластия. 2. Каков был расклад политических сил и каковы альтернативы ...

0 комментариев


Наверх