mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:50:43 +00:00
increased game length, balanced attacks
This commit is contained in:
@@ -110,7 +110,7 @@ export class ClientGame {
|
||||
|
||||
this.renderer.initialize()
|
||||
this.input.initialize()
|
||||
this.executor.spawnBots(1000)
|
||||
this.executor.spawnBots(this.config.numBots())
|
||||
|
||||
|
||||
this.intervalID = setInterval(() => this.tick(), 10);
|
||||
|
||||
@@ -2,4 +2,8 @@ import {Cell} from "./Game";
|
||||
|
||||
export function manhattanDist(c1: Cell, c2: Cell): number {
|
||||
return Math.abs(c1.x - c2.x) + Math.abs(c1.y - c2.y);
|
||||
}
|
||||
|
||||
export function within(value: number, min: number, max: number): number {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import {Player, PlayerID, PlayerInfo, TerrainType, TerrainTypes, TerraNullius, Tile} from "../Game";
|
||||
import {Colord, colord} from "colord";
|
||||
import {pastelTheme} from "./PastelTheme";
|
||||
|
||||
|
||||
export interface Config {
|
||||
@@ -9,6 +8,7 @@ export interface Config {
|
||||
turnIntervalMs(): number
|
||||
gameCreationRate(): number
|
||||
lobbyLifetime(): number
|
||||
numBots(): number
|
||||
}
|
||||
|
||||
export interface PlayerConfig {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import {Player, PlayerInfo, TerraNullius, Tile} from "../Game";
|
||||
import {within} from "../Util";
|
||||
import {Config, PlayerConfig, Theme} from "./Config";
|
||||
import {pastelTheme} from "./PastelTheme";
|
||||
|
||||
export const defaultConfig = new class implements Config {
|
||||
numBots(): number {
|
||||
return 1000
|
||||
}
|
||||
player(): PlayerConfig {
|
||||
return defaultPlayerConfig
|
||||
}
|
||||
@@ -23,9 +27,9 @@ export const defaultPlayerConfig = new class implements PlayerConfig {
|
||||
attackLogic(attacker: Player, defender: Player | TerraNullius, tileToConquer: Tile): {attackerTroopLoss: number; defenderTroopLoss: number; tilesPerTickUsed: number} {
|
||||
if (defender.isPlayer()) {
|
||||
return {
|
||||
attackerTroopLoss: Math.max(defender.troops() / attacker.troops(), 1),
|
||||
defenderTroopLoss: 0,
|
||||
tilesPerTickUsed: Math.max(defender.troops() / attacker.troops(), .25)
|
||||
attackerTroopLoss: Math.min(defender.troops() / 1000, 10),
|
||||
defenderTroopLoss: Math.min(attacker.troops() / 2000, 5),
|
||||
tilesPerTickUsed: 1
|
||||
}
|
||||
} else {
|
||||
return {attackerTroopLoss: 1, defenderTroopLoss: 0, tilesPerTickUsed: 1}
|
||||
@@ -34,7 +38,11 @@ export const defaultPlayerConfig = new class implements PlayerConfig {
|
||||
}
|
||||
|
||||
attackTilesPerTick(attacker: Player, defender: Player | TerraNullius, numAdjacentTilesWithEnemy: number): number {
|
||||
return numAdjacentTilesWithEnemy / 4
|
||||
if (defender.isPlayer()) {
|
||||
return within(attacker.numTilesOwned() / defender.numTilesOwned(), .01, .5) * numAdjacentTilesWithEnemy
|
||||
} else {
|
||||
return numAdjacentTilesWithEnemy / 4
|
||||
}
|
||||
}
|
||||
|
||||
boatAttackAmount(attacker: Player, defender: Player | TerraNullius): number {
|
||||
@@ -50,16 +58,17 @@ export const defaultPlayerConfig = new class implements PlayerConfig {
|
||||
}
|
||||
|
||||
startTroops(playerInfo: PlayerInfo): number {
|
||||
return 1000
|
||||
if (playerInfo.isBot) {
|
||||
return 1000
|
||||
}
|
||||
return 5000
|
||||
}
|
||||
|
||||
troopAdditionRate(player: Player): number {
|
||||
let toAdd = Math.sqrt(player.numTilesOwned() * player.troops()) / 5
|
||||
const max = Math.sqrt(player.numTilesOwned()) * 1000 + 1000
|
||||
|
||||
let toAdd = 10 + (player.troops() + Math.sqrt(player.troops() * player.numTilesOwned())) / 250
|
||||
|
||||
const max = Math.sqrt(player.numTilesOwned()) * 100 + 1000
|
||||
const ratio = 1 - player.troops() / max
|
||||
toAdd *= ratio * ratio * ratio
|
||||
toAdd = Math.max(2, toAdd)
|
||||
return Math.min(player.troops() + toAdd, max)
|
||||
}
|
||||
|
||||
|
||||
@@ -36,22 +36,28 @@ export class AttackExecution implements Execution {
|
||||
this._owner.setTroops(this._owner.troops() - this.troops)
|
||||
this.mg = mg
|
||||
|
||||
if (this.target.isPlayer()) {
|
||||
for (const exec of mg.executions()) {
|
||||
if (exec instanceof AttackExecution) {
|
||||
const otherAttack = exec as AttackExecution
|
||||
if (otherAttack.target == this._owner && this.target == otherAttack._owner) {
|
||||
if (otherAttack.troops > this.troops) {
|
||||
otherAttack.troops -= this.troops
|
||||
otherAttack.calculateToConquer()
|
||||
this.active = false
|
||||
return
|
||||
} else {
|
||||
this.troops -= otherAttack.troops
|
||||
otherAttack.active = false
|
||||
}
|
||||
for (const exec of mg.executions()) {
|
||||
if (exec.isActive() && exec instanceof AttackExecution) {
|
||||
const otherAttack = exec as AttackExecution
|
||||
// Target has opposing attack, cancel them out
|
||||
if (this.target.isPlayer() && otherAttack.target == this._owner && this.target == otherAttack._owner) {
|
||||
if (otherAttack.troops > this.troops) {
|
||||
otherAttack.troops -= this.troops
|
||||
otherAttack.calculateToConquer()
|
||||
this.active = false
|
||||
return
|
||||
} else {
|
||||
this.troops -= otherAttack.troops
|
||||
otherAttack.active = false
|
||||
}
|
||||
}
|
||||
// Existing attack on same target, add troops
|
||||
if (otherAttack._owner == this._owner && otherAttack.target == this.target) {
|
||||
otherAttack.troops += this.troops
|
||||
otherAttack.calculateToConquer()
|
||||
this.active = false
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +83,15 @@ export class AttackExecution implements Execution {
|
||||
if (this.toConquer.size() < this.numTilesWithEnemy / 2) {
|
||||
this.calculateToConquer()
|
||||
}
|
||||
if (this.toConquer.size() == 0 || badTiles > 100) {
|
||||
if (badTiles > 1000) {
|
||||
console.log('bad tiles')
|
||||
this.borderTiles.clear()
|
||||
this.calculateToConquer()
|
||||
badTiles = 0
|
||||
continue
|
||||
}
|
||||
if (this.toConquer.size() == 0) {
|
||||
badTiles = 0
|
||||
this.active = false
|
||||
this._owner.addTroops(this.troops)
|
||||
return
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {PlayerConfig} from "../configuration/Config";
|
||||
import {Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, PlayerInfo, TerraNullius} from "../Game"
|
||||
import {Cell, Execution, MutableGame, MutablePlayer, Player, PlayerID, PlayerInfo, TerrainTypes, TerraNullius} from "../Game"
|
||||
import {PseudoRandom} from "../PseudoRandom"
|
||||
import {AttackExecution} from "./AttackExecution";
|
||||
|
||||
@@ -33,7 +33,7 @@ export class BotExecution implements Execution {
|
||||
if (this.neighborsTerra) {
|
||||
for (const b of this.bot.borderTiles()) {
|
||||
for (const n of b.neighbors()) {
|
||||
if (n.owner() == this.gs.terraNullius()) {
|
||||
if (n.owner() == this.gs.terraNullius() && n.terrain() == TerrainTypes.Land) {
|
||||
this.sendAttack(this.gs.terraNullius())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ export enum GamePhase {
|
||||
export class GameServer {
|
||||
|
||||
|
||||
private gameDuration = 5 * 60 * 1000 // TODO!!! fix this
|
||||
private gameDuration = 20 * 60 * 1000 // TODO!!! fix this
|
||||
|
||||
private turns: Turn[] = []
|
||||
private intents: Intent[] = []
|
||||
|
||||
Reference in New Issue
Block a user