井字游戏板使用2D阵列还是2D切片?

时间:2018-06-29 11:34:23

标签: arrays go slice

我开始学习GoLang并遇到麻烦。当我尝试将数组(从输出输入它们后定义大小)传递给函数时,出现诸如“抱歉,但您键入[] [] string不像[] [] string”这样的get错误。我尝试了不同的方法,但无法应对。有什么建议么?

主要功能如下:

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\n", 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)
}
}

离开数组的函数示例:

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("\n")
}
fmt.Print("\n")
}

我要达到的目标是针对Tic / Tac toe游戏。例如:-

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!!!

3 个答案:

答案 0 :(得分:4)

不要使用Go数组。数组大小是一个编译时常量。数组(整个数组)通过值作为参数传递给函数参数或接收器。

使用切片。声明基于切片的Board类型。给该类型提供一组方法;将该类型作为方法的接收者。


例如,

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("\n")
    }
}

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("\n%v\n%v %v\n%v\n",
        board,
        board.Rows(), board.Cols(),
        board[1][1],
    )
}

输出:

[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]

参考文献:

The Go Blog: Go Slices: usage and internals

The Go Programming Language Specification

答案 1 :(得分:2)

在Go中,[]string是一个切片,而[42]string是一个数组。这些类型非常不同。

请参见https://blog.golang.org/slices

在这种情况下,您应该使用切片,因为木板的尺寸可变。

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

答案 2 :(得分:1)

由于在调用printBoard函数时传递了数组,但是在函数定义中,您传递了Slice作为参数,这就是type mismatch错误的原因。所以我的建议是您可以将slice传递给printBoard函数。

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\n", 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)
    }
}

有关切片检查Go Slices: usage and internals blog

的更多信息