Skip to content

Commit

Permalink
Merge branch 'engine-fixes'
Browse files Browse the repository at this point in the history
  • Loading branch information
TheApplePieGod committed Jan 24, 2024
2 parents a00e64e + ba751db commit 2f84d5b
Show file tree
Hide file tree
Showing 31 changed files with 166 additions and 49 deletions.
11 changes: 11 additions & 0 deletions client/src/components/forms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,21 @@ export const NumInput: React.FC<NumInputProps> = (props) => {
handleInputChange(tempValue || '')
}

/*
* TODO: these useEffects() are a little mid, they should really store the disabled state
* and restore it instead of absolutely setting it to false
*/

React.useEffect(() => {
context.setState((prevState) => ({ ...prevState, disableHotkeys: focused }))
}, [focused])

React.useEffect(() => {
return () => {
context.setState((prevState) => ({ ...prevState, disableHotkeys: false }))
}
}, [])

return (
<input
className={'border border-black py-0.5 px-1 rounded-md w-12 ' + (props.className ?? '')}
Expand Down
42 changes: 32 additions & 10 deletions client/src/components/sidebar/game/game.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { BiMedal } from 'react-icons/bi'
import { EventType, useListenEvent } from '../../../app-events'
import Tooltip from '../../tooltip'
import { useForceUpdate } from '../../../util/react-util'
import Match from '../../../playback/Match'
import { Team } from '../../../playback/Game'

const NO_GAME_TEAM_NAME = '?????'

Expand All @@ -28,25 +30,45 @@ export const GamePage: React.FC<Props> = React.memo((props) => {

if (!props.open) return null

const getWinCount = (team: Team) => {
// Only return up to the current match if tournament mode is enabled
if (!activeGame) return 0
let stopCounting = false
const isWinner = (match: Match) => {
if (context.state.tournament && stopCounting) return 0
if (match == activeGame.currentMatch) stopCounting = true
return match.winner?.id === team.id ? 1 : 0
}
return activeGame.matches.reduce((val, match) => val + isWinner(match), 0)
}

const teamBox = (teamIdx: number) => {
let showMatchWinner =
!context.state.tournament || (context.state.activeMatch && context.state.activeMatch.currentTurn.isEnd())
const winCount = activeGame ? getWinCount(activeGame.teams[teamIdx]) : 0
const isEndOfMatch = context.state.activeMatch && context.state.activeMatch.currentTurn.isEnd()

let showMatchWinner = !context.state.tournament || isEndOfMatch
showMatchWinner = showMatchWinner && activeGame && activeGame.currentMatch?.winner === activeGame.teams[teamIdx]
let showGameWinner =
!context.state.tournament ||
(showMatchWinner &&
context.state.activeMatch ==
context.state.activeGame?.matches[context.state.activeGame.matches.length - 1])
let showGameWinner = !context.state.tournament || (showMatchWinner && winCount >= 3)
showGameWinner = showGameWinner && activeGame && activeGame.winner === activeGame.teams[teamIdx]

return (
<div className={'relative w-full py-2 px-3 text-center ' + (teamIdx == 0 ? 'bg-team0' : 'bg-team1')}>
<div>{activeGame?.teams[teamIdx].name ?? NO_GAME_TEAM_NAME}</div>
<div className="absolute top-2 left-3">
{showMatchWinner && (
<Tooltip text={'Current match winner'} location={'right'}>
<BiMedal fontSize={'24px'} width={'20px'} color={'yellow'} />
</Tooltip>
<div className="relative flex items-center w-[24px] h-[24px]">
<div className="absolute">
<Tooltip text={'Current match winner'} location={'right'}>
<BiMedal opacity={0.5} fontSize={'24px'} width={'20px'} color={'yellow'} />
</Tooltip>
</div>
<div
className="absolute w-full text-sm pointer-events-none z-5"
style={{ textShadow: 'white 0px 0px 4px' }}
>
{winCount > 0 && winCount}
</div>
</div>
)}
</div>
<div className="absolute top-3 right-3">
Expand Down
18 changes: 9 additions & 9 deletions client/src/components/sidebar/game/team-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,20 @@ export const UnitsTable: React.FC<UnitsTableProps> = ({ teamStat, teamIdx }) =>
}

const GlobalUpgradeSection: React.FC<{ teamStat: TeamTurnStat | undefined }> = ({ teamStat }) => {
const upgradeTypes: [schema.GlobalUpgradeType, string][] = [
[schema.GlobalUpgradeType.ACTION_UPGRADE, 'Global Attack Upgrade'],
[schema.GlobalUpgradeType.CAPTURING_UPGRADE, 'Global Capturing Upgrade'],
[schema.GlobalUpgradeType.HEALING_UPGRADE, 'Global Healing Upgrade']
]
const upgradeTypes: Record<schema.GlobalUpgradeType, string> = {
[schema.GlobalUpgradeType.ACTION_UPGRADE]: 'Global Attack Upgrade',
[schema.GlobalUpgradeType.CAPTURING_UPGRADE]: 'Global Capturing Upgrade',
[schema.GlobalUpgradeType.HEALING_UPGRADE]: 'Global Healing Upgrade'
}
if (!teamStat) return <> </>
return (
<>
{upgradeTypes.map(
([type, name]) =>
teamStat.globalUpgrades.has(type) && (
{teamStat.globalUpgrades.map(
(type) =>
upgradeTypes[type] && (
<div className="text-sm flex flex-row justify-center font-bold" key={type}>
<DoubleChevronUpIcon />
{name}
{upgradeTypes[type]}
</div>
)
)}
Expand Down
15 changes: 8 additions & 7 deletions client/src/components/sidebar/runner/runner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { SectionHeader } from '../../section-header'
import { FixedSizeList, ListOnScrollProps } from 'react-window'
import { OpenExternal } from '../../../icons/open-external'
import { BasicDialog } from '../../basic-dialog'
import { RingBuffer } from '../../../util/ring-buffer'

type RunnerPageProps = {
open: boolean
Expand Down Expand Up @@ -67,7 +68,7 @@ export const RunnerPage: React.FC<RunnerPageProps> = ({ open, scaffold }) => {
if (availablePlayers.size > 1) setTeamB([...availablePlayers][1])
}, [availablePlayers])

const MemoConsole = React.useMemo(() => <Console lines={consoleLines} />, [consoleLines])
const MemoConsole = React.useMemo(() => <Console lines={consoleLines} />, [consoleLines.effectiveLength()])

if (!open) return null

Expand Down Expand Up @@ -299,7 +300,7 @@ const JavaSelector: React.FC<JavaSelectorProps> = (props) => {
export type ConsoleLine = { content: string; type: 'output' | 'error' | 'bold' }

type Props = {
lines: ConsoleLine[]
lines: RingBuffer<ConsoleLine>
}

export const Console: React.FC<Props> = ({ lines }) => {
Expand All @@ -320,8 +321,8 @@ export const Console: React.FC<Props> = ({ lines }) => {
}

const ConsoleRow = (props: { index: number; style: any }) => (
<span style={props.style} className={getLineClass(lines[props.index]) + ' text-xs whitespace-nowrap'}>
{lines[props.index].content}
<span style={props.style} className={getLineClass(lines.get(props.index)!) + ' text-xs whitespace-nowrap'}>
{lines.get(props.index)!.content}
</span>
)

Expand All @@ -345,17 +346,17 @@ export const Console: React.FC<Props> = ({ lines }) => {
}

useEffect(() => {
if (lines.length == 0) setTail(true)
if (lines.effectiveLength() == 0) setTail(true)
if (tail && consoleRef.current) {
scrollToBottom()
}
}, [lines])
}, [lines.effectiveLength()])

const lineList = (
<FixedSizeList
outerRef={consoleRef}
height={2000}
itemCount={lines.length}
itemCount={lines.length()}
itemSize={20}
layout="vertical"
width={'100%'}
Expand Down
18 changes: 11 additions & 7 deletions client/src/components/sidebar/runner/scaffold.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import WebSocketListener from './websocket'
import { useAppContext } from '../../../app-context'
import Game from '../../../playback/Game'
import Match from '../../../playback/Match'
import { RingBuffer } from '../../../util/ring-buffer'

export type JavaInstall = {
display: string
Expand All @@ -23,7 +24,7 @@ type Scaffold = [
scaffoldLoading: boolean,
runMatch: (javaPath: string, teamA: string, teamB: string, selectedMaps: Set<string>) => Promise<void>,
killMatch: (() => Promise<void>) | undefined,
console: ConsoleLine[]
console: RingBuffer<ConsoleLine>
]

export function useScaffold(): Scaffold {
Expand All @@ -35,12 +36,15 @@ export function useScaffold(): Scaffold {
const [scaffoldPath, setScaffoldPath] = useState<string | undefined>(undefined)
const matchPID = useRef<string | undefined>(undefined)
const forceUpdate = useForceUpdate()
const [consoleLines, setConsoleLines] = useState<ConsoleLine[]>([])
const log = (line: ConsoleLine) =>
setConsoleLines((prev) => (prev.length > 10000 ? [...prev.slice(1), line] : [...prev, line]))
const consoleLines = useRef<RingBuffer<ConsoleLine>>(new RingBuffer(10000))

const [webSocketListener, setWebSocketListener] = useState<WebSocketListener | undefined>()

const log = (line: ConsoleLine) => {
consoleLines.current.push(line)
forceUpdate()
}

async function manuallySetupScaffold() {
if (!nativeAPI) return
setLoading(true)
Expand All @@ -52,6 +56,7 @@ export function useScaffold(): Scaffold {
async function runMatch(javaPath: string, teamA: string, teamB: string, selectedMaps: Set<string>): Promise<void> {
if (matchPID.current || !scaffoldPath) return
const shouldProfile = false
consoleLines.current.clear()
try {
const newPID = await dispatchMatch(
javaPath,
Expand All @@ -63,10 +68,9 @@ export function useScaffold(): Scaffold {
appContext.state.config.validateMaps,
shouldProfile
)
setConsoleLines([])
matchPID.current = newPID
} catch (e: any) {
setConsoleLines([{ content: e, type: 'error' }])
consoleLines.current.push({ content: e, type: 'error' })
}
forceUpdate()
}
Expand Down Expand Up @@ -193,7 +197,7 @@ export function useScaffold(): Scaffold {
loading,
runMatch,
matchPID.current ? killMatch : undefined,
consoleLines
consoleLines.current
]
}

Expand Down
18 changes: 18 additions & 0 deletions client/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ export const ENGINE_BUILTIN_MAP_NAMES: string[] = [
'DefaultMedium',
'DefaultLarge',
'DefaultHuge',
'BedWars',
'Bunkers',
'Checkered',
'Diagonal',
'Divergent',
'EndAround',
'FloodGates',
'Foxes',
'Fusbol',
'GaltonBoard',
'HeMustBeFreed',
'Intercontinental',
'Klein',
'QueenOfHearts',
'QuestionableChess',
'Racetrack',
'Rainbow',
'TreeSearch',
'AceOfSpades',
'Alien',
'Ambush',
Expand Down
2 changes: 1 addition & 1 deletion client/src/playback/Actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action> = {
[schema.Action.GLOBAL_UPGRADE]: class GlobalUpgrade extends Action {
apply(turn: Turn): void {
const team = turn.bodies.getById(this.robotID).team
turn.stat.getTeamStat(team).globalUpgrades.add(this.target)
turn.stat.getTeamStat(team).globalUpgrades.push(this.target)
}
}
}
6 changes: 3 additions & 3 deletions client/src/playback/TurnStat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ export class TeamTurnStat {
specializationTotalLevels: [number, number, number, number, number] = [0, 0, 0, 0, 0]
resourceAmount: number = 0
resourceAmountAverageDatapoint: number | undefined = undefined
globalUpgrades: Set<schema.GlobalUpgradeType> = new Set()
globalUpgrades: schema.GlobalUpgradeType[] = []

copy(): TeamTurnStat {
const newStat = Object.assign(Object.create(Object.getPrototypeOf(this)), this)
const newStat: TeamTurnStat = Object.assign(Object.create(Object.getPrototypeOf(this)), this)

// Copy any internal objects here
newStat.robots = [...this.robots]
newStat.specializationTotalLevels = [...this.specializationTotalLevels]
newStat.globalUpgrades = new Set(this.globalUpgrades)
newStat.globalUpgrades = [...this.globalUpgrades]

return newStat
}
Expand Down
53 changes: 53 additions & 0 deletions client/src/util/ring-buffer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
export class RingBuffer<T> {
private _array: T[]
private _effectiveLength: number

constructor(n: number) {
this._array = new Array(n)
this._effectiveLength = 0
}

public toString() {
return '[object RingBuffer(' + this._array.length + ') effectiveLength ' + this._effectiveLength + ']'
}

public length() {
return Math.min(this._array.length, this._effectiveLength)
}

public effectiveLength() {
return this._effectiveLength
}

public get(i: number) {
if (i < 0 || i >= this.length()) return undefined
const index = this.computeActualIndex(i)
return this._array[index]
}

public set(i: number, v: T) {
if (i < 0 || i >= this.length()) throw new Error('set() Index out of range')
const index = this.computeActualIndex(i)
this._array[index] = v
}

public push(v: T) {
const index = this.computeActualIndex(this._effectiveLength)
this._array[index] = v
this._effectiveLength++
}

public clear() {
this._effectiveLength = 0
}

public *[Symbol.iterator]() {
for (let i = 0; i < this.length(); i++) {
yield this.get(i)
}
}

private computeActualIndex(offset: number) {
return Math.max((this._effectiveLength - this._array.length, 0) + offset) % this._array.length
}
}
2 changes: 1 addition & 1 deletion engine/src/main/battlecode/common/GameConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public class GameConstants {
public static final int PASSIVE_CRUMBS_INCREASE = 10;

/** The amount of crumbs you gain if your bot kills an enemy while in enemy territory */
public static final int KILL_CRUMB_REWARD = 50;
public static final int KILL_CRUMB_REWARD = 30;

/** The end of the setup rounds in the game */
public static final int SETUP_ROUNDS = 200;
Expand Down
8 changes: 4 additions & 4 deletions engine/src/main/battlecode/common/GlobalUpgrade.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@
public enum GlobalUpgrade {

/**
* Attack upgrade increases the base attack by 75.
* Attack upgrade increases the base attack by 60.
*/
ATTACK(75, 0, 0, 0),
ATTACK(60, 0, 0, 0),

/**
* Healing increases base heal by 50.
*/
HEALING(0, 50, 0, 0),

/**
* Capture upgrade increases the dropped flag delay from 4 rounds to 12 rounds. It also decreases the movement penalty for holding a flag by 8.
* Capture upgrade increases the dropped flag delay from 4 rounds to 25 rounds. It also decreases the movement penalty for holding a flag by 8.
*/
CAPTURING(0, 0, 8, -8),
CAPTURING(0, 0, 21, -8),

/**
* !DO NOT USE!
Expand Down
4 changes: 2 additions & 2 deletions engine/src/main/battlecode/common/TrapType.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public enum TrapType {
* When an opponent enters, explosive traps deal 750 damage to all opponents within a sqrt 13 radius
* If an opponent digs/breaks under the trap, it deals 500 damage to all opponnets in radius sqrt 9
*/
EXPLOSIVE (250, 0, 4, 2, 750, 200, false, 5, true, 0),
EXPLOSIVE (200, 0, 4, 2, 750, 200, false, 5, true, 0),

/**
* When an opponent enters, water traps dig all unoccupied tiles within a radius of sqrt 9
Expand All @@ -22,7 +22,7 @@ public enum TrapType {
/**
* When an opponent enters, all opponent robots movement and action cooldowns are set to 40.
*/
STUN (100, 2, 13, 0, 0, 0, false, 5, true, 50),
STUN (100, 2, 13, 0, 0, 0, false, 5, true, 40),

NONE (100, 0, 0, 0, 0, 0, false, 0, false, 0);

Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 2f84d5b

Please sign in to comment.