package main import ( "fmt" "strconv" "strings" ) const ( skipBoardCreation = false skipUserCreation = false ) func createBoard(size int) [][]string { board := make([][]string, size) for r := 0; r < size; r++ { rowSlice := make([]string, size) for i := range rowSlice { rowSlice[i] = " " } board[r] = rowSlice } return board } func getBoardDimensions(board [][]string) (rows, columns int) { rows = len(board) columns = 0 for _, row := range board { if len(row) > columns { columns = len(row) } } return } func boardToString(board [][]string) string { maxRowLength := 0 rowStrings := make([]string, len(board)+1) for i, row := range board { if len(row) > maxRowLength { maxRowLength = len(row) } rowIndex := strconv.Itoa(i) if i < 10 { rowIndex += " " } rowStrings[i+1] = rowIndex + strings.Join(row, "|") } columnIndices := make([]string, maxRowLength) for i := 0; i < maxRowLength; i++ { rowIndex := strconv.Itoa(i) if i < 10 { rowIndex = " " + rowIndex } columnIndices[i] = rowIndex } rowStrings[0] = "/" + strings.Join(columnIndices, "") return strings.Join(rowStrings, "\n") } func createBoardUserInput() [][]string { var size int for { fmt.Print("canvas size? ") fmt.Scanln(&size) if size < 100 { return createBoard(size) } else { fmt.Println("There can't be more than 99 rows.") } } } func createUsersUserInput() []string { users := []string{} existingUsers := map[string]bool{} fmt.Println("Add users to the game. Users are a single alphabetical char.\nIf you're done submit an empty user.") for { fmt.Print("new user: ") var input string fmt.Scanln(&input) input = strings.Trim(input, " \n") if len(input) == 0 { if len(users) == 0 { fmt.Println("You need to add at least one user.") } else { break } } if len(input) == 1 { newUser := strings.ToUpper(input) if _, ok := existingUsers[newUser]; ok { fmt.Println("This user already exists.") } else { existingUsers[newUser] = false users = append(users, newUser) } } else { fmt.Println("The input can only be one character.") } } return users } func changeCellUserInput(board [][]string, user string) { var row []string for { var rowIndex int fmt.Print("row: ") fmt.Scanln(&rowIndex) if 0 <= rowIndex && rowIndex < len(board) { row = board[rowIndex] break } else { fmt.Println("The value needs to be in the range of the board rows.") continue } } for { var colIndex int fmt.Print("col: ") fmt.Scanln(&colIndex) if 0 <= colIndex && colIndex < len(row) { if row[colIndex] != " " { fmt.Println("This cell is already occupied.") defer changeCellUserInput(board, user) break } row[colIndex] = user break } else { fmt.Println("The value needs to be in the range of the board columns.") continue } } } func analyzeWin(board [][]string) string { for r := range board { didWin := true firstItem := board[r][0] for c := range board[r] { if board[r][c] != firstItem { didWin = false break } } if didWin && firstItem != " " { return firstItem } } for c := range board[0] { didWin := true firstItem := board[0][c] for r := range board { if board[r][c] != firstItem { didWin = false break } } if didWin && firstItem != " " { return firstItem } } size := len(board) { didWin := true firstItem := board[0][0] for i := 0; i < size; i++ { if board[i][i] != firstItem { didWin = false break } } if didWin && firstItem != " " { return firstItem } } { didWin := true firstItem := board[0][size-1] for i := 0; i < size; i++ { if board[i][size-i-1] != firstItem { didWin = false break } } if didWin && firstItem != " " { return firstItem } } return "" } func main() { var board [][]string if skipBoardCreation { board = createBoard(3) } else { board = createBoardUserInput() fmt.Println() } var users []string if skipUserCreation { users = []string{"X", "O"} } else { users = createUsersUserInput() fmt.Println() } printStats := func() { fmt.Println("Users playing:", strings.Join(users, " ")) rows, columns := getBoardDimensions(board) fmt.Println("Board Dimension:", rows, columns) fmt.Println(boardToString(board)) } currentUser := 0 for { fmt.Println() printStats() didWin := analyzeWin(board) if didWin != "" { fmt.Println() fmt.Println(didWin + " WINS!!") break } fmt.Println() fmt.Println("it's the turn of " + users[currentUser]) changeCellUserInput(board, users[currentUser]) currentUser = (currentUser + 1) % len(users) } }