Function or subroutine?

New to FreeBASIC? Post your questions here.
Post Reply
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Function or subroutine?

Post by Luis Babboni »

Hi people, I bother you again after some time! :-)

For the new version of my chess engine Soberango, I need to read an string (the inicital FEN to whos knows what it is) and return 35 values. 32 of them are ULongInt values and 3 are Int values.

Is better to use a Sub or a Function (If it is possible to use both, I have still no clear how to return differents type of values with a function... if it is necessary, those 3 integer values could be ULongInt too)?
Note: I need to use it just once before the start of each chess game. So no worries about speed for example.

Thanks!
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Function or subroutine?

Post by dodicat »

What exactly is the datatype int?
Remember in 64 bits ulongint is the same as uinteger, longint is the same as integer, all 8 bits long.
The 32 bit compiler will make integer and uinteger 4 bits.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Function or subroutine?

Post by jj2007 »

dodicat wrote:all 8 bits long
You meant bytes, obviously: 64 bits
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Function or subroutine?

Post by caseih »

FB functions can only return a single value. So either you can use a user-defined type to hold all these values and return an instance of that (which would invoke copying on the caller's part), or pass them in by reference. The latter would make for a very messy and error prone sub declaration, though!

What will you eventually do with these 35 values? This may be crying out for a little bit of encapsulation using object-oriented programming.

Another possibility is to use an array to return the values.
paul doe
Moderator
Posts: 1733
Joined: Jul 25, 2017 17:22
Location: Argentina

Re: Function or subroutine?

Post by paul doe »

Code: Select all

type RetValue
  as ulongint foo( 0 to 34 )
  as long bar( 0 to 2 )
end type

function DoSomething() as RetValue
  dim as RetValue result
  
  '' Fill in the values
  
  return( result )
end function

var r = DoSomething()

sleep()
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Function or subroutine?

Post by grindstone »

In my Colochessum engine testing program I solved this with properties. You only have to write the fen string to the UDT and immediately afterwards you can read all corresponding values. Conversely you can get the fen from the actual values (you should replace the Integers with ULongs):

Code: Select all

Type tFen
	pieces As String
	opponent As String
	castling As String
	enPassant As String
	halfmoves As Integer
	moves As Integer
	Declare Property fen As String 'read fen
	Declare Property fen(board() As Integer) As String 'generate fen from internal board
	Declare Property fen(f As String) 'write fen
	Declare Property fen(f As String, board() As Integer) 'write fen and set internal board
End Type

Property tFen.fen(f As String) 'parse fen
	Dim As Integer ptr1, ptr2
	
	ptr1 = InStr(f, " ")
	pieces = Left(f, ptr1 - 1)
	ptr2 = InStr(ptr1 + 1, f, " ") 
	opponent = Mid(f, ptr1 + 1, ptr2 - ptr1 - 1)
	ptr1 = InStr(ptr2 + 1, f, " ")
	castling = Mid(f, ptr2 + 1, ptr1 - ptr2 - 1)
	ptr2 = InStr(ptr1 + 1, f, " ")
	enPassant = Mid(f, ptr1 + 1, ptr2 - ptr1 - 1)
	ptr1 = InStr(ptr2 + 1,f," ")
	halfmoves = Val(Mid(f, ptr2 + 1, ptr1 - ptr2 - 1))
	moves = Val(Mid(f, ptr1 + 1))
                     
End Property

Property tFen.fen As String
	Return pieces + " " + opponent + " " + castling + " " + enPassant + " " + _
	       Str(halfmoves) + " " + Str(moves)
End Property

Property tFen.fen(f As String, bo() As Integer) 'write fen and set internal board
	Dim As Integer x, y, i, row, col
	Dim As String opp, g
		
	If Len(f) Then
		fen = f 'write fen
	EndIf
	
	'preset internal board
	For row = 0 To 11
		For col = 0 To 11
			bo(col, row) = 7 'border
		Next
	Next
			
	row = 2
	col = 1
	
	For x = 1 To Len(pieces)
		g = Mid(pieces, x, 1)
		Select Case g
			Case "1" To "8" 'empty field(s)
				i = Val(g)
				For y = 1 To i
					bo(col + y, row) = 0 'empty field
				Next
				col += i
			Case "/" 'next row
				row += 1
				col = 1
			Case Else
				col += 1 'next column
				bo(col, row) = InStr("kqbnrp0PRNBQK", g) - 7 'put piece to field
		End Select
	Next
		
End Property

Property tFen.fen(bo() As Integer) As String 'generate fen from internal board
	Dim As Integer col, lin, countFree
	Dim As String g
	
	pieces = ""
	For col = 2 To 9
		For lin = 2 To 9
			'convert internal board to fen-string
			g = Mid("kqbnrp0PRNBQK", bo(lin, col) + 7, 1)
			If g = "0" Then
				countFree += 1
			Else
				If countFree Then
					pieces += Str(countFree)
					countFree = 0
				EndIf
				pieces += g
			EndIf
		Next
		If countFree Then
			pieces += Str(countFree)
			countFree = 0
		EndIf
		pieces += "/"
	Next
	pieces = RTrim(pieces, "/")
	
	Return fen
	
End Property
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Function or subroutine?

Post by Luis Babboni »

Thanks to all!
I understand that a function is not a good idea. But not see you said a subroutine is. :-O

What is UDT grindstone?
This is your parser for extract data from the FEN?
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Function or subroutine?

Post by caseih »

UDT is a user-defined type. It's a structure that can encapsulate multiple pieces of data together, optionally with methods for manipulating that data, including properties. An instance of a UDT can be passed around and manipulated. Putting methods (functions and subs) inside a UDT is called object-oriented programming.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Function or subroutine?

Post by Luis Babboni »

caseih wrote:UDT is a user-defined type. It's a structure that can encapsulate multiple pieces of data together, optionally with methods for manipulating that data, including properties. An instance of a UDT can be passed around and manipulated. Putting methods (functions and subs) inside a UDT is called object-oriented programming.
Thanks caseih..... I never studied programmation.
The only book of programation I read was the Spectrum manual in the 80s! :-D
EDIT: ap, and an assembler book... for spectrum too.
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Function or subroutine?

Post by grindstone »

Luis Babboni wrote:This is your parser for extract data from the FEN?
It's a parser as well as a generator. The advantage is that you don't have to care about the conversion. Just read or write either the FEN or any of its values as a variable.

The example I've posted won't work as standalone, because it's linked with Colochessum's internal board, but if you'd tell me exactly what you intend to do, I could recode it, so you could check out how it works.
Luis Babboni
Posts: 375
Joined: Mar 15, 2015 12:41

Re: Function or subroutine?

Post by Luis Babboni »

grindstone wrote:
Luis Babboni wrote:This is your parser for extract data from the FEN?
It's a parser as well as a generator. The advantage is that you don't have to care about the conversion. Just read or write either the FEN or any of its values as a variable.

The example I've posted won't work as standalone, because it's linked with Colochessum's internal board, but if you'd tell me exactly what you intend to do, I could recode it, so you could check out how it works.
Sorry, "Generator" of what? From chessboard to FEN?

I finished my parser from FEN to bitboards yet.... now I have not too much advance in move generator with bitboards. :-D
grindstone
Posts: 862
Joined: May 05, 2015 5:35
Location: Germany

Re: Function or subroutine?

Post by grindstone »

Luis Babboni wrote:Sorry, "Generator" of what? From chessboard to FEN?
And vice versa. You can set and read the FEN as well as the board:

Code: Select all

Dim As Integer board(12,12)
Dim As tFen gamefen
Dim As String myFEN

myFEN = gamefen.fen 'generates a FEN from the members of "gamefen"

myFEN = gamefen.fen(board()) 'generates a FEN from "board(12,12)" and sets up the members of "gamefen"

gamefen.fen = ("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1", board()) 'sets up "board(12,12)" and the members of "gamefen" to the initial postition

myFEN = "7K/6q1/7b/8/8/8/8/6k1 w - - 3 41" 'mate
gamefen.fen = myFEN 'parses the FEN and sets the members of "gamefen" (without affecting the board)
Furthermore you can set and read every single member of the UDT.
Post Reply