I have just started learning f# and developed a basic game however, at the moment you specify the cell to play on using a single array. For example to place an X or O on the middle cell, you would type 5 when promoted. I want to change this to accept 1,1
I have listed my source code for the game below
let arrayOfCells = [|" "; " "; " "; " "; " "; " "; " "; " " ;" "|]
let drawGrid()=
Console.Write("\n\n\t\t" + arrayOfCells.[0] + "|" + arrayOfCells.[1]+ "|" + arrayOfCells.[2] + "\n" )
Console.Write("\t\t------ "+ "\n" )
Console.Write("\t\t" + arrayOfCells.[3] + "|" + arrayOfCells.[4]+ "|" + arrayOfCells.[5] + "\n" )
Console.Write("\t\t------ "+ "\n" )
Console.Write("\t\t" + arrayOfCells.[6] + "|" + arrayOfCells.[7]+ "|" + arrayOfCells.[8] + "\n" )
You can create a 2D array in F# using the array2D function, so to initialize the cells, you could use:
let cells =
array2D [
[ " "; " "; " " ]
[ " "; " "; " " ]
[ " "; " "; " " ]
]
Now you can access elements using cells.[0, 0] and modify the values using:
cells.[1, 1] <- "X"
The indices are from 0 to 2 so if you want to iterate over all cells to draw the grid, you need:
printfn "-------------"
for x in 0 .. 2 do
printf "| "
for y in 0 .. 2 do
printf " %s |" cells.[x,y]
printfn "\n--------------"
This should give you all the information about 2D arrays, so that you can change the data structure in your game - there are other ways to improve this, but that's probably question for the Code Review site.
I am working on an AutoIt script that will take in a text file. The text file is made up of a series of test results in groups of 5 lines. This script is to go through the file and output the median score for each group. the score is displayed after the 11th ",". For example with this sample file:
a,a,a,a,a,a,a,a,a,a,100.2
a,a,a,a,a,a,a,a,a,a,300.2
a,a,a,a,a,a,a,a,a,a,160.2
a,a,a,a,a,a,a,a,a,a,301.2
a,a,a,a,a,a,a,a,a,a,161.2
b,b,b,b,b,b,b,b,b,b,110.5
b,b,b,b,b,b,b,b,b,b,87.5
b,b,b,b,b,b,b,b,b,b,89.5
b,b,b,b,b,b,b,b,b,b,190.5
b,b,b,b,b,b,b,b,b,b,170.5
c,c,c,c,c,c,c,c,c,c,90.2
c,c,c,c,c,c,c,c,c,c,190.2
c,c,c,c,c,c,c,c,c,c,40.2
c,c,c,c,c,c,c,c,c,c,20.2
c,c,c,c,c,c,c,c,c,c,80.2
I am expecting median scores of 161.2, 110.5 and 80.2 for groups a, b and c respectively. However, the output result is as follows:
median is = 161.2 ----- sorted array : 100.2 , 160.2 , 161.2 , 300.2 , 301.2
median is = 190.5 ----- sorted array : 110.5 , 170.5 , 190.5 , 87.5 , 89.5
median is = 40.2 ----- sorted array : 190.2 , 20.2 , 40.2 , 80.2 , 90.2
The first group gets sorted correctly but after that the array is no longer being sorted. And this is despite _ArraySort(...) being called directly before the output. Any idea why this could be happening?
The code is as follows:
Func CondenseResults()
$size = 5 ;temporary, variable to be passed on from other function
$gameDetail = ""
$rawResult = "D:\RTG_Benchmark\results\results.txt"
local $openResults = FileOpen("D:\RTG_Benchmark\results\results2.txt", 1)
Local $i = 1
Local $j = 0
Local $spaceCount = 0
Local $score[$size]
Local $runMultiplier[2] ; 0 = previous, 1 = current
Local $subString
Do
$resultLine = FileReadLine($rawResult, $i) ; read line from raw result
$subString = StringSplit($resultLine,",") ; split
If StringLen($resultLine) = 0 Then
$spaceCount += 1
$j = 0
FileWriteLine ( $openResults, "" & #CRLF)
Else
$gameDetail = $subString[1] & $subString[2] & $subString[3] & $subString[4] & $subString[5] & $subString[6] & $subString[7] & $subString[8] & $subString[9] & $subString[10] ; substring 1 - 10
$runMultiplier[1] = $gameDetail
If $i = 1 Then ;
$score[$j] = $subString[11]
Else
If $runMultiplier[1] <> $runMultiplier[0] Then
$j = 0
$score[$j] = $subString[11]
Else
$j += 1
If $j >= $size Then
$j = 0
EndIf
$score[$j] = $subString[11]
EndIf
$resultLine = FileReadLine($rawResult, $i+1)
$subString = StringSplit($resultLine,",") ; split
If StringLen($resultLine) = 0 Or $gameDetail <> $subString[1] & $subString[2] & $subString[3] & $subString[4] & $subString[5] & $subString[6] & $subString[7] & $subString[8] & $subString[9] & $subString[10] Then
_ArraySort($score, 0,0,0,0,1)
ConsoleWrite("median is = " & ($score[$size/2] & " ----- sorted array : " & $score[0] & " , " & $score[1] & " , " & $score[2] & " , " & $score[3] & " , " & $score[4]& #CRLF))
$j = 0
EndIf
EndIf
EndIf
$i += 1
$runMultiplier[0] = $runMultiplier[1]
Until $i >=_FileCountLines($rawResult)
$j += 1
$score[$j] = $subString[11]
_ArraySort($score)
ConsoleWrite("median is =" & ($score[$size/2] & " ----- sorted array : " & $score[0] & " , " & $score[1] & " , " & $score[2] & " , " & $score[3] & " , " & $score[4]& #CRLF))
FileClose($openResults)
sleep(100000)
Return 0
EndFunc
I found the issue. AutoIt was treating the numbers as strings and was sorting it one digit at a time from left to right.
Number() function took care of this issue.
I am trying to pass parameters from a .Net console app to a batch file. The parameters are not coming into the batch file.
How can I properly set up passing the parameters into the bat file?
Here is the method in the console app that I'm executing.
private static int ProcessBatFile(string ifldr, string ofldr, string iext, string oext, Int16 filewidth, Int16 fileheight, Int16 ctr)
{
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = ConfigurationSettings.AppSettings.Get("BatProcessDir") + "imagemagick.bat";
psi.Arguments = "-ifldr=" + ifldr + " -ofldr=" + ofldr + " -iext=" + iext + " -oext=" + oext + " -iwid=" + filewidth + " -ihgt=" + fileheight;
psi.UseShellExecute = false;
Process process = new Process();
process.StartInfo = psi;
process.Start();
return ctr;
}
Below, is the code in the bat file I'm trying to execute:
#echo on
echo %ofldr%
echo %ifldr%
echo %iwid%
echo %ihgt%
echo %oext%
echo %iext%
If you pass them as paramters, you can do this in the c# code:
psi.Arguments = ifldr + " " + ofldr + " " + iext + " " + oext + " " + filewidth + " " + fileheight;
and do this in the batch file:
#echo on
set ifldr=%1
set ofldr=%2
set iext=%3
set oext=%4
set iwid=%5
set ihgt=%6
echo %ofldr%
echo %ifldr%
echo %iwid%
echo %ihgt%
echo %oext%
echo %iext%
As an alternative solution, you can also directly modify the environment before executing the batch file using System.Environment.SetEnvironmentVariable:
System.Environment.SetEnvironmentVariable ("ifldr", ifldr);
....
This causes less problems if the parameters may contain spaces.
This is the exact code I am running in my system with sh lookup.sh. I don't see any details within nawk block printed or written to the file abc.txt. Only I am here 0 and I am here 1 are printed. Even the printf in nawk is not working. Please help.
processbody() {
nawk '
NR == FNR {
split($0, x, "#")
country_code[x[2]] = x[1]
next
system(" echo " I am here ">>/tmp/abc.txt")
}
{
CITIZEN_COUNTRY_NAME = "INDIA"
system(" echo " I am here 1">>/tmp/abc.txt")
if (CITIZEN_COUNTRY_NAME in country_code) {
value = country_code[CITIZEN_COUNTRY_NAME]
system(" echo " I am here 2">>/tmp/abc.txt")
} else {
value = "null"
system(" echo " I am here 3">>/tmp/abc.txt")
}
system(" echo " I am here 4">>/tmp/abc.txt")
print "found " value " for country name " CITIZEN_COUNTRY_NAME >> "/tmp/standalone.txt"
} ' /tmp/country_codes.config
echo "I am here 5" >> /tmp/abc.txt
}
# Main program starts here
echo "I am here 0" >> /tmp/abc.txt
processbody
And my country_codes.config file:
$ cat country_codes.config
IND#INDIA
IND#INDIB
USA#USA
CAN#CANADA
That's some pretty interesting awk code. The problem is that your first condition, the NR == FNR one, is active for each record read from the first file - the country_codes.config file, but the processing action contains next so after it reads a record and splits it and saves it, it goes and reads the next record - not executing the second block of the awk script. At the end, it is done - nothing more to do, so it never prints anything.
This works sanely:
processbody()
{
awk '
{
split($0, x, "#")
country_code[x[2]] = x[1]
#next
}
END {
CITIZEN_COUNTRY_NAME = "INDIA"
if (CITIZEN_COUNTRY_NAME in country_code) {
value = country_code[CITIZEN_COUNTRY_NAME]
} else {
value = "null"
}
print "found " value " for country name " CITIZEN_COUNTRY_NAME
} ' /tmp/country_codes.config
}
# Main program starts here
processbody
It produces the output:
found IND for country name INDIA
As Hai Vu notes, you can use awk's intrinsic record splitting facilities to simplify life:
processbody()
{
awk -F# '
{ country_code[$2] = $1 }
END {
CITIZEN_COUNTRY_NAME = "INDIA"
if (CITIZEN_COUNTRY_NAME in country_code) {
value = country_code[CITIZEN_COUNTRY_NAME]
} else {
value = "null"
}
print "found " value " for country name " CITIZEN_COUNTRY_NAME
} ' /tmp/country_codes.config
}
# Main program starts here
processbody
I don't know what you want to accomplish, but let me guess: if country is INDIA, then print the following output:
found IND for country name INDIA
If that is the case, the following code will accomplish that goal:
awk -F# '/INDIA/ {print "found " $1 " for country name " $2 }' /tmp/country_codes.config
The -F# flag tells awk (or nawk) to use # as the field separator.
#user549432 I think that you want one awk script that first reads in the country codes file and builds the associative array, and then reads in the input files (not # delimited) and does a substitution?
if so, let's assume that /tmp/country_codes.config has:
IND#INDIA
IND#INDIB
USA#USA
CAN#CANADA
and /tmp/input_file (not # delimited) has:
I am from INDIA
I am from INDIB
I am from CANADA
Then, we can have a nawk script like this:
nawk '
BEGIN {
while (getline < "/tmp/country_codes.config")
{
split($0,x,"#")
country_code[x[2]] = x[1]
}
}
{ print $1,$2,$3,country_code[$4]}
' /tmp/input_file
The output will be:
I am from IND
I am from IND
I am from CAN