Joel Uckelman on Thu, 5 Aug 2010 09:27:20 -0700 (MST) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[game-lang] defining static parts of games |
I'm thinking about how one would go about defining static game features, i.e., components which don't change with the game state. I'm using some sort of Prolog-ish language here to describe a small hex grid and the adjacency relation on it. I'm expecting that the people who will be using this would not be writing the adjacency rules themselves, but rather the adjacency rules would be something they'd import from a library. # # This is a 3-column, 3-row hex grid. # hex([0,0]). hex([0,1]). hex([0,2]). hex([1,0]). hex([1,1]). hex([1,2]). hex([2,0]). hex([2,1]). hex([2,2]). # # Adjacency. Note that odd columns are up columns. # # These are the four adjacencies which hold for all columns adj(a,b) :- hex(a) & hex(b) & col(a)-1 = col(b) & row(a) = row(b). adj(a,b) :- hex(a) & hex(b) & col(a) = col(b) & row(a)-1 = row(b). adj(a,b) :- hex(a) & hex(b) & col(a) = col(b) & row(a)+1 = row(b). adj(a,b) :- hex(a) & hex(b) & col(a)+1 = col(b) & row(a) = row(b). even(n) := int(n) & n % 2 = 0. odd(n) := int(n) & !even(n). # These are the adjacencies specific to even columns adj(a,b) :- hex(a) & hex(b) & col(a)-1 = col(b) & row(a) = row(b) & even(col(a)). adj(a,b) :- hex(a) & hex(b) & col(a)+1 = col(b) & row(a) = row(b) & even(col(a)). # These are the adjacencies specific to odd columns adj(a,b) :- hex(a) & hex(b) & col(a)-1 = col(b) & row(a) = row(b) & odd(col(a)). adj(a,b) :- hex(a) & hex(b) & col(a)+1 = col(b) & row(a) = row(b) & odd(col(a)). This takes care of the edges properly---hex([0,-1]) is false, for example--- so hex([0,0]) has only three adjacencies. It's not too bad for readability. You have to specify the hexes manually, which will be painful for a map which is 100x100, but the adjacency relation works for grids of any size (which have N-S grain and odd colulmns as up columns). Some repetition syntax would be nice. I sort of feel like doing this: for (int r = 0; r < 4; r++) { for (int c = 0; c < 4; c++) { printf("hex([%d,%d])", c, r); } } where the loop is *not* part of the logic program----rather, it means that "hex[c,r]" will be printed into the program the desired number of times. (Metaprogramming can be quite handy.) Or, perhaps, just do this: hex([c,r]) :- 0 <= c & c < 4 & 0 <= r & r < 4. What else is going on here? * There is arithmetic. * There are some other functions which are not boolean-valued, namely col() and row(), which are just the obvious projection functions from coordinate pairs. If you can't define functions which are not predicates, then I suspect things will become ugly very quickly. For example, if you're forced to write col() as a two-place predicate col(h,c) which is true iff c is the column component of h, then simple things like the tests I wrote above become harder: col(a)+1 = col(b) gets translated to: col(a,c+1) & col(b,c) where c is a free variable. I find this harder to read. -- J. _______________________________________________ game-lang mailing list game-lang@xxxxxxxxx http://lists.ellipsis.cx/mailman/listinfo/game-lang