Если это ваш первый визит, рекомендуем почитать справку по форуму. Для размещения своих сообщений необходимо зарегистрироваться. Для просмотра сообщений выберите раздел. |
switch statement |
Философия, технологии, алгоритмы! |
|
Опции темы |
11.01.2004, 15:26 | #1 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
switch statement
Сталкнулся с такой штукой:
Как на Си перевести обыкновенный оператор выбора: Код:
Select Number Case 1 To 5 Debug.WriteLine("Between 1 and 5") Case 6 To 10 Debug.WriteLine("Between 6 and 5") Case Else Debug.WriteLine("Not between 1 and 10") End Select |
12.01.2004, 07:20 | #2 |
Форумец
Сообщений: 2,045
Регистрация: 27.08.2003
Не в сети |
Я понимаю, что пример - условный, потому что такую вещь лучше не свитчем делать. Примерно так, если со свитчем:
switch (value) { case 1: case 2: case 3: case 4: case 5: //... break; //... } Но это неправильно и не элегантно. Начать с того, что и сам пример не элегантен хотя бы из за использования магических чисел. |
14.01.2004, 13:54 | #7 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
zss_vrn
Ошибка на этапе проектирования или постановки задачи У меня ? Код:
/// <summary> /// Генерация случайной карты, с пропорциями местности в процентах. /// </summary> private void GenerateRandomMap(byte perForest, byte perMirror, byte perMud, byte perWall, byte perWater) { Random rand = new Random(); if(perForest + perMirror + perMud + perWall + perWater != 100) throw new Exception(); perMirror += perForest; perMud += perMirror; perWall += perMud; perWater += perWall; for(byte x = 0; x < maxX; x++) for(byte y = 0; y < maxY; y++) { int per = rand.Next(100); if(per < perForest) cell[x, y] = new Cell(CellName.Forest); else if(per >= perForest && per < perMirror) cell[x, y] = new Cell(CellName.Mirror); else if(per >= perMirror && per < perMud) cell[x, y] = new Cell(CellName.Mud); else if(per >= perMud && per < perWall) cell[x, y] = new Cell(CellName.Wall); else if(per >= perWall && per < perWater) cell[x, y] = new Cell(CellName.Wall); } } |
15.01.2004, 08:59 | #8 | ||
Форумец
Сообщений: 2,045
Регистрация: 27.08.2003
Не в сети |
Ну, это не совсем С++
Общий смысл ясен, но не совсем. Цитата:
Из всех per... я бы сделал класс - всдруг захочется еще элементов добавить, что тогда? Ну, ченть вроде такого вышло бы: Цитата:
|
||
15.01.2004, 17:17 | #9 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
zss_vrn
Ну, это не совсем С++ Это совсем не Си.. это Си-шарп perMirror += perForest; perMud += perMirror; perWall += perMud; perWater += perWall; Всё просто.. это переменные передаваемые в метод, они определяют процентное соотношение территорий Cell() То есть: Вода - 20% Лес - 30% Суша - 50% Всё остальное - 0% Теперь с учётом этих процентов, территорию нужно случайно распределить по карте. Всего maxX*maxY клеток. В каждой итерации цикла создаётся случайное число (0-99), затем проверяется в какой промежуток попало это число, ширина промежутка как раз и задаётся per... -переменными, т.е чем выше процент суши тем больше вероятность что случайное число попадёт в промежуток суши.. промежуток - представляется значением "от" и "до", и его просто представить отрезком с делениями, perForest, perMirror, perMud.. т.е приходится прибавлять к предыдущему значению текущее... При попадении случайного числа в промежуток в массиве (внутреннем члене класса "карта", этот метод тоже является закрытым членом класса "карта", его вызывает конструктор) создается элемент характеризуемый перечислением возможных вариантов местности.. и др. перечислений... На бейсике было бы проще.. (select case) |
16.01.2004, 11:09 | #11 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
zss_vrn Болота есть - perMud Вводить новый тип местности, это менять логику игры... в дизайне этого не предусмотрено. Если я бы решил оставить возможность быстрого добавления разных типов местности, например плагинами или скриптами, я бы так сделал.
|
16.01.2004, 15:49 | #13 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
is В фрагменте кода который привёл на C# zss_vrn переменные передаются по значению
LSL добавил [date]1074261421[/date]: Впрочем, если theMap - ссылочный тип (класс) то он всё равно будет изменён. Т.к. создаётся новая ссылка внутри метода на существующий класс theMap. |
16.01.2004, 17:06 | #14 |
Форумец
Сообщений: 111
Регистрация: 04.02.2003
Не в сети |
LSL Будет время - я сам это проверю
is добавил [date]1074271967[/date]: LSL Т.е. ты передаешь в функцию данные для генерации карты? С точки зрения дизайна класса (отразится на дальнейшем супорте) не очень хорошо, когда функция неявно меняет данные класса. Т.е. я когда взглянул на неё, для меня это было неочевидно - потому и подумал, что идет передача ссылок. В шарпе есть префиксный инкремент? Если да, то лучше использовать его, чем постфиксный. Т.е. в циклах вместо y++ записать ++y. В дизайне приложения что-то не видно принципа Барбары Лисков При расширении (ты сейчас это категорически отвергаешь) будут проблемы. Следовательно, уже сейчас нужен рефакторинг Попробуй провести более детальный анализ предметной области и конструкций, с которыми придется оперировать. Кроме того, я не очень пониманию почему тебе не подошла инструкция switch? Сорри - изложил мысли несистематизированно и несколько сумбурно - на данный момент не располагаю свободным временем в достаточной степени, чтобы выразиться яснее. |
19.01.2004, 07:13 | #15 | |||
Форумец
Сообщений: 2,045
Регистрация: 27.08.2003
Не в сети |
LSL
Цитата:
Кстати, заранее извиняюсь - я коды эти по-быстрому пишу, не прооверяя, так что ляпы могут быть в большом количестве. Цитата:
is Цитата:
|
|||
19.01.2004, 16:09 | #16 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
is
LSL Т.е. ты передаешь в функцию данные для генерации карты? С точки зрения дизайна класса (отразится на дальнейшем супорте) не очень хорошо, когда функция неявно меняет данные класса. Т.е. я когда взглянул на неё, для меня это было неочевидно - потому и подумал, что идет передача ссылок. Фунция является методом того класса в котором явно(почему неявно?) меняет, даже не меняет а инициализирует, его данные. Этот метод закрыт и вызывается из конструктора этого класса. Эту функцию можно представить как конструктор класса. Почему передача по значению не очевидна ? В C# по дефолту параметры передаются по значению, препятствовать этому не вижу смысла. В шарпе есть префиксный инкремент? Если да, то лучше использовать его, чем постфиксный. Т.е. в циклах вместо y++ записать ++y. Префиксный инкремент -есть. В дизайне приложения что-то не видно принципа Барбары Лисков При расширении (ты сейчас это категорически отвергаешь) будут проблемы. Следовательно, уже сейчас нужен рефакторинг Попробуй провести более детальный анализ предметной области и конструкций, с которыми придется оперировать. принципа Барбары Лисков.. у меня свои принципы Начальным этапом разработки приложения было его проектирование, в дизайн-документе всё точно расписано, сколько где и как, менять это нет никакой надобности. Кроме того, я не очень пониманию почему тебе не подошла инструкция switch? Не настолько фукциональна как аналогичный оператор из VB "select case" в котором можно задавать промежуток выбора. см. первый пост. Нельзя записать так: Код:
Select num Case 1 To 5 Debug.WriteLine("num - от одного до пяти") Case Is > 5 Debug.WriteLine("num - больше пяти") Case Else Debug.WriteLine("Любой другой случай") End Select Ну, конечно, только ссылка на объект НЕ МЕНЯЕТСЯ, я просто вызываю его метод, вот и все. Состояние объекта, правда, меняется, но я очччень не люблю глобальных объектов и переменных. Ссылка на объект МЕНЯЕТСЯ В C# если ссылочная переменная передаётся ПО ЗНАЧЕНИЮ, то как и любой другой переменной создаётся локальная копия. Только хитрость в том что новая локальная ссылка всё равно будет ссылаться на тот же объект. Дело - не в плагинах и скриптах - вот гор например нету. ёклмн. гор нет и не будет Так написано в спецификации игры. Не пугай ребенка Со временем понимаешь что за молодыми не угнаться. Это печально не так ли?... LSL добавил [date]1074522041[/date]: zss_vrn кстати, называть методы в стиле camel case не красиво. Это я про твой код Это тебе нужен рефакторинг... |
20.01.2004, 00:42 | #17 |
Форумец
Сообщений: 111
Регистрация: 04.02.2003
Не в сети |
zss_vrn Так уж и ребенка. Поаккуратнее в оценках-то. Художника легко обидеть
LSL Не очевидно для меня относительно члена cell. Ну, это я так придираюсь Вот ты пишешь, что инициализируешь - так вынеси это в сам конструктор. Двухфазное конструирование в большинстве случаев - не лучший вариант. По передаче по значению: я ж в шарпе не разбираюсь. Думал, что по умолчанию как раз по ссылкам и передаются. В данном случае похоже, что размер передаваемых значений небольшой - на ссылки можно забить. Да я понимаю, что у каждого свои принципы, но на классиков забивать не надо. Ты какие паттерны используешь? В некотором смысле насчет switch'а я согласен, но кто тебе мешает, как уже показано выше перечислить все кейсы без ключевого слова break - будет то же самое как с case 1 to 5, но, опять же, это скорее дело вкуса. Кстати, а когда будет выполняться инструкция после case else? |
20.01.2004, 01:17 | #18 |
Форумец
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39
Не в сети |
is
Вот ты пишешь, что инициализируешь - так вынеси это в сам конструктор. Двухфазное конструирование в большинстве случаев - не лучший вариант. Этот вариант я может быть ещё поменяю. Пока не до конца решил как это будет построено... Переменные не должны передаваться в конструктор: byte perForest, byte perMirror, byte perMud, byte perWall, byte perWater они должны генерироваться в классе. Конструктор перегружен, в него ещё может передаваться имя файла карты. Скорее всего в конструктор для построения случайной карты будет передаваться член перечисления, на основе которого уже в конструкторе будет задаваться определённая пропорция местности.. и вызываться процедура генерации случайной карты... Да я понимаю, что у каждого свои принципы, но на классиков забивать не надо. Ты какие паттерны используешь? Ты про это: http://www.dotsite.spb.ru/solutions/patterns/ Осознанно ни разу не использовал.. решения там интересные. Скорее всего паттерны нужны для больших проектов, игра которую мы пишем к таким не относится. Ко всему прочему у меня акцент смещён немного в другую сторону. Эта игра первая более менее серьёзная программа на C# для меня. Технологию OpenGL я использую тоже первый раз. Дойдёт очередь и до паттернов... В некотором смысле насчет switch'а я согласен, но кто тебе мешает, как уже показано выше перечислить все кейсы без ключевого слова break - будет то же самое как с case 1 to 5, но, опять же, это скорее дело вкуса. В коде более крупные промежутки. 1-50, 50-40, 40-100... слишком много кейсов получится.. Кстати, а когда будет выполняться инструкция после case else? Всё что меньше единицы. Аналогично default.... |
20.01.2004, 07:32 | #19 | ||||
Форумец
Сообщений: 2,045
Регистрация: 27.08.2003
Не в сети |
LSL
Цитата:
Цитата:
В каждом положении есть свои плюсы и минусы, мадо только их различать. В данном случае гнаться не за чем. А молодость - это недостаток, который очень быстро проходит. Цитата:
Цитата:
|
||||