give fake humans alliance behavior

This commit is contained in:
evanpelle
2024-09-22 13:00:48 -07:00
parent e559af941f
commit 49aafe6379
5 changed files with 68 additions and 9 deletions
+1 -1
View File
@@ -109,7 +109,7 @@ export class AttackExecution implements Execution {
if (ticks < this.mg.config().numSpawnPhaseTurns()) {
return
}
if (this.breakAlliance) {
if (this.breakAlliance && this._owner.alliedWith(this.target as Player)) {
this.breakAlliance = false
this._owner.breakAllianceWith(this.target as Player)
}
+47 -5
View File
@@ -1,5 +1,5 @@
import {EventBus} from "../EventBus";
import {Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tile} from "../game/Game"
import {Cell, Execution, MutableGame, MutablePlayer, Player, PlayerInfo, PlayerType, TerrainType, TerraNullius, Tile} from "../game/Game"
import {PseudoRandom} from "../PseudoRandom"
import {and, bfs, dist, simpleHash} from "../Util";
import {AttackExecution} from "./AttackExecution";
@@ -13,10 +13,12 @@ export class FakeHumanExecution implements Execution {
private attackRate: number
private mg: MutableGame
private neighborsTerraNullius = true
private player: Player = null
private player: MutablePlayer = null
private enemy: Player | null = null
private rejected: Set<Player> = new Set<Player>
constructor(private playerInfo: PlayerInfo) {
this.random = new PseudoRandom(simpleHash(playerInfo.id))
@@ -52,6 +54,8 @@ export class FakeHumanExecution implements Execution {
return
}
this.handleAllianceRequests()
if (ticks % 100 == 0) {
this.enemy = null
}
@@ -94,10 +98,48 @@ export class FakeHumanExecution implements Execution {
const enemies = enemyborder.map(t => t.owner()).filter(o => o.isPlayer()).map(o => o as Player).sort((a, b) => a.troops() - b.troops())
if (this.random.nextInt(0, 1) == 1) {
this.sendAttack(enemies[0])
if (this.random.chance(10)) {
const toAlly = this.random.randElement(enemies)
if (!this.player.alliedWith(toAlly)) {
this.player.createAllianceRequest(toAlly)
}
}
if (this.random.chance(2)) {
if (!this.player.alliedWith(enemies[0]) || this.random.chance(30)) {
this.sendAttack(enemies[0])
}
} else {
this.sendAttack(enemies[this.random.nextInt(0, enemies.length)])
if (!this.player.alliedWith(enemies[0]) || this.random.chance(60)) {
this.sendAttack(this.random.randElement(enemies))
}
}
}
handleAllianceRequests() {
for (const req of this.player.incomingAllianceRequests()) {
if (this.rejected.has(req.requestor())) {
continue
}
if (req.requestor().numTilesOwned() > this.player.numTilesOwned() * 2) {
req.accept()
continue
}
if (req.recipient().numTilesOwned() > this.player.numTilesOwned()) {
if (this.random.chance(2)) {
req.accept()
} else {
req.reject()
this.rejected.add(req.recipient())
}
continue
}
if (this.random.chance(5)) {
req.accept()
} else {
req.reject()
this.rejected.add(req.recipient())
}
}
}
+16 -2
View File
@@ -49,7 +49,21 @@ export class GameImpl implements MutableGame {
}
}
createAllianceRequest(requestor: Player, recipient: Player): MutableAllianceRequest {
createAllianceRequest(requestor: MutablePlayer, recipient: Player): MutableAllianceRequest {
if (requestor.alliedWith(recipient)) {
console.log('cannot request alliance, already allied')
return
}
if (recipient.incomingAllianceRequests().find(ar => ar.requestor() == requestor) != null) {
console.log(`duplicate alliance request from ${requestor.name()}`)
return
}
const correspondingReq = requestor.incomingAllianceRequests().find(ar => ar.requestor() == recipient)
if (correspondingReq != null) {
console.log(`got corresponding alliance requests, accepting`)
correspondingReq.accept()
return
}
const ar = new AllianceRequestImpl(requestor, recipient, this._ticks, this)
this.allianceRequests.push(ar)
this.eventBus.emit(new AllianceRequestEvent(ar))
@@ -333,7 +347,7 @@ export class GameImpl implements MutableGame {
const breakerSet = new Set(breaker.alliances())
const alliances = other.alliances().filter(a => breakerSet.has(a))
if (alliances.length != 1) {
throw new Error('must have exactly one alliance')
throw new Error(`must have exactly one alliance, have ${alliances.length}`)
}
this.alliances_ = this.alliances_.filter(a => a != alliances[0])
this.eventBus.emit(new BrokeAllianceEvent(breaker, other))
+3
View File
@@ -151,6 +151,9 @@ export class PlayerImpl implements MutablePlayer {
}
createAllianceRequest(recipient: Player): MutableAllianceRequest {
if (this.alliedWith(recipient)) {
throw new Error(`cannot create alliance request, already allies`)
}
return this.gs.createAllianceRequest(this, recipient)
}