Skip to content

Commit b00b23a

Browse files
authored
Merge pull request #61 from battlecode/engine-release
Merge engine to master
2 parents 2d86fa8 + e911630 commit b00b23a

39 files changed

Lines changed: 371 additions & 281 deletions

.github/workflows/release-engine.yml

Lines changed: 71 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -92,79 +92,79 @@ jobs:
9292
9393
- name: Upload specs
9494
run: gsutil -m rsync -a $OBJECT_ACL -r ./specs gs://$GCS_BUCKET/specs/${RELEASE_ARTIFACT_ID}/$RELEASE_VERSION
95-
release-python:
96-
name: Release Python
97-
runs-on: ubuntu-latest
98-
permissions:
99-
contents: read
100-
id-token: write
101-
102-
steps:
103-
- uses: conda-incubator/setup-miniconda@v3
104-
with:
105-
python-version: 3.12
106-
107-
- name: Checkout branch
108-
uses: actions/checkout@v3
109-
110-
- name: Inject release version
111-
run: |
112-
release_version=${GITHUB_REF#refs/*/}
113-
release_version=${release_version#engine.}
114-
echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
115-
echo "The release version is $release_version"
116-
117-
- name: Authenticate to Google Cloud Platform
118-
uses: google-github-actions/auth@v1
119-
with:
120-
create_credentials_file: true
121-
workload_identity_provider: projects/830784087321/locations/global/workloadIdentityPools/releases/providers/github-workflow
122-
service_account: releases-agent@mitbattlecode.iam.gserviceaccount.com
123-
124-
- name: Set up Google Cloud SDK
125-
uses: 'google-github-actions/setup-gcloud@v1'
126-
127-
- name: Clone private maps
128-
if: ${{ env.IS_PUBLIC != 'YES' }}
129-
uses: actions/checkout@v3
130-
with:
131-
repository: battlecode/private-maps
132-
token: ${{ secrets.CI_REPOSITORY_CLONE_PAT }}
133-
path: private-maps
95+
# release-python:
96+
# name: Release Python
97+
# runs-on: ubuntu-latest
98+
# permissions:
99+
# contents: read
100+
# id-token: write
101+
102+
# steps:
103+
# - uses: conda-incubator/setup-miniconda@v3
104+
# with:
105+
# python-version: 3.12
106+
107+
# - name: Checkout branch
108+
# uses: actions/checkout@v3
109+
110+
# - name: Inject release version
111+
# run: |
112+
# release_version=${GITHUB_REF#refs/*/}
113+
# release_version=${release_version#engine.}
114+
# echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
115+
# echo "The release version is $release_version"
116+
117+
# - name: Authenticate to Google Cloud Platform
118+
# uses: google-github-actions/auth@v1
119+
# with:
120+
# create_credentials_file: true
121+
# workload_identity_provider: projects/830784087321/locations/global/workloadIdentityPools/releases/providers/github-workflow
122+
# service_account: releases-agent@mitbattlecode.iam.gserviceaccount.com
123+
124+
# - name: Set up Google Cloud SDK
125+
# uses: 'google-github-actions/setup-gcloud@v1'
126+
127+
# - name: Clone private maps
128+
# if: ${{ env.IS_PUBLIC != 'YES' }}
129+
# uses: actions/checkout@v3
130+
# with:
131+
# repository: battlecode/private-maps
132+
# token: ${{ secrets.CI_REPOSITORY_CLONE_PAT }}
133+
# path: private-maps
134134

135-
- name: Inject private maps
136-
if: ${{ env.IS_PUBLIC != 'YES' }}
137-
run: |
138-
source="private-maps/$RELEASE_ARTIFACT_ID"
139-
dest="$RELEASE_ARTIFACT_ID/maps"
140-
if [ -d "$source" ]; then
141-
cp -r -i "$source/." "$dest/" < /dev/null &> private-maps-copy-log
142-
if [ -s "private-maps-copy-log" ]; then
143-
echo "FAILED! Public and private maps should not intersect."
144-
cat private-maps-copy-log
145-
exit 1
146-
fi
147-
fi
135+
# - name: Inject private maps
136+
# if: ${{ env.IS_PUBLIC != 'YES' }}
137+
# run: |
138+
# source="private-maps/$RELEASE_ARTIFACT_ID"
139+
# dest="$RELEASE_ARTIFACT_ID/maps"
140+
# if [ -d "$source" ]; then
141+
# cp -r -i "$source/." "$dest/" < /dev/null &> private-maps-copy-log
142+
# if [ -s "private-maps-copy-log" ]; then
143+
# echo "FAILED! Public and private maps should not intersect."
144+
# cat private-maps-copy-log
145+
# exit 1
146+
# fi
147+
# fi
148148

149-
- name: Build python package
150-
shell: bash -el {0} # Make sure conda is activated
151-
run: |
152-
conda info
153-
python --version
154-
pip install --upgrade build
155-
SETUPTOOLS_SCM_PRETEND_VERSION=${RELEASE_VERSION} python -m build
156-
157-
- name: Determine access control
158-
run: |
159-
[[ "$IS_PUBLIC" = "YES" ]] && acl="public-read" || acl="project-private"
160-
echo "OBJECT_ACL=$acl" >> $GITHUB_ENV
161-
echo "Objects will be uploaded with ACL $acl"
162-
163-
- name: Upload python package to remote repository
164-
run: |
165-
mv *.tar.gz battlecode.tar.gz
166-
gsutil -m cp -a $OBJECT_ACL battlecode.tar.gz gs://$GCS_BUCKET/maven/org/battlecode/${RELEASE_ARTIFACT_ID}-python/${RELEASE_VERSION}/
167-
working-directory: ./dist
149+
# - name: Build python package
150+
# shell: bash -el {0} # Make sure conda is activated
151+
# run: |
152+
# conda info
153+
# python --version
154+
# pip install --upgrade build
155+
# SETUPTOOLS_SCM_PRETEND_VERSION=${RELEASE_VERSION} python -m build
156+
157+
# - name: Determine access control
158+
# run: |
159+
# [[ "$IS_PUBLIC" = "YES" ]] && acl="public-read" || acl="project-private"
160+
# echo "OBJECT_ACL=$acl" >> $GITHUB_ENV
161+
# echo "Objects will be uploaded with ACL $acl"
162+
163+
# - name: Upload python package to remote repository
164+
# run: |
165+
# mv *.tar.gz battlecode.tar.gz
166+
# gsutil -m cp -a $OBJECT_ACL battlecode.tar.gz gs://$GCS_BUCKET/maven/org/battlecode/${RELEASE_ARTIFACT_ID}-python/${RELEASE_VERSION}/
167+
# working-directory: ./dist
168168

169169
# TODO: docs?
170170
#- name: Upload javadocs

client/icons/icon.icns

1.04 KB
Binary file not shown.

client/icons/icon.ico

-158 KB
Binary file not shown.

client/icons/icon.png

658 Bytes
Loading

client/src/components/sidebar/game/game.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ export const GamePage: React.FC<Props> = React.memo((props) => {
9494
}
9595

9696
const isGameModeCooperation =
97-
!!round &&
97+
(round ?? true) &&
9898
!!game &&
9999
(() => {
100-
const t0 = round.stat.getTeamStat(game.teams[0])?.gameModeCooperation ?? true
101-
const t1 = round.stat.getTeamStat(game.teams[1])?.gameModeCooperation ?? true
100+
const t0 = round?.stat.getTeamStat(game.teams[0])?.gameModeCooperation ?? true
101+
const t1 = round?.stat.getTeamStat(game.teams[1])?.gameModeCooperation ?? true
102102
return t0 && t1
103103
})()
104104

client/src/components/sidebar/game/team-table.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ export const ResourceTable: React.FC<ResourceTableProps> = ({ map, teamStat, tea
7272
ratKingPercent = teamStat.ratKingPercent
7373
}
7474

75+
const formatPercent = (val: number) => (val * 100).toFixed(1).toString() + '%'
76+
7577
const teamName = TEAM_COLOR_NAMES[teamIdx].toLowerCase()
7678
return (
7779
<div className="flex flex-col items-center">
@@ -80,15 +82,15 @@ export const ResourceTable: React.FC<ResourceTableProps> = ({ map, teamStat, tea
8082
<div className="w-[30px] h-[30px] mr-5">
8183
<img style={{ transform: 'scale(1.5)' }} src={imageSource(`icons/cheese_64x64.png`)} />
8284
</div>
83-
<div>Count:</div>
85+
<div>Amount:</div>
8486
<div className="ml-1">
8587
<b>{cheeseAmount}</b>
8688
</div>
8789
</div>
8890
<div className="flex items-center w-[145px]">
8991
<div>Percent:</div>
9092
<div className="ml-1">
91-
<b>{cheesePercent}</b>
93+
<b>{formatPercent(cheesePercent)}</b>
9294
</div>
9395
</div>
9496
</div>
@@ -97,15 +99,15 @@ export const ResourceTable: React.FC<ResourceTableProps> = ({ map, teamStat, tea
9799
<div className="w-[30px] h-[30px] mr-5">
98100
<img style={{ transform: 'scale(1.5)' }} src={imageSource(`robots/cat/cat_0.png`)} />
99101
</div>
100-
<div>Count:</div>
102+
<div>Damage:</div>
101103
<div className="ml-1">
102104
<b>{catDamageAmount}</b>
103105
</div>
104106
</div>
105107
<div className="flex items-center w-[145px]">
106108
<div>Percent:</div>
107109
<div className="ml-1">
108-
<b>{catDamagePercent}</b>
110+
<b>{formatPercent(catDamagePercent)}</b>
109111
</div>
110112
</div>
111113
</div>
@@ -125,7 +127,7 @@ export const ResourceTable: React.FC<ResourceTableProps> = ({ map, teamStat, tea
125127
<div className="flex items-center w-[145px]">
126128
<div>Percent:</div>
127129
<div className="ml-1">
128-
<b>{ratKingPercent}</b>
130+
<b>{formatPercent(ratKingPercent)}</b>
129131
</div>
130132
</div>
131133
</div>

client/src/components/sidebar/map-editor/MapGenerator.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import Game, { Team } from '../../../playback/Game'
33
import Match from '../../../playback/Match'
44
import { CurrentMap, StaticMap } from '../../../playback/Map'
55
import Round from '../../../playback/Round'
6-
import Bodies from '../../../playback/Bodies'
6+
import Bodies, { Body } from '../../../playback/Bodies'
77
import { BATTLECODE_YEAR, DIRECTIONS, TEAM_COLOR_NAMES } from '../../../constants'
88
import { nativeAPI } from '../runner/native-api-wrapper'
99
import { Vector } from '../../../playback/Vector'
@@ -180,6 +180,13 @@ function verifyMap(map: CurrentMap, bodies: Bodies): string {
180180
`>= 3 away`
181181
)
182182
}
183+
184+
if (body.robotType === schema.RobotType.CAT) {
185+
if (!map.staticMap.catWaypoints.get(body.id) || map.staticMap.catWaypoints.get(body.id)?.length === 0) {
186+
return `Cat with id ${body.id} has no waypoints`
187+
}
188+
}
189+
183190
}
184191

185192
return ''

client/src/playback/Actions.ts

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,43 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action<ActionUnion
183183
}
184184
},
185185
[schema.Action.RatNap]: class RatNapAction extends Action<schema.RatNap> {
186+
private static readonly OFFSET = { x: -0.35, y: 0 }
186187
apply(round: Round): void {
187188
// move the target onto the source adjust target's size using scale factor
188189
const src = round.bodies.getById(this.robotId)
189190
const target = round.bodies.getById(this.actionData.id()) // rat getting napped
191+
192+
target.carriedRobot = undefined
193+
src.carriedRobot = target.id
194+
195+
target.lastPos = { ...target.pos }
196+
target.pos = { x: src.pos.x + RatNapAction.OFFSET.x, y: src.pos.y + RatNapAction.OFFSET.y }
197+
target.size = 0.6
190198
}
191199
draw(match: Match, ctx: CanvasRenderingContext2D): void {
192200
//target rat moves onto src rat, circle around carried group thing
193-
const src = match.currentRound.bodies.getById(this.robotId)
194-
const target = match.currentRound.bodies.getById(this.actionData.id()) // rat getting napped
201+
const src = match.currentRound.bodies.getById(this.robotId)
202+
const srcCoords = renderUtils.getRenderCoords(src.pos.x, src.pos.y, match.map.dimension, true)
203+
const t = match.getInterpolationFactor()
204+
const bump = Math.sin(t * Math.PI * 8) * 0.03
205+
const half = 0.5 + bump
206+
const radius = 0.08 // corner radius
207+
208+
ctx.save()
209+
ctx.shadowBlur = 12
210+
ctx.shadowColor = src.team.color
211+
ctx.strokeStyle = src.team.color
212+
ctx.globalAlpha = 0.7
213+
ctx.lineWidth = 0.04
214+
ctx.beginPath()
215+
ctx.moveTo(srcCoords.x - half + radius, srcCoords.y - half)
216+
ctx.arcTo(srcCoords.x + half, srcCoords.y - half, srcCoords.x + half, srcCoords.y + half, radius)
217+
ctx.arcTo(srcCoords.x + half, srcCoords.y + half, srcCoords.x - half, srcCoords.y + half, radius)
218+
ctx.arcTo(srcCoords.x - half, srcCoords.y + half, srcCoords.x - half, srcCoords.y - half, radius)
219+
ctx.arcTo(srcCoords.x - half, srcCoords.y - half, srcCoords.x + half, srcCoords.y - half, radius)
220+
ctx.stroke()
221+
ctx.restore()
222+
ctx.restore()
195223
}
196224
},
197225
[schema.Action.RatCollision]: class RatCollisionAction extends Action<schema.RatCollision> {
@@ -200,6 +228,33 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action<ActionUnion
200228
const src = match.currentRound.bodies.getById(this.robotId)
201229
const pos = match.map.indexToLocation(this.actionData.loc())
202230
const coords = renderUtils.getRenderCoords(pos.x, pos.y, match.map.dimension, true)
231+
const t = match.getInterpolationFactor()
232+
233+
ctx.save()
234+
// dusty base color that fills the cell and fades out
235+
const baseAlpha = 0.4 * (1 - t)
236+
ctx.fillStyle = `rgba(150,130,110,${baseAlpha})`
237+
ctx.fillRect(coords.x - 0.5, coords.y - 0.5, 1, 1)
238+
239+
// these are the random rocks that fill the cell
240+
const rockCount = 10
241+
for (let i = 0; i < rockCount; i++) {
242+
const rx = coords.x - 0.5 + Math.random() * 1
243+
const ry = coords.y - 0.5 + Math.random() * 1
244+
const size = 0.08 + Math.random() * 0.15
245+
const shade = 90 + Math.floor(Math.random() * 50)
246+
const alpha = 0.7 * (1 - t)
247+
ctx.fillStyle = `rgba(${shade},${shade - 10},${shade - 20},${alpha})`
248+
ctx.fillRect(rx, ry, size, size)
249+
}
250+
251+
// ring outside the cell (also fades out)
252+
ctx.strokeStyle = src.team.color
253+
ctx.globalAlpha = 0.35 * (1 - t)
254+
ctx.lineWidth = 0.04
255+
ctx.strokeRect(coords.x - 0.5, coords.y - 0.5, 1, 1)
256+
ctx.restore()
257+
203258
}
204259
},
205260
[schema.Action.PlaceDirt]: class PlaceDirtAction extends Action<schema.PlaceDirt> {
@@ -284,8 +339,8 @@ export const ACTION_DEFINITIONS: Record<schema.Action, typeof Action<ActionUnion
284339
const target = round.bodies.getById(this.actionData.id())
285340
const amount = this.actionData.amount()
286341

287-
body.cheese -= amount
288-
target.cheese += amount
342+
body.cheese -= Math.min(body.cheese, amount)
343+
target.cheese += Math.min(body.cheese, amount)
289344
}
290345
draw(match: Match, ctx: CanvasRenderingContext2D): void {
291346
const srcBody = match.currentRound.bodies.getById(this.robotId)

client/src/playback/Bodies.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,8 @@ export default class Bodies {
9999

100100
return body
101101
}
102+
102103
checkBodyCollisionAtLocation(type: schema.RobotType, pos: Vector): boolean {
103-
const bodyClass = BODY_DEFINITIONS[type] ?? assert.fail(`Body type ${type} not found in BODY_DEFINITIONS`)
104-
const tempBody = new bodyClass(this.game, pos, this.game.getTeamByID(1), 0)
105-
const bodySize = tempBody.size
106104
const occupiedSpaces: Vector[] = []
107105

108106
for (const otherBody of this.bodies.values()) {
@@ -154,6 +152,34 @@ export default class Bodies {
154152
return false
155153
}
156154

155+
checkBodyOutofBoundsAtLocation(type: schema.RobotType, pos: Vector): boolean {
156+
const map = this.game.currentMatch?.map
157+
if(!map) return false
158+
159+
const dimension = map.dimension
160+
const occupiedSpaces: Vector[] = []
161+
162+
if (type == schema.RobotType.RAT) {
163+
if(!map.inBounds(pos.x, pos.y)) return false
164+
}
165+
if (type == schema.RobotType.CAT) {
166+
for (let xoff = 0; xoff <= 1; xoff++) {
167+
for (let yoff = 0; yoff <= 1; yoff++) {
168+
if(!map.inBounds(pos.x+xoff, pos.y+yoff)) return false
169+
}
170+
}
171+
}
172+
if (type == schema.RobotType.RAT_KING) {
173+
for (let xoff = -1; xoff <= 1; xoff++) {
174+
for (let yoff = -1; yoff <= 1; yoff++) {
175+
if(!map.inBounds(pos.x+xoff, pos.y+yoff)) return false
176+
}
177+
}
178+
}
179+
180+
return true
181+
}
182+
157183
markBodyAsDead(id: number): void {
158184
const body = this.getById(id)
159185
body.dead = true
@@ -337,6 +363,7 @@ export class Body {
337363
public moveCooldown: number = 0
338364
public actionCooldown: number = 0
339365
public turningCooldown: number = 0
366+
public carriedRobot: number | undefined = undefined // id of carried robot
340367
public bytecodesUsed: number = 0
341368
public cheese: number = 0
342369

@@ -661,6 +688,7 @@ export class Body {
661688
`Move Cooldown: ${this.moveCooldown}`,
662689
`Action Cooldown: ${this.actionCooldown}`,
663690
`${this.robotType !== schema.RobotType.CAT ? 'Turning Cooldown: ' + this.turningCooldown : ''}`,
691+
`${this.carriedRobot !== undefined ? 'Carrying: ' + this.carriedRobot : ''}`,
664692
`Bytecodes Used: ${this.bytecodesUsed}${
665693
this.bytecodesUsed >= this.metadata.bytecodeLimit() ? ' <EXCEEDED!>' : ''
666694
}`

0 commit comments

Comments
 (0)