Best Way to do commands

Blitz3D Forums/Blitz3D Beginners Area/Best Way to do commands

Gauge(Posted 2003) [#1]
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?


jhocking(Posted 2003) [#2]
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."


GfK(Posted 2003) [#3]
Select Lower$(Command$)
  Case "north", "nort", "nor", "no", "n"
;    Do Stuff
  Case "south", "sout", "sou", "so", "s"
;    Do more stuff
End Select
Not really sure what you're on about with the skills thing...


Ross C(Posted 2003) [#4]
or you could look at the string and use Left$ on it

north$="north"

for loop=0 to 5
    if string$=left$(north$,loop) then GoNorth
next




Gauge(Posted 2003) [#5]
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.


Warren(Posted 2003) [#6]
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.


Rob Farley(Posted 2003) [#7]
Why not just do

if upper(left(command$,1)="N" then gonorth

?


_PJ_(Posted 2003) [#8]
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.


Rob Farley(Posted 2003) [#9]
Then you check for other commands first.


Foppy(Posted 2003) [#10]
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>"