Commit 35715c72 authored by ceddral's avatar ceddral
Browse files

game: add farm scoring

parent 00c812c7
......@@ -250,6 +250,7 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
// evaluate score, closed
closed = true
score = 0
baseScore := 0 // score but without multiplicators, e.g. just number of tiles in city or number of cities in farm
pennants := 0
switch place.piece.fieldIdToType[id] {
case fCloister:
......@@ -257,11 +258,12 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
for dy := -1; dy <= 1; dy++ {
_, ok := b.Get(x + dx, y + dy)
if ok {
score++
baseScore++
}
}
}
closed = (score == 9)
score = baseScore
case fRoad:
visited := make(map[Coord]struct{})
hasInn := false
......@@ -283,9 +285,10 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
}
return struct{}{}
}, struct{}{}, x, y, id)
score = len(visited)
baseScore = len(visited)
score = baseScore
if closed && hasInn {
score = 2 * score
score = 2 * baseScore
} else if !closed && hasInn {
score = 0
}
......@@ -311,19 +314,65 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
}
return struct{}{}
}, struct{}{}, x, y, id)
score = pennants + len(visited)
baseScore = pennants + len(visited)
if closed && hasCathedral {
score = 3 * score
score = 3 * baseScore
} else if closed && !hasCathedral {
score = 2 * score
score = 2 * baseScore
} else if !closed && !hasCathedral {
score = 1 * score
score = 1 * baseScore
} else if !closed && hasCathedral {
score = 0
}
case fFarm:
println("farm scoring not yet implemented")
return false, 0
// collect city tiles connected to our farm
connectedCityTiles := make(map[MapCursor]struct{})
b.MapStructure(func(acc interface{}, c MapCursor)interface{} {
place, _ := b.Get(c.x, c.y) // can never fial, map only visits placed pieces
// iterate neighbour fields of all fields within piece
fs := place.piece.f[place.rot]
for y := range fs {
for x, f := range fs[y] {
// iterate top left half of neighbours
// 0 1 2
// 3 x -
// - - -
for i := 0; i < 4; i++ {
dx := -1 + (i % 3)
dy := -1 + (i / 3)
ny := y + dy
nx := x + dx
if ny < 0 { continue }
if ny >= len(fs) { continue }
if nx < 0 { continue }
if nx >= len(fs[ny]) { continue }
nf := fs[y + dy][x + dx]
if f.id != c.id && nf.id != c.id {
// neither of the pair is our farm
continue
}
if f.t == fCity {
connectedCityTiles[MapCursor{c.x, c.y, f.id}] = struct{}{}
}
if nf.t == fCity {
connectedCityTiles[MapCursor{c.x, c.y, nf.id}] = struct{}{}
}
}
}
}
return struct{}{}
}, struct{}{}, x, y, id)
// filter city tiles belonging to the same city
baseScore := 0
for c, _ := range connectedCityTiles {
b.MapStructure(func(acc interface{}, cur MapCursor)interface{} {
delete(connectedCityTiles, cur)
return struct{}{}
}, struct{}{}, c.x, c.y, c.id)
baseScore++
}
closed = false
score = 3 * baseScore
default:
panic("trying to score unknown structure type")
}
......@@ -333,6 +382,7 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
}
// assign score, return followers to players
majority := 0
playerToBonus := make(map[*GamePlayer]int)
// map player -> sum of token weights
weights := make(map[*GamePlayer]int)
b.MapStructure(func(acc interface{}, c MapCursor)interface{} {
......@@ -349,6 +399,9 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
if majority < weights[p] {
majority = weights[p]
}
if t == tPig {
playerToBonus[p] = baseScore
}
// return followers
delete(place.fieldIdToPlayer, c.id)
delete(place.fieldIdToToken, c.id)
......@@ -360,6 +413,9 @@ func (b *Board) TryScore(x, y int, id byte, gameEnd bool) (closed bool, score in
for p, w := range weights {
if majority == w {
p.score += score
if bonus, ok := playerToBonus[p]; ok {
p.score += bonus
}
}
}
}
......
......@@ -472,8 +472,7 @@ type StatePlacePiece struct {
func NewStatePlacePiece(g *Game, a *GamePlayer) GameState {
if len(g.pieceOrder) == 0 {
// TODO wertung
panic("we did it")
return &StateFinished{g : g, agent: a}
}
p := g.drawPiece()
placeable := false
......@@ -802,3 +801,27 @@ func (s *StateScore) agentTransition(p *GamePlayer) {
func (s *StateScore) patientTransition(p *GamePlayer) {}
func (s *StateScore) agentAction(p *GamePlayer, key Key) bool { return false }
func (s *StateScore) patientAction(p *GamePlayer, key Key) bool { return false }
type StateFinished struct{
g *Game
agent *GamePlayer
}
func (s *StateFinished) getAgent() *GamePlayer { return s.agent }
func (s *StateFinished) getGame() *Game { return s.g }
func (s *StateFinished) String() string { return "StateFinished" }
func (s *StateFinished) agentTransition(p *GamePlayer) {
// final scoring
s.g.board.m.Range(func(k, v interface{})bool {
c := k.(Coord)
p := v.(Place)
// only score structures that contain at least one token
for id, _ := range p.fieldIdToToken {
s.g.board.TryScore(c.x, c.y, id, true)
}
return true
})
}
func (s *StateFinished) patientTransition(p *GamePlayer) {}
func (s *StateFinished) agentAction(p *GamePlayer, key Key) bool { return true }
func (s *StateFinished) patientAction(p *GamePlayer, key Key) bool { return true }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment