Zaphos
Guest
|
|
« Reply #80 on: February 04, 2010, 02:01:16 AM » |
|
I believe Rube Goldberg proved definitively that over-engineering is a good thing.
|
|
|
Logged
|
|
|
|
westquote
|
|
« Reply #81 on: February 04, 2010, 02:02:28 AM » |
|
Clarity in code is rather subjective, and is often defined per-individual as a function of their familiarity with programming paradigms, techniques, and languages. For example, novice programmers often express themselves with extreme verbosity in code, because they wish for it to map more closely to what they would say in spoken language. More experienced programmers usually grow to prefer less-long-winded code because it more directly expresses the essence of the computation. That being said, whether a given stylistic decision is motivated by brevity or by clarity can be difficult to determine, because the two are so often conflated. On that note, here are a couple of controversial expressions with regards to clarity: Clamp Expressionx = x < 0 and 0 or x > 10 and 10 or x x = std::max(0, std::min(10, x)) Ternary Lookup Tableint ret = x > 5 ? 10 : x > 4 ? 9 : x > 3 ? 8 : x < 1 ? 3 : 5; When I first saw this kind of expression, I did a double-take, and silently scolded the author for writing unclear ("clever") code. In retrospect, though, the code would have been perfectly clear to me if I were used to seeing these kinds of expressions. The fault, if any, was simply my unfamiliarity with the paradigm being used. While a group of people may agree collectively to cater to the lowest common denominator, it is by no means a given. I mention all of this as a roundabout way of saying that if you don't know the precedence rules for your language, it's really not the fault of the person who does. If someone doesn't understand how for loops work, it's not reasonable for them to expect or demand that their coworkers only write while loops on the basis that for loops are confusing. By analogy, I don't think you should expect them to wrap all their expressions up in needless parentheses; doing so would be a courtesy to you, like speaking slowly and enunciating when communicating with an inexperienced English speaker. Unrelated, here's a class of solution to the original poster's question that can be quite fast in a number of languages: const int lut[] = { 0, 10, 10, 10, 10, 10, 0, 0, 0, 0 }; b = lut[a]; This approach can work exceptionally well in situations where you are comparing a single integral key from a small domain. RapidXml, for example, uses these kinds of lookup tables for a number of inner-loop operations, primarily because it's a performance win. LUTs are also probably the closest thing you can get to a switch statement in Lua, so they are important to understand in that context as well. Goodnight! --Tim A.
|
|
|
Logged
|
|
|
|
Alex May
...is probably drunk right now.
Level 10
hen hao wan
|
|
« Reply #82 on: February 04, 2010, 02:09:58 AM » |
|
By analogy, I don't think you should expect them to wrap all their expressions up in needless parentheses; doing so would be a courtesy to you, like speaking slowly and enunciating when communicating with an inexperienced English speaker.
Well, quite. And we never come across programmers who are inexperienced with the language, do we? Just as we never encounter persons for whom English is a second language.
|
|
|
Logged
|
|
|
|
nikki
|
|
« Reply #83 on: February 04, 2010, 03:15:59 AM » |
|
@westquote a lookup table is something that hadn't crossed my mind in this case. it could save alot of retyping the same code. but i don't think i can use it here because the actual if statements look more like this: ElseIf lower_level>0 If this_level=0 If lower_level=255 tile=5 EndIf ElseIf this_level=2 If lower_level=253 tile=5 ElseIf lower_level=357 tile=22 ElseIf lower_level=291 tile=11 EndIf ElseIf this_level=4 If lower_level=251 tile=5 EndIf ElseIf this_level=6 If lower_level=293 tile=11 ElseIf lower_level=249 tile=5 ElseIf lower_level=185 tile=19 EndIf ElseIf this_level=8 If lower_level=405 tile=25 ElseIf lower_level=281 tile=12 ElseIf lower_level=247 tile=2 EndIf ElseIf this_level=9 If lower_level=246 tile=4 EndIf ElseIf this_level=10 If lower_level Mod 2=1 If lower_level <256 tile=2 Else tile=1 EndIf EndIf ElseIf this_level=11 If lower_level=244 tile=4 EndIf If lower_level=212 tile=4 EndIf ElseIf this_level=12 If lower_level=277 tile=12 ElseIf lower_level=243 tile=2 ElseIf lower_level=115 tile=1 EndIf ElseIf this_level=13 If lower_level=242 tile=4 EndIf If lower_level=114 tile=33 EndIf ElseIf this_level=14 If lower_level=185 Or lower_level=49 Or lower_level=115 Or lower_level=17 Or lower_level=33'Or lower_level=245 tile=1 EndIf If lower_level=245 Or lower_level=241 Or lower_level=177 tile=2 EndIf ElseIf this_level=15 If lower_level=240 tile=4 ElseIf lower_level=16 tile=16 ElseIf lower_level=144 tile=4 EndIf If lower_level=48 tile=33 EndIf EndIf EndIf
as you can see its nested a few times, and not uniform enough for such an approach. (I think)
|
|
|
Logged
|
|
|
|
Hajo
|
|
« Reply #84 on: February 04, 2010, 07:22:29 AM » |
|
Such if constructs have a high chance to turn into a error den and a maintenance nightmare. Particularly with all the magic numbers there ...
I'd assume you can break that down in smaller procedures which are easier to understand, and inside each you can use lookup tables and loops ... most likely you can have _one_ procedure that is just called for each level, and fed the proper data (lookup tables) for this one level to do the tile calculation.
|
|
|
Logged
|
Per aspera ad astra
|
|
|
westquote
|
|
« Reply #85 on: February 04, 2010, 09:02:11 AM » |
|
as you can see its nested a few times, and not uniform enough for such an approach. (I think)
Hmm, let me give it a shot. This seems more like a problem of data entry, so the optimal solution is probably expressed in those terms. One approach you might take is to generate a unique hash for each (this, lower) tuple, and then to store your data in a hash -> tile map. tileMap = {} function AddTile(thisLevel, lowerLevel, tile) assert(thisLevel < 65536 && lowerLevel < 65536) local hash = thisLevel << 16 & lowerLevel tileMap[hash] = tile end In this specific case, most of the values fall into this schema, with the notable exception of 10. In this case, a simple exception case may be all you need. if lowerLevel > 0 then if lowerLevel == 10 then if lowerLevel % 2 == 1 then tile = lowerLevel < 256 and 2 or 1 end else tile = tileMap[hash] end end From that point on, the question becomes how you input your data. Here's a rather direct, brute-force example. function LoadTiles() AddTile(0, 255, 5) AddTile(2, 253, 5) AddTile(2, 357, 22) AddTile(2, 291, 11) AddTile(4, 251, 5) AddTile(6, 293, 11) AddTile(6, 249, 5) AddTile(6, 185, 19) AddTile(8, 405, 25) AddTile(8, 281, 12) AddTile(8, 247, 2) AddTile(9, 246, 4) -- 10 is special-cased above AddTile(11, 244, 4) AddTile(11, 212, 4) AddTile(12, 277, 12) AddTile(12, 243, 2) AddTile(12, 115, 1) AddTile(13, 242, 4) AddTile(13, 114, 33) for _, v in pairs({185, 49, 115, 17, 33, 245}) do AddTile(14, v, 1) end for _, v in pairs({245, 241, 177}) do AddTile(14, v, 2) end AddTile(15, 240, 4) AddTile(15, 16, 16) AddTile(15, 144, 4) AddTile(15, 48, 33) end This isn't to say that this is will be better or faster for your needs (though it may), but more to show you how you might express it in terms of a table lookup instead of nested if statements. At the end of the day, expressing things as table lookups usually boils down to transforming logic into data. I hope it's of some help, --Tim A.
|
|
|
Logged
|
|
|
|
nikki
|
|
« Reply #86 on: February 04, 2010, 09:33:14 AM » |
|
first of all thanks for taking the time to actually fill in all the data.
what does this:"local hash = thisLevel << 16 & lowerLevel" mean in people english ? and likewise what do you do here :"for _, v in pairs({185, 49, 115, 17, 33, 245}) do"
again, It's alot of help, thanks !
|
|
|
Logged
|
|
|
|
Ben_Hurr
|
|
« Reply #87 on: February 04, 2010, 11:05:57 AM » |
|
first of all thanks for taking the time to actually fill in all the data.
what does this:"local hash = thisLevel << 16 & lowerLevel" mean in people english ? and likewise what do you do here :"for _, v in pairs({185, 49, 115, 17, 33, 245}) do"
again, It's alot of help, thanks !
My question is what exactly are you trying to do with this code? It obviously involves layers of tiles?
|
|
|
Logged
|
|
|
|
nikki
|
|
« Reply #88 on: February 04, 2010, 12:28:42 PM » |
|
the code comes from this programBasically it's a 3d tile calculater that checks its 9+9+8 neighbours (thus the large amount of 'magic' numbers) and well works out wich tile to show . This happens 4 times (once for every possible visible side) And so it 'generates' the proper tile.
|
|
|
Logged
|
|
|
|
Core Xii
|
|
« Reply #89 on: February 08, 2010, 05:32:18 AM » |
|
I believe Rube Goldberg proved definitively that over-engineering is a good thing.
Zing!
|
|
|
Logged
|
|
|
|
CiroContinisio
|
|
« Reply #90 on: February 08, 2010, 05:54:49 AM » |
|
The problem exposed on the first page seemed so simple, and still after 6 pages the discussion is still going on... incredible. EDIT: 7 pages now
|
|
|
Logged
|
|
|
|
Mikademus
|
|
« Reply #91 on: February 08, 2010, 09:23:47 AM » |
|
Hey! The smaller the problem the bigger the discussion! Are you new to committees or something?
|
|
|
Logged
|
\\\"There\\\'s a tendency among the press to attribute the creation of a game to a single person,\\\" says Warren Spector, creator of Thief and Deus Ex. --IGN<br />My compilation of game engines for indies
|
|
|
CiroContinisio
|
|
« Reply #92 on: February 08, 2010, 11:46:42 AM » |
|
Hey! The smaller the problem the bigger the discussion! Are you new to committees or something? Yes surely I am.
|
|
|
Logged
|
|
|
|
|