parse a string

BlitzMax Forums/BlitzMax Beginners Area/parse a string

Many thanks for your help. I'll use this code into my game editor. So the editor user could describe/add some paths to the ennemies ships.

Concept code :
Strict

Const CTE_VITESSE  = 1
Const CTE_DEPLACER = 2
Const CTE_TOURNER  = 3
Const CTE_PAUSE    = 4
Const CTE_VITESSE_ROTATION = 5
Const CTE_ARRETER  = 6

' --------------------------------------------------------------------------------------------------	
	
Type Tpile

	Field Code_action
	Field Parametre
	
	Function Ajouter:TPile (Code_action, Parametre)
	
		Local p:TPile = New Tpile
		p.Code_action = Code_action
		p.Parametre = Parametre
		Return p
		
	End Function
	
End Type

' --------------------------------------------------------------------------------------------------

Type TVecteur

	Field Liste_action : TList = CreateList()
	Field Link_liste_action:TLink = Liste_action.FirstLink()
	
	Field bAction_terminee
	Field bEnPause

	Field PosX    : Float
	Field PosY    : Float
	Field Angle   : Float
	Field Vitesse : Float
	
	Field angle_cible : Float
	Field Vitesse_rotation : Float
	
	Field Deplacement_index
	Field Deplacement_max
	Field Deplacement_sens
	
	Field TempsPause : Int
	Field Temps      : Int
	
	Field x_dep#
	Field y_dep#
	
	Field Code_action

	'-----------------------------------------------------------------------------------------------
	
	Function Creer : Tvecteur (PosX#, PosY#)
		Local v:TVecteur = New TVecteur
		
		v.PosX# = PosX#
		v.PosY# = PosY#
		v.Angle = 0
		v.Vitesse# = 0.0
		v.Vitesse_rotation# = 0.0
		v.Deplacement_index = 0
		v.Deplacement_max = 0
		v.bAction_terminee = True
		v.bEnPause = False
		
		Return v
		
	End Function

	'-----------------------------------------------------------------------------------------------
	
	Method Ajouter_action (Code_action, pParametre)
		Local a:TPile
		a = TPile.Ajouter (Code_action, pParametre)
		Link_liste_action = Liste_action.FirstLink() 
		ListAddLast Liste_action, a
	End Method

	'-----------------------------------------------------------------------------------------------
	
	Method Donner_prochaine_action:TPile()
		
		Local a:TPile
		
		If TPile(Link_liste_action.value()) <> Null Then
			a.Code_action = TPile(Link_liste_action.value() ).code_action
			a.Parametre = TPile(Link_liste_action.value() ).parametre
		Else
			Return Null
		End If
		
		If Link_liste_action.NextLink() <> Null Then
			Link_liste_action = Link_liste_action.NextLink()
		Else 
			Return Null
		End If 
		
		Return a

	End Method

	'-----------------------------------------------------------------------------------------------
	
	Method Gerer_actions()
	
		Local a:TPile
		If bAction_terminee = True Then

			a = Donner_prochaine_action()

			If a.Code_action<>Null Then
			
				Select a.Code_action
				
					Case CTE_VITESSE
						FixerVitesse (a.Parametre)
						bAction_terminee = False
						Code_action = a.Code_action
					
					Case CTE_DEPLACER
					
						Deplacer (a.Parametre)
						bAction_terminee = False
						Code_action = a.Code_action
						
					Case CTE_TOURNER
						Tourner (a.Parametre)
						bAction_terminee = False
						Code_action = a.Code_action
						
					Case CTE_PAUSE
						Pause (a.Parametre)
						bAction_Terminee = False
						Code_action = a.Code_action

					Case CTE_VITESSE_ROTATION
						FixerVitesse_rotation (a.Parametre)
						bAction_Terminee = False
						Code_action = a.Code_action
						
						
					Case CTE_ARRETER
						Arreter()
						bAction_terminee = False
						Code_action = a.Code_action
				
				End Select
				
			End If
		End If
	
	End Method

	'-----------------------------------------------------------------------------------------------

	Method Deplacer (pNombre_de_points)
		
		If pNombre_de_points > 0 Then 
			Deplacement_Sens = 1
		End If
		
		If pNombre_de_points < 0 Then 
			Deplacement_Sens = - 1
		End If

		Deplacement_Max = Abs (pNombre_de_points)

	End Method

	'-----------------------------------------------------------------------------------------------

	Method FixerVitesse_rotation (pVitesse#)
		Vitesse_rotation# = pVitesse#
	End Method 	

	'-----------------------------------------------------------------------------------------------
	
	Method FixerVitesse (pVitesse#)
		Vitesse# = pVitesse#
	End Method 

	'-----------------------------------------------------------------------------------------------
	
	Method Tourner (pAngle)
		Angle_Cible = pAngle
	End Method

	'-----------------------------------------------------------------------------------------------
	
	Method Pause (pTempsPause)
		TempsPause = pTempsPause
	End Method 

	'-----------------------------------------------------------------------------------------------
	
	Method Arreter ()
	End Method 

	'-----------------------------------------------------------------------------------------------
	
	Method Calculer()

		Select Code_action

			Case CTE_VITESSE
					bAction_terminee = True
		
			Case CTE_DEPLACER
			
				
				If deplacement_index >= deplacement_max Then
					deplacement_index = 0
					x_dep# = 0
					y_dep# = 0
					bAction_terminee = True
				Else
					deplacement_index = deplacement_index + 1
					x_dep# =  Cos (Angle) * Vitesse#
					y_dep# =  Sin (Angle) * Vitesse#
				End If

				Select deplacement_sens
				
					Case 1
					 posx# = posx# + x_dep#
					 posy# = posy# + y_dep#
					Case -1
					 posx# = posx# - x_dep#
					 posy# = posy# - y_dep#
				
				End Select 
				
			Case CTE_PAUSE
			
				If bEnPause = False And bAction_terminee = False Then
					Temps = MilliSecs()
					bEnPause = True
				End If
			
				If Temps + TempsPause < MilliSecs() Then 
					bEnPause = False
					bAction_terminee = True
					Temps = 0
					TempsPause = 0
				End If
					
			Case CTE_TOURNER
			
				' deviation progressive
				
				Local TE# = RotaryDir( angle# , angle_cible#)
						
				If TE# < 0 Then angle# :- Vitesse_rotation#
				If TE# > 0 Then angle# :+ Vitesse_rotation#
				'
				While angle# > 360 angle#:-360 Wend
				While angle# <= 0 angle#:+360 Wend		
				
				angle = Int (angle)			

				x_dep# =  Cos (Angle#) * Vitesse#
				y_dep# =  Sin (Angle#) * Vitesse#
				
				Select deplacement_sens
				
					Case 1
					 posx# = posx# + x_dep#
					 posy# = posy# + y_dep#
					Case -1
					 posx# = posx# - x_dep#
					 posy# = posy# - y_dep#
				
				End Select 				
				
				If Angle# = Angle_cible# Then bAction_terminee = True
				
			Case CTE_VITESSE_ROTATION
				bAction_terminee = True
			
			Case CTE_ARRETER
			
				x_dep# = 0
				y_dep# = 0
				bAction_terminee = True
			
		End Select

	End Method

	'-----------------------------------------------------------------------------------------------
	
	Method Afficher()
	
		DrawOval posx#-3.0, posy#-3.0,6,6
	
	End Method
	
	' Fonction split Noel Cower's dans le code archive du site officiel
	'-----------------------------------------------------------------------------------------------
	
	Function SplitString$[]( s$, sp$ )
	    Local p:Int, l:Int, o$[32], x%
	    Local n:Int
	    For n = 0 Until s.length
	        Local lx% = x
	        For p = 0 Until sp.length
	            If s[n] = sp[p] Then
	                If x = o.length Then o = o[..o.length*2]
	                o[x] = s[l..n+(n = s.Length-1 And (Not (s[n]=sp[p])))].Trim( )
	                l = n+1
	                If o[x].length=0 Then Exit
	                x :+ 1
	                Exit
	            EndIf
	        Next
	        If x <> lx Then Continue
	        If n = s.length-1 Then
	            If x = o.length Then o = o[..o.length*2]
	            o[x] = s[l..n+(n = s.length-1 And (Not (s[n]=sp[p])))].Trim( )
	            If o[x].length = 0 Then Exit
	            x :+ 1
	        EndIf
	    Next
	    If x = 0 Then Return Null
	    Return o[0..x]
	End Function
	
	' Parser codé par SebHoll (http://www.blitzbasic.com/Community/posts.php?topic=72190)
	'-----------------------------------------------------------------------------------------------
	
	Method ProcessInstructionsFromString( pString$ )
	
		'Let's remove all spaces from the string, and then split up the instructions
		Local strInstructions$[] = SplitString(pString.Replace(" ",""),",")
		
		'Now, we can process each instruction one at a time
		For Local tmpInstruction$ = EachIn strInstructions
			
			'For each instruction, we want to split it to retrieve the function (index: 0) and the value (index: 1)
			Local tmpParts$[] = SplitString(tmpInstruction,"=")
			
			'Let's make sure that there was an equals in the instruction, and that there was a value (index: 1) 
			If tmpParts.length <> 2 Or Not tmpParts[1].length Then
				Print "Error: Cannot parse instruction: ~q" + tmpInstruction + "~q"
				Continue
			EndIf
			
			'Next, let's find out what function we should be using
			Select tmpParts[0].ToLower$()
				
				'Pass the value (index: 1) to the function we want by casting it as a float
				Case "ro";Ajouter_action(CTE_VITESSE_ROTATION, Float(tmpParts[1]))
				Case "v";Ajouter_action(CTE_VITESSE, Float(tmpParts[1]))
				Case "a";Ajouter_action(CTE_DEPLACER, Float(tmpParts[1]))
				Case "r";Ajouter_action(CTE_DEPLACER, - Float(tmpParts[1]))
				Case "t";AJouter_action(CTE_TOURNER, Float(tmpParts[1]))
				Case "p";Ajouter_action(CTE_PAUSE, Int(tmpParts[1]))
				Case "s";Ajouter_action(CTE_ARRETER, Float(tmpParts[1]))
				
				'Otherwise, let us know that the function specified is not understood
				Default;Print "Error: I do not understand the instruction ~q" + tmpParts[0] + "~q"
		
			EndSelect
			
		Next


	End Method	
	
	' Function trouvée sur le forum officiel 
	' (http://www.blitzbasic.com/Community/posts.php?topic=57317#637149)
	'-----------------------------------------------------------------------------------------------
	
	Function RotaryDir#(SourceDir#,DestDir#)
	
		Local Diff1#,Diff2#,Dir#
	
		If SourceDir# > DestDir#
			Diff1#=SourceDir-DestDir
			diff2#=(360.0-SourceDir)+DestDir
			If diff2<diff1
				dir#=diff2
			Else
				dir#=diff1/-1
			EndIf
		Else
			If SourceDir#<DestDir#
				diff1=DestDir-SourceDir
				diff2=(360.0-DestDir)+SourceDir
				If diff2<diff1
					dir#=diff2/-1
				Else
					dir#=diff1
				EndIf
			Else
				dir=0
			EndIf
		EndIf
		Return dir
		
	End Function	
	
End Type

' --------------------------------------------------------------------------------------------------

' Programme principal

' --------------------------------------------------------------------------------------------------

' v : set speed, param# = speed
' ro : set rotation, ro# = rotation factor
' a : advance, param = pixels 
' r : rear, param = pixels
' t : turn, param = angle
' p : pause, param = millisecs
' s=0 put this at the end.



Local v1:TVecteur = TVecteur.Creer (100,100)
v1.ProcessInstructionsFromString( "v=2.0,ro=6.0,a=100,t=120,a=200,p=2000,t=180,r=200,t=30,r=200,s=0" )

Local v2:TVecteur = TVecteur.Creer (400,400)
v2.ProcessInstructionsFromString( "v=1.0,ro=2.0,a=100,t=020,a=300,t=80,a=100,p=3000,t=130,r=100,s=0" )


Graphics 1024,768

SetBlend alphablend

While Not KeyDown (KEY_ESCAPE)
	'Cls
	v1.Gerer_actions()
	v2.Gerer_actions()
	v1.Calculer()
	v2.Calculer()
	SetColor 255,0,0
	v1.Afficher()
	SetColor 0,255,0
	v2.Afficher()
	Flip 
Wend