Add day four Bingo player
This commit is contained in:
216
four/bingo.go
Normal file
216
four/bingo.go
Normal file
@@ -0,0 +1,216 @@
|
||||
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
|
||||
}
|
Reference in New Issue
Block a user