Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Beam=Style TBA Text Parser
- I hope to support the full Beam 'Inglish' with this, eventually, but
- if not, it should be a modest text parser tor TBA style quests, or even
- normal quests where the developer can read strings to find command keywords and
- act on them.
- At present, there is a five WORD stack, and a heap that can support caching
- commands, offsetting them, and acting on them later.
- This is not fully-considered, as Beam's 'Inglish' parser supported conjunctions
- and prepositions. Adding those, or at least the logic for those will require a
- larger stack, and some unconventional memory management.
- Beam's maximum parse string length was 128-characters.
- */
- int instructions[214747];
- int command[18];
- int tempbuffer[55];
- int outputbuffers[10];
- void OutputText(int bufferID, int outoutID){
- //copy text from input to output
- }
- void GameText(){
- //string processor
- }
- int stack[5]; //holds the four possible command components
- int heap[32]; //May not need it, but it might be good for something.
- int ADJ_NOUN[36]; //buffer for a combined adjective and noun pairing.
- //Used to compare the names of screen items, and enemies.
- //36 chars = 17+17+space+NULL Probably too long for any pair, but that is a minor waste.
- //Perhaps a SAY string?
- //ASM TYPES
- #define ACTION 1;
- #define NOUN 2;
- #define ADJECTIVE 3;
- #define INVALID -1;
- /* Do we want to allow constructing very complex chains, such as OLD KEY as two
- compinents, or do we want to hardcode OLD KEY or HIDEOUS TROLL as one string?
- Clearly, the latter is easier.
- */
- //ASM DEFINE
- #define NORTH 1;
- #define EAST 2;
- #define WEST 3;
- #define SOUTH 4;
- #define UP 5;
- #define DOWN 6;
- #define LOOK 7;
- #define TAKE 8;
- #define WAIT 9;
- #define ASK 10;
- #define SAY 11;
- #define ATTACK 12;
- #define USE 13;
- #define EQUIP 14;
- #define GIVE 15;
- int matchaction(int command){
- }
- //Returns how many total WORDS are in one instruction set.
- int numinstructions(int _buffer){
- ///count the number of spaces in the buffer. THe number of total instructions
- ///equals the number of spaces, plus onwe
- int spc; int nextchar; bool trailspacedone;
- INSTRUCTIONS_SIZE = SizeOfArray(_buffer);
- for ( int q = SizeOfArray(_buffer); q >= 0; q-- ) {
- //don't count trailing spaces, or contiguous spaces.
- if ( _buffer[q] == CHAR_SPACE ) {
- if ( __buffer[q-1] !isLetter() && !trailspacedone ) {
- trailspacedone = false; continue;
- }
- else if ( __buffer[q-1] isLetter() && !trailspacedone ) {
- trailspacedone = true;
- spc++; continue;
- }
- else if ( __buffer[q-1] !isLetter() && trailspacedone ) continue;
- else if ( __buffer[q-1] isLetter() && trailspacedone ) {
- spc++;
- }
- }
- }
- //WORDCOUNT[0] = spc+1; //store the total number of words.
- return spc+1;
- }
- //int WORDS[4];
- //holds the indices of each word?
- #define MAX_WORDS 5; //Max words per instruction. SAY GANDALF GIVE OLD KEY
- //Store each word in these buffers.
- int WORD_1[18];
- int WORD_2[18];
- int WORD_3[18];
- int WORD_4[18];
- int WORD_5[18];
- int WordCount; //how many words this time, and the index at which they occur.
- int INSTRUCTIONS_SIZE; //Used by functions to minimise loop wastage.
- //Stores the present commands in the text parsing buffer into command slots.
- void GetInstructions(int _buffer){
- int wordcount = numinstructions(_buffer);
- int WORDS[5]={WORD_1, WORD_2, WORD_3, WORD4, WORD_5}; //holds the array pointers.
- //This time, read the array forward.
- int spc; int nextchar; bool trailspacedone; int curword = 0;
- for ( int q = 0; q < INSTRUCTIONS_SIZE; q++ ) {
- //don't count trailing spaces, or contiguous spaces.
- if ( curword < wordcount ) {
- do {
- int ptr = WORDS[curword];
- ptr[q] = _buffer[q];
- }
- while ( _buffer[q] != CHAR_SPACE && spc < wordcount );
- curword++;
- }
- }
- }
- //Add instructions to the 'stack', starting with a COMMAND, then its variables.
- void StringToCommand(){
- int buf[3] = "0"; int buf2[2];
- //one string per command
- //command lengths
- //this speeds up matching the string to a command by finding one of the same length
- int commandlengths[]={5, 4, 4, 5, 2, 4, 4, 4, 4, 4, 3, 3, 6, 3}; //list the length of each command in order.
- //match the
- int legalcommands[]="
- 01NORTH
- 2EAST
- 3WEST
- 4SOUTH
- 5UP
- 6DOWN
- 7LOOK
- 8TAKE
- 9WAIT
- 10ASK
- 11SAY
- 12ATTACK
- 13USE
- ";
- //We then check the length of the command
- /* We probably don't need a switch for this. Just do:
- */
- //Do we want a switch for this?
- //switch (INSTRUCTIONS_SIZE){
- // case 1:
- //COMMAND only, no verb, no say.
- //Parse WORD_1
- int curWord = 0;
- int WORDS[5]={WORD_1, WORD_2, WORD_3, WORD4, WORD_5}; //holds the array pointers.
- //First, the command
- strcpy(WORDS[curWord], temp_command); //store the present word
- for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
- bool match;
- if ( commandlengths[q] == strlen(temp_command) {
- //if the position of q is < 10, append a leading 0
- if ( q < 10 ) {
- itoa(q,buf2);
- strcat(buf2, but);
- }
- //otherwise, just store it
- itoa(q, buf); //overwrite the temp buffer.
- //find that number in legal commands
- for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
- //! stringparser finds a matching string, and returns its position?
- //if ( stringparser(buf) ) return q; //if the string matches
- //This is the inverse of the old string parser, so instead, let's do this
- int bufcompare[18];
- stringparser(q, bufcompare); //copy instruction q into the compare buffer
- for ( int e = 0; e < strlen(bufcompare); e++ ) {
- //compare each index
- if ( temp_command[e] != bufcompare[3] ) {
- //failed to compare
- match = false;
- break;
- }
- match = true; //we found the match.
- //return atoi(buf); //return the command ID.
- //! no, we want to store the commcomamnd, to parse,
- //! and add variables to it.
- stack[curWord] = atoi(buf);
- break;
- }
- //the parsed string, thast is its command number.
- //so, return it.
- }
- break; //if we fail, we fall through.
- }
- if ( !match ) stack[curWord] = INVALID; //return INVALID; //invalid command
- //!! no, put INVALID into the stack.
- }
- curWord++; //Increase the SP.
- int legal_variables="
- ";
- //Then, its VARIABLES, if any.
- for ( int q = 1; q < WordCount; q++ ) {
- strcpy(WORDS[curWord], temp_command); //store the present word
- for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
- bool match;
- if ( commandlengths[q] == strlen(temp_command) {
- //if the position of q is < 10, append a leading 0
- if ( q < 10 ) {
- itoa(q,buf2);
- strcat(buf2, but);
- }
- //otherwise, just store it
- itoa(q, buf); //overwrite the temp buffer.
- //find that number in legal commands
- for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
- //! stringparser finds a matching string, and returns its position?
- //if ( stringparser(buf) ) return q; //if the string matches
- //This is the inverse of the old string parser, so instead, let's do this
- int bufcompare[18];
- stringparser(q, bufcompare); //copy instruction q into the compare buffer
- for ( int e = 0; e < strlen(bufcompare); e++ ) {
- //compare each index
- if ( temp_command[e] != bufcompare[3] ) {
- //failed to compare
- match = false;
- break;
- }
- match = true; //we found the match.
- //return atoi(buf); //return the command ID.
- //! no, we want to store the commcomamnd, to parse,
- //! and add variables to it.
- stack[curWord] = atoi(buf);
- break;
- }
- //the parsed string, thast is its command number.
- //so, return it.
- }
- break; //if we fail, we fall through.
- }
- if ( !match ) stack[curWord] = INVALID; //return INVALID; //invalid command
- //!! no, put INVALID into the stack.
- }
- currWord++; //Increase the SP.
- }
- }
- void doaction(int action){
- //get actions off the stack, and pop them
- int tempheap[5]; int command;
- for ( int q = 0; q <= MAX_WORDS; q++ ){
- hempheap[q] = stack[q];
- stack[q] = 0; //popped
- }
- switch(NUMWORDS){
- case 1:
- //actions only
- command = tempheap[0];
- switch(command){
- }
- case 2:
- //action and noun
- int command = tempstack[0];
- int adjective = tempstack[1];
- int noun = tempstack[2];
- switch(noun){
- //find the object by checking for NOUN on screen
- case 1:
- switch(command){
- case 1:
- //perform action on noun
- }
- }
- }
- case 3: //command, and two words
- //can be 'command adjective noun'
- int command = tempstack[0];
- int adjective = tempstack[1];
- int noun = tempstack[2];
- //append adjective to ADJECTIVE_NOUN[36]
- //and append a space
- //append the noun to the ADCECTIVE_NOUN string
- switch(noun){
- //!!!!!!!
- //! it might improve performance to do the adjective and noun first, and perform the command
- //case, on those.
- //determine of the noun is an enemy, or an item.
- case 1:
- case 2:
- case 3: //items
- //item cases go here
- //check for items matchint the ADJECTIVE_NOUN string by name
- //if they exist, perform the action on them, if possible
- //if they are not on screen, but are in inventory, perform the action.
- switch(action){
- case TAKE:
- break;
- case GIVE;
- break;
- case USE:
- break;
- case EQUIP:
- break;
- default:
- SyntaxErr();
- break;
- //Perform the action on the target.
- }
- break;
- //enemies
- case TROLL:
- case GOBLIN:
- case GOLLUM:
- case SMAUG:
- switch(action){
- case ATTACK:
- break;
- default:
- SyntaxErr();
- break;
- //Perform the action on the target.
- }
- break;
- //Scan the screen for an npc that matches the string ADJECTIVE_NOUN
- case OTHER:
- SyntaxErr();
- break;
- /*
- switch(adjective){
- //narrow the field? Do we ever need to do this?
- case 1:
- int noun = tempstack[2];
- //append adjective to ADJECTIVE_NOUN[36]
- //and append a space
- switch(noun){
- //append the noun to the ADCECTIVE_NOUN string
- case 1:
- //item cases go here
- //check for items matchint the ADJECTIVE_NOUN string by name
- //if they exist, perform the action on them, if possible
- //if they are not on screen, but are in inventory, perform the action.
- }
- }
- switch(action){
- Perform the action on the target.
- }
- */
- default:
- SyntaxErr();
- break;
- }
- case 4: //command and three words
- /* this is where things become quite complex, as this includes the SAY
- instruction. In fact... I believe that 4 must alays be the say instruction.
- //! Don;t forget 'CARRY'
- */
- int person = tempstack[1];
- int action = tempstack[2];
- int noun = tempstack[3];
- switch (command){
- case SAY:
- //if the command isn't say, then we're doing something else, likely syntax err.,
- case (person){
- //check to see if the person is present.
- case GANDALF:
- if ( !isGandalfPresent() ) break;
- case THORIN:
- if ( !isThorinPresent() ) break;
- case ELROND:
- if ( !isElrondPresent() ) break;
- case GOLLUM
- if ( !isTHorinPresent() ) break;
- case BEORN:
- if ( !isBeornPresent() ) break;
- case BARD:
- if ( !isTHorinPresent() ) break;
- case SMAUG
- if ( !isTHorinPresent() ) break;
- //Each character gets this block, with legal actions and such.
- switch(action){
- case GIVE:
- switch(noun){
- case 1:
- //check objects in inventory
- //if we give the object to a character, mark their inventory
- //array and remove the object from our own
- }
- case ATTACK;
- switch(noun){
- //check the screen for some creature that matches
- //noun by name.
- case 1:
- }
- }
- }
- default:
- //not the say command, return an error.
- }
- case 5:
- //say, person, action, adjective, noun
- //! Don;t forget 'CARRY'
- switch (command){
- case SAY:
- int person = tempstack[1];
- case (person){
- case 1:
- int action = tempstack[2];
- switch(action){
- int adj = tempstack[3];
- case 1:
- switch(adj){
- int noun = tempstack[4];
- case 1:
- switch(noun){
- case 1:
- }
- }
- }
- }
- default:
- //not the say command, return an error.
- }
- switch(action){
- case :
- default:
- break;
- }
- }
- //ASM VARIABLES
- //NOUNS
- //Items
- #define KEY 1;
- #define MAP 2;
- #define GOLD 3;
- #define SWORD 4;
- #define TORCH 5;
- #define DAGGER 6;
- #define ME 7;
- //NPCs (person)
- #define GANDALF 1;
- #define THORIN 2;
- #define BARD 3;
- #define BEORN 4;
- #define ELROND 5;
- //Enemies
- #define TROLL 1;
- #define GOBLIN 2;
- #define GOLLUM 3;
- #define SMAUG 4;
- //ADJECTIVES
- #define STRANGE 1;
- #define OLD 2;
- #define UNUSUAL 3;
- #define GOLDEN 4;
- #define UGLY 5;
- #define MAGICAL 6;
- #define HIDEOUS 7;
- #define SHINY 8;
- //Parse types, based on number of commands issued
- #define COMMAND 1;
- #define VERB 2;
- #define NOUN 3;
- #define SPEAK 4;
- //Constructs
- //ACTION
- //ACTION NOUN
- //ACTION VERB NOUN
- //SAY NPC SPEAK
- /*
- GAME DICTIONARY
- Movements:
- DOWN D, EAST E, NORTH N, NORTHEAST NE, NORTHWEST NW, SOUTH S,
- SOUTHEAST SE, SOUTHWEST SW, UP U, WEST W.
- Special verbs:
- EXAMINE, HELP, INVENTORY I, LOAD, LOOK L, NOPRINT, PAUSE, PRINT,
- QUIT, SAVE, SCORE.
- DICTIONARY
- Action verbs:
- BREAK, CLIMB, CLOSE, CROSS, DIG, DROP, DRINK, EMPTY, ENTER, EAT,
- FILL, FOLLOW, GIVE, GO, KILL, LOCK, PICK, PUT, OPEN, RUN, SAY,
- SHOOT, SWIM, TIE, TAKE, THROW, TURN, UNLOCK, UNTIE, WEAR.
- Prepositions:
- ACROSS, AT, FROM, IN, INTO, ON, OUT, OFF, THROUGH, TO, UP, WITH
- Adverbs:
- CAREFULLY, GENTLY, QUICKLY, SOFTLY, VICIOUSLY
- */
- //SPEAK
- //ONE WORD
- //TWO WORDS
- //"GIVE" item
- //item NOUN
- //item VERB NOUN
- //"CARRY" item, person
- //item NOUN, person
- //item VERB NOUN, person
- //"ATTACK" npc
- //attack, NPC
- //attack VERB NPC
- bool Parse(int inputBuffer){
- int
- /*
- switch (strlen(temp_command)){
- int buf[3] = "0"; int buf2[2];
- case 3:
- //check commands with a length of 3...
- for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
- if ( commandlengths[q] == 3 ) {
- //if the position of q is < 10, append a leading 0
- if ( q < 10 ) {
- itoa(q,buf2);
- strcat(buf2, but);
- }
- //otherwise, just store it
- itoa(q, buf); //overwrite the temp buffer.
- //find that number in legal commands
- for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
- if ( stringparser(buf) ) return q; //if the string matches
- //the parsed string, thast is its command number.
- //so, return it.
- }
- break; //if we fail, we fall through.
- }
- break; //fall though
- }
- case 4:
- //check commands with a length of 3.
- for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
- if ( commandlengths[q] == 4 ) {
- //if the position of q is < 10, append a leading 0
- if ( q < 10 ) {
- itoa(q,buf2);
- strcat(buf2, but);
- }
- //otherwise, just store it
- itoa(q, buf); //overwrite the temp buffer.
- //find that number in legal commands
- for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
- if ( stringparser(buf) ) return q; //if the string matches
- //the parsed string, thast is its command number.
- //so, return it.
- }
- break; //if we fail, we fall through.
- }
- break; //fall though
- }
- case 5:
- //check commands with a length of 3.
- for ( int q = 0; q < SizeOfArray(commandlengths); q++ ) {
- if ( commandlengths[q] == 4 ) {
- //if the position of q is < 10, append a leading 0
- if ( q < 10 ) {
- itoa(q,buf2);
- strcat(buf2, but);
- }
- //otherwise, just store it
- itoa(q, buf); //overwrite the temp buffer.
- //find that number in legal commands
- for ( int w = 0; 2 < SizeOfArraylegalcommands; w++ ){
- if ( stringparser(buf) ) return q; //if the string matches
- //the parsed string, thast is its command number.
- //so, return it.
- }
- break; //if we fail, we fall through.
- }
- break; //fall though
- }
- case 6:
- default:
- //invalid command.
- }
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement