142 lines
2.9 KiB
Go
142 lines
2.9 KiB
Go
package main
|
|
|
|
import "fmt"
|
|
|
|
type player struct {
|
|
position int
|
|
score int
|
|
roundsPlayed int
|
|
}
|
|
|
|
type game struct {
|
|
players [2]player
|
|
currentPlayer int
|
|
winner int
|
|
winscore int
|
|
}
|
|
|
|
func main() {
|
|
n := 6
|
|
player1 := player{8, 0, 0}
|
|
player2 := player{7, 0, 0}
|
|
|
|
part1(player1, player2, n)
|
|
part2(player1, player2)
|
|
}
|
|
|
|
func part2(player1 player, player2 player) {
|
|
diceResultMap := generateDiceResultMap()
|
|
gameMap := make(map[game]int64)
|
|
startGame := game{[2]player{player1, player2}, 0, -1, 21}
|
|
gameMap[startGame] = 1
|
|
for i := 0; i < 20; i++ {
|
|
tmpGameMap := make(map[game]int64)
|
|
for game, gameAmount := range gameMap {
|
|
if game.winner == -1 {
|
|
for diceResult1, diceResultAmount1 := range diceResultMap {
|
|
tmpGame := game
|
|
tmpGame.playOneRoung(diceResult1)
|
|
tmpGameMap[tmpGame] += gameAmount * diceResultAmount1
|
|
}
|
|
} else {
|
|
tmpGameMap[game] += gameAmount
|
|
}
|
|
}
|
|
gameMap = tmpGameMap
|
|
printGameMapInfos(gameMap)
|
|
fmt.Println()
|
|
}
|
|
|
|
}
|
|
|
|
func printGameMapInfos(gameMap map[game]int64) {
|
|
fmt.Println(len(gameMap))
|
|
var amountGames int64
|
|
var winnersPlayer1 int64
|
|
var winnersPlayer2 int64
|
|
var winSum int64
|
|
var bothWinners int64
|
|
var noWin int64
|
|
for key, val := range gameMap {
|
|
if key.winner == 0 {
|
|
winnersPlayer1 += val
|
|
winSum += val
|
|
}
|
|
if key.winner == 1 {
|
|
winnersPlayer2 += val
|
|
winSum += val
|
|
}
|
|
if key.winner == -1 {
|
|
noWin += val
|
|
}
|
|
amountGames += val
|
|
}
|
|
fmt.Printf("Amount Games: %d \n", amountGames)
|
|
fmt.Printf("Winners: %d \n", winSum)
|
|
fmt.Printf("Games Winner 1: %d \n", winnersPlayer1)
|
|
fmt.Printf("Games Winner 2: %d \n", winnersPlayer2)
|
|
fmt.Printf("Games No Win: %d \n", noWin)
|
|
fmt.Printf("Games Both Win: %d \n", bothWinners)
|
|
}
|
|
|
|
func (game *game) playOneRoung(increase int) {
|
|
if increasePlayer(&game.players[game.currentPlayer], increase, game.winscore) {
|
|
game.winner = game.currentPlayer
|
|
}
|
|
if game.currentPlayer == 1 {
|
|
game.currentPlayer = 0
|
|
} else {
|
|
game.currentPlayer = 1
|
|
}
|
|
}
|
|
|
|
func generateDiceResultMap() map[int]int64 {
|
|
tmpDiceResultMap := make(map[int]int64)
|
|
for a := 1; a < 4; a++ {
|
|
for b := 1; b < 4; b++ {
|
|
for c := 1; c < 4; c++ {
|
|
tmpDiceResultMap[a+b+c] += 1
|
|
}
|
|
}
|
|
}
|
|
return tmpDiceResultMap
|
|
}
|
|
|
|
func part1(player1 player, player2 player, n int) (diceRolls int) {
|
|
game := game{[2]player{player1, player2}, 0, -1, 1000}
|
|
for {
|
|
game.playOneRoung(n)
|
|
reduceN(&n, &diceRolls)
|
|
if game.winner != -1 {
|
|
fmt.Println(min(game.players[0].score, game.players[1].score) * diceRolls)
|
|
return
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
func reduceN(n *int, counter *int) {
|
|
*n--
|
|
if *n < 0 {
|
|
*n = 9
|
|
}
|
|
*counter += 3
|
|
}
|
|
|
|
func increasePlayer(player *player, n int, winscore int) bool {
|
|
(*player).position += n
|
|
if (*player).position > 10 {
|
|
(*player).position -= 10
|
|
}
|
|
(*player).score += (*player).position
|
|
(*player).roundsPlayed++
|
|
return (*player).score >= winscore
|
|
}
|
|
|
|
func min(a, b int) int {
|
|
if a < b {
|
|
return a
|
|
}
|
|
return b
|
|
}
|