Best Way to do commands
Blitz3D Forums/Blitz3D Beginners Area/Best Way to do commands
| ||
I am still working on my text base mud, and would like to know the best way to do commmands. I'm currently storing them in types etc. But is their a better way to do it. Say for example the command is "north", which also must accept "nort","nor","no", and "n". My program currently runs an If command$= "north" then Move p,North. But it has to run thru several If commands, and for skills it runs a for each p.player/skill. Is their a faster way to do this? Or any other ideas? |
| ||
You could do multiple Ifs on a single line (as in "If command="north" or command="nort" or command="n" Then etc.) but that won't be any faster to execute, just more efficient code. If you have enough commands (for a text based MUD I assume you have a lot of commands) you could do a separate input checker which determines what the player intends to do (ie. what the typed command means to the game) and then feed the result of that into your game code. In other words a separate function which parses the input text to determine the intended commands and then feeds those commands to the game. For example, if the player types "nort" the input checker would determine the player wants command 1 and pass 1 to the movement code. Frankly however I don't know why you want to capture typos. Most games only understand "north" and anything else comes up "I don't understand." |
| ||
Select Lower$(Command$) Case "north", "nort", "nor", "no", "n" ; Do Stuff Case "south", "sout", "sou", "so", "s" ; Do more stuff End SelectNot really sure what you're on about with the skills thing... |
| ||
or you could look at the string and use Left$ on itnorth$="north" for loop=0 to 5 if string$=left$(north$,loop) then GoNorth next |
| ||
thanks i was thinking about using the left$, etc commands. Their may not be a better way other then running if/thens and loops. Select case i was told is slower, will try it though. |
| ||
Select case i was told is slower, will try it though. Perhaps, but how fast does it have to be really? Text parsing isn't something that happens more than a few times per second. |
| ||
Why not just do if upper(left(command$,1)="N" then gonorth ? |
| ||
I reckon the select/case example wold be best sited, especially if you order it so the most common commands.. (I assume will be N,S,E,W etc) are at the beginning of your argument. @DrAv, This would prevent other commands that begin with the first letter. I.e. Eat wold always be read as East etc. |
| ||
Then you check for other commands first. |
| ||
In any case it would be easier to use an if-then *loop*. Instead of putting similar lines of code in your program for every individual command you could use the same single line of code for all commands. Here's an example in which first, the commands are read from data statements into objects. Then, the program reads your input and tests it against all commands in memory. It is a match when it matches as a whole, or when it matches the beginning of a command (and the first hit wins if more than one command has the same beginning; the directional commands are before the others in the data statement, so "e" will be read as "east" and not as "examine"). A special command is "quit" which ends the program. I would imagine that in a full game, the COMMAND object is extended to contain more information on the command, like the number of arguments it can handle ("get hammer", "put hammer in bag" (that's more complicated though with "in" inbetween arguments) etc.), or some internal representation of the command, like "move north" in the case of "north".Const END_OF_DATA$ = "<end>" ; command type definition Type COMMAND Field f_word$ End Type ; function for checking if input matches command Function COMMAND_matchInput(p_command.COMMAND,p_input$) ; get length of command length = Len(p_command\f_word) ; check for smaller and smaller lengths if prefix of command matches input For i = length To 1 Step -1 If (p_input = Left(p_command\f_word,i)) Then Return(True) End If Next Return(False) End Function ; function for searching all commands for match with input Function COMMAND_find.COMMAND(p_input$) For command.COMMAND = Each COMMAND If (COMMAND_matchInput(command,p_input)) Then Return(command) End If Next Return(Null) End Function ; reset data reading to start of command data Restore commandData ; read words and create corresponding command objects Repeat Read word$ If (word = END_OF_DATA) Then Exit newCommand.COMMAND = New COMMAND newCommand\f_word = word Forever ; run game Repeat order$ = Input("> ") If (order = "quit") Then Exit command.COMMAND = COMMAND_find(order) If (command = Null) Then Print("I didn't understand the order ["+order+"]") Else Print("The command you used was ["+command\f_word+"]") End If Forever ; at end of game, delete command objects Delete Each COMMAND End .commandData Data "north","south","east","west","examine","talk","get","put","<end>" |