Tic-Tac-Toe板的2D阵列或2D切片?

I started to learn GoLang and meet trouble. When i tried to pass array (which size is defined after enter them from output) to the function a get error like "sorry but you type [][]string is not like [][]string". I tried different ways but can't cope with it. Any suggestions?

There is the main func:

func main(){
fmt.Println("Enter number of rows: ")
fmt.Scanf("%d", &size)
var board [size][size]string
for i:=0;i<size;i++{
    for j:=0;j<size;j++{
        board[i][j] = "_"
    }
}
fmt.Println("Choose side of fight (X, 0): ")
fmt.Scanf("%s", &opt)
fmt.Printf("Your side is %s
", opt)
for !win{
    printBoard(board, size)
    fmt.Println("Your move(a b, \"a\" is number of row, \"b\" is number of column: ")
    fmt.Scanf("%d %d", &move[0], &move[1])
    if move[0]>=1 && move[1]>=1 && move[0]<=3 && move[1]<=3{
        board[move[0]-1][move[1]-1] = opt
    }
    bot(&board, size)
    win, winner = checkWin(board, opt, size)
}
}

And example of function which depart take array:

func printBoard(in [][]string, size int){
for k:=0;k<size+1;k++{
    fmt.Printf("%d\t", k)
}
fmt.Println()
    for i:=0;i<size;i++{
        fmt.Printf("%d ", i+1)
    for j:=0;j<size;j++     {
        fmt.Printf("\t%s", in[i][j])
    }
    fmt.Print("
")
}
fmt.Print("
")
}

The ouput that I am trying to achieve is for Tic/Tac toe game. for eg:-

Enter number of rows: 3 Choose side of fight (X, 0): X 
Your side is X  0   1   2   3   1 _ _   _ 2 _   _   _ 3 _   _   _ 
Your move(a b, "a" is number of row, "b" is number of column: 1 1 0 1   2   3   1 X _   _ 2 _   _   _ 3 _   _   _ 
Your move(a b, "a" is number of row, "b" is number of column: 2 2 0 1   2   3   1 X _   _ 2 _   X   _ 3 _   _   _ 
Your move(a b, "a" is number of row, "b" is number of column: 3 3 0 1   2   3   1 X _   _ 2 _   X   _ 3 _   _   X You're winner!!!

In Go []string is a slice and [42]string is an array. Those types are very different.

See https://blog.golang.org/slices

In this case you should use slices as the board is of variable size.

board := make([][]string, size)
for i:=0;i<size;i++{
    board[i] = make([]string, size)
    for j:=0;j<size;j++{
        board[i][j] = "_"
    }
}

Since you are passing an array when calling printBoard function but in function definition you have passed Slice as an argument that's why the error of type mismatch. So my suggestion will be you can pass slice to the printBoard function.

func main() {
    fmt.Println("Enter number of rows: ")
    fmt.Scanf("%d", &size)
    var board [][]string
    board = make([][]string, size, (2*size)+1)

    fmt.Println("Choose side of fight (X, 0): ")
    var opt int
    fmt.Scanf("%s", &opt)
    fmt.Printf("Your side is %s
", opt)
    var win bool
    for !win {
        printBoard(board, size)
        fmt.Println("Your move(a b, \"a\" is number of row, \"b\" is number of column: ")
        fmt.Scanf("%d %d", &move[0], &move[1])
        if move[0] >= 1 && move[1] >= 1 && move[0] <= 3 && move[1] <= 3 {
            board[move[0]-1][move[1]-1] = opt
        }
        bot(&board, size)
        win, winner = checkWin(board, opt, size)
    }
}

For more information on Slice Check Go Slices: usage and internals blog

Don't use Go arrays. Array size is a compile-time constant. An array, the entire array, is passed by value as an argument to a function parameter or receiver.

Use slices. Declare a slice-based Board type. Give the type a set of methods; pass that type as the method receiver.


For example,

package main

import "fmt"

type Board [][]string // [rows][cols]

func NewBoard(rows, cols int) Board {
    b := make([][]string, rows)
    for r := range b {
        b[r] = make([]string, cols)
    }
    return Board(b)
}

func (b Board) Rows() int {
    return len(b)
}

func (b Board) Cols() int {
    if len(b) == 0 {
        return 0
    }
    return len(b[0])
}

func (b Board) Print() {
    maxWidth := 0
    for r := range b {
        for c := range b[r] {
            if width := len(b[r][c]); maxWidth < width {
                maxWidth = width
            }
        }
    }
    width := maxWidth + 2
    for r := range b {
        for c := range b[r] {
            fmt.Printf("%-*s", width, b[r][c])
        }
        fmt.Printf("
")
    }
}

func main() {
    rows, cols := 3, 2 // input from user?
    board := NewBoard(rows, cols)

    for r := range board {
        for c := range board[r] {
            board[r][c] = fmt.Sprintf("[R%d, C%d]", r, c)
        }
    }
    board.Print()

    fmt.Printf("
%v
%v %v
%v
",
        board,
        board.Rows(), board.Cols(),
        board[1][1],
    )
}

Output:

[R0, C0]  [R0, C1]  
[R1, C0]  [R1, C1]  
[R2, C0]  [R2, C1]  

[[[R0, C0] [R0, C1]] [[R1, C0] [R1, C1]] [[R2, C0] [R2, C1]]]
3 2
[R1, C1]

References:

The Go Blog: Go Slices: usage and internals

The Go Programming Language Specification