parse a string

BlitzMax Forums/BlitzMax Beginners Area/parse a string

The Forum Archive is locked. These are the original blitzbasic.com forums, kept so their posts can still be read and searched. No new topics, replies or edits can be made here. To join the conversation, head over to the Blitz3D+ forums.

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