Skip to content

Commit

Permalink
Update UIs
Browse files Browse the repository at this point in the history
  • Loading branch information
Petah committed Sep 3, 2020
1 parent 5509da1 commit 8b1ad95
Show file tree
Hide file tree
Showing 7 changed files with 253 additions and 222 deletions.
28 changes: 10 additions & 18 deletions debug/debug.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,8 @@ function readJsonFile($file)
return $b['mtime'] <=> $a['mtime'];
});
$files = array_slice($files, 0, 50);
// $files = array_map(function ($file) {
// var_dump($file);
// $content = file_get_contents($file['file']);
// // $content = file_get_contents($file['file']);
// // if (!$content) {
// // throw new \Exception('Could not load file: ' . $file['file']);
// // }
// // $content = json_decode($content, true);
// // $file['content'] = [
// // 'snake' => $content['snake'],
// // ];
// return $file;
// }, $files);
?>
<html>
<html ng-app="battleSnake" ng-controller="DebugController" ng-init="moveJson = <?= htmlentities(json_encode($moveJson)); ?>">

<head>
<!-- @todo use a cache buster -->
Expand All @@ -76,7 +63,12 @@ function readJsonFile($file)

<body>
<div class="wrapper">
<div class="grid">
<div>
<div class="grid">
</div>
<div>
<button type="button" ng-click="recomputeWeights()">Recompute weights</button>
</div>
</div>
<div class="scroll">
<div class="games">
Expand Down Expand Up @@ -116,11 +108,11 @@ function readJsonFile($file)
<div class="data"></div>
</pre>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.js"></script>
<script src="https://code.jquery.com/jquery-3.5.1.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.js"></script>
<script src="bundle.js?cache=<?= md5_file(__DIR__ . '/bundle.js'); ?>"></script>
<script>
loadGrid(<?= json_encode($moveJson); ?>);
// loadGrid();
</script>
</body>

Expand Down
55 changes: 29 additions & 26 deletions debug/socket.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,51 @@
<div class="container-fluid">
<div class="row">
<div ng-class="{'col-md-5': watching, 'col-md-12': !watching}">
<div class="form-group">
<label for="boardWidth">Board width</label>
<input type="number" step="1" class="form-control" id="boardWidth" ng-model="options.boardWidth" />
</div>
<div class="form-group">
<label for="boardHeight">Board height</label>
<input type="number" step="1" class="form-control" id="boardHeight" ng-model="options.boardHeight" />
</div>
<div class="form-group">
<label for="startingFood">Starting food</label>
<input type="number" step="1" class="form-control" id="startingFood" ng-model="options.startingFood" />
</div>
<div class="form-group">
<label for="foodSpawnTime">Max turns to food spawn</label>
<input type="number" step="1" class="form-control" id="foodSpawnTime" ng-model="options.foodSpawnTime" />
</div>
<div class="form-group">
<label for="concurrentGames">Concurrent Games</label>
<input type="number" step="1" class="form-control" id="concurrentGames" ng-model="options.concurrentGames" />
</div>
<div class="form-group">
<div class="form-group mt-3">
<button ng-click="options.showConfig = !options.showConfig" class="btn btn-primary btn-sm">Config</button>
<button ng-click="start()" class="btn btn-primary btn-sm">Start</button>
<button ng-click="stop()" class="btn btn-primary btn-sm">Stop</button>
<input type="checkbox" ng-model="options.autoStart" /> Auto Start
</div>

<div ng-show="options.showConfig">
<div class="form-group">
<label for="boardWidth">Board width</label>
<input type="number" step="1" class="form-control" id="boardWidth" ng-model="options.boardWidth" />
</div>
<div class="form-group">
<label for="boardHeight">Board height</label>
<input type="number" step="1" class="form-control" id="boardHeight" ng-model="options.boardHeight" />
</div>
<div class="form-group">
<label for="startingFood">Starting food</label>
<input type="number" step="1" class="form-control" id="startingFood" ng-model="options.startingFood" />
</div>
<div class="form-group">
<label for="foodSpawnTime">Max turns to food spawn</label>
<input type="number" step="1" class="form-control" id="foodSpawnTime" ng-model="options.foodSpawnTime" />
</div>
<div class="form-group">
<label for="concurrentGames">Concurrent Games</label>
<input type="number" step="1" class="form-control" id="concurrentGames" ng-model="options.concurrentGames" />
</div>
</div>

<table class="table table-striped table-sm border">
<thead>
<tr>
<th></th>
<th ng-show="options.showConfig"></th>
<th>Name</th>
<th>Port</th>
<!-- <th>Port</th> -->
<th>Wins</th>
<th>Wins Percent</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="webSocketClient in webSocketClients | orderBy: '-snake.wins'">
<td><input type="number" class="form-control form-control-sm" ng-model="options.enabledSnakes[webSocketClient.snake.name]" /></td>
<td ng-show="options.showConfig"><input type=" number" class="form-control form-control-sm" ng-model="options.enabledSnakes[webSocketClient.snake.name]" />
</td>
<td>{{ webSocketClient.snake.name }}</td>
<td>{{ webSocketClient.snake.port }}</td>
<!-- <td>{{ webSocketClient.snake.port }}</td> -->
<td>{{ webSocketClient.snake.wins }}</td>
<td>{{ percentWins(webSocketClient.snake.wins) }}%</td>
</tr>
Expand Down
2 changes: 1 addition & 1 deletion src/web/angular-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ export interface AngularScope {
$on: (event: string, callback: () => void) => void,
$apply: () => void,
$broadcast: (message: string) => void,
$watch: (watchExpression: string, listener: () => void, deepCompare: boolean) => void,
$watch: (watchExpression: string, listener: (...any) => void, deepCompare?: boolean) => void,
}
174 changes: 5 additions & 169 deletions src/web/app.ts
Original file line number Diff line number Diff line change
@@ -1,173 +1,9 @@
import { WebSocketClient } from "./WebSocketClient";
import snakes from "../server/snakes";
import { GameManager } from './GameManager';
import { AngularScope } from './angular-scope';
import { response } from 'express';
import { Game } from './Game';
import { log } from '../lib/log';
import { RootController } from './controllers/root';
import { DebugController } from './controllers/debug';

const app = angular.module('battleSnake', []);

interface RootControllerScope extends AngularScope {
gameManager: GameManager,
webSocketClients: WebSocketClient[],
options: Options,
watching: boolean,
app.controller('RootController', RootController);
app.controller('DebugController', DebugController);

start: () => void,
stop: () => void,
watch: (gameId: string) => void,
updateAutoStart: () => void,
percentWins: (wins: number) => void,
getAverageMoves: () => number,
sortGames: (sort: string) => void,
}

interface Options {
boardWidth: number,
boardHeight: number,
startingFood: number,
foodSpawnTime: number,
autoStart: boolean,
enabledSnakes: EnabledSnake,
orderGames: string,
concurrentGames: number,
}

interface EnabledSnake {
[id: string]: number;
}
app.controller('RootController', [
'$scope',
'$http',
function (
$scope: RootControllerScope,
$http,
) {
$scope.gameManager = new GameManager();
$scope.webSocketClients = snakes.map(snake => {
return new WebSocketClient(snake, snakes, $scope.gameManager, $scope);
});
try {
$scope.options = JSON.parse(localStorage.getItem('options'));
} catch (error) {
console.error('Error parsing local storage options', error, localStorage.getItem('options'));
}
$scope.options = $.extend({
boardWidth: 10,
boardHeight: 10,
startingFood: 10,
foodSpawnTime: 10,
autoStart: false,
enabledSnakes: {},
orderGames: 'index',
concurrentGames: 1,
}, $scope.options || {});

let started = false;
let pendingGames = 0;

$scope.start = () => {
let gamesToStart = $scope.options.concurrentGames - $scope.gameManager.getRunningGames().length;
log.verbose('Starting games', gamesToStart);
while (gamesToStart > 0) {
gamesToStart--;
pendingGames++;
started = true;
const config = {
width: $scope.options.boardWidth,
height: $scope.options.boardHeight,
food: $scope.options.startingFood,
MaxTurnsToNextFoodSpawn: $scope.options.foodSpawnTime,
snakes: [],
};
for (const snakeName in $scope.options.enabledSnakes) {
const snakeCount = $scope.options.enabledSnakes[snakeName];
for (let i = 0; i < snakeCount; i++) {
const webSocketClient = $scope.webSocketClients.find(w => w.snake.name == snakeName);
config.snakes.push(webSocketClient.snake.config);
}
}
if (!config.snakes.length) {
log('No enabled snakes');
return;
}
log.verbose('Initializing game');
let game: Game;
$http({
url: 'http://localhost:3005/games',
method: 'POST',
data: config,
})
.then((response) => {
game = $scope.gameManager.initGame(response.data.ID);
log.verbose('Starting game', game.id);
return $http({
url: `http://localhost:3005/games/${game.id}/start`,
method: 'POST',
});
})
.then(() => {
log.verbose('Started game', game.id);
game.started = new Date();
game.pending = false;
pendingGames--;
})
.catch((error) => console.error(error));
}
};

$scope.start();

$scope.$on('end', () => {
// @todo allow concurrent games
// @todo abandon stalled games
if (started && pendingGames < $scope.options.concurrentGames && $scope.options.autoStart) {
log.verbose('Auto starting game');
$scope.start();
}
});

$scope.stop = () => {
started = false;
};

$scope.watch = (gameId) => {
$scope.watching = true;
$('#board').attr('src', `http://localhost:3009?engine=http://localhost:3005&game=${gameId}`);
};

$scope.getAverageMoves = () => {
return Math.round($scope.gameManager.games.reduce((c, n) => c + n.moves, 0) / $scope.gameManager.games.length);
};

$scope.$watch('options', () => {
localStorage.setItem('options', JSON.stringify($scope.options));
}, true);

$scope.percentWins = (wins) => {
let sum = 0;
for (const webSocketClient of $scope.webSocketClients) {
sum += webSocketClient.snake.wins;
}
if (sum === 0) {
return 0;
}
return (100 / sum * wins).toFixed(1);
};

$scope.sortGames = (sort: string) => {
if ($scope.options.orderGames == sort) {
$scope.options.orderGames = '-' + sort;
} else {
$scope.options.orderGames = sort;
}
};

setInterval(() => {
$scope.$apply();
}, 500);
},
]);

export default app;
export default app;
30 changes: 30 additions & 0 deletions src/web/controllers/debug.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { AngularScope } from '../angular-scope';
import { MoveData, loadGrid } from '../grid';
import { weight } from '../../lib/weight';

interface DebugControllerScope extends AngularScope {
moveJson: MoveData,
recomputeWeights: () => void,
}

export const DebugController = [
'$scope',
function (
$scope: DebugControllerScope,
) {
$scope.$watch('moveJson', () => {
loadGrid($scope.moveJson);
});

$scope.recomputeWeights = () => {
console.log('Recompute weights');
for (var y = 0; y < $scope.moveJson.body.board.height; y++) {
for (var x = 0; x < $scope.moveJson.body.board.width; x++) {
$scope.moveJson.body.grid[y][x].weight = undefined;
weight($scope.moveJson.body, x, y);
}
}
loadGrid($scope.moveJson);
};
},
];
Loading

0 comments on commit 8b1ad95

Please sign in to comment.