Skip to content

Commit

Permalink
Merge pull request #55 from stfc/release-1.2.0
Browse files Browse the repository at this point in the history
Release 1.2.0 to master
  • Loading branch information
gregcorbett authored Jul 13, 2019
2 parents 1e5986d + 80d2787 commit 34ad23a
Show file tree
Hide file tree
Showing 39 changed files with 1,990 additions and 503 deletions.
28 changes: 11 additions & 17 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,29 +1,23 @@
img/UV/
img/UV/*
img/SKA/
img/SKA/*
img/DataHunt/
img/DataHunt/*
img/GAIA/
img/GAIA/*
img/*
!img/Default/*

logo.png

scenarios/UV.scibot
scenarios/SKA.scibot
scenarios/Default.scibot
scenarios/DataHunt.scibot
scenarios/GAIA.scibot
scenarios/*

scenarioWriters/ScenarioWriterUV.py
scenarioWriters/ScenarioWriterSKA.py
scenarioWriters/ScenarioWriterDataHunt.py
scenarioWriters/ScenarioWriterGAIA.py
scenarioWriters/*.py
!scenarioWriters/ScenarioWriterBlank.py
!scenarioWriters/ScenarioWriterDefault.py

scenarios.zip

*.pyc
*Thumbs.db

build/
dist/

runSciBot.spec

runSciBot.log
runSciBot.exe
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
language: python
python:
- "3.4"
- "3.6"
- "3.6-dev" # 3.6 development branch
- "3.7-dev" # 3.7 development branch
- "nightly"
matrix:
allow_failures:
- python: "3.6-dev"
- python: "3.7-dev"
- python: "nightly"
fast_finish: true

Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
========== Version 1.2.0 ==========

New Features and Minor Changes:

- Adds support for multi-sprite Goals and BeeBots: #51
- Add a display for commands programmed into the BeeBot: #39
- Introduce Component, ComponentGroup, Icon and IconGroup classes to reduce
duplication of code: #32, #33, #36, #44
- Add support for Python 3.6, drop support for Python 3.4 and 3.5: #37, #46

Patches, Bug Fixes and Documentation Changes:

- Fix bugs in Goal and GoalGroup equality testing: #28
- Improve test cases: #30, #38
- Add documentation explaining what an incompatible/breaking API change is: #31
- Document when the Point class should be used and make changes where that
documentation is not followed: #48
- Rework .gitignore to be generic with exceptions: #47


========== Version 1.1.0 ==========

New Features and Minor Changes:
Expand Down
42 changes: 23 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,35 @@
contact: scibot-dev@googlegroups.com

## Users
The primary method to run SciBot is via the `runSciBot.exe`.

1. Go to https://github.com/stfc/SciBot/releases/latest
2. Download runSciBot.exe and scenarios.zip into the same place
3. Unzip scenarios.zip
3. Run the .exe file (by double clicking it.)
2. Download `runSciBot.exe` and `scenarios.zip` into the same place
3. Unzip `scenarios.zip`
4. Run `runSciBot.exe` (by double clicking it.)

## Developers
If you wish to develop for SciBot, clone the repository and create a feature branch off of develop. Once your feature is ready, make a Pull Request back into develop. SciBot is written in Python 3, hence you will need to install the Python interpreter first. We recommend using [Python 3.6](https://www.python.org/ftp/python/3.6.4/python-3.6.4.exe).

If you wish to develop for SciBot, clone the repository and create a feature branch off of develop. Once your feature is ready, make a Pull Request back into develop.

### Requirements for building and developing SciBot
### Requirements for developing, testing and building SciBot
To install SciBot's requirements, run the following command:
```
pip install -r requirements.txt
```

Microsoft installers have been linked for each requirement for ease of installation.
### Building the runSciBot.exe file
If you wish to build a new `runSciBot.exe` file, run the following command:
```
pyinstaller --windowed -F runSciBot.py
```

1. Python, 3.4 or higher (https://www.python.org/downloads/)
* exact version used in testing ( https://www.python.org/ftp/python/3.4.3/python-3.4.3.msi)
2. Pygame, 1.9.2 or higher (https://bitbucket.org/pygame/pygame/downloads)
* exact version used in testing (https://bitbucket.org/pygame/pygame/downloads/pygame-1.9.2a0-hg_ea3b3bb8714a.win32-py3.4.msi)
3. py2exe 0.9.2.2 (https://pypi.python.org/pypi/py2exe/)
* exact version used in testing (https://pypi.python.org/packages/any/p/py2exe/py2exe-0.9.2.2.win32.exe)

### Building the exe file
## Image Sources
SciBot image sourced from: https://www.tes.co.uk/teaching-resource/bee-bot-sequence-powerpoint-6415227

After the requirements above are met, open a command line and navigate to the unzipped directory.
## A note about version numbers
SciBot tries to use [semantic versioning](https://semver.org) with respect to the API exposed to the user by the scenario class/files.
This means that for any given major version of the SciBot executable, all previous scenario files (that share the same major version) should continue to work as they did when the scenario file was created.

Run `python setup.py py2exe`.
As a result of this, we consider a breaking API change to be a change that prevents an older scenario file (that shares the current major version) from working as expected with the next release of SciBot. If such a change is merged, the next release would be the next major version.

## Image Sources
SciBot image sourced from: https://www.tes.co.uk/teaching-resource/bee-bot-sequence-powerpoint-6415227
Changes that are not exposed to the user by the scenario class/files will not be considered breaking API changes.
2 changes: 2 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ pygame
unittest2
coveralls
mock
# Dependencies for building
pyinstaller
15 changes: 0 additions & 15 deletions setup.py

This file was deleted.

90 changes: 56 additions & 34 deletions src/BeeBot.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from enum import Enum
from time import sleep
import pygame
from src.Component import Component
from src.CustomEvent import CustomEvent
from src.Point import Point

Expand All @@ -17,27 +18,26 @@ class Heading(Enum):
WEST = 4


class BeeBot(pygame.sprite.Sprite):
class BeeBot(Component):
"""This class defines the BeeBot."""

def __init__(self, scenario):
"""Create a BeeBot."""
# Initial position of the BeeBot in terms of square on the Board.
self.start_logical_position = Point(
scenario.get_beebot_start_position())
# Read the sprite and assume it is the "NORTH" sprite.
self.original_sprite_list = scenario.get_beebot_sprite()

# The amount the BeeBot moves.
self.step = scenario.get_board_step()

# The BeeBot's position of the BeeBot in terms of pixels.
self.screen_location = self.start_logical_position.scale(self.step)

# The BeeBot's position of the BeeBot in terms of the Board.
self.logical_position = self.start_logical_position.copy()
# Initial position of the BeeBot in terms of square on the Board.
self.start_logical_position = Point(
scenario.get_beebot_start_position())

# Read the sprite and assume it is the "NORTH" sprite.
self.original_sprite = scenario.get_beebot_sprite()
self.sprite = self.original_sprite
# Call the superclass constructor.
# Use copy() here to copy the objects not just the reference.
super().__init__(self.original_sprite_list.copy(),
self.start_logical_position.copy(),
self.step)

# Which way is the BeeBot facing.
self.start_heading = scenario.get_beebot_heading()
Expand All @@ -60,6 +60,24 @@ def __init__(self, scenario):

self.running = False

def increment_sprite(self):
"""
Increment the sprite to display for this BeeBot.
Also ensures the visual Heading of the sprite is consistent before and
after this method is called.
"""
super().increment_sprite()
# The new sprite will be facing Heading.NORTH regardless of
# self.heading, so fix that.
if self.heading == Heading.EAST:
self.sprite = self.rotate(self.sprite, 270)
elif self.heading == Heading.WEST:
self.sprite = self.rotate(self.sprite, 90)
elif self.heading == Heading.SOUTH:
self.sprite = self.rotate(self.sprite, 180)


def move(self, event):
"""Move the BeeBot."""
if event.type == CustomEvent.MOVE_BEEBOT_UP:
Expand Down Expand Up @@ -90,64 +108,59 @@ def clear_memory(self):
"""Clear the BeeBot's "memory"."""
self.memory = []

def display(self, screen):
"""Display the BeeBot on screen."""
screen.blit(self.sprite, (self.screen_location.x,
self.screen_location.y))

def move_backward(self):
"""Move the BeeBot backward."""
# The origin is in the top left corner
if self.heading == Heading.SOUTH:
for _ in range(0, self.step):
self.screen_location.y = self.screen_location.y - 1
self.screen_location = self.screen_location - (0, 1)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.y = self.logical_position.y - 1
self.logical_position = self.logical_position - (0, 1)

elif self.heading == Heading.WEST:
for _ in range(0, self.step):
self.screen_location.x = self.screen_location.x + 1
self.screen_location = self.screen_location + (1, 0)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.x = self.logical_position.x + 1
self.logical_position = self.logical_position + (1, 0)

elif self.heading == Heading.NORTH:
for _ in range(0, self.step):
self.screen_location.y = self.screen_location.y + 1
self.screen_location = self.screen_location + (0, 1)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.y = self.logical_position.y + 1
self.logical_position = self.logical_position + (0, 1)

elif self.heading == Heading.EAST:
for _ in range(0, self.step):
self.screen_location.x = self.screen_location.x - 1
self.screen_location = self.screen_location - (1, 0)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.x = self.logical_position.x - 1
self.logical_position = self.logical_position - (1, 0)

def move_forward(self):
"""Move the BeeBot forward."""
# The origin is in the top left corner
if self.heading == Heading.NORTH:
for _ in range(0, self.step):
self.screen_location.y = self.screen_location.y - 1
self.screen_location = self.screen_location - (0, 1)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.y = self.logical_position.y - 1
self.logical_position = self.logical_position - (0, 1)

elif self.heading == Heading.EAST:
for _ in range(0, self.step):
self.screen_location.x = self.screen_location.x + 1
self.screen_location = self.screen_location + (1, 0)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.x = self.logical_position.x + 1
self.logical_position = self.logical_position + (1, 0)

elif self.heading == Heading.SOUTH:
for _ in range(0, self.step):
self.screen_location.y = self.screen_location.y + 1
self.screen_location = self.screen_location + (0, 1)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.y = self.logical_position.y + 1
self.logical_position = self.logical_position + (0, 1)

elif self.heading == Heading.WEST:
for _ in range(0, self.step):
self.screen_location.x = self.screen_location.x - 1
self.screen_location = self.screen_location - (1, 0)
sleep(0.01) # sleep prevents the BeeBot moving too quickly
self.logical_position.x = self.logical_position.x - 1
self.logical_position = self.logical_position - (1, 0)

def move_right(self):
"""Turn the BeeBot right."""
Expand Down Expand Up @@ -210,7 +223,8 @@ def reset_position(self):
self.screen_location = self.start_logical_position.scale(self.step)

# Reset BeeBot sprite
self.sprite = self.original_sprite
self._sprite_list = self.original_sprite_list.copy()
self._sprite_list_index = 0

# From the original sprite, rotate to the start_heading
if self.start_heading == Heading.EAST:
Expand All @@ -226,6 +240,14 @@ def crash(self):
"""Set the sprite to be displayed to the fail sprite."""
self.sprite = self.fail_sprite

def is_equal_to(self, other_component):
"""Compare this BeeBot for equality with other_component."""
if not isinstance(other_component, BeeBot):
# An BeeBot can obviously never be equal to a non BeeBot
return False
# Comparing a BeeBot to another BeeBot has not yet been implemented
raise NotImplementedError()

@classmethod
def rotate(cls, image, angle):
"""Rotate given image by given angle."""
Expand Down
Loading

0 comments on commit 34ad23a

Please sign in to comment.