Ultima attività 1750171421

ticktacktoe.go Raw
1package main
2
3import (
4 "fmt"
5 "strconv"
6 "strings"
7)
8
9const (
10 skipBoardCreation = false
11 skipUserCreation = false
12)
13
14func createBoard(size int) [][]string {
15 board := make([][]string, size)
16
17 for r := 0; r < size; r++ {
18 rowSlice := make([]string, size)
19 for i := range rowSlice {
20 rowSlice[i] = " "
21 }
22
23 board[r] = rowSlice
24 }
25
26 return board
27}
28
29func getBoardDimensions(board [][]string) (rows, columns int) {
30 rows = len(board)
31 columns = 0
32
33 for _, row := range board {
34 if len(row) > columns {
35 columns = len(row)
36 }
37 }
38
39 return
40}
41
42func boardToString(board [][]string) string {
43 maxRowLength := 0
44 rowStrings := make([]string, len(board)+1)
45 for i, row := range board {
46 if len(row) > maxRowLength {
47 maxRowLength = len(row)
48 }
49
50 rowIndex := strconv.Itoa(i)
51 if i < 10 {
52 rowIndex += " "
53 }
54 rowStrings[i+1] = rowIndex + strings.Join(row, "|")
55 }
56
57 columnIndices := make([]string, maxRowLength)
58 for i := 0; i < maxRowLength; i++ {
59 rowIndex := strconv.Itoa(i)
60 if i < 10 {
61 rowIndex = " " + rowIndex
62 }
63 columnIndices[i] = rowIndex
64 }
65 rowStrings[0] = "/" + strings.Join(columnIndices, "")
66
67 return strings.Join(rowStrings, "\n")
68}
69
70func createBoardUserInput() [][]string {
71 var size int
72 for {
73 fmt.Print("canvas size? ")
74 fmt.Scanln(&size)
75 if size < 100 {
76 return createBoard(size)
77 } else {
78 fmt.Println("There can't be more than 99 rows.")
79 }
80 }
81}
82
83func createUsersUserInput() []string {
84 users := []string{}
85 existingUsers := map[string]bool{}
86
87 fmt.Println("Add users to the game. Users are a single alphabetical char.\nIf you're done submit an empty user.")
88 for {
89 fmt.Print("new user: ")
90 var input string
91 fmt.Scanln(&input)
92 input = strings.Trim(input, " \n")
93
94 if len(input) == 0 {
95 if len(users) == 0 {
96 fmt.Println("You need to add at least one user.")
97 } else {
98 break
99 }
100 }
101
102 if len(input) == 1 {
103 newUser := strings.ToUpper(input)
104 if _, ok := existingUsers[newUser]; ok {
105 fmt.Println("This user already exists.")
106 } else {
107 existingUsers[newUser] = false
108 users = append(users, newUser)
109 }
110 } else {
111 fmt.Println("The input can only be one character.")
112 }
113 }
114 return users
115}
116
117func changeCellUserInput(board [][]string, user string) {
118 var row []string
119
120 for {
121 var rowIndex int
122 fmt.Print("row: ")
123 fmt.Scanln(&rowIndex)
124
125 if 0 <= rowIndex && rowIndex < len(board) {
126 row = board[rowIndex]
127 break
128 } else {
129 fmt.Println("The value needs to be in the range of the board rows.")
130 continue
131 }
132 }
133
134 for {
135 var colIndex int
136 fmt.Print("col: ")
137 fmt.Scanln(&colIndex)
138
139 if 0 <= colIndex && colIndex < len(row) {
140 if row[colIndex] != " " {
141 fmt.Println("This cell is already occupied.")
142 defer changeCellUserInput(board, user)
143 break
144 }
145
146 row[colIndex] = user
147 break
148 } else {
149 fmt.Println("The value needs to be in the range of the board columns.")
150 continue
151 }
152 }
153}
154
155func analyzeWin(board [][]string) string {
156 for r := range board {
157 didWin := true
158 firstItem := board[r][0]
159 for c := range board[r] {
160 if board[r][c] != firstItem {
161 didWin = false
162 break
163 }
164 }
165
166 if didWin && firstItem != " " {
167 return firstItem
168 }
169 }
170
171 for c := range board[0] {
172 didWin := true
173 firstItem := board[0][c]
174 for r := range board {
175 if board[r][c] != firstItem {
176 didWin = false
177 break
178 }
179 }
180
181 if didWin && firstItem != " " {
182 return firstItem
183 }
184 }
185
186 size := len(board)
187 {
188 didWin := true
189 firstItem := board[0][0]
190 for i := 0; i < size; i++ {
191 if board[i][i] != firstItem {
192 didWin = false
193 break
194 }
195 }
196
197 if didWin && firstItem != " " {
198 return firstItem
199 }
200 }
201
202 {
203 didWin := true
204 firstItem := board[0][size-1]
205 for i := 0; i < size; i++ {
206 if board[i][size-i-1] != firstItem {
207 didWin = false
208 break
209 }
210 }
211
212 if didWin && firstItem != " " {
213 return firstItem
214 }
215 }
216
217 return ""
218}
219
220func main() {
221 var board [][]string
222 if skipBoardCreation {
223 board = createBoard(3)
224 } else {
225 board = createBoardUserInput()
226 fmt.Println()
227 }
228
229 var users []string
230 if skipUserCreation {
231 users = []string{"X", "O"}
232 } else {
233 users = createUsersUserInput()
234 fmt.Println()
235 }
236
237 printStats := func() {
238 fmt.Println("Users playing:", strings.Join(users, " "))
239 rows, columns := getBoardDimensions(board)
240 fmt.Println("Board Dimension:", rows, columns)
241 fmt.Println(boardToString(board))
242 }
243
244 currentUser := 0
245 for {
246 fmt.Println()
247 printStats()
248
249 didWin := analyzeWin(board)
250 if didWin != "" {
251 fmt.Println()
252 fmt.Println(didWin + " WINS!!")
253 break
254 }
255
256 fmt.Println()
257 fmt.Println("it's the turn of " + users[currentUser])
258 changeCellUserInput(board, users[currentUser])
259 currentUser = (currentUser + 1) % len(users)
260 }
261}
262