how to print a multidimension array in kotlin? - kotlin

i'm new to kotlin and need help printing this problem below
how do you print this code:
val chessBoard = mutableListOf(
mutableListOf<String>(" ", "a", "b", "c", "d", "e", "f", "g", "h"),
mutableListOf<String>("1", " ", " ", " ", " ", " ", " ", " ", " "),
mutableListOf<String>("2", "W", "W", "W", "W", "W", "W", "W", "W"),
mutableListOf<String>("3", " ", " ", " ", " ", " ", " ", " ", " "),
mutableListOf<String>("4", " ", " ", " ", " ", " ", " ", " ", " "),
mutableListOf<String>("5", " ", " ", " ", " ", " ", " ", " ", " "),
mutableListOf<String>("6", " ", " ", " ", " ", " ", " ", " ", " "),
mutableListOf<String>("7", "B", "B", "B", "B", "B", "B", "B", "B"),
mutableListOf<String>("8", " ", " ", " ", " ", " ", " ", " ", " "),
)
into this:
+---+---+---+---+---+---+---+---+
8 | | | | | | | | |
+---+---+---+---+---+---+---+---+
7 | B | B | B | B | B | B | B | B |
+---+---+---+---+---+---+---+---+
6 | | | | | | | | |
+---+---+---+---+---+---+---+---+
5 | | | | | | | | |
+---+---+---+---+---+---+---+---+
4 | | | | | | | | |
+---+---+---+---+---+---+---+---+
3 | | | | | | | | |
+---+---+---+---+---+---+---+---+
2 | W | W | W | W | W | W | W | W |
+---+---+---+---+---+---+---+---+
1 | | | | | | | | |
+---+---+---+---+---+---+---+---+
a b c d e f g h
thanks for helping out

joinToString() is your friend:
val line = "\n +---+---+---+---+---+---+---+---+\n"
chessBoard.reversed().joinToString(separator = line, prefix = line) { l ->
l.joinToString(separator = "|", postfix = "|") { " $it " }
}.also{println(it)}

This could do it:
println(
((chessBoard)
.reversed()
.map { (it + "").joinToString(if (it[0] != " ") " | " else " ") + "\n" })
.run { arrayOf("") + this }
.joinToString(" +---+---+---+---+---+---+---+---+\n")
)

Related

How do I move the position of the player based on user input. (Represented by O). Code I have written So far. Pls answer in vb

Module Program
Dim startx As Integer
Dim starty As Integer
Dim endx As Integer
Dim endy As Integer
Dim maze As String(,) = {
{"x ", "x ", "x ", "x ", "x ", "x ", "x ", "x ", "x ", "x"},
{"O ", " ", " ", " ", " ", " ", " ", " ", " ", "x"},
{"x ", "x ", "x ", "x ", "x ", " ", "x ", "x ", " ", "x"},
{"x ", "x ", " ", "x ", "x ", " ", "x ", "x ", " ", "x"},
{"x ", "x ", " ", " ", " ", " ", "x ", "x ", " ", "x"},
{"x ", "x ", "x ", "x ", "x ", " ", "x ", "x ", "x ", "x"},
{"x ", " ", " ", " ", " ", " ", " ", " ", " ", "x"},
{"x ", " ", "x ", "x ", "x ", "x ", "x ", "x ", " ", "x"},
{"x ", " ", " ", " ", " ", "x ", "x ", "x ", " ", " "},
{"x ", "x ", "x ", "x ", "x ", "x ", "x ", "x ", "x ", "x"}}
Sub Main(args As String())
Console.WriteLine("This is a maze game")
Console.WriteLine("Please enter where you want to go (x and y cordinate)")
start
displaychessboard()
End Sub
Sub displaychessboard()
Console.WriteLine(" 0 1 2 3 4 5 6 7 8 9")
For x As Integer = 0 To 9
Console.Write(x & " ")
For y As Integer = 0 To 9
Console.Write(maze(x, y))
Next
Console.WriteLine()
Next
End Sub
Sub makemove()
End Sub
End Module
How do I move the position of the player based on user input.
You store the position of a player in one or more variables. Since you have a two-dimensional maze, you can use a two-element tuple or, for simplicity, a player_x and a player_y variable.
When the user provides input, you modify the variables accordingly. For example, "moving left" would decrease player_x by one.
When drawing your maze, you look at the current values of player_x and player_y. If they match the current position in your loop, you output "O" instead of a space.
Pls answer in vb
The Stack Overflow community will gladly help you understand concepts and teach you how to improve your Visual Basic skills, but we are not a "here is my task, you write code" service.

2d array of generic length in a class

I have a class that currently works like this.
Class Maze
Public board(10, 10) As Object
Dim maze1 As New Maze With {.board = {{" ", " ", "X", "X", " ", "X", "X", "X", " ", "X"},
{"X", " ", " ", " ", " ", "X", " ", " ", " ", "X"},
{" ", " ", "X", " ", "X", " ", " ", " ", " ", "X"},
{"X", " ", "X", " ", " ", "X", "X", "X", " ", " "},
{"X", " ", "X", "X", " ", " ", " ", " ", "X", " "},
{" ", "X", " ", " ", "X", " ", " ", "X", " ", " "},
{" ", "X", "X", " ", "X", " ", " ", " ", " ", "X"},
{" ", " ", " ", " ", " ", "X", "X", " ", " ", "X"},
{"X", "X", " ", "X", " ", " ", " ", "X", " ", " "},
{" ", " ", " ", "X", "X", " ", " ", " ", "X", " "}}}
However I cant find away to remove the prespecified length without methods such as GetLength now not working.
In the .Net world, if you define a type as Object you're almost always doing something very wrong you will soon come to regret. In this case, it looks like String may be more appropriate. However, perhaps based on how this is used later it might turn out that Integer or a specific class type could be better, alongside a special method to translate this into text or graphics for output.
Moving on to the specific issue of size... consider a List:
Class Maze
Dim board As List(Of List(Of String))
board = New List(Of List(Of string)) From {
New List(Of String) From {" ", " ", "X", "X", " ", "X", "X", "X", " ", "X"},
New List(Of String) From {"X", " ", " ", " ", " ", "X", " ", " ", " ", "X"},
New List(Of String) From {" ", " ", "X", " ", "X", " ", " ", " ", " ", "X"},
New List(Of String) From {"X", " ", "X", " ", " ", "X", "X", "X", " ", " "},
New List(Of String) From {"X", " ", "X", "X", " ", " ", " ", " ", "X", " "},
New List(Of String) From {" ", "X", " ", " ", "X", " ", " ", "X", " ", " "},
New List(Of String) From {" ", "X", "X", " ", "X", " ", " ", " ", " ", "X"},
New List(Of String) From {" ", " ", " ", " ", " ", "X", "X", " ", " ", "X"},
New List(Of String) From {"X", "X", " ", "X", " ", " ", " ", "X", " ", " "},
New List(Of String) From {" ", " ", " ", "X", "X", " ", " ", " ", "X", " "}
}
Now you can add a line to end like so:
board.Add(New List(Of String) From {" ", "X", " ", " ", " " ... })
Or add a column like this:
For Each c As List(Of String) In board
c.Add(" ")
Next
This allows you to have 2d array without specifying length explicitly
Public board(,) As Object = {}

Splitting NoName column in SQL Query

I want to use a CSV file Test1.csv to create a Recordset with customized column names.
The CSV file format:
(Blank) | SomeAggr | (Blank) | Div1 | Div2 | Div3
-----------------------------------------------------------
G0.1 | 1.23 | | ABC | DEF | GHI
G0.2 | 2.45 | | JKL | MNO | PQR
G0.3 | 9.02 | | STU | VWX | YZA
G1.1 | 3.32 | | ZYX | WVU | TSR
G1.2 | 5.53 | | QPO | NML | KJI
G1.3 | 1.15 | | HGF | EDC | BAZ
G1.4 | 4.65 | | FKJ | OTU | WKL
The 1st & 3rd Columns have blank headers. The 1st column contains data I want to split it into two columns as shown in SQL Query.
Note - I am creating a recordset and do not want to do any transformations using a WorkSheet.
The final Recordset via SQL Query should look like this:
GVal | Pos | Aggr | (Blank) | DV A | DV B | DV C
--------------------------------------------------------------------
0 | 1 | 1.23 | | ABC | DEF | GHI
0 | 2 | 2.45 | | JKL | MNO | PQR
0 | 3 | 9.02 | | STU | VWX | YZA
1 | 1 | 3.32 | | ZYX | WVU | TSR
1 | 2 | 5.53 | | QPO | NML | KJI
1 | 3 | 1.15 | | HGF | EDC | BAZ
1 | 4 | 4.65 | | FKJ | OTU | WKL
I am running the following code:
Option Explicit
Sub Testing()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
Dim strDataSource$, strF1$, strFF1$, strSql$, oCon as Object, oRs as Object, i%, Fld
strFF1 = "Test1.csv"
strF1 = "`C:\Users\adam\Downloads\Test Folder`\"
strDataSource = Thisworkbook.Path
Set oCon = CreateObject("ADODB.Connection")
Set oRs = CreateObject("ADODB.Recordset")
strCon = "Driver=Microsoft Access Text Driver (*.txt, *.csv);Dbq=" & strDataSource & ";Extensions=asc,csv,tab,txt;HDR=Yes;"
'Getting Top 1 row to loop through fields and create SQL string accordingly.
strSql = "SELECT TOP 1 * FROM " & strF1 & strFF1
oCon.Open strCon
Set oRs = oCon.Execute(strSql)
i = 1
strSql = "SELECT "
For Each Fld In oRs.Fields
Select Case True
Case Is = Fld.Name = "NoName" '1st NoName column
If Fld.Value <> vbNullString Then
strSql = strSql & "CLng(Replace(Left(" & Fld.Name & ", InStr(" & Fld.Name & ", ""."") - 1), ""G"", """"))" & " AS [GVal], "
strSql = strSql & "CLng(Right(" & Fld.Name & ", Len(" & Fld.Name & ") - InStr(" & Fld.Name & ", ""."")))" & " AS [Pos], "
Else
strSql = strSql & Fld.Name & ", " '2nd NoName column
End If
Case Is = Fld.Name = "SomeAggr"
strSql = strSql & "[" & Fld.Name & "] AS [Aggr],"
Case Is = InStr(1, Fld.Name, "Div") > 0
strSql = strSql & "[" & Fld.Name & "] AS [DV " & Chr(i + 64) & "], "
i = i + 1
End Select
Next Fld
If Right(Trim(strSql), 1) = "," Then strSql = Left(Trim(strSql), Len(Trim(strSql)) - 1)
strSql = strSql & " FROM " & strF1 & strFF1
oRs.Close
' >>> getting error on below `Set oRs` line
[Microsoft][ODBC Text Driver] '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.
Set oRs = oCon.Execute(strSql)
Stop
ExitSub:
oRs.Close
oCon.Close
Set oRs = Nothing
Set oCon = Nothing
Application.ScreenUpdating = True
Application.DisplayAlerts = True
Exit Sub
ErrorHandler:
MsgBox "Error No: " & Err.Number & vbCrLf & "Description: " & Err.Description, vbCritical + vbOKOnly, "An Error occurred!"
Err.Clear
On Error GoTo 0
Resume ExitSub
End Sub
Here is the SQL Query.
SELECT CLng(Replace(Left(NoName, InStr(NoName,".")-1), "G", "")) AS [GVal],
CLng(Right(NoName, Len(NoName) - InStr(NoName,"."))) AS [Pos],
[SomeAggr] AS [Aggr],
[Div1] AS [DV A],
[Div2] AS [DV B],
[Div3] AS [DV C]
FROM `\C:\Users\Adam\Downloads\Test Folder`\Test1.csv
The code gives me the following error:
[Microsoft][ODBC Text Driver] '' is not a valid name. Make sure that it does not include invalid characters or punctuation and that it is not too long.
I don't know how to get a reference or select the 1st Blank Column to split it's values into two columns.
The Query works in MSAccess and the 1st NoName column is shown as Field1 and 2nd NoName column is shown as Field3.
SQL code expects single quotes as string deliminators instead of double quotes. In the For Each Fld In oRs.Fields loop, there are two lines which use double quotes instead of single quotes while constructing strSql:
strSql = strSql & "CLng(Replace(Left(" & Fld.Name & ", InStr(" & Fld.Name & ", ""."") - 1), ""G"", """"))" & " AS [GVal], "
strSql = strSql & "CLng(Right(" & Fld.Name & ", Len(" & Fld.Name & ") - InStr(" & Fld.Name & ", ""."")))" & " AS [Pos], "
These should be changed to:
strSql = strSql & "CLng(Replace(Left(" & Fld.Name & ", InStr(" & Fld.Name & ", '.') - 1), 'G', ''))" & " AS [GVal], "
strSql = strSql & "CLng(Right(" & Fld.Name & ", Len(" & Fld.Name & ") - InStr(" & Fld.Name & ", '.')))" & " AS [Pos], "
when i try to replicate your code i get the following:
a) Not sure if it is the problem but you have two columns names [NoName] so you need to distinguish between the two. (b) Could you to put the NoName columns in square brackets and try single quotes instead of double quotes?
SELECT
CLng(Replace(Left(NoName, InStr(NoName, ".") - 1), "G", "")) AS [GVal],
CLng(Right(NoName, Len(NoName) - InStr(NoName, "."))) AS [Pos], [SomeAggr] AS [Aggr],
NoName,
[Div1] AS [DV A],
[Div2] AS [DV B],
[Div3] AS [DV C]
FROM
`C:\Temp`\Test.csv

Sending Email within loop in a function

code is building the email but it is only displaying one row when there is six. I got it correct on the text file but I need it to do the same in the email message. I think I got the for next statement in the wrong location. Here is the example of the code that I am having problem with. I do not know how to place the for next statement without interrupting the vbLine
For Each p In query
If p.Contract_No IsNot Nothing Then
ContractNo = p.Contract_No
Else
ContractNo = " "
End If
If p.Vendor_Name IsNot Nothing Then
VenderName = p.Vendor_Name
Else
VenderName = " "
End If
If p.Termination_Date IsNot Nothing Then
TerminationDate = p.Termination_Date
' ReportDateStr = ReportDate.ToString
TerminationDateStr = String.Format("{0:MM/dd/yyyy}", TerminationDate)
Else
TerminationDateStr = " "
End If
If p.Dept_Name IsNot Nothing Then
DeptName = p.Dept_Name
Else
DeptName = " "
End If
If p.Renewal_Option_Desc IsNot Nothing Then
RenewalOption = p.Renewal_Option_Desc
Else
RenewalOption = " "
End If
If p.Contract_Desc IsNot Nothing Then
ContractDesc = p.Contract_Desc
Else
ContractDesc = " "
End If
If p.Contact_Email IsNot Nothing Then
ContactEmail = p.Contact_Email
Else
ContactEmail = "** N/A ** "
End If
' sends email with attachment
EmailMsgBody = "-- TOTAL # OF CONTRACTS WITH FAILSAFE DATE ON " + DateStr + " IS: " + icnt.ToString + vbCrLf +
vbNewLine + " __________________ " +
vbNewLine +
vbNewLine + " *****Contracts**** " +
vbNewLine + " __________________ " +
vbNewLine +
vbNewLine + "Contract#" + " " + "Vender Name" + " " + "Termination Date" + " " + "Dept Name" + " " + "Renewal Option" + " " + "Contract Desc" + " " + "Email Address" +
vbNewLine + "------------" + " " + "-----------------" + " " + "---------------------" + " " + "--------------" + " " + "--------------------" + " " + "-----------------" + " " + "-----------------" +
vbNewLine + ContractNo.PadRight(18) + " " + _
VenderName.PadRight(38) + " " + _
TerminationDateStr.PadRight(26) + " " + _
DeptName.PadRight(27) + " " + _
RenewalOption.PadRight(45) + " " + _
ContractDesc.PadRight(32) + " " + _
ContactEmail.PadRight(11) + " "

Left Join works with table but fails with query

The following left join query in MS Access 2007
SELECT
Table1.Field_A,
Table1.Field_B,
qry_Table2_Combined.Field_A,
qry_Table2_Combined.Field_B,
qry_Table2_Combined.Combined_Field
FROM Table1
LEFT JOIN qry_Table2_Combined
ON (Table1.Field_A = qry_Table2_Combined.Field_A)
AND (Table1.Field_B = qry_Table2_Combined.Field_B);
is expected by me to return this result:
+--------+---------+---------+---------+----------------+
|Field_A | Field_B | Field_A | Field_B | Combined_Field |
+--------+---------+---------+---------+----------------+
|1 | | | | |
+--------+---------+---------+---------+----------------+
|1 | | | | |
+--------+---------+---------+---------+----------------+
|2 |1 |2 |1 |John, Doe |
+--------+---------+---------+---------+----------------+
|2 |2 | | | |
+--------+---------+---------+---------+----------------+
[Table1] has 4 records, [qry_Table2_Combined] has 1 record.
But it gives me this:
+--------+---------+---------+---------+----------------+
|Field_A | Field_B | Field_A | Field_B | Combined_Field |
+--------+---------+---------+---------+----------------+
|2 |1 |2 |1 |John, Doe |
+--------+---------+---------+---------+----------------+
|2 |2 |2 | |, |
+--------+---------+---------+---------+----------------+
Really weird is that the [Combined_Field] has a comma in the second row. I use a comma to concatenate two fields in [qry_Table2_Combined].
If the left join query uses a table created from the query [qry_Table2_Combined] it works as expected.
Why does this left join query not give the same result for a query and a table? And how can i get the right results using a query in the left join?
Looking at you logic, it seems that you only want combined fields where field_A = "2" (SELECT '2' AS Field_A). I suspect that this is causing the problem. Would it be possible to go about a solution in a different way, for example:
SELECT
t1.Field_A,
t1.Field_B,
t2.Field_B As t2B,
[t2].[Col_1] & ", " & [t2].[Col_2] AS Combined
FROM t1 LEFT JOIN t2
ON t1.Field_B = t2.Field_B
WHERE t1.Field_A="2"
UNION ALL
SELECT
t1.Field_A,
t1.Field_B,
"None" As t2B,
"None" AS Combined
FROM t1
WHERE t1.Field_A<>"2"
Concatenation: change the & operators to + operators and the result should be as expected.
Missing rows: I can reproduce this issue but cannot explain it, other than to say a) it's probably a bug and b) it will probably never get fixed :(
For sanity I tested the same code in SQL Server and it works as expected.
As a general point an outer join can be simulated using union and padding the missing values e.g. pseudo code:
( A JOIN B )
UNION
( A NOT MATCH B { A.*, <pad values for B> } )
In your case and in Access SQL:
SELECT Table1.Field_A, Table1.Field_B,
qry_Table2_Combined.Field_A,
qry_Table2_Combined.Field_B,
qry_Table2_Combined.Combined_Field
FROM Table1
INNER JOIN qry_Table2_Combined
ON (Table1.Field_A = qry_Table2_Combined.Field_A)
AND (Table1.Field_B = qry_Table2_Combined.Field_B)
UNION ALL
SELECT Table1.Field_A, Table1.Field_B,
NULL AS Field_A,
NULL AS Field_B,
NULL AS Combined_Field
FROM Table1
WHERE NOT EXISTS ( SELECT *
FROM qry_Table2_Combined
WHERE (Table1.Field_A = qry_Table2_Combined.Field_A)
AND (Table1.Field_B = qry_Table2_Combined.Field_B) );
The above seems to produce the results you were expecting.
Access repro code, with concatenation fix, uncomment code for suggested workaround:
Sub EXfewfTempler()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
With .ActiveConnection
Dim Sql As String
Sql = "CREATE TABLE Table1 ( Field_A VARCHAR(10), Field_B VARCHAR(10) );"
.Execute Sql
Sql = "CREATE TABLE Table2 ( Field_B VARCHAR(10), Col_1 VARCHAR(10), Col_2 VARCHAR(10));"
.Execute Sql
Sql = "CREATE VIEW qry_Table2_Combined AS SELECT '2' AS Field_A, Table2.Field_B, Table2.Col_1 + ', ' + Table2.Col_2 AS Combined_Field FROM Table2; "
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (1, NULL);"
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (1, NULL);"
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (2, 1);"
.Execute Sql
Sql = "INSERT INTO Table1 VALUES (2, 2);"
.Execute Sql
Sql = "INSERT INTO Table2 VALUES (1, 'John', 'Doe');"
.Execute Sql
Sql = _
"SELECT " & _
"Table1.Field_A, " & _
"Table1.Field_B, " & _
"qry_Table2_Combined.Field_A, " & _
"qry_Table2_Combined.Field_B, " & _
"qry_Table2_Combined.Combined_Field " & _
"FROM Table1 " & _
"LEFT JOIN qry_Table2_Combined " & _
" ON (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
"AND (Table1.Field_B = qry_Table2_Combined.Field_B);"
' Sql = _
' "SELECT Table1.Field_A, Table1.Field_B, " & _
' " qry_Table2_Combined.Field_A, " & _
' " qry_Table2_Combined.Field_B, " & _
' " qry_Table2_Combined.Combined_Field " & _
' " FROM Table1 " & _
' " INNER JOIN qry_Table2_Combined " & _
' " ON (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
' " AND (Table1.Field_B = qry_Table2_Combined.Field_B) " & _
' "UNION ALL " & _
' "SELECT Table1.Field_A, Table1.Field_B, " & _
' " NULL AS Field_A, " & _
' " NULL AS Field_B, " & _
' " NULL AS Combined_Field " & _
' " FROM Table1 " & _
' " WHERE NOT EXISTS ( SELECT * " & _
' " FROM qry_Table2_Combined " & _
' " WHERE (Table1.Field_A = qry_Table2_Combined.Field_A) " & _
' " AND (Table1.Field_B = qry_Table2_Combined.Field_B) );"
Dim rs
Set rs = .Execute(Sql)
MsgBox rs.GetString(2, , vbTab & vbTab, , "<NULL>")
End With
Set .ActiveConnection = Nothing
End With
End Sub
isn't this a problem with MSAccess parsing. for a test change the field names in the query to Field_C and Field_D and see if you still have the same problem