Coder Social home page Coder Social logo

redhat-israel / rose Goto Github PK

View Code? Open in Web Editor NEW
34.0 5.0 125.0 12.29 MB

ROSE project car race game

License: GNU General Public License v2.0

Python 77.59% HTML 1.73% CSS 2.55% JavaScript 16.49% Makefile 0.53% Dockerfile 1.12%
education python opensource game javascript html5 twisted self-driving-car hacktoberfest

rose's Introduction

ROSE Project

CI WorkFlow

This project is a game that has been developed to assist in teaching kids python. The students need to code the behavior of a car to achieve the best score.

Here is a video of a race (running code from students): (Click on the screenshot to play the video)

ROSE Race Car Game

In this game, two race cars compete to achieve the most points. The race car must recognize the race track, the obstacles, and the bonus areas; then calculate the best path where the pitfalls are avoided and all the bonus points are collected. The cars move autonomously on the screen within the race track game with no interference from the students. No joystick or mouse shall be used.

In order to control the car movements, the students needs to implement a 'driver'. This code controls the car and will decide what the next action of the car will be.

For each type of obstacles there is a different action and different points assigned.

See examples/README.md for an explanation on how to write a driver module.

GitHub pages

Refer to our GitHub pages for the course materials and additional resources: https://redhat-israel.github.io/ROSE/

Talks and presentations

Getting started

The following commands should be performed only once; after creating the environment you will be connecting to the same environment each time you open a new session.

Use venv to create a virtual environment and to install the rest of the dependencies:

python3 -m venv ~/.venv/rose

After creating the environment, we want to activate and enter our environment (make sure you're in the ROSE directory):

source ~/.venv/rose/bin/activate

After entering the virtual enviornment we need to install the project dependencies:

pip install -r requirements.txt

Indication that you are inside the environment, the prompt line will look like this:

(rose) [username@hostname ROSE]$

Running the server

If you are not in your virtual environment, please activate it:

source ~/.venv/rose/bin/activate

Start the server on some machine:

./rose-server

For running the same track for all drivers (instead or random) start the server using:

./rose-server -t same

Open a browser at http://{server-address}:8880 to view and control the game.

Running the server in Podman

Build the Docker image:

podman build -t rose_server .

Run the Docker image on port 8880:

podman run -it --rm --name=rose_server -p 8880:8880 rose_server python ./rose-server

If you don't want to see the log of the run in the current window, replace -it with -d.

Open a browser at http://{server-address}:8880 to view and control the game.

Tunneling the UI server to your browser

You can use SSH tunneling when running the server on your remote VM, so you can view the game in you local browser:

ssh -L 8880:127.0.0.1:8880 {user}@{server-address}

After starting the server (as mentioned above), open a browser at http://127.0.0.1:8880/ to view and control the game.

Opening firewall ports

You can also open ports 8880 and 8888 on the remote VM running the server, and browse from a local machine in case port 8880 or 8888 are blocked by firewalld:

sudo firewall-cmd --add-port=8880/tcp --permanent
sudo firewall-cmd --add-port=8888/tcp --permanent
sudo firewall-cmd --reload

Running a driver

In a new window, open your virtual environment:

source ~/.venv/rose/bin/activate

Create your driver file:

cp examples/none.py mydriver.py

Edit the file mydriver.py and change the driver_name variable to your name.

Start up the client, using your driver file:

./rose-client mydriver.py

The server address can be specified that way (Replace '10.20.30.44' with your server address):

./rose-client -s 10.20.30.44 mydriver.py

For running the driver on the Docker container use:

docker exec -it rose_server python ./rose-client examples/random-driver.py

For driver modules, see the examples directory.

You can run the game with just 1 driver!

To let 2 drivers compete, repeat these commands in 2 terminals.

Command line interface

You can control the game from the command line using the rose-admin tool.

To start a race, use the rose-admin tool on any machine:

./rose-admin {server-address} start

To stop a race, use the rose-admin tool on any machine:

./rose-admin {server-address} stop

To modify the game rate, you can use the "set-rate" command. The following command would change game rate to 10 frames per second:

./rose-admin {server-address} set-rate 10

Using tmux / screen

./rose-server and ./rose-client {driver name} do not return, but continue running, in order to run both server and drivers a user need to run them in separate shells, using the same virtual environment. shell. tmux may be useful in this case.

Example tmux commands:

Command Description
Ctrl+b + c Create a new window
Ctrl+b + n Toggle to next window
Ctrl+b + w List open windows
Ctrl+b + 0 Select Window 0
Ctrl+b + 1 Select Window 1
Ctrl+d Close a window (exit bash)

Creating a tarball

python setup.py sdist

Developing

Should you want to contribute to the project, please read the Code of Conduct.

To create venv use:

python3 -m venv ~/.venv/rose

To enter the venv:

source ~/.venv/rose/bin/activate

To install development requirements:

pip install -r requirements-dev.txt

For development in docker, use:

docker build --build-arg DEV=True -t rose_dev .

Before submitting patches, please run the tests:

flake8
pytest

Creating coverage report in html format:

pytest --cov-report html
xdg-open htmlcov/index.html

rose's People

Contributors

aabawer avatar abelarm avatar annadinaburgvulikh avatar benipeled avatar bronhaim avatar cben avatar codingben avatar cotyembry avatar didib avatar ditti4 avatar eb-h avatar emesika avatar eshulman2 avatar itayfree avatar kobihk avatar moshe742 avatar mureinik avatar nirs avatar rollandf avatar sfishbai avatar shiramax avatar sleviim avatar syed-shah-zepto avatar tareqalayan avatar uda avatar yaacov avatar yifatmakias avatar yoavtzelnick avatar yodem avatar yuvalturg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

rose's Issues

Configurable timeout

Allow changing the game timeout from rtp-admin. This requires adding a new verb to the xmlrpc interface on both server and client.

Mute/unmute the sound in the web interface

Some people (e.g. me) do not like the soundtrack. It will be useful to mute the sound easily from the web UI without muting the entire machine.

The UI should probably be at the top of the window near the other elements, something like a laptop mute button maybe.

The system should keep the mute state; closing and opening the browser will keep the sound muted.

I think html5 local storage api is the best way to implement this, since we don't have any concept of authentication in this application.
See https://html.spec.whatwg.org/multipage/webstorage.html#storage-2

improper behaviour on car collision

consider the following scenario:

Car A is in line X1
Car B is in line X2 (X2 != X1)

Both X1 and X2 are on the same Y position
Now
Car A tries to move from X1 to X2
result : Car A moves to (X2,Y) while car B moves to (X2, Y+1) , i.e. the car that owned the line (B) was punished
required fix : Car A should get a CAR as obstacle and if it moves to a place of another car the result should be (in the above scenario) : A (X2, Y+1) , B (X2, Y)

Add good samples for training

We need to create new samples based on teh score.py and zigzag.py that can be given as a pyc files for students for trainign purpose.
Those can be used by us as well to test that game and find bugs ....

Add sound to the game

A cool feature would be to add in configuration two options

PlaySound -> boolean
SoundfFile -> file location

Then if that is set, teh game will run the track in in a loop while the game is running

Web demo

Have a static demo playing a pre-created (or randomly generated) game. Can be served as part of the documentation.

The game can be simulated by client side "server" receiving control requests (e.g. start/stop/rate) and emitting game update messages, using a pre-created game state.

Being able to replace a real sever with client side fake server is a good idea regardless the demo, for testing the web interface. Currently the server is accesses via the Client class and also directly via jquery.post. The code to post message should move into the Client.

Handle splash screen

Open the splash picture in the middle of the screen
NOTE : you have a class that encapsulate the splash named splash.py

Complete web interface

The web interface do not render the obstacles and cars yet.

Should be pretty easy to port the python code for this to javascript.

Remove pygame code

Since we have now a web interface, the pygame code is not needed.

The changes needed:

  • remove the rendering code in rose/client/game.py
  • remove the module rendering the components in rose/client/
  • remove the configuration options in rose/common/config.py needed only by the client
  • move modules from rose/common to rose/server that are used now only by the server
  • remove pygame from the requirements.txt / Pipfile

Note: removing code without leaving unused stuff is not easy.

Handle end-of-game screen

Open the finish line picture in the middle of the screen
NOTE : you have a class that encapsulate the game finish named end.py

ROSE client container

Create a client container for students and publish it on docker hub.

With the container, the students can run their code using docker without installing anything but docker.

Update readme for new makefile

The readme show how to run the project installed using pip, we have now pipenv support and a makefile making it much easier to use.

Stop the game

Currently the game never stop, and you have to stop it manually using rtp-admin tool.

Instead, stop the game when the first player reach the top of the track, or after a configurable timeout (e.g. 60 seconds).

Add sound in the web UI

In the old pygame code we played a sound from rose/res/soundtrack/Nyan_Cat.ogg when starting a client.

We like to restore this functionality by playing this sound in a loop when opening the web interface.

Add flake8 to the travis build

flake8 includes both pyflakes (finding code quality issues) and pycodestyle (finding code style issues). We want to fail the build if a pull request introduce such issues.

This task should be done in several steps:

  1. Add flake8 to travis - the build will probably fail at this point
  2. Fix easy issues
  3. Silence issues which are hard to fix using #noqa comments
  4. Silence unwanted warnings using flake8 configuration file

It should be possible to run flake8 locally without any command line options.

Related docs:

Port to windows?

If we want easy deployment in schools, the client should work in windows.

The current code should work as is, but we never tested it.

ROSE Server container

Create a container for the server and publish it on docker hub.

With the container, instructor and/or students can run a game using docker without installing anything but docker.

Remove Makefile, document how to use pipenv

The recently added Makefile is not useful:

  • rose-client and rose-admin need arguments, running them using the makefile is not a good idea
  • this won't work on platforms where installing make is hard
  • running "pytest" is nicer and more useful then "make test" best use the simpler and powerful way instead of having tow ways to run the tests.

We need to remove it and document instead of to use pipenv, replacing the old way using bare pip.

Playing with pipenv, it seems that the best way to use it is:

Requirement:

  • pip install --user pipenv

Setup for users:

  • pipenv install

Creating a shell for running the server or client:
pipenv shell

Setup for developers:

  • pipenv install --dev

With this the rest of the documentation does not need any change.

It is possible to use "pipenv run" but having to repeat this is annoying and error prone, I don't want to make it harder for teachers or students.

Notes:

  • Setup for developers should be separate from user setup, we don't want to confuse users with developers tasks.
  • For users we have two use cases:
    • students - need to run both local server and one or more clients for testing their code
    • teacher - need to run the server, and ask student to connect to the server
      Maybe we need to document this separately to make it easier?
  • Students are young and may have no technical experience, we need to avoid stuff like "old fashioned way" since they don't know anything about it

Rethink the "life" concept - introduce energy

The life concept does not make sense as is. It was added to allow selection of a winner when several players finish the game in the same position. The value is set to the number of penguins collected.

We should consider different idea - "engery" or "fuel" - each action you take consume amount of energy. If a player is not efficient enough, its energy may finish before the race is done, and the car would stop. This can be used in the same way as life for picking a winner when players end in the same position (higher energy win).

The implementation is simple, initialize to configured value and decrease on each operation according to configured value for each operation.

Require service_identity for better TLS client hostname verification

This warning gets shown when trying to run the server
:0: UserWarning: You do not have a working installation of the service_identity module: 'No module named service_identity'. Please install it from <https://pypi.python.org/pypi/serv ice_identity> and make sure all of its dependencies are satisfied. Without the service_identity module, Twisted can perform only rudimentary TLS client hostname verification. Many valid certificate/hostname mappings may be rejected.

Remove server address from car impl

enable to define the server address as a command line option will enable us to use pyc sample files on any server , currently it will be only the compiled one defined statically in the car impl file

Fair obstacle generation

Current code generates one random obstacle per row at a random cell. This creates unfair conditions for the two players, causing a random player to win, even if the other player code is better.

When playing with same code for each client, we should expect that both clients finish in the same or very similar result, but what we see is totally random results - even when using the new code using 3 lanes for player and considering player lane on collisions.

Possible solutions:

  • generate the same sequence of obstacles for both lanes
  • generate the same sequence of obstacles for both lanes but different cells
  • use pre-made sequences with known quality
  • use pre-made sequences randomized before use

Publish documentation using github pages

Students should use the published documentation on the web.

Add docs directory with couple of markdown files based on current readme files, and publish in github pages.

Heroku integration

Beni suggests in #175 that it will be easier to integrate with Heroku:
https://devcenter.heroku.com/articles/heroku-button

The goal of this integration is allow anyone to deploy the rose-server on Heroku with few clicks.

The expected flow:

  1. User clicks a deploy-on-heroku button in the project README
  2. System open Heroku deploy page, with most parameters already filled up
  3. User enter only the details that cannot be automated, such as application name (e.g. my-rose-server)
  4. User confirm the deployment on Heroku
  5. Application is deployed on Heruku, ready to accept connections from rose-client(s) on my-rose-server.herokuapp.com:8888, and showing the game UI at http://my-rose-server.herokuapp.com:8880/

Deployment details:

  • Install the rose/common and rose/server packages
    • rose/client is not needed, but it is ok to install it for simplicity
  • install the rose-server script
  • When the application starts, rose-server should run
  • When the application stops, rose-server process should terminate
  • The Heroku instance should allow incoming traffic to ports 8888 (client port) and 8880 (web port)

Testing the deployment:

  1. Open http://my-rose-server.herokuapp.com:8880/ - should show an empty game
  2. Create driver.py module with the server address:
$ cat driver.py
from rose.common import obstacles, actions

server_address = "my-rose-server.herokuapp.com"
driver_name = "My Driver"

def drive(world):
    return actions.NONE
  1. Connect client to server:
./rose-client driver.py
  1. Start the game in the web UI

The game should run, showing the connected client.

I'm not sure all this is possible, will needs some research.

Less noise in the client log

The client log is too noisy, hiding debug messages from the drive module. Display only important messages such as successful login, game status change etc.

Support compiled driver modules

When running a client you need to provide a driver python module:

./rose-client mydriver.py

This is fine for developing a driver code, but a student may like test her code against an example driver. But providing a good driver example code will spoil the challenge of developing a driver module. We like to provide pre-complied driver modules (see #137) in .pyc format, so this will work:

./rose-client example_driver.pyc

When loading pyc file, we can create a code object:

data = open('drivers/score.pyc').read()
magic_number = data[:4]
assert magic_number == imp.get_magic()
bytecode = data[8:]
code = marshal.loads(bytecode)

But I don't think we should use this method - this will be hard to maintain when python change the .pyc header format - this was recently changed in python 3.7.

I think the best way to solve this would be to use dynamic import using importlib.
https://docs.python.org/3/library/importlib.html

Reversed sorting in server stats

When a game completes, the server print the stats to the console:

Stats
1     Zig Zag  row:5  score:620
2       Score  row:2  score:707

The order of the drivers is wrong - should be sorted by score, highest score first.

Modernize imports

Replace the old imports like:

import track

With modern imports:

from rose.server import track

Or:

from . import track

Some score tests fail

$ py.test
rose/server/player_test.py ..
rose/server/score_test.py FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Last commit where the tests passed is 73afb53

Looks like 49159b4 broke the tests.

Provide server address as a parameter from command line

Currently the server address is specified in the driver module. This does not work well in the classroom, when students have to modify the server address many times.

After discussing this in #163, we agreed on this command line inteface:

./rose-client [-h|--help] [-s|--server SERVER] DRIVER
  • If the server is not specified in the command line, fallback to driver module.
  • if server is not specified anywhere, use localhost
  • If server is specified both in command line and driver module, command line wins (silently)

The admin tool should be modified to use the command line interface.

Relevant docs:

Add contribution guide

The guide should explain the recommend workflow:

  • Fork the project on github
  • Add upstream remote
  • How to send PR with multiple commits
    • squash mode - fixing review comments by adding more commits
    • rebase - amending the commits, keeping clean history
  • How to test changes before posing patches
  • How to write good commit messages
  • Project coding style (probably separate document)

Exit client after server errors

Currently when the client misbehave and the server disconnect it, the client ignore the error and connect again. This make it harder to debug issue such as trying to run two clients with same driver name.

Add makefile

Make it easy to run the various tools with the virtual environment.

Use websocket for client communication

Currently we have listen to 2 ports:

  • TCP/8888 - using line based protocol, used by rose-client
  • TCP/8880 - used for web side, xmlrpc, and websocket

Trying to deploy on Heroku (see #187), it seems that we don't have a way to serve a custom port in this platform. I'm not sure if this is also an issue on OpenShift.

We discussed offline the option of replacing the custom port with websocket, enabling deployment on Heruko and other platforms that are optimized for web development.

New design

Player connection protocol

  • player: connect to server using websocket
  • server: accept connection, wait for message
  • player: send "join" message
  • server: register player, send "update" message to all clients

Watcher connection protocol

  • watcher: connect to server using websocket
  • server: accept connection, wait for message
  • watcher: send "watch" message
  • server: register watcher, send "update" message to all clients

Game protocol

  • server: send "update" message with "started: true" to all clients
  • player: send "drive" message
  • watcher: update the UI

Game completion

  • server: send "update" message with "started: false"
  • player: ignore
  • watcher: update the UI

Changes needed

Code coverage report includes the tests modules

The coverage should include only the code. Looks like the eaiset
way would be to move the test out of the rose package.

---------- coverage: platform linux2, python 2.7.13-final-0 ----------
Name                         Stmts   Miss  Cover
------------------------------------------------
rose/__init__.py                 0      0   100%
rose/client/__init__.py          1      1     0%
rose/client/car.py              32     32     0%
rose/client/component.py         4      4     0%
rose/client/dashboard.py        36     36     0%
rose/client/end.py              11     11     0%
rose/client/finish.py           17     17     0%
rose/client/game.py             87     87     0%
rose/client/main.py             51     51     0%
rose/client/splash.py           11     11     0%
rose/client/track.py            38     38     0%
rose/client/world.py            13     13     0%
rose/common/__init__.py          0      0   100%
rose/common/actions.py           1      0   100%
rose/common/config.py           39      0   100%
rose/common/error.py            25     25     0%
rose/common/message.py          17     17     0%
rose/common/obstacles.py         4      1    75%
rose/server/__init__.py          0      0   100%
rose/server/game.py             95     95     0%
rose/server/main.py            145    145     0%
rose/server/player.py           27      2    93%
rose/server/player_test.py      11      0   100%
rose/server/score.py            48      0   100%
rose/server/score_test.py      244      0   100%
rose/server/track.py            28     11    61%
------------------------------------------------
TOTAL                          985    597    39%

Log car summary for obtcales and penguins

Log car summary for obtcales and penguins
Suggested format
CAR : , : .... : :

Note for obstacle is the number that the car didn't do the right action
on penguin is the number collected (action.PICKUP)

The server should collect this information and write it to the log/stdout
When rtp-admin is called with stop it will display such line per car as summary

Publish in pypy

I think the only change needed is fixing the setup.py which is very old and probably missing stuff.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.