It is currently 03 Jul 2022, 20:49
Text Size

Hint Generation from spoiler text

Moderators: Malban, CCGHQ Admins

Hint Generation from spoiler text

Postby Malban » 13 Mar 2011, 18:58

Text to Hint Conversion

I plan to be able in the future to generate Hints automatically from card text.

This will not work all the time, but in about 80% of new cards this should be
working reasonably well.

There will allways be new cards with new types of action, but a game like JPortal is
an ever growing game and this section will likewise allways grow.

The plan further is, for each NEWLY supported card, the Text->Hint conversion will
be implemented (if not working allready), so that this feature will grow with the
time and more and more cards can be processed automatically.

I will not implement the 700 or so card (already implemented) with one go.

First goal is to build an "engine" that can be extended to the required things.
Than with each new card the rules-set, which builds the hints will be expanded.
After a couple of hundred cards this might be easy going.

Current Status and Thoughts...

Classes for this can be found in the package:

The thought behind the whole thing is, that the spoiler texts are (more or less) based on
static rules, which can be interpreted.

I think of these rules as "Phrases".

This phrases can be converted to JPortal Hints.

One phrase is an ordered collection of keywords. If the keywords occur in the correct order
they have a certain meaning, which I can generate hints from.

The basic idea thus is:
- look for keywords in a specific order,
- if found, supply a set of hints
- test the next phrase

The class Phrase
I implemented a class called phrase, which more or less does all the work.
Upon construction the class is provided wirh following entities:
- A) an ordered array of keywords to look for
- B) the card for which the hints will be built
- C) the allready found phrases
- D) a Bundle of Hints

All tested text is "cleaned" - with that I mean, special characters and markers are removed, the
text is converted to upper case, all whitepaces are converted to spaces, all exceeding spaces
are removed.

The card text is split into tokens. Each such token has a position in the text,
which - well is just the position in the text.
After a phrase was found, the position of the last found phrase is remembered, and the
next phrase will be looked for AFTER that position. The position thus increments
with each found phrase.

A) Keywords
- the keywords in general are the words which will be looked for in the card text.
- the order of the keywords must be the same as the keywords
- there can be other words between keywords

new Phrase(new StringArray("Target", "creature"), card, phrasesFound, new HintBundle(TA_FROM_FIELD, TR_CARD_TYPE_CREATURE));

Which does:
- split the text of the card into tokens.
- looks if in the tokens a token is equal to: "TARGET".
- if found - all tokens with a position higher than the above found one are checked if they
are equal to: "CREATURE"
- if that happens, the phrase is marked as "found".
- Postion counter of the phrase is to set the position of token "CREATURE" + 1
- the phrase is added to the "phrasesFound" collection

Special rules in keywords
With the above simple keywords it would still be very cumbersome to generate meaningfull hints.
For this a parsing of the keywords is implemented, which effect the "meaning".

A keyword can be "OR"ed. With that I mean that a keyword is true if one or another is found.
Keywords that have the same meaning, can be seperated within the same string using a "PIPE" sign
-> "|"

If either "IF" or "WHENEVER" is found, the keyword of the phrase is marked as found.

VALUE of a Keyword
The hints sometimes must have a value of a kind - or a type or key must be set.
For this reason you must be able to extract a "value" from a hint, or rather from the provided
card text.

If one of the keywords has also a value, it must start with a DOLLAR "$".
(When further the OR is used, only one dollar at the beginning of the keyword is accepted).

"Target", "$Creature"

This phrase (when the keywords TARGET and CREATURE are found in the correct order) also
has the value of "Creature".

VALUE for a hint
The above value of a hint is at first glance rather meaningless. But when the value of
a hint (many hints must have a value!) comes into play this gets interesting.

In order to set the value of a phrase to a hint one of the keywords (anywhere, in any order) must
be "$AS_VALUE".
Than all hints of the supplied HintBundle which can have a value, will be set to the value of the
(This will become clearer in a meaningfull example below)

KEY for a hint
Same as above. ALL Hints must have a key, what situation they refer to.
The situation must be gathered from the card text. The phrase than must generate as it´s value
the situation key. Than the key can be set using the special keyword "$AS_KEY".

All Hints wihtin that phrase, all hints befor found and all phrases that still will be found, will
use that key!

Once a key is found and set in any phrase, all other phrases and their hints will be set to
use that key!

As you may have guessed, many times the card text will not supply the neccessary values to
use in a hint. For that you can use a substition.
Using an ARROW "->" will substitute a keyword when found with the right side of the arrow.

Code: Select all
  new Phrase(new StringArray("$a card->1", "$AS_VALUE"), card, phrasesFound, new HintBundle(CT_TARGET_COUNT));
Here you see an allready usefull example of a Phrase.
If the card text (in the respect of previous found hints) finds the keyword "a card"
It will generate a hint called "CT_TARGET_COUNT" and set its value (since the keyword "$AS_VALUE" was found)
to the value of the key keyword which starts with a DOLLOR ("$") sign which in turn is substituted
with the value of "1".

Thus a hint will be generated with a TARGET COUNT = 1.

No Position increment
Using the special keywword "$NO_POS+" anywhere within the keyowrds, will result in NOT
incrementing the token pointer to the card text.
The pointer will remain in the same position as befor processing this phrase.

Position Reset
Using the special keywword "$RESET_POS" anywhere within the keyowrds, will result in setting
the position to 0. This should be the first keyword in the keyowrd order.

Card Type
The special keyword "$TYPE|XXXX" will be "true" if the type of the card has the type "XXXX".

Card Name
The special keyword "$NAME" will be substituted with the name of the card.

Possibly in the future the keywording must be further extended.
As it is one can already build quite obscure phrases, which result in meaningfull hint generation.

Card: Lurking Nightstalker
Whenever Lurking Nightstalker attacks, it gets +2/+0 until end of turn.

Using the checks with phrases:
Code: Select all
        new Phrase(new StringArray("If|Whenever", "$attack->"+HINT_SITUATION_ATTACKER+"|attacks->"+HINT_SITUATION_ATTACKER, "$AS_KEY"), card, phrasesFound,
                   new HintBundle(O_WHEN_ATTACKING));
Code: Select all
        new Phrase(new StringArray("$NAME", "$TYPE|Creature", "it_gets|he_gets|she_gets|the_gets", "$NO_POS+"), card, phrasesFound,
                   new HintBundle(TA_FROM_FIELD, CT_SINGLE, TA_SELF, TR_CARD_SELF_OK));
Code: Select all
        new Phrase(new StringArray("get|gets", "$+1/+0->1|+2/+0->2|+3/+0->3|+4/+0->4|+1/+1->1|+2/+1->2|+3/+1->3|+4/+1->4|+1/+2->1|+2/+2->2|+3/+2->3|+4/+2->4|+1/+4->1|+2/+4->2|+3/+4->3|+4/+4->4", "$AS_VALUE", "$NO_POS+"), card, phrasesFound,
                   new HintBundle(TY_GENERAL_BUF, TY_POWER_ADD, CT_AMOUNT_COUNT));

Code: Select all
        new Phrase(new StringArray("$until_end_of_turn->1", "$AS_VALUE"), card, phrasesFound,
                   new HintBundle(TI_TURN_COUNT));
Will build the following Hints:
Code: Select all
No   Key             Type                   Name             Value
1   ATTACKING       OCCURRENCE             WHEN ATTACKING     true
1   ATTACKING       EFFECT TIME             TURN COUNT           1
1   ATTACKING       TARGET                 TARGET FROM FIELD   true
1   ATTACKING       TARGET                 TARGET SELF         true
1   ATTACKING       TARGET RESTRICTION     SELF OK             true
1   ATTACKING       TARGET EFFECT TYPE     ADD POWER             2
Homepage of JPortal:
Posts: 84
Joined: 26 Apr 2010, 14:11
Has thanked: 0 time
Been thanked: 12 times

Return to JPortal Documentation

Who is online

Users browsing this forum: No registered users and 1 guest

Who is online

In total there is 1 user online :: 0 registered, 0 hidden and 1 guest (based on users active over the past 10 minutes)
Most users ever online was 1922 on 07 Jun 2021, 06:01

Users browsing this forum: No registered users and 1 guest

Login Form