Старый 11.01.2004, 15:26   #1   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
Question 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
Как выбрать промежуток значений с помощью switch ?
  Ответить с цитированием
Старый 12.01.2004, 07:20   #2   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
Я понимаю, что пример - условный, потому что такую вещь лучше не свитчем делать. Примерно так, если со свитчем:
switch (value)
{
case 1:
case 2:
case 3:
case 4:
case 5:
//...
break;
//...
}

Но это неправильно и не элегантно. Начать с того, что и сам пример не элегантен хотя бы из за использования магических чисел.
  Ответить с цитированием
Старый 12.01.2004, 12:59   #3   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
zss_vrn Мне этот же вариант сегодня подсказал друг сишник, select в бейсике - функциональнее. Предётся использовать if()...
  Ответить с цитированием
Старый 13.01.2004, 15:46   #4   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
design fault
  Ответить с цитированием
Старый 13.01.2004, 17:16   #5   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
zss_vrn Чего ? Что ты имеешь в виду ?
  Ответить с цитированием
Старый 14.01.2004, 06:53   #6   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
Ошибка на этапе проектирования или постановки задачи - не на этапе кодирования. Сишный код ужасен, но и бейсиковский тоже тянет на 2 с плюсом
  Ответить с цитированием
Старый 14.01.2004, 13:54   #7   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
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   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
Ну, это не совсем С++

Общий смысл ясен, но не совсем.

Цитата:
perMirror += perForest;
perMud += perMirror;
perWall += perMud;
perWater += perWall;
Этого я не понял, тупой стал. К тому же, переменные эти - не возвращаемые, ну да ладно.

Из всех per... я бы сделал класс - всдруг захочется еще элементов добавить, что тогда?

Ну, ченть вроде такого вышло бы:

Цитата:
private void GenerateRandomMap(theMap)
{
Random rand = new Random();

theMap.reSize();// исключение здесь может выброситься

for(byte x = 0; x < maxX; x++)
for(byte y = 0; y < maxY; y++)
{

cell[x, y] = new Cell(theMap.getElement(rand.Next(100)));
}
Может, я и загнался, вопрос-то был не о том
  Ответить с цитированием
Старый 15.01.2004, 17:17   #9   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
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, 07:12   #10   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
LSL
Проще-то проще, но если захочется ввести, например, болота, то придется менять в нескольких местах, что есть неправильно.
  Ответить с цитированием
Старый 16.01.2004, 11:09   #11   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
zss_vrn Болота есть - perMud Вводить новый тип местности, это менять логику игры... в дизайне этого не предусмотрено. Если я бы решил оставить возможность быстрого добавления разных типов местности, например плагинами или скриптами, я бы так сделал.
  Ответить с цитированием
Старый 16.01.2004, 15:32   #12   
Форумец
 
Аватар для is
 
Сообщений: 111
Регистрация: 04.02.2003

is вне форума Не в сети
zss_vrn в приведенном методе, как я понимаю, переменные передаются по ссылкам, а не по значению - поэтому все нормально. Впрочем, в шарпе не силен
  Ответить с цитированием
Старый 16.01.2004, 15:49   #13   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
is В фрагменте кода который привёл на C# zss_vrn переменные передаются по значению

LSL добавил [date]1074261421[/date]:
Впрочем, если theMap - ссылочный тип (класс) то он всё равно будет изменён. Т.к. создаётся новая ссылка внутри метода на существующий класс theMap.
  Ответить с цитированием
Старый 16.01.2004, 17:06   #14   
Форумец
 
Аватар для is
 
Сообщений: 111
Регистрация: 04.02.2003

is вне форума Не в сети
LSL Будет время - я сам это проверю

is добавил [date]1074271967[/date]:
LSL Т.е. ты передаешь в функцию данные для генерации карты? С точки зрения дизайна класса (отразится на дальнейшем супорте) не очень хорошо, когда функция неявно меняет данные класса. Т.е. я когда взглянул на неё, для меня это было неочевидно - потому и подумал, что идет передача ссылок.

В шарпе есть префиксный инкремент? Если да, то лучше использовать его, чем постфиксный. Т.е. в циклах вместо y++ записать ++y.

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

Кроме того, я не очень пониманию почему тебе не подошла инструкция switch?

Сорри - изложил мысли несистематизированно и несколько сумбурно - на данный момент не располагаю свободным временем в достаточной степени, чтобы выразиться яснее.
  Ответить с цитированием
Старый 19.01.2004, 07:13   #15   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
LSL
Цитата:
Впрочем, если theMap - ссылочный тип (класс) то он всё равно будет изменён. Т.к. создаётся новая ссылка внутри метода на существующий класс theMap.
Ну, конечно, только ссылка на объект НЕ МЕНЯЕТСЯ, я просто вызываю его метод, вот и все. Состояние объекта, правда, меняется, но я очччень не люблю глобальных объектов и переменных.

Кстати, заранее извиняюсь - я коды эти по-быстрому пишу, не прооверяя, так что ляпы могут быть в большом количестве.
Цитата:
Вводить новый тип местности, это менять логику игры... в дизайне этого не предусмотрено. Если я бы решил оставить возможность быстрого добавления разных типов местности, например плагинами или скриптами, я бы так сделал.
Дело - не в плагинах и скриптах - вот гор например нету.
is
Цитата:
Следовательно, уже сейчас нужен рефакторинг
Не пугай ребенка
  Ответить с цитированием
Старый 19.01.2004, 16:09   #16   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
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
zss_vrn
Ну, конечно, только ссылка на объект НЕ МЕНЯЕТСЯ, я просто вызываю его метод, вот и все. Состояние объекта, правда, меняется, но я очччень не люблю глобальных объектов и переменных.

Ссылка на объект МЕНЯЕТСЯ В C# если ссылочная переменная передаётся ПО ЗНАЧЕНИЮ, то как и любой другой переменной создаётся локальная копия. Только хитрость в том что новая локальная ссылка всё равно будет ссылаться на тот же объект.

Дело - не в плагинах и скриптах - вот гор например нету.

ёклмн. гор нет и не будет Так написано в спецификации игры.

Не пугай ребенка

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

LSL добавил [date]1074522041[/date]:
zss_vrn кстати, называть методы в стиле camel case не красиво. Это я про твой код Это тебе нужен рефакторинг...
  Ответить с цитированием
Старый 20.01.2004, 00:42   #17   
Форумец
 
Аватар для is
 
Сообщений: 111
Регистрация: 04.02.2003

is вне форума Не в сети
zss_vrn Так уж и ребенка. Поаккуратнее в оценках-то. Художника легко обидеть

LSL

Не очевидно для меня относительно члена cell. Ну, это я так придираюсь

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

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

Да я понимаю, что у каждого свои принципы, но на классиков забивать не надо. Ты какие паттерны используешь?

В некотором смысле насчет switch'а я согласен, но кто тебе мешает, как уже показано выше перечислить все кейсы без ключевого слова break - будет то же самое как с case 1 to 5, но, опять же, это скорее дело вкуса.

Кстати, а когда будет выполняться инструкция после case else?
  Ответить с цитированием
Старый 20.01.2004, 01:17   #18   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
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   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
LSL
Цитата:
ёклмн. гор нет и не будет
Может, и так, но может и появятся. Проекты часто растут быстрее, чем мы это планируем.
Цитата:
Со временем понимаешь что за молодыми не угнаться. Это печально не так ли?...
Кажется, я тебя задел - извини, буду осторожнее с шутками.

В каждом положении есть свои плюсы и минусы, мадо только их различать. В данном случае гнаться не за чем. А молодость - это недостаток, который очень быстро проходит.
Цитата:
Это тебе нужен рефакторинг...
Не я его предлагал.
Цитата:
кстати, называть методы в стиле camel case не красиво.
Не согласен.
  Ответить с цитированием
Старый 21.01.2004, 12:05   #20   
Форумец
 
Сообщений: 1,696
Регистрация: 24.11.2002
Возраст: 39

LSL вне форума Не в сети
zss_vrn

Не согласен.

Я первый раз вижу название методов в camel case, возможно, в C++Bulder так принято. В С# по соглашению C# Coding Style Guide by Mike Krueger, методы именуются в стиле Pascal Case.
  Ответить с цитированием
Старый 23.01.2004, 10:34   #21   
Форумец
 
Аватар для zss_vrn
 
Сообщений: 2,045
Регистрация: 27.08.2003

zss_vrn вне форума Не в сети
LSL
Java. Наш корпоративный стандарт такой же.
  Ответить с цитированием
Поиск в теме: 



Быстрый переход:

  Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Support by DrIQ & Netwind