New Magic program: Gleemin
General Discussion of the Intricacies
Moderator: CCGHQ Admins
Re: New Magic program: Gleemin
by Arch » 10 Jan 2011, 15:13
Given the interest shown in other languages in this thread the rating of that endeavour might actually have gone from "Completely doomed" to "Most possibly doomed". Which would be an improvement.Huggybaby wrote:If you do, try to keep it modular and remember if it's not in Java, good luck finding help from volunteers.
Re: New Magic program: Gleemin
by Ye Goblyn Queenne » 10 Jan 2011, 18:36
Just a quick post to say I think I'm going to have to write a parser after all. I mean, right now- in the coming weeks. If I don't, I'll have to convert the text of each individual card to Prolog... and of course once I finally write the parser it will be useless. So I guess, I may as well do it now. Also, I guess it will take a crazy amount of time to translate each card in Prolog by hand and I'll need most of my time for the AI.
The good news is that I may have underestimated the time I need to write a parser. Like I said Prolog's DCG notation makes your life easier. Here's an example.
This is a very, very simple magic grammar that can read a single ability: Flying:
Here's a more complex example to give you a feel for what it would entail to parse a more complex card's text (% starts a comment line):
Also, note that the above examples are full programs, that is they run without any other code needed. You can expand the grammar rules as much as you like, or keep them as short as you like, they're ready to go.
So now what I need is a quick and dirty way to generate grammar rules... hmm, I think there's some sort of data mining kit/classes/thingy for Java?
The good news is that I may have underestimated the time I need to write a parser. Like I said Prolog's DCG notation makes your life easier. Here's an example.
This is a very, very simple magic grammar that can read a single ability: Flying:
- Code: Select all
ability --> static_ability.
static_ability --> keyword_ability.
keyword_ability --> ['Flying'], {write('Flyiiiinggg!!'), nl}.
- Code: Select all
| ?- phrase(ability, ['Flying']).
- Code: Select all
Flyiiiinggg!!
yes
Here's a more complex example to give you a feel for what it would entail to parse a more complex card's text (% starts a comment line):
- Code: Select all
% Ability
ability --> static_ability.
% Static ability
static_ability --> triggered_ability.
% Triggered ability
triggered_ability --> trigger_word, condition, effect.
condition --> domain, context.
domain --> determinant, domain.
domain --> player.
domain --> permanent.
effect --> domain, instructions.
instructions --> options, action, domain.
action --> verb, product.
% Terminals
trigger_word --> [when];[whenever];[at].
player --> ['you'].
context --> ['gain life'].
options --> ['may'].
verb --> ['put'].
product --> determinant, counter.
counter --> ['+1/+1 counter'], {(write('+1/+1 OK')), nl}.
counter --> ['+1/+1 counters'].
permanent --> ['Ajani''s'],['Pridemate'].
determinant --> [a];[on];[two].
- Code: Select all
| ?- phrase(ability, [whenever,you,'gain life','you',may,put,a,'+1/+1,counter',on,'Ajani''s','Pridemate']).
- Code: Select all
+1/+1 OK
yes
Also, note that the above examples are full programs, that is they run without any other code needed. You can expand the grammar rules as much as you like, or keep them as short as you like, they're ready to go.
So now what I need is a quick and dirty way to generate grammar rules... hmm, I think there's some sort of data mining kit/classes/thingy for Java?
No worries, once I got the DCG rules in place, I could write some sort of translator to generate, say a Backus-Naur-Form grammar, that could be imported in any application. Er. After I finish with my project you understand, heh... did I mention I'm a bit strapped for time?? #^_^Arch wrote:Given the interest shown in other languages in this thread the rating of that endeavour might actually have gone from "Completely doomed" to "Most possibly doomed". Which would be an improvement.Huggybaby wrote:If you do, try to keep it modular and remember if it's not in Java, good luck finding help from volunteers.
- Ye Goblyn Queenne
- Posts: 20
- Joined: 07 Jan 2011, 14:55
- Has thanked: 1 time
- Been thanked: 1 time
Re: New Magic program: Gleemin
by Incantus » 10 Jan 2011, 22:24
Wow, that would be awesome if you could normalize magic card text into Backus-Naur form or some other regularizable syntax!Ye Goblyn Queenne wrote:No worries, once I got the DCG rules in place, I could write some sort of translator to generate, say a Backus-Naur-Form grammar, that could be imported in any application. Er. After I finish with my project you understand, heh... did I mention I'm a bit strapped for time?? #^_^
Re: New Magic program: Gleemin
by MageKing17 » 14 Jan 2011, 12:41
Proud was working on something like that, and there's also someone who made a branch of Incantus and started writing a grammar for it (and then there's the very simple parser I made, but it's not grammar-based, just a bunch of if-else checks).Incantus wrote:Wow, that would be awesome if you could normalize magic card text into Backus-Naur form or some other regularizable syntax!Ye Goblyn Queenne wrote:No worries, once I got the DCG rules in place, I could write some sort of translator to generate, say a Backus-Naur-Form grammar, that could be imported in any application. Er. After I finish with my project you understand, heh... did I mention I'm a bit strapped for time?? #^_^
Also, Ye Goblyn Queenne, why do you have Triggered Abilities as a subset of Static Abilities?
(Also, keyword abilities shouldn't fall under "static abilities" unless you consider them to be a static ability that gives the card the abilities it stands for (which you very well could do, from an implementation standpoint).)
-
MageKing17 - Programmer
- Posts: 473
- Joined: 12 Jun 2008, 20:40
- Has thanked: 5 times
- Been thanked: 9 times
Re: New Magic program: Gleemin
by Ye Goblyn Queenne » 17 Jan 2011, 00:16
Sorry for the lag, I'm down with the flu... x_x Where would the human race be without chicken soup, I ask of you...?
@Arch: thank you very much for your Gatherer parser/ downloader, I used it to build my cardpool and it saved me hours of mind-numbingly boring copy-pasting.
@MageKing, I read proud's post, I checked out all the links above. I also read about your parser. I haven't had the time (or the brains) to look at them yet!
(Actually, it's really a Horn clause: "X is true if Y is true". So Prolog tries to prove that Y is true and if it does it's proved X to be true. In other words, if all the conditions for, say a triggered_ability hold true, then, yep, we got a triggered ability here. Hooray!).
Oh, btw, I just realised... the code snippet above won't work, there's a superfluous comma between "+1/+1" and "counter". I guess I was in a hurry... again... ^_^
I'll update my blog again in a couple of days, definitely after the 20th (assignment hand-in day). I'll try to explain what I intend to do with the parser a bit better, there. I'll probably just cross-post here, too (though I may go on a bit!).
@Arch: thank you very much for your Gatherer parser/ downloader, I used it to build my cardpool and it saved me hours of mind-numbingly boring copy-pasting.
@MageKing, I read proud's post, I checked out all the links above. I also read about your parser. I haven't had the time (or the brains) to look at them yet!
Oops, I was cutting a more extensive example down to size to post it here. Normally you'd go from ability --> triggered_ability directly. Sorry about that.MageKing17 wrote:Also, Ye Goblyn Queenne, why do you have Triggered Abilities as a subset of Static Abilities?
Heh, that's 'cause the example is just a partial grammar. All four types of ability (spell, activated, triggered and static) can be a keyword ability, so the full grammar would have a clause like: "<ability type> --> keyword_ability" for each of the four ability types. In this case you may find it clearer to think of the syntax "X --> Y" as "X can-be-a Y".MageKing17 wrote:(Also, keyword abilities shouldn't fall under "static abilities" unless you consider them to be a static ability that gives the card the abilities it stands for (which you very well could do, from an implementation standpoint).)
(Actually, it's really a Horn clause: "X is true if Y is true". So Prolog tries to prove that Y is true and if it does it's proved X to be true. In other words, if all the conditions for, say a triggered_ability hold true, then, yep, we got a triggered ability here. Hooray!).
Oh, btw, I just realised... the code snippet above won't work, there's a superfluous comma between "+1/+1" and "counter". I guess I was in a hurry... again... ^_^
I'll update my blog again in a couple of days, definitely after the 20th (assignment hand-in day). I'll try to explain what I intend to do with the parser a bit better, there. I'll probably just cross-post here, too (though I may go on a bit!).
- Ye Goblyn Queenne
- Posts: 20
- Joined: 07 Jan 2011, 14:55
- Has thanked: 1 time
- Been thanked: 1 time
Re: New Magic program: Gleemin
by Huggybaby » 17 Jan 2011, 04:42
Long posts are acceptable.
Please put a link to your blog in your signature. We have lots of excellent bloggers here and I'm going to collect the links soon.
Please put a link to your blog in your signature. We have lots of excellent bloggers here and I'm going to collect the links soon.
-
Huggybaby - Administrator
- Posts: 3209
- Joined: 15 Jan 2006, 19:44
- Location: Finally out of Atlanta
- Has thanked: 704 times
- Been thanked: 595 times
Re: New Magic program: Gleemin
by Ye Goblyn Queenne » 17 Jan 2011, 15:50
:smacks head:Huggybaby wrote:Long posts are acceptable.
Please put a link to your blog in your signature. We have lots of excellent bloggers here and I'm going to collect the links soon.
... done
- Ye Goblyn Queenne
- Posts: 20
- Joined: 07 Jan 2011, 14:55
- Has thanked: 1 time
- Been thanked: 1 time
Re: New Magic program: Gleemin
by Arch » 19 Jan 2011, 19:10
You're welcome, that's why I posted it.Ye Goblyn Queenne wrote:@Arch: thank you very much for your Gatherer parser/ downloader, I used it to build my cardpool and it saved me hours of mind-numbingly boring copy-pasting.
I was looking at your code or rather the parts of your code that's not code.
- Code: Select all
%%%%%%%%%%%%%%output/3 (7.2) 03/01/11
Which leads into my second question; what's your preferred editor/IDE?
Re: New Magic program: Gleemin
by Ye Goblyn Queenne » 20 Jan 2011, 17:10
Arch, hi. That's how I do documentationArch wrote:You're welcome, that's why I posted it.Ye Goblyn Queenne wrote:@Arch: thank you very much for your Gatherer parser/ downloader, I used it to build my cardpool and it saved me hours of mind-numbingly boring copy-pasting.
I was looking at your code or rather the parts of your code that's not code.What's up with this? As far as I can tell it contains numbering for rules and date but it doesn't really seem consistent. Is it just how you do documentation or is it something that your IDE does automatically?
- Code: Select all
%%%%%%%%%%%%%%output/3 (7.2) 03/01/11
The name/arity combination is typical, that's how Prolog predicates are normally identified. The numbers in parentheses help me identify the clause currently being executed, when using a source-level debugger. The dates are just version control. I guess I'm a bit anal... :/
Rule no 1: all Prolog IDEs must suck. It's like they make it deliberately hard for you so you give up and go play with something friendlier, like C or a hex editor. You've been warnedArch wrote:Which leads into my second question; what's your preferred editor/IDE?
My favourite one? Hm. I've mostly worked with Swi-Prolog and LPA's Win-Prolog. I guess I tend to use Win-Prolog the most, because it has a good graphical tracer. It also has dynamic syntax highlighting (eg, compiled clauses change colour.). Generally, it's pretty garish and an all-around eyesore, but you get used to it after a while. Comments in particular stand out (all those %%%%% blocks) so if you see my code in their editor, all this blocking-out makes a little more sense. You can download a trial from LPA's site, I believe (http://www.lpa.co.uk/win.htm). Of course you can change their defaults, but I'm used to them by now... Anyway I often jump between Win-Prolog, Swi's Emacs-based editor and Notepad++/ Gedit ... to rest my eyes a bit, you understand... O_x
Are you trying to decide on an IDE? I'd say stick with the free stuff and go for Swi, for now- but do download the Win-Prolog trial just to check out their gui tracer (enter "trace" at the command line before executing a query, "notrace" turns it off- or "spy(<predicate name>)" then "nospyall" to turn it off).
- Ye Goblyn Queenne
- Posts: 20
- Joined: 07 Jan 2011, 14:55
- Has thanked: 1 time
- Been thanked: 1 time
Re: New Magic program: Gleemin
by Arch » 20 Jan 2011, 20:08
So you're not using actual version control? If so you should. It makes such stuff easier, and safer.Ye Goblyn Queenne wrote:The dates are just version control.
Yes, I use emacs for pretty much everything I do and was using the mode that came with the default installation. It was pretty bad; as in not even highlighting consistently. (Ended up with this http://bruda.ca/emacs-prolog/, which seems ok.) The SWI tools look nice so I'll definitly have to try them. Don't know if I can get the LPA stuff working though as I'm on Ubuntu but it sounds like it would be worth a try. Either way, thanks for the input.Ye Goblyn Queenne wrote:Are you trying to decide on an IDE?
Re: New Magic program: Gleemin
by Ye Goblyn Queenne » 21 Jan 2011, 19:14
I guess I should, only currently there's just me on the project and it's still manageably small, so there's no much point. But you're right, I should.Arch wrote:So you're not using actual version control? If so you should. It makes such stuff easier, and safer.Ye Goblyn Queenne wrote:The dates are just version control.
I've used that Emacs mode. It's true, it's not very good. Swi's own editor is much better, indeed. Swi does have a Linux version btw, I've used it to generate the Linux exec. I uploaded a while ago. There's also a gnu-Prolog but I don't think it's very fast (Prologs can get rather slow if they're not very patiently optimised).Arch wrote:Yes, I use emacs for pretty much everything I do and was using the mode that came with the default installation. It was pretty bad; as in not even highlighting consistently. (Ended up with this http://bruda.ca/emacs-prolog/, which seems ok.) The SWI tools look nice so I'll definitly have to try them. Don't know if I can get the LPA stuff working though as I'm on Ubuntu but it sounds like it would be worth a try. Either way, thanks for the input.Ye Goblyn Queenne wrote:Are you trying to decide on an IDE?
Win-Prolog is, for, well... Windows! I don't think they even have it compiled for anything but windows. Did I mention it's proprietary? As in very expensive...
- Ye Goblyn Queenne
- Posts: 20
- Joined: 07 Jan 2011, 14:55
- Has thanked: 1 time
- Been thanked: 1 time
Re: New Magic program: Gleemin
by YeGoblynQueenne » 28 Feb 2011, 06:28
Hi again, folks. I'm back with some news about how the project is going, in case anyone is still interested )
I have good news and bad news. The bad news is a) I'm behind schedule and b) I'm dropping Swi-Prolog from my workflow and focusing on Win-Prolog entierly. The difference is, Swi is free, open-source and allows me to publish executables, while Win-Prolog isn't, isn't and doesn't. You can read more about the whys and wheretofore's on my blog but the short of it is that, well, I'm behind schedule and I'm cutting corners! As usual...! I'll resume the development on Swi after I've reached my deadline safely (in exactly 2 months from now, on the 28th of April). Actually, I'll have some more assignments and exams to do so I'll probably publish sometime in the summer.
Now, for the good news. The engine is mostly complete, enough that I can start working on the AI this week, hopefully. Yeah, hope dies last XD
As promised, I've written an interpreter for MGL (the Magic Gaming Language), that understands and executes Magic rules text directly, as it is on the cards. Well, OK, you have to turn it into a comma-separated list, first but that's it more or less. Here's how cards look into the program's database:
Note that this is a card "class", but that's not exactly how MGL Objects (ie, cards, permanents, spells, abilities on the stack and so on) are represented. card entries store the information about the characteristics of Objects. Objects themselves have three fields, Name, Id and State.
Now, the text_box field is identified as an ability by the interpeter, then executed in terms of the game engine. For example, tapping a permanent means adding the state "tapped" to its State field, bouncing it is calling a predicate "move_to_zone" and passing it the Name and Id of the permanent and so on.
That means the syntatctic rules I've defined for the interpeter will not be directly compatible with every game engine, since each will have its own internal representation of the games' various states and transitions between them. On the other hand, the syntax follows the definitions of the Comprehensive Rules (and where it doesn't, it should so I'll just have to fix it). This means it will be possible to translate in an intermediary syntax, liek BNF, that every engine will be able to use, either to populate a database or to translate in its own internal syntax.
Of course, nothing is done by, well, magic There's a long explanation on my blog, of how the interperter goes from MGL to state transitions in the Magic Virtual Machine. The blog link is in my signature, but really it's doing what I explain in the posts above, more or less. Currently, the only effect I'm actually implementing is bouncing (Unsummon, Boomerang etc) because I want to start on the AI, but the bulk of the work is done, basically. Well, at least as far as simple effects are concerned, that involve moving things around zones or altering their states and so on. As usual, more complicated stuff will take longer and will be more buggy
Oh, btw, as you can see from above, type lines are not correct MGL yet (they should be of the form "Supertype Type - Subtypes" instead of [S][T][s], but I was working with types before I started on the interpeter, for some reason. So I'll just have to fix it eventually).
OK, that's it for now, I'll go back to not having a life and sleeping three times a day by a couple of hours a time, for the next two months! Have fun and as usual feedback is welcome.
Take care
I have good news and bad news. The bad news is a) I'm behind schedule and b) I'm dropping Swi-Prolog from my workflow and focusing on Win-Prolog entierly. The difference is, Swi is free, open-source and allows me to publish executables, while Win-Prolog isn't, isn't and doesn't. You can read more about the whys and wheretofore's on my blog but the short of it is that, well, I'm behind schedule and I'm cutting corners! As usual...! I'll resume the development on Swi after I've reached my deadline safely (in exactly 2 months from now, on the 28th of April). Actually, I'll have some more assignments and exams to do so I'll probably publish sometime in the summer.
Now, for the good news. The engine is mostly complete, enough that I can start working on the AI this week, hopefully. Yeah, hope dies last XD
As promised, I've written an interpreter for MGL (the Magic Gaming Language), that understands and executes Magic rules text directly, as it is on the cards. Well, OK, you have to turn it into a comma-separated list, first but that's it more or less. Here's how cards look into the program's database:
- Code: Select all
card([
card_name 'Plains',
mana_cost 0,
%illustration 'Plains'
type_line [['Basic'], ['Land'], ['Plains']],
text_box [['tap',':','add','w','to','your','mana','pool']],
power [],
toughness [],
loyalty [],
state [['untapped', 'unflipped', 'face_up', 'phased_in']]
]).
card([
card_name 'Unsummon',
mana_cost 'u',
%illustration 'Unsummon'
type_line [[], ['Instant'], []],
text_box [['Return',target,'Creature',to,its,'owner''s',hand]],
power [],
toughness [],
loyalty [],
state []
]).
card([
card_name 'Aether Adept',
mana_cost '1uu',
%illustration 'Aether Adept'
type_line [[], ['Creature'], ['Human', 'Wizard']],
text_box ['When','Aether Adept','enters','the','battlefield',(','),'return','target','creature','to','its','owner''s','hand'],
power [2],
toughness [2],
loyalty [],
state [['untapped', 'unflipped', 'face_up', 'phased_in']]
]).
Note that this is a card "class", but that's not exactly how MGL Objects (ie, cards, permanents, spells, abilities on the stack and so on) are represented. card entries store the information about the characteristics of Objects. Objects themselves have three fields, Name, Id and State.
Now, the text_box field is identified as an ability by the interpeter, then executed in terms of the game engine. For example, tapping a permanent means adding the state "tapped" to its State field, bouncing it is calling a predicate "move_to_zone" and passing it the Name and Id of the permanent and so on.
That means the syntatctic rules I've defined for the interpeter will not be directly compatible with every game engine, since each will have its own internal representation of the games' various states and transitions between them. On the other hand, the syntax follows the definitions of the Comprehensive Rules (and where it doesn't, it should so I'll just have to fix it). This means it will be possible to translate in an intermediary syntax, liek BNF, that every engine will be able to use, either to populate a database or to translate in its own internal syntax.
Of course, nothing is done by, well, magic There's a long explanation on my blog, of how the interperter goes from MGL to state transitions in the Magic Virtual Machine. The blog link is in my signature, but really it's doing what I explain in the posts above, more or less. Currently, the only effect I'm actually implementing is bouncing (Unsummon, Boomerang etc) because I want to start on the AI, but the bulk of the work is done, basically. Well, at least as far as simple effects are concerned, that involve moving things around zones or altering their states and so on. As usual, more complicated stuff will take longer and will be more buggy
Oh, btw, as you can see from above, type lines are not correct MGL yet (they should be of the form "Supertype Type - Subtypes" instead of [S][T][s], but I was working with types before I started on the interpeter, for some reason. So I'll just have to fix it eventually).
OK, that's it for now, I'll go back to not having a life and sleeping three times a day by a couple of hours a time, for the next two months! Have fun and as usual feedback is welcome.
Take care
- YeGoblynQueenne
- Posts: 8
- Joined: 05 Jan 2011, 02:45
- Has thanked: 0 time
- Been thanked: 4 times
Re: New Magic program: Gleemin
by Huggybaby » 28 Feb 2011, 07:20
You logged in with a different name, and this one has no sig. Best to pick only one...
-
Huggybaby - Administrator
- Posts: 3209
- Joined: 15 Jan 2006, 19:44
- Location: Finally out of Atlanta
- Has thanked: 704 times
- Been thanked: 595 times
Re: New Magic program: Gleemin
by Ye Goblyn Queenne » 01 Mar 2011, 09:15
Oops! Sorry about that. When I joined, I wasn't receiving the confirmation email, so I made a new account. This is the right account.Huggybaby wrote:You logged in with a different name, and this one has no sig. Best to pick only one...
- Ye Goblyn Queenne
- Posts: 20
- Joined: 07 Jan 2011, 14:55
- Has thanked: 1 time
- Been thanked: 1 time
Re: New Magic program: Gleemin
by Arch » 01 Mar 2011, 19:08
I had nearly forgotten about prolog again. Thanks for reminding me. Here's some random questions for your trouble.
I saw this, card([card_name Name, _, _, text_box Ability, _, _, _, _]), in the blog post. Would this mean that if you want to add additional data (like uncommenting the illustration line in your code posted here) that you'd have to update all such pieces of code? It kinda looks like an associative datastructure (with the key-value pairs) but at the same time not (when you have to explicitly indicate each member).
What the purpose/meaning of underscore-variables? Such as
Object = copy(Name, _Id, State),
and
Target = copy(Name, Id, _State).
Is this the same as just underscore or is it just a mental helper for 'I actually don't care about this but it might be good to see that it's an Id/State' notation?
Why is "state" part of the card-database? Seems like something that should be handled when MGL objects are created rather than being an intrinsic property of a card.
Would you be willing to post the full source? I'd be fun to take a look at how all the things are connected.
I saw this, card([card_name Name, _, _, text_box Ability, _, _, _, _]), in the blog post. Would this mean that if you want to add additional data (like uncommenting the illustration line in your code posted here) that you'd have to update all such pieces of code? It kinda looks like an associative datastructure (with the key-value pairs) but at the same time not (when you have to explicitly indicate each member).
What the purpose/meaning of underscore-variables? Such as
Object = copy(Name, _Id, State),
and
Target = copy(Name, Id, _State).
Is this the same as just underscore or is it just a mental helper for 'I actually don't care about this but it might be good to see that it's an Id/State' notation?
Why is "state" part of the card-database? Seems like something that should be handled when MGL objects are created rather than being an intrinsic property of a card.
Would you be willing to post the full source? I'd be fun to take a look at how all the things are connected.
42 posts
• Page 2 of 3 • 1, 2, 3
Return to Magic Rules Engine Programming
Who is online
Users browsing this forum: No registered users and 2 guests