Skip to content

Commit

Permalink
0.1.6 - Manually Play
Browse files Browse the repository at this point in the history
  • Loading branch information
adamjeffries committed Jan 10, 2020
1 parent ca3922d commit 49405fd
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 79 deletions.
2 changes: 1 addition & 1 deletion kaggle_environments/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from .core import *
from . import utils

version = "0.1.5"
version = "0.1.6"

__all__ = ["environments", "evaluate", "make", "register", "utils", "version"]

Expand Down
37 changes: 37 additions & 0 deletions kaggle_environments/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,16 @@

import copy
import json
import uuid
from .errors import DeadlineExceeded, FailedPrecondition, Internal, InvalidArgument
from .utils import get, has, get_player, process_schema, schemas, structify, timeout

# Registered Environments.
environments = {}

# Registered Interactive Sessions.
interactives = {}


def register(name, environment):
"""
Expand Down Expand Up @@ -90,6 +94,7 @@ def __init__(
html_renderer=None,
debug=False,
):
self.id = str(uuid.uuid1())
self.debug = debug

err, specification = self.__process_specification(specification)
Expand Down Expand Up @@ -263,6 +268,21 @@ def render(self, **kwargs):
raise InvalidArgument(
"Available render modes: human, ansi, html, ipython")

def play(self, agents=[], **kwargs):
"""
Renders a visual representation of the environment and allows interactive action selection.
Args:
**kwargs (dict): Args directly passed into render(). Mode is fixed to ipython.
Returns:
None: prints directly to an IPython notebook
"""
env = self.clone()
trainer = env.train(agents)
interactives[env.id] = (env, trainer)
env.render(mode="ipython", interactive=True, **kwargs)

def train(self, agents=[]):
"""
Setup a lightweight training environment for a single agent.
Expand Down Expand Up @@ -344,6 +364,7 @@ def toJSON(self):
spec = self.specification
return copy.deepcopy(
{
"id": self.id,
"name": spec.name,
"title": spec.title,
"description": spec.description,
Expand All @@ -365,6 +386,22 @@ def toJSON(self):
}
)

def clone(self):
"""
Returns:
Environment: A copy of the current environment.
"""
return Environment(
specification=self.specification,
configuration=self.configuration,
steps=self.steps,
agents=self.agents,
interpreter=self.interpreter,
renderer=self.renderer,
html_renderer=self.html_renderer,
debug=self.debug,
)

@property
def __state_schema(self):
if not hasattr(self, "__state_schema_value"):
Expand Down
39 changes: 24 additions & 15 deletions kaggle_environments/envs/connectx/connectx.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,18 @@
// limitations under the License.

function renderer({
parent,
step,
frame,
act,
agents,
environment,
width = 400,
frame,
height = 400,
interactive,
isInteractive,
parent,
step,
update,
width = 400,
}) {
// Canvas Setup.
let canvas = parent.querySelector("canvas");
if (!canvas) {
canvas = document.createElement("canvas");
parent.appendChild(canvas);

canvas.addEventListener("click", () => {
console.log("canvas click");
});
}

// Configuration.
const { rows, columns, inarow } = environment.configuration;

Expand All @@ -49,6 +41,23 @@ function renderer({
const xOffset = Math.max(0, (width - cellSize * columns) / 2);
const yOffset = Math.max(0, (height - cellSize * rows) / 2);

// Canvas Setup.
let canvas = parent.querySelector("canvas");
if (!canvas) {
canvas = document.createElement("canvas");
parent.appendChild(canvas);

if (interactive) {
canvas.addEventListener("click", evt => {
if (!isInteractive()) return;
const rect = evt.target.getBoundingClientRect();
const col = Math.floor((evt.clientX - rect.left - xOffset) / cellSize);
if (col >= 0 && col < columns) act(col);
});
}
}
canvas.style.cursor = isInteractive() ? "pointer" : "default";

// Character Paths (based on 100x100 tiles).
const kPath = new Path2D(
`M78.3,96.5c-0.1,0.4-0.5,0.6-1.1,0.6H64.9c-0.7,0-1.4-0.3-1.9-1l-20.3-26L37,75.5v20.1 c0,0.9-0.5,1.4-1.4,1.4H26c-0.9,0-1.4-0.5-1.4-1.4V3.9c0-0.9,0.5-1.4,1.4-1.4h9.5C36.5,2.5,37,3,37,3.9v56.5l24.3-24.7 c0.6-0.6,1.3-1,1.9-1H76c0.6,0,0.9,0.2,1.1,0.7c0.2,0.6,0.1,1-0.1,1.2l-25.7,25L78,95.1C78.4,95.5,78.5,95.9,78.3,96.5z`
Expand Down
50 changes: 31 additions & 19 deletions kaggle_environments/envs/tictactoe/tictactoe.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,44 @@
// See the License for the specific language governing permissions and
// limitations under the License.

function renderer({
agents,
parent,
step,
frame,
environment,
width = 400,
height = 400,
update,
}) {
async function renderer(context) {
const {
act,
agents,
environment,
frame,
height = 400,
interactive,
isInteractive,
parent,
step,
update,
width = 400,
} = context;

// Common Dimensions.
const canvasSize = Math.min(height, width);
const unit = 8;
const offset = canvasSize > 400 ? canvasSize * 0.1 : unit / 2;
const cellSize = (canvasSize - offset * 2) / 3;

// Canvas Setup.
let canvas = parent.querySelector("canvas");
if (!canvas) {
canvas = document.createElement("canvas");
parent.appendChild(canvas);

canvas.addEventListener("click", () => {
console.log("canvas click");
});
if (interactive) {
canvas.addEventListener("click", evt => {
if (!isInteractive()) return;
const rect = evt.target.getBoundingClientRect();
const x = evt.clientX - rect.left - offset;
const y = evt.clientY - rect.top - offset;
act(Math.floor(x / cellSize) + Math.floor(y / cellSize) * 3);
});
}
}

// Common Dimensions.
const canvasSize = Math.min(height, width);
const unit = 8;
const offset = canvasSize > 400 ? canvasSize * 0.1 : unit / 2;
const cellSize = (canvasSize - offset * 2) / 3;
canvas.style.cursor = isInteractive() ? "pointer" : "default";

// Canvas setup and reset.
let c = canvas.getContext("2d");
Expand Down
Loading

0 comments on commit 49405fd

Please sign in to comment.