package four import ( "bufio" "os" "strconv" "strings" ) type cell struct { value int called bool } type board struct { cells [5][5]cell bingo bool } type bingo struct { calls []int boards []board } func (b *bingo) read(filename string) error { file, err := os.Open(filename) if err != nil { return err } defer file.Close() scanner := bufio.NewScanner(file) // Read the first line scanner.Scan() calls := strings.Split(scanner.Text(), ",") for _, n := range calls { number, err := strconv.Atoi(n) if err != nil { return err } b.calls = append(b.calls, number) } // Read the game boards line := 0 var current board for scanner.Scan() { if scanner.Text() == "" { if line > 0 { b.boards = append(b.boards, current) } line = 0 current = board{} continue } withoutWhitespace := strings.Fields(scanner.Text()) for i, n := range withoutWhitespace { number, err := strconv.Atoi(n) if err != nil { return err } current.cells[line][i].value = number } line++ } if line > 0 { b.boards = append(b.boards, current) } return nil } func (b *bingo) reset() { for i := range b.boards { b.boards[i].bingo = false for row := 0; row < 5; row++ { for column := 0; column < 5; column++ { b.boards[i].cells[row][column].called = false } } } } func (b *bingo) play() (int, int) { winningCall := -1 score := -1 for _, call := range b.calls { for i := range b.boards { bingo := b.boards[i].called(call) if bingo { score := 0 for row := 0; row < 5; row++ { for column := 0; column < 5; column++ { if !b.boards[i].cells[row][column].called { score += b.boards[i].cells[row][column].value } } } return score, call } } } return score, winningCall } func (b *bingo) slowPlay() (int, int) { winningCall := -1 score := -1 callingBoards := b.boards for _, call := range b.calls { filteredBoards := []board{} for i := range callingBoards { bingo := callingBoards[i].called(call) if !bingo { filteredBoards = append(filteredBoards, callingBoards[i]) } else if len(callingBoards) == 1 { score := 0 for row := 0; row < 5; row++ { for column := 0; column < 5; column++ { if !callingBoards[i].cells[row][column].called { score += callingBoards[i].cells[row][column].value } } } return score, call } } callingBoards = filteredBoards } return score, winningCall } func (b *board) called(number int) bool { // Mark the called number found := false for row := 0; row < 5; row++ { for column := 0; column < 5; column++ { if b.cells[row][column].value == number { b.cells[row][column].called = true found = true break } } if found { break } } // Check to see if there is a win // Check rows found = false for row := 0; row < 5; row++ { winner := true for column := 0; column < 5; column++ { if !b.cells[row][column].called { winner = false } } if winner { b.bingo = true return b.bingo } } // Check columns for column := 0; column < 5; column++ { winner := true for row := 0; row < 5; row++ { if !b.cells[row][column].called { winner = false } } if winner { b.bingo = true return b.bingo } } // // Check left diagonal // winner := true // for index := 0; index < 5; index++ { // if !b.cells[index][index].called { // winner = false // break // } // } // if winner { // b.bingo = true // return b.bingo // } // // Check right diagonal // winner = true // for index := 0; index < 5; index++ { // if !b.cells[index][4-index].called { // winner = false // break // } // } // if winner { // b.bingo = true // return b.bingo // } return b.bingo }