Игра "Балда" с поддержкой работы по сети

Общие сведения об игре "Балда", обзор ее аналогов и основные требования, предъявляемые к данному программному продукту. Состав и параметры технических средств, оценка параметров совместимости. Основные классы приложения и их общая характеристика.

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 10.05.2015
Размер файла 381,2 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

Игра "Балда" с поддержкой работы по сети

Введение

программный приложение игра балда

Сетевые игры (игры с сетевой структурой) являются разделом теории игр, который изучает как методы формирования связей между игроками в конфликтно-управляемых системах, так и правила определения выигрышей игроков с учётом этих связей. В основном выделяют три подхода к формированию связей между игроками: стратегический, кооперативный и динамический.

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

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

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

«Балда» -- лингвистическая настольная игра для 2--4 игроков, в которой необходимо составлять слова с помощью букв, добавляемых определённым образом на квадратное игровое поле. В наиболее популярном варианте игры, который имеет множество компьютерных реализаций, слова составляются посредством переходов от буквы к букве под прямым углом.

1. Общие сведения, обзор аналогов и формирование требований к проектируемому программному средству

1.1 Общие сведения об игре «Балда»

В наиболее популярном варианте игровое поле представляет собой 25-клеточную квадратную таблицу, ячейки/клетки центральной строки которой содержат по одной букве, а строка целиком -- произвольное 5-буквенное нарицательное имя существительное в именительном падеже и единственном числе (множественном числе, если слово не имеет единственного числа). Размеры поля, расположение и длина слова могут варьироваться, тем не менее количество пустых клеток в начале игры должно быть чётным, чтобы у обоих игроков было одинаковое количество ходов/слов.

Во время своего хода игрок может добавить букву в клетку, примыкающую по вертикали/горизонтали (в варианте «Королевский квадрат» также по диагонали) к заполненной клетке таким образом, чтобы получалась неразрывная и не самопересекающаяся прямоугольная ломаная («змейка») из клетки с добавленной буквой и других заполненных клеток, представляющая собой слово (соответствующее описанным выше требованиям), или пропустить ход (если оба игрока трижды подряд пропускают ход, то фиксируется ничья). В течение игры должны соблюдаться также следующие правила:

Игроки ходят по очереди (в варианте «Королевский квадрат» для двух игроков ходы двойные, то есть игрок, если не пропускает ход, добавляет подряд две буквы в разные клетки).

Каждая клетка содержит только одну букву, каждая буква в составленном слове приносит игроку одно очко.

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

Слова в одной игре повторяться не могут, даже если это омонимы (в варианте «Королевский квадрат» запрещается составление слов, уже образовавшихся на игровом поле, даже если они не были составлены ни одним из игроков).

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

Рисунок 1.1.1 Игра «Балда». Главное игровое поле.

1.2 Обзор аналогов

1. Андройд-приложения «King Square».

Рисунок 1.2.1 Загрузка приложения King Square

Приложение King Square устанавливается на Андройд платформу.

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

Сетевое взаимодействие осуществляется через сеть-интернет.

Рисунок 1.2.2 Конфигурация игры приложения King Square.

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

Рисунок 1.2.3 Конфигурация игры приложения King Square.

1.3 Требования к проектируемому программному средству

Назначение разработки

Целью разработки приложения является создание приложения, которое представляет собой сетевую игру «Балда» где пользователи могут играть на одном компьютере, либо по сети.

Выполняемые функции

· Выбор режима игры. Доступные режимы:

1. Игра на одном компьютере.

2. Сетевая игра.

· При создании комнаты для игры пользователь может выбрать количество игроков и размер матрицы для ввода слов.

· Приложение может выступать в качестве клиента и сервера одновременно.

· С приложением одновременно могут работать несколько пользователей.

Входные данные

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

Выходные данные

В качестве выходных данных используются скачиваемые файлы, описания файлов.

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

· Процессор: рекомендуемая частота - 1.0 ГГц и выше.

· ОЗУ: не менее 512 Мб.

· Жесткий диск: 32-bit - не менее 850 Мб, 64-bit - не менее 2 Гб.

Требования к программной совместимости

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

· .Net Framework 4.5

1.4 Постановка задачи

В рамках данного курсового проекта необходимо разработать программное средство, представляющее собой сетевую игру «Балда». Это приложение должно выполнять функции, описанные в пункте 1.3.

2. Анализ требований к ПС и разработка функциональных требований

2.1 Обоснование выбора технологий

Платформа.NET Framework состоит из общеязыковой среды выполнения (среды CLR) и библиотеки классов.NET Framework. Основой платформы.NET Framework является среда CLR. Среду выполнения можно считать агентом, который управляет кодом во время выполнения и предоставляет основные службы, такие как управление памятью, управление потоками и удаленное взаимодействие. При этом накладываются условия строгой типизации и другие виды проверки точности кода, обеспечивающие безопасность и надежность. Фактически основной задачей среды выполнения является управление кодом. Код, который обращается к среде выполнения, называют управляемым кодом, а код, который не обращается к среде выполнения, называют неуправляемым кодом. Библиотека классов является комплексной объектно-ориентированной коллекцией допускающих повторное использование типов, которые применяются для разработки приложений -- начиная с обычных приложений, запускаемых из командной строки, и приложений с графическим интерфейсом пользователя (GUI), и заканчивая приложениями, использующими последние технологические возможности ASP.NET, такие как Web Forms и веб-службы XML.

Класс TcpClient запрашивает данные из ресурса в интернете по протоколу TCP. Методы и свойства TcpClient резюмируют сведения для создания Socket для запроса и получения данных по протоколу TCP. Поскольку подключение к удаленному устройство представлено в виде потока, данные можно считывать и записывать с платформой.NET Framework поток- методы обработки.Протокол TCP устанавливает соединение с удаленной конечной точкой, а затем пользами, соединение отправлять и получать пакеты данных. Протокол TCP отвечает за обеспечение, что пакеты данных отправлены к конечной точке, и сборка, когда они поступают в правильном порядке.

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

TcpListener используется для контроля портов для входящих запросов, а затем создать или Сокет или TcpClient, которое управляет подключением клиенту. МетодStart входит прослушивание, а метод Stop отключить прослушивание порта. Метод AcceptTcpClient принимает запросы входящего подключения и создает TcpClientдля обработки запроса, а метод AcceptSocket принимает запросы входящего подключения и создает Сокет для обработки запроса.

В следующем примере показано создание сервер времени сети с помощью монитора TcpListener на TCP-порт 13. При получении запроса входящего подключения, сервер отвечает времени текущей датой и временем из хоста-сервера.

2.2 Спецификация функциональных требований

Работа программы с точки зрения пользователя представлена на EDF0 диаграмме.

Основные этапы функционирования системы.

1. Создание комнаты.

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

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

3. Процесс игры

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

4. Подведение итогов игры.

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

3. Основные классы приложения и их описание

Имя класса

Описание класса

Логика отображения

DisplayManager

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

DisplaySettings

Класс-хранитель настроек для отображения.

GameLogicControls

Класс хранитель элементов управления, которые участвуют в процессе игры.

DisplayCell

Ячейка матрицы. Игровой элемент управления, который хранит вставленныую букву

Посредничество

NegotiationManager

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

Сетевая логика

NetworkManager

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

NetworkMassageHandler

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

MessageType

Тип сообщения

NetworkClient

Сетевой клиент. Класс основанный на TCP клиенте для взаимодействия клиенского и серверного приложения.

NetworkServer

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

Сереализация

SerializerManager

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

SettingsManager

Класс для управления игровыми настройками.

Игровая логика

GamePlayManager

Класс для управления игровой логикой.

GameSattistics

Коллекция элементов отражающих статистику игры.

LogicCell

Логическая абстракция ячейки матрицы

Player

Игрок - пользователь приложения

Word

Абстракция слова.

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

Делегат

Назначение

void DisplayMatrixCells(List<LogicCell> logicCells);

Отображение на графическом интерфейсе обновленных логических ячеек игровой логики.

void DisplayMessage(string message);

Отображение на графическом интерфейсе подсказки.

void DisplayError(string message);

Отображение на графическом ошибки.

bool ConditionAction(string word);

Проверка условия.

4. Тестирование приложения

Приложение тестировалось на компьютерах следующих конфигураций:

· Intel Core i5-3470 (3.2 GHz), 8 Gb RAM, 500 Gb HDD.

· AMD A8-4500M (1,9 GHz), 6 Gb RAM, 500 Gb HDD.

Тестирование производилось с помощью дополнительно разработанного клиентского приложения.

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

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

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

Тестирование режима на игры на одном компьютере

Тест

Ожидаемое поведение

Результат

Нажать “Игра на одном компьютере”, выбрать Количество игроков 3, - Размер матрицы 7. Нажать кнопку «ОК»

Появилось 3 поля для ввода имён ползователя.

Тест пройден

Нажать на кнопку «ОК»

Появилоась матрица 7 на 7.

Тест пройден

Выбрать ячейку для вставки буквы. Попытаться выбрать ячейку отдалённую от других букв на несколько ячеек.

Ячейка подсвечена оранжевым цветом. При выборе неправильной ячейки появляется соответствующее сообщение.

Тест пройден

Выбрать слово. Попытаться выбрать слово без вставленной буквы.

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

Тест пройден

Тестирование сетевого режима на игры

Тест

Ожидаемое поведение

Результат

Запустить три экземпляра приложения.

На трёх экземплярах появляется стартовое меню.

Тест пройден.

На первом выбрать режим «Сетевая игра», выбрать «Создать комнату», выбрать 3 человека и размер матрицы 5. Нажать кнопку «ОК».

На экране появляется форма с заданием имени пользователя.

При нажатиии «ОК» появляется сообщение «Ожидайте».

Тест пройден.

На клиентских приложениях выбрать сетевой режим игры, подклучиться к серверу, нажать клавишу «ОК»

На экране появляется форма задания имени пользователя и ip сервера. После нажатия «ОК» появляется надпись ожидание.

Тест пройден.

После подключения к серверу ещё 2 пользователей на всех 3 приложениях появляется список участников. Нажать кнопку ОК

На экране появляется матрица 5 на пять. Процесс игры аналогичен режиму на одним компьютере.

Тест пройден.

5. Руководство пользователя

Разработанное приложение является одновременно и клиентским и серверным. При загрузке приложения появляется форма.

Рисунок 5.1. Внешний вид приложения

Можно выбрать два варианта игры: Игра на одном компьютере и игра на по сети.

При выборе игры на одном компьютере появляется форма настройки комнаты.

Рисунок 5.2 Настройки комнаты

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

При нажатии кнопки ОК появляется форма для ввода имён пользователей.

Рисунок 5.3. Форма ввода имён пользователей

Затем происходит старт игры. Появляется матрица для выбора букв и ввода слов.

Рисунок 5.4. Выбор ячейки для вставки буквы

В соответствии с правилами можно выбрать только соседнюю ячейку для вставки букв. Затем с клавиатуры набирается буква и нажимается метка «Принять».

Затем происходит выбор слова.

Рисунок 5.5. Выбор слова

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

Рисунок 5.6. Выбор слова

Заключение

В результате работы над курсовым проектом было создано программное средство, представляющее собой сетевую игру «Балда».Игра имеет дружественный интерфейс, два режима работы, высокую надёжность и производительность.

Стоит отметить, что в данном приложении не реализованы все возможности игры «Балда», а только наиболее важные. Тем не менее этого набора хватает для полноценной работы с игрой.

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

В ходе работы так же укрепил знания по технологиями.Net таким, как WinForms, сереализация объектов в Xml.

Приложение было сделано в соответствии с принципами ООП. Широко использовалась событийная модель и делегаты.

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

1. Герберт Шилдт. Полный справочник по С# -- М.: Издательский дом "Вильямс", 2004. -- 752 с.

2. Эндрю Троелсен. Язык программирования C# 2010 и платформа.NET 4.0 - M.: Вильямс, 2010. --1392 c.

3. Мэтью Мак-Дональд C# для профессионалов - М.: Издательский дом "Вильямс", 2010. -- 656 с.

4. Википедия [Электронный ресурс]. - Электронные данные. - Режим доступа: http://ru.wikipedia.org/wiki/

5. WPF - Windows Presentation Foundatin[Электронный ресурс]. - Электронные данные. - Режим доступа: http://professorweb.ru/my/WPF/base_WPF/level1/info_WPF.php

6. Windows Presentation Foundation[Электронный ресурс]. - Электронные данные. - Режим доступа: http://msdn.microsoft.com/ru-ru/library/ms754130.aspx

Приложение

Листинг класса NegotiationManager.

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using System.Windows.Forms;

using BaldaClient.DisplayLogic;

using BaldaClient.NetworkManagment;

using BaldaClient.SettingsManagment;

using BaldaGameLogic.Delegates;

using BaldaGameLogic.GameLogic;

using BaldaGameLogic.GameModel;

namespace BaldaClient.Negotiation

{

public class NegotiationManager

{

#region GameManagment

private GameLogicManager gameLogicManager;

private DisplayManager displayManager;

private NetworkManager networkManager;

public SettingsManager SettingsManager { get; set; }

public GameLogicControls GameLogicControls { get; set; }

public bool IsProcessServer { get; set; }

public BaldaAplicationForm MainForm

{

get;

set;

}

public String ProcessUserName { get; set; }

private LogicCell previousLogicCell;

#endregion

#region GameLogicFlags

public bool IsCellSelectionExpected

{

get { return gameLogicManager.IsCellSelectionExpected; }

set { gameLogicManager.IsCellSelectionExpected = value; }

}

public bool IsLetterSelectionExpected

{

get { return gameLogicManager.IsLetterSelectionExpected; }

set { gameLogicManager.IsLetterSelectionExpected = value; }

}

public bool IsWordSelectionExpected

{

get { return gameLogicManager.IsWordSelectionExpected; }

set { gameLogicManager.IsWordSelectionExpected = value; }

}

public bool IsSelectedNetworkGameMode

{

get { return gameLogicManager.IsSelectedNetworkGameMode; }

set { gameLogicManager.IsSelectedNetworkGameMode = value; }

}

#endregion

public List<Player> Players

{

get { return gameLogicManager.Players; }

set { gameLogicManager.Players = value; }

}

public List<Player> TempPlayerList { get; set; }

public NegotiationManager(BaldaAplicationForm mainForm)

{

MainForm = mainForm;

gameLogicManager = new GameLogicManager();

networkManager = new NetworkManager(this);

}

public void AddPlayerToTempPlayerList(String userName)

{

if (TempPlayerList == null)

{

TempPlayerList = new List<Player>();

}

if (TempPlayerList.FirstOrDefault(pl => pl.Name == userName) == null)

{

var number = TempPlayerList.Count + 1;

TempPlayerList.Add(new Player{Name = userName,Number = number});

}

if (gameLogicManager.Settings.PlayerCount == TempPlayerList.Count)

{

gameLogicManager.Players = TempPlayerList;

MainForm.CreateAllPlayersNameControls();

}

}

private void BindGameManagers()

{

gameLogicManager.DisplayCells = displayManager.DisplayCells;

gameLogicManager.DisplayCellAsLight = displayManager.DisplayCellsAsLight;

gameLogicManager.DisplayCurrentWord = displayManager.DispalyCurrentWord;

gameLogicManager.DisplayCurrentPlayerName = displayManager.DisplayCurrentPlayerName;

gameLogicManager.DisplayCurrentGuide = displayManager.DisplayCurrentGuide;

gameLogicManager.DisplayCurrentError = displayManager.DisplayCurrentError;

gameLogicManager.AddWordConfirmationButtons =

GameLogicControls.GameForm.CreateWordConfirmationLabels;

gameLogicManager.RemoveConfirmationLabels = GameLogicControls.GameForm.RemoveConfirmationLabels;

gameLogicManager.AddLetterConfirmationButtons = GameLogicControls.GameForm.AddLetterConfirmationLabels;

}

public void ConfigureGame()

{

ConfigureGameSettings();

gameLogicManager.CreateGameLogicObjects();

}

public void ConfigureGameSettings()

{

gameLogicManager.Settings = SettingsManager.GameLogicSettings;

}

public void StartGame()

{

gameLogicManager.StartGame();

displayManager.DrawFullMatrix();

SetFirstWord("БАЛДА");

}

private void SetFirstWord(string word)

{

gameLogicManager.SetFirstWord(word);

}

public void TrySelectCell(int xCor, int yCor)

{

var logicCell = displayManager.GetLogicCellByCor(xCor, yCor);

if (logicCell!= null)

{

if (gameLogicManager.TrySelectCellForInsertingLetter(logicCell))

{

IsLetterSelectionExpected = true;

IsCellSelectionExpected = false;

}

}

}

public void SetLetterToCell(string letter)

{

if (gameLogicManager.LetterIsValidForInserting(letter))

{

gameLogicManager.SetLetterToCell(letter);

}

}

public void TryAddNextCellToWordSelection(int xCor, int yCor)

{

var logicCell = displayManager.GetLogicCellByCor(xCor, yCor);

if (logicCell!= null && previousLogicCell!= logicCell)

{

previousLogicCell = logicCell;

if (gameLogicManager.IsLogicCellValidForWordSelection(logicCell))

{

gameLogicManager.AddCellToWordSelection(logicCell);

}

}

}

public void StopWordSelection()

{

gameLogicManager.StopWordSelection();

}

public void ConfigureDisplaySettings()

{

displayManager =

new DisplayManager(GameLogicControls, SettingsManager.DisplaySettings, gameLogicManager.LogicCells);

BindGameManagers();

}

public void CancelSelectedWord()

{

gameLogicManager.CancelSelectedWord();

}

public void AcceptLetter()

{

gameLogicManager.AcceptLetter();

}

public void CancelLetter()

{

gameLogicManager.CancelLetter();

}

public void AcceptWord()

{

gameLogicManager.AcceptWord();

}

public void CreateGameRoom(String userName)

{

IsProcessServer = true;

ProcessUserName = userName;

networkManager.CreateGameRoom();

networkManager.ConnectToServer("localhost",userName);

}

public void ConnectToRoom(String ipString, String userName)

{

networkManager.ConnectToServer(ipString,userName);

networkManager.SendUserInformation(userName);

}

public void ConfigureGameParameters(List<Player> players, int size)

{

var gameLogicSettings = new GameSettings

{

MatrixSize = size,

PlayerCount = players.Count

};

var settingsManager = new SettingsManager

{

GameLogicSettings = gameLogicSettings,

DisplaySettings = new DisplaySettings

{

cellBackgroundColor = Color.Black,

cellBorderColor = Color.Chartreuse,

selectedCellBackroundColor = Color.Bisque,

cellLetterColor = Color.DarkOrange,

StartWorldTextColor = Color.Aqua,

MatrixCellSize = 360 / gameLogicSettings.MatrixSize - 2,

MatrixCellBorderWidth = 2

}

};

SettingsManager = settingsManager;

ConfigureGame();

Players = players;

MainForm.CreateAllPlayersNameControls();

}

}

}

public abstract class FtpCommandParserBase

{

protected readonly Dictionary<FtpCommand, Action<FtpCommandParserBase, string>> CommandHandlers =

new Dictionary<FtpCommand, Action<FtpCommandParserBase, string>>

{

{ FtpCommand.Abor, (parser, s) => parser.AborCommandHandler(s) },

{ FtpCommand.Cdup, (parser, s) => parser.CdupCommandHandler(s) },

{ FtpCommand.Cwd, (parser, s) => parser.CwdCommandHandler(s) },

{ FtpCommand.Dele, (parser, s) => parser.DeleCommandHandler(s) },

{ FtpCommand.List, (parser, s) => parser.ListCommandHandler(s) },

{ FtpCommand.Mdtm, (parser, s) => parser.MdtmCommandHandler(s) },

{ FtpCommand.Mkd, (parser, s) => parser.MkdCommandHandler(s) },

{ FtpCommand.Nlst, (parser, s) => parser.NlstCommandHandler(s) },

{ FtpCommand.Noop, (parser, s) => parser.NoopCommandHandler(s) },

{ FtpCommand.Pass, (parser, s) => parser.PassCommandHandler(s) },

{ FtpCommand.Pasv, (parser, s) => parser.PasvCommandHandler(s) },

{ FtpCommand.Port, (parser, s) => parser.PortCommandHandler(s) },

{ FtpCommand.Pwd, (parser, s) => parser.PwdCommandHandler(s) },

{ FtpCommand.Quit, (parser, s) => parser.QuitCommandHandler(s) },

{ FtpCommand.Rein, (parser, s) => parser.ReinCommandHandler(s) },

{ FtpCommand.Retr, (parser, s) => parser.RetrCommandHandler(s) },

{ FtpCommand.Rmd, (parser, s) => parser.RmdCommandHandler(s) },

{ FtpCommand.Rnfr, (parser, s) => parser.RnfrCommandHandler(s) },

{ FtpCommand.Rnto, (parser, s) => parser.RntoCommandHandler(s) },

{ FtpCommand.Size, (parser, s) => parser.SizeCommandHandler(s) },

{ FtpCommand.Stor, (parser, s) => parser.StorCommandHandler(s) },

{ FtpCommand.Stou, (parser, s) => parser.StouCommandHandler(s) },

{ FtpCommand.User, (parser, s) => parser.UserCommandHandler(s) }

};

#region Command delegates

public virtual Action AborCommand { get; set; }

public virtual Action CdupCommand { get; set; }

public virtual Action<string> CwdCommand { get; set; }

public virtual Action<string> DeleCommand { get; set; }

public virtual Action<string> ListCommand { get; set; }

public virtual Action<string> MdtmCommand { get; set; }

public virtual Action<string> MkdCommand { get; set; }

public virtual Action<string> NlstCommand { get; set; }

public virtual Action NoopCommand { get; set; }

public virtual Action<string> PassCommand { get; set; }

public virtual Action PasvCommand { get; set; }

public virtual Action<long, int> PortCommand { get; set; }

public virtual Action PwdCommand { get; set; }

public virtual Action QuitCommand { get; set; }

public virtual Action ReinCommand { get; set; }

public virtual Action<string> RetrCommand { get; set; }

public virtual Action<string> RmdCommand { get; set; }

public virtual Action<string> RnfrCommand { get; set; }

public virtual Action<string> RntoCommand { get; set; }

public virtual Action<string> SizeCommand { get; set; }

public virtual Action<string> StorCommand { get; set; }

public virtual Action<string> StouCommand { get; set; }

public virtual Action<string> UserCommand { get; set; }

#endregion

#region Command handlers

protected abstract void AborCommandHandler(string parameters);

protected abstract void CdupCommandHandler(string parameters);

protected abstract void CwdCommandHandler(string parameters);

protected abstract void DeleCommandHandler(string parameters);

protected abstract void ListCommandHandler(string parameters);

protected abstract void MdtmCommandHandler(string parameters);

protected abstract void MkdCommandHandler(string parameters);

protected abstract void NlstCommandHandler(string parameters);

protected abstract void NoopCommandHandler(string parameters);

protected abstract void PassCommandHandler(string parameters);

protected abstract void PasvCommandHandler(string parameters);

protected abstract void PortCommandHandler(string parameters);

protected abstract void PwdCommandHandler(string parameters);

protected abstract void QuitCommandHandler(string parameters);

protected abstract void ReinCommandHandler(string parameters);

protected abstract void RetrCommandHandler(string parameters);

protected abstract void RmdCommandHandler(string parameters);

protected abstract void RnfrCommandHandler(string parameters);

protected abstract void RntoCommandHandler(string parameters);

protected abstract void SizeCommandHandler(string parameters);

protected abstract void StorCommandHandler(string parameters);

protected abstract void StouCommandHandler(string parameters);

protected abstract void UserCommandHandler(string parameters);

#endregion

#region Methods

public abstract void Parse(string message);

#endregion

}

public class FtpCommandParser: FtpCommandParserBase

{

#region Fields

private readonly Action<FtpCommand> _onUnsupportedCommand;

#endregion

#region ctor

public FtpCommandParser(Action<FtpCommand> onUnsupportedCommandAction = null)

{

if (onUnsupportedCommandAction == null)

_onUnsupportedCommand = c => { throw new UnsupportedFtpCommandException(c); };

else

_onUnsupportedCommand = onUnsupportedCommandAction;

}

#endregion

#region Methods

#region Public methods

public override void Parse(string message)

{

message = message.Trim(' ', '\n', '\r', '\t');

if (string.IsNullOrEmpty(message))

return;

string[] parts = message.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

FtpCommand ftpCommand;

if (!FtpCommandHelper.Commands.TryGetValue(parts[0], out ftpCommand))

throw new UnknownFtpCommandException(parts[0]);

CommandHandlers[ftpCommand](this, string.Join(" ", parts.Skip(1)));

}

#endregion

#region Private methods

private void InvokeCommand(FtpCommand command, Action commandAction)

{

if (commandAction!= null)

commandAction();

else

_onUnsupportedCommand(command);

}

private void InvokeCommand(FtpCommand command, Action<string> commandAction, string parameter)

{

if (commandAction!= null)

{

if (parameter == null)

throw new IncorrectFtpCommandFormatException(command);

commandAction(parameter);

}

else

_onUnsupportedCommand(command);

}

#endregion

#region FtpCommandParserBase

#region Command handlers

protected override void AborCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Abor, AborCommand);

}

protected override void CdupCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Cdup, CdupCommand);

}

protected override void CwdCommandHandler(string parameters)

{

string[] args = parameters.Split(new []{' '}, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Cwd, CwdCommand, args.Length > 0? args[0]: null);

}

protected override void DeleCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Dele, DeleCommand, args.Length > 0? args[0]: null);

}

protected override void ListCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.List, ListCommand, args.Length > 0? args[0]: string.Empty);

}

protected override void MdtmCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Mdtm, MdtmCommand, args.Length > 0? args[0]: null);

}

protected override void MkdCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Mkd, MkdCommand, args.Length > 0? args[0]: null);

}

protected override void NlstCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Nlst, NlstCommand, args.Length > 0? args[0]: string.Empty);

}

protected override void NoopCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Noop, NoopCommand);

}

protected override void PassCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Pass, PassCommand, args.Length > 0? args[0]: null);

}

protected override void PasvCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Pasv, PasvCommand);

}

protected override void PortCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] {','}, StringSplitOptions.RemoveEmptyEntries);

if (args.Length < 6)

throw new IncorrectFtpCommandFormatException(FtpCommand.Port);

if (PortCommand == null)

{

_onUnsupportedCommand(FtpCommand.Port);

return;

}

long address = 0;

int port = 0;

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

{

byte part;

if (!byte.TryParse(args[i], out part))

throw new IncorrectFtpCommandFormatException(FtpCommand.Port);

if (i < 4)

address += part << (8 * i);

else

port = port * 256 + part;

}

PortCommand(address, port);

}

protected override void PwdCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Pwd, PwdCommand);

}

protected override void QuitCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Quit, QuitCommand);

}

protected override void ReinCommandHandler(string parameters)

{

InvokeCommand(FtpCommand.Rein, ReinCommand);

}

protected override void RetrCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Retr, RetrCommand, args.Length > 0? args[0]: null);

}

protected override void RmdCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Rmd, RmdCommand, args.Length > 0? args[0]: null);

}

protected override void RnfrCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Rnfr, RnfrCommand, args.Length > 0? args[0]: null);

}

protected override void RntoCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Rnto, RntoCommand, args.Length > 0? args[0]: null);

}

protected override void SizeCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Size, SizeCommand, args.Length > 0? args[0]: null);

}

protected override void StorCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Stor, StorCommand, args.Length > 0? args[0]: null);

}

protected override void StouCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.Stou, StouCommand, args.Length > 0? args[0]: string.Empty);

}

protected override void UserCommandHandler(string parameters)

{

string[] args = parameters.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

InvokeCommand(FtpCommand.User, UserCommand, args.Length > 0? args[0]: null);

}

#endregion

#endregion

#endregion

}

Листинг класса FileSystemWorker.cs

public class FileSystemWorker

{

private readonly string _rootDirectory;

private UserRights _userRights;

private FileStream _savingFile;

private FileStream _readingFile;

public const int BufferSize = 1048576; //1MB

public FileSystemWorker(string rootDirectory)

{

if (!Directory.Exists(rootDirectory))

throw new DirectoryNotFoundException(rootDirectory);

_rootDirectory = Path.GetFullPath(rootDirectory);

Directory.SetCurrentDirectory(_rootDirectory);

}

public void InitUserRights(UserRights userRights)

{

_userRights = userRights;

}

public void GoToParentDirectory()

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

string currentPath = CheckAndGetCurrentDirectory();

if (string.Compare(_rootDirectory, currentPath, StringComparison.OrdinalIgnoreCase)!= 0)

Directory.SetCurrentDirectory(Directory.GetParent(currentPath).FullName);

}

public void GoToRootDirectory()

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

Directory.SetCurrentDirectory(_rootDirectory);

}

public void ChangeDirecroty(string directory)

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

string newPath = Path.Combine(CheckAndGetCurrentDirectory(), directory.TrimStart(new [] { '\\', '/' }));

if (!Directory.Exists(newPath))

throw new FileSystemAccessDeniedException();

Directory.SetCurrentDirectory(newPath);

}

public string CreateDirectory(string directory)

{

if (!_userRights.CanCreate())

throw new FileSystemAccessDeniedException();

string path = Path.Combine(CheckAndGetCurrentDirectory(), directory.TrimStart(new[] { '\\', '/' }));

if (Directory.Exists(path))

throw new FileSystemException(string.Format("Directory \"{0}\" already exists", directory));

try

{

Directory.CreateDirectory(path);

}

catch (IOException ex)

{

throw new FileSystemException(ex.Message.Replace(_rootDirectory, ""));

}

return path.Replace(_rootDirectory, "");

}

public void RemoveDirectory(string directory)

{

if (!_userRights.CanCreate())

throw new FileSystemAccessDeniedException();

string path = Path.Combine(CheckAndGetCurrentDirectory(), directory.TrimStart(new[] { '\\', '/' }));

try

{

Directory.Delete(path);

}

catch (IOException)

{

throw new FileSystemAccessDeniedException();

}

}

public string GetCurrentDirectory()

{

string path = CheckAndGetCurrentDirectory().Replace(_rootDirectory, "");

return Path.IsPathRooted(path)? path: "\\" + path;

}

public void DeleteFile(string fileName)

{

if (!_userRights.CanCreate())

throw new FileSystemAccessDeniedException();

string filePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new [] { '\\', '/' }));

if (!File.Exists(filePath))

throw new FileSystemAccessDeniedException();

try

{

File.Delete(filePath);

}

catch (IOException ex)

{

throw new FileSystemException(ex.Message.Replace(_rootDirectory, ""));

}

}

public void RenameFile(string fileName, string newFileName)

{

if (!_userRights.CanCreate())

throw new FileSystemAccessDeniedException();

string oldFilePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new[] { '\\', '/' }));

if (!File.Exists(oldFilePath))

throw new FileSystemAccessDeniedException();

string newFilePath = Path.Combine(CheckAndGetCurrentDirectory(), newFileName.TrimStart(new[] { '\\', '/' }));

if (File.Exists(newFilePath))

throw new FileSystemException(string.Format("File \"{0}\" already exists", newFileName));

try

{

File.Move(oldFilePath, newFilePath);

}

catch (IOException ex)

{

throw new FileSystemException(ex.Message.Replace(_rootDirectory, ""));

}

}

public string BeginWriteFile(string fileName, bool newNameIfExists = false)

{

if (_savingFile!= null)

throw new Exception("Previous file not saved");

if (!_userRights.CanUpload())

throw new FileSystemAccessDeniedException();

string filePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new [] { '\\', '/' }));

if (File.Exists(filePath) || string.IsNullOrWhiteSpace(fileName))

{

if (!newNameIfExists)

throw new FileSystemAccessDeniedException();

fileName = Guid.NewGuid().ToString().Substring(0, 8);

filePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new [] { '\\', '/' }));

}

_savingFile = new FileStream(filePath, FileMode.CreateNew, FileAccess.Write, FileShare.None, BufferSize,

FileOptions.SequentialScan);

return fileName;

}

public void WriteData(byte[] data, int size)

{

if (_savingFile == null ||!_savingFile.CanWrite)

throw new Exception("File not accessible to write");

_savingFile.Write(data, 0, size);

}

public void EndWriteFile()

{

if (_savingFile == null)

throw new Exception("File not opened");

_savingFile.Close();

_savingFile = null;

}

public void BeginReadFile(string fileName)

{

if (_readingFile!= null)

throw new Exception("Previous file not closed");

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

string filePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new[] { '\\', '/' }));

if (!File.Exists(filePath))

throw new FileSystemAccessDeniedException();

_readingFile = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read, BufferSize,

FileOptions.SequentialScan);

}

public int ReadData(byte[] buffer, int size)

{

if (_readingFile == null ||!_readingFile.CanRead)

throw new Exception("File not accessible to read");

return _readingFile.Read(buffer, 0, size);

}

public void EndReadFile()

{

if (_readingFile == null)

throw new Exception("File not opened");

_readingFile.Close();

_readingFile = null;

}

public bool FileExists(string fileName)

{

return File.Exists(Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new[] { '\\', '/' })));

}

public bool CanRenameFile()

{

return _userRights.CanCreate();

}

public bool CanUploadFile()

{

return _userRights.CanUpload();

}

public bool CanDownloadFile()

{

return _userRights.CanDownload();

}

public DateTime GetFileModifiedDate(string fileName)

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

string filePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new[] { '\\', '/' }));

if (!File.Exists(filePath))

throw new FileSystemAccessDeniedException();

return File.GetLastWriteTime(filePath);

}

public long GetFileSize(string fileName)

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

string filePath = Path.Combine(CheckAndGetCurrentDirectory(), fileName.TrimStart(new[] { '\\', '/' }));

if (!File.Exists(filePath))

throw new FileSystemAccessDeniedException();

try

{

return new FileInfo(filePath).Length;

}

catch (IOException ex)

{

throw new FileSystemException(ex.Message.Replace(_rootDirectory, ""));

}

}

public string[] GetFileInfo(string fileName, bool onlyNames = false)

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

List<FileInfo> files = new List<FileInfo>();

List<DirectoryInfo> directories = new List<DirectoryInfo>();

string currentDirectory = CheckAndGetCurrentDirectory();

string filePath = string.IsNullOrWhiteSpace(fileName)

? currentDirectory

: Path.Combine(currentDirectory, fileName.TrimStart(new[] {'\\', '/'}));

if (File.Exists(filePath))

{

files.Add(new FileInfo(filePath));

}

else if (Directory.Exists(filePath))

{

files.AddRange(Directory.GetFiles(filePath).Select(v => new FileInfo(v)));

directories.AddRange(Directory.GetDirectories(filePath).Select(v => new DirectoryInfo(v)));

}

else

{

throw new FileSystemAccessDeniedException();

}

Func<FileInfo, string> getFileInfo;

Func<DirectoryInfo, string> getDirectoryInfo;

if (onlyNames)

{

getFileInfo =

f => string.Format("\t{0}", f.Name.Replace(_rootDirectory, ""));

getDirectoryInfo =

d => string.Format("dir\t{0}", d.Name.Replace(_rootDirectory, ""));

}

else

{

getFileInfo =

f => string.Format("\t{0}\t{1}\t{2}", f.Name.Replace(_rootDirectory, ""), f.Length, f.LastWriteTime);

getDirectoryInfo =

d => string.Format("dir\t{0}\t{1}\t{2}", d.Name.Replace(_rootDirectory, ""), "", d.LastWriteTime);

}

List<string> result = new List<string>();

result.AddRange(

files.Select(

v => getFileInfo(v)));

result.AddRange(

directories.Select(

v => getDirectoryInfo(v)));

return result.ToArray();

}

private string CheckAndGetCurrentDirectory()

{

if (!_userRights.CanDownload())

throw new FileSystemAccessDeniedException();

string currentDirectory = Directory.GetCurrentDirectory();

if (!currentDirectory.StartsWith(_rootDirectory))

throw new Exception("Incorrect working directory");

return currentDirectory;

}

}

Листинг класса DisplayManager

using System;

using System.Collections.Generic;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Linq;

using System.Text;

using System.Windows.Forms;

using BaldaClient.DisplayModel;

using BaldaGameLogic.GameLogic;

using BaldaGameLogic.GameModel;

namespace BaldaClient.DisplayLogic

{

public class DisplayManager

{

#region Properties for bindings

public GameLogicControls GameControls { get; set; }

#endregion

#region gameLogicFields

private List<LogicCell> logicCells;

private List<DisplayCell> displayCells;

private DisplayCell previousSelectedCell;

private Dictionary<LogicCell, DisplayCell> cellDictionary;

#endregion

#region forDisplayFields

private int cellBackgroundOffset;

private int cellBackgroundSize;

private int cellTextOffset;

private PictureBox pb;

private Graphics gr;

private Pen pen;

private Brush primaryBrush;

private Brush lightBrush;

private Brush textBrush;

private Font font;

private Label selectedWordLabel;

private DisplaySettings displaySettings;

#endregion

private DisplayCell selectedCellForLetter;

public LogicCell SelectedCellForLetter

{

get { return (selectedCellForLetter!= null)? selectedCellForLetter.LogicCell: null; }

}

public DisplayManager(GameLogicControls gameLogicControls, DisplaySettings displaySettings, List<LogicCell> logiccells)

{

this.GameControls = gameLogicControls;

this.pb = gameLogicControls.pictureBox;

this.selectedWordLabel = gameLogicControls.SelectedWordLabel;

pb.Refresh();

gr = pb.CreateGraphics();

this.displaySettings = displaySettings;

pen = new Pen(displaySettings.cellBorderColor, displaySettings.MatrixCellBorderWidth);

primaryBrush = new SolidBrush(displaySettings.cellBackgroundColor);

lightBrush = new SolidBrush(displaySettings.selectedCellBackroundColor);

textBrush = new SolidBrush(displaySettings.cellLetterColor);

font = new Font(FontFamily.GenericMonospace, (displaySettings.MatrixCellSize / 2), FontStyle.Bold);

cellBackgroundOffset = displaySettings.MatrixCellBorderWidth/2;

cellBackgroundSize = displaySettings.MatrixCellSize - displaySettings.MatrixCellBorderWidth;

cellTextOffset = displaySettings.MatrixCellBorderWidth/2 + 6;

logicCells = logiccells;

CreateDisplayCells();

}

private void CreateDisplayCells()

{

displayCells = new List<DisplayCell>();

cellDictionary = new Dictionary<LogicCell, DisplayCell>();

logicCells.ForEach(lc =>

{

var dispayCell = new DisplayCell

{

LogicCell = lc,

offsetX = (lc.X - 1)*displaySettings.MatrixCellSize + cellBackgroundOffset,

offsetY = (lc.Y - 1)*displaySettings.MatrixCellSize + cellBackgroundOffset,

};

displayCells.Add(dispayCell);

cellDictionary.Add(lc, dispayCell);

});

}

public void DrawCell(DisplayCell cell, Brush backGroundBrush)

{

try

{

if (cell!= null)

{

gr.DrawRectangle(pen, cell.offsetX, cell.offsetY, displaySettings.MatrixCellSize, displaySettings.MatrixCellSize);

gr.FillRectangle(backGroundBrush, cell.offsetX + cellBackgroundOffset, cell.offsetY + cellBackgroundOffset,

cellBackgroundSize, cellBackgroundSize);

if (!String.IsNullOrEmpty(cell.LogicCell.Letter))

gr.DrawString(cell.LogicCell.Letter, font, textBrush, cell.offsetX + cellTextOffset,

cell.offsetY + cellTextOffset);

}

}

catch (Exception ex)

{

throw ex;

}

}

public void DrawLightCell(DisplayCell cell)

{

}

public void DrawFullMatrix()

{

displayCells.ForEach(cell => DrawCell(cell, primaryBrush));

}

public void DisplayCells(List<LogicCell> logCells)

{

logCells.ForEach(lc=> DrawCell(cellDictionary[lc],primaryBrush));

}

public void DisplayCellsAsLight(List<LogicCell> logCells)

{

logCells.ForEach(lc => DrawCell(cellDictionary[lc], lightBrush));

}

public bool SelectCellForInsertingLetter(int xCor, int yCor)

{

if (previousSelectedCell!= null)

{

DrawCell(previousSelectedCell,primaryBrush);

}

LightCellByCor(xCor,yCor);

return true;

}

private void LightCellByCor(int xCor, int yCor)

{

var cell = GetDisplayCellByCor(xCor, yCor);

previousSelectedCell = cell;

DrawCell(cell,lightBrush);

}

private DisplayCell GetDisplayCellByCor(int xCor, int yCor)

{

var logicX = xCor / displaySettings.MatrixCellSize + 1;

var logicY = yCor / displaySettings.MatrixCellSize + 1;

return GetCellByLogicCor(logicX, logicY);

}

private DisplayCell GetCellByLogicCor(int x, int y)

{

return displayCells.FirstOrDefault(cell => (cell.LogicCell.X == x) && (cell.LogicCell.Y == y));

}

public LogicCell GetLogicCellByCor(int x, int y)

{

var logicX = x / displaySettings.MatrixCellSize + 1;

var logicY = y / displaySettings.MatrixCellSize + 1;

var displayCell = GetCellByLogicCor(logicX, logicY);

return (displayCell!=null)? displayCell.LogicCell: null;

}

public void DispalyCurrentWord(string message)

{

selectedWordLabel.Text = message;

}

public void DisplayCurrentPlayerName(string message)

{

GameControls.CurrentPlayerLabel.Text = message;

}

public void DisplayCurrentGuide(string message)

{

GameControls.GuideLabel.Text = message;

}

public void DisplayCurrentError(string message)

{

GameControls.ErrorLabel.Text = message;

}

}

}

using System;

using System.Collections.Generic;

using System.IO;

using System.Linq;

using System.Net;

using System.Net.Sockets;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

using System.Windows.Forms;

public delegate void HandleMassageActivity(String message);

namespace BaldaClient.NetworkModel

{

public class NetworkClient: IDisposable

{

private StreamWriter swSender;

private StreamReader srReceiver;

private TcpClient tcpServer;

private delegate void UpdateLogCallback(string strMessage);

private delegate void CloseConnectionCallback(string strReason);

private Thread thrMessaging;

private IPAddress ipAddr;

private bool Connected;

private HandleMassageActivity HandleMessage;

public NetworkClient(HandleMassageActivity handleMessage)

{

this.HandleMessage = handleMessage;

}

public void ConnectToServer(String ipString,String userName)

{

if (Connected == false)

{

InitializeConnection(ipString,userName);

}

else

{

CloseConnection("Disconnected at user's request.");

}

}

private void InitializeConnection(String ipString, String userName)

{

tcpServer = new TcpClient();

tcpServer.Connect("localhost", 1986);

Connected = true;

swSender = new StreamWriter(tcpServer.GetStream());

swSender.WriteLine(userName);

swSender.Flush();

thrMessaging = new Thread(new ThreadStart(ReceiveMessages));

thrMessaging.Start();

}

private void ReceiveMessages()

{

srReceiver = new StreamReader(tcpServer.GetStream());

string ConResponse = srReceiver.ReadLine();

if (ConResponse[0] == '1')

{

UpdateLog("Connected Successfully!");

}

else

{

string Reason = "Not Connected: ";

Reason += ConResponse.Substring(2, ConResponse.Length - 2);

UpdateLog(Reason);

return;

}

while (Connected)

{

var newMessage = srReceiver.ReadLine();

HandleMessage(newMessage);

}

}

private void UpdateLog(string strMessage)

{

Console.WriteLine(strMessage);

}

private void CloseConnection(string Reason)

{

Connected = false;

swSender.Close();

srReceiver.Close();

tcpServer.Close();

}

public void SendMessage(String message)

{

swSender.WriteLine(message);

swSender.Flush();

}

public void Dispose()

{

if (Connected == true)

{

Connected = false;

swSender.Close();

srReceiver.Close();

tcpServer.Close();

}

}

}

}

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using BaldaGameLogic.Delegates;

using BaldaGameLogic.GameModel;

namespace BaldaGameLogic.GameLogic

{

public class GameLogicManager

{

public GameSettings Settings { get; set; }

public List<LogicCell> LogicCells { get; private set; }

public List<LogicCell> MainWordLogicCells { get; private set; }

private LogicCell selectedCell;

public List<Player> Players { get; set; }

private List<LogicCell> SelectedCellsForWord;

private String selectedWord { get; set; }


Подобные документы

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

    дипломная работа [1,1 M], добавлен 07.05.2014

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

    курсовая работа [3,0 M], добавлен 20.09.2014

  • Разработка адресных и технических требований к игре. Написание сценария. Общая концепция разработки приложения. Разработка схем алгоритмов приложения. Игровые технологии. Выбор среды и программированного языка. Описание пользовательского интерфейса.

    курсовая работа [1,6 M], добавлен 14.06.2014

  • Требования к функциональным характеристикам, составу и параметрам технических средств, информационной и программной совместимости. Описание программы: общие сведения, логическая структура. Средства и порядок испытаний. Входные и выходные данные.

    курсовая работа [6,3 M], добавлен 12.01.2015

  • Анализ требований к программному продукту. Требования к информационной и программной совместимости. Проектирование архитектуры программного продукта. Виды программ и программных документов. Общие сведения о С++. Технология разработки программного модуля.

    дипломная работа [1,2 M], добавлен 05.08.2011

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

    курсовая работа [678,1 K], добавлен 15.02.2016

  • Требования к программе или программному продукту. Условия эксплуатации и требования к параметрам технических средств. Программное обеспечение, рекомендуемое для функционирования программы. Руководство системного программиста и настройка программы.

    отчет по практике [1,1 M], добавлен 22.07.2012

  • Предпроектное обследование объекта автоматизации. Область применения разработки Web-приложения "Туристическое агенство", ее назначение, требования к программному продукту и документации. Календарный план и порядок приемки. Приемы работы с программой.

    курсовая работа [60,3 K], добавлен 28.12.2011

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

    курсовая работа [1,6 M], добавлен 22.06.2011

  • Общие сведения и основные задачи о ФСИН России, размещение производственных и административных зданий. Оценка необходимости создания на предприятии корпоративной информационной сети. Масштабы проектируемой сети, определение параметров и выбор технологий.

    курсовая работа [34,1 K], добавлен 08.12.2009

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.