Code Monkey home page Code Monkey logo

roboprojekt's Introduction

RoboProject

This is a video game based on the board game RoboRally.

It includes a network server and graphical desktop clients.

The Project

Advanced PyLadies CZ Project

This project was created for PyLadies who successfully passed beginner Python courses and wanted to continue with Python via a "real" assignment. Its aim was to show participants the process of software development from the very basics, and enable them to try it on their own. It was focused on team cooperation, using Python for real tasks, working with Git and GitHub, showing best practices and trying various useful tools.

You can read about the progress on our blog (in Czech).

Contribution

After over a year of developing we've decided to publish the first version of the game. From now on anyone is welcome to contribute. If we like your changes, we'll happily merge it. If you spot a bug or have an idea for enhancement, write us an GitHub issue.

Requirements

Python v. 3.7 We recommend to use virtual environment.

To successfully run the project, run the script below. It will install all the requirements including additional libraries:

  • pyglet - the graphical library,
  • asyncio and aiohttp - asynchronous frameworks to run server and clients,
  • pyyaml - for reading the configuration files.
python -m pip install -r requirements.txt

For testing of this project we use pytest framework. If you want to run the tests and don't have pytest on your computer, you can install it with the following command:

python -m pip install pytest

The game

How do you run the game?

The game is playable through the network. Therefore it is divided into server and client parts. In order to play the game, you need to run the server first.

python server.py

You can choose a map to play directly from command line by writing the location of the JSON map as the optional argument -m, --map-name. For easier choice you can see the preview of maps in folder maps/. The same way you can enter the number of players -p, --players. The current maps are prepared for the max. 8 players.

python server.py -m maps/game_1.json -p 6

If you run server on a different computer than the clients, get the server's hostname and run clients with its value as the named argument -h, --hostname. If you want to run both server and client/-s on the same computer, the default value localhost will be automatically set. In order to see the game board with small players' avatars, use for example:

python client_receiver.py -h 192.168.10.1

And if you want to play with your own robot, there is a prepared interface which you can access through the welcome board. There you can type a custom name for your robot and pick one from the available list.

python client_welcome_board.py -h 192.168.10.1

In case you want to get the first available robot with his factory name, you can run the interface directly. This will skip the choice screen. The list of factory names is available in robots.yaml (and can be customized if wanted). In case you know which robot you want, use optional argument -r, --robot-name to pick him.

python client_interface.py -h 192.168.10.1 -r Bender

Get the list of all possible arguments by typing the client name and --help. Note that the possibility to connect to server run on a different computer may be limited by your network provider. In order to play the game, run as many interfaces as there are starting points on the map and at least one receiver.

How do you win and how does the game round look like?

Each player has one robot which can be programmed by cards. The goal is to collect all flags on the board in the increasing order. The first robot who collects all flags wins.

It is possible to play using both keyboard and the mouse. The keys are listed directly on the interface screen.

At the beginning of each round you get a random set of cards and by choosing cards for robot's slots you will set his moves for the round. There is a time limit for choosing the cards. During the "choosing cards" part you can also put your robot to Power Down mode which means they won't make any actions by their own but they can be affected by other robots' actions. Switching on Power Down also requires confirming the selection. Once the "choosing cards" phase ends, the following steps will repeat 5 times:

  1. The robots' card actions are performed in order of priority
  2. The effects of tiles robots stand on are performed
  3. Robots are shooting
  4. If robot stands on the right flag tile, the flag is collected
  5. If robot stands on the repair tile, the start position changes

After this phase is complete, the robots standing on the repair tile or in Power Down mode repair themselves and the next round begins.

Tests

The tests are places in tests/ folder. They are divided into separate files, eg. test_effects.py, test_backend.py, test_loading.py, covering respective modules. test_effects.py reads the subfolders with test maps and commands. It executes the game on the background and asserts the robots performed the steps and their attributes were changed according to tile effects. For more details about testing framework see tests/README-tests.md. test_loading.py also contains map validator (see map details below).

To run the tests, write the following command into the command line: python -m pytest -v

If you want to run only one of the testing files, add the name of the file after the command above. The current tests handle only the game logic, not the network interfaces.

Create your own map

Current maps were created in Tiled map editor, version at least 1.2.1. You can create your own map with the prepared tileset development_tileset.json. When creating multiple-layered tiles, we strongly recommend to create the new layer for every kind of tiles, including the separate layers for lasers (horizontal, vertical) and walls (N, S, E, W). The order of layers is checked by validator and must follow the pattern:

  1. earth
  2. one of the following: hole, start,
  3. one of the following: repair, belt, gear
  4. flag
  5. pusher, laser, wall

Automatic conversion from .SVG to .PNG

This project also contains a program export_img.py for automatic conversion of images in .SVG format to .PNG format. The current version of the program uses Inkscape vector graphic editor so if you want to use this program, you need to install Inkscape first.
To convert all images, run the export_img.py file from the root directory of the project. It will then export all images in .SVG to .PNG in all subdirectories.

roboprojekt's People

Contributors

amazonkaarya avatar anezkamll avatar befeleme avatar encukou avatar ivet1987 avatar jureckovak avatar myshiczkah avatar vahalova avatar yaplik avatar zstankova avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

roboprojekt's Issues

⚠ Předělat strukturu dat

  • Políčka na jedné souřadnici by měly být u sebe, v jednom seznamu.
  • Roboti by si měli pamatovat svoje souřadnice.

Otestovat efekty políček

Napsat testy a otestovat již hotové efekty políček z PR #137 :

  • hole
  • pusher
  • gear
  • laser - otestovat, jestli funguje správně trasování laseru i skrz křižovatky laserů
  • flag
  • repair

Hlavně otestovat správné přidítání/odečítání zranění, odečítání životů a následné (ne)oživení robota.

Větší mapy

Budeme potřebovat načítat větší mapy.
Aktuálně program neschroustá mapu rozšířenou o startovací pásek 12x4.

Vytvořit testovací mapu 12x16 a upravit kod, aby se zobrazovala celá.

Odstranit "WIP" z API

Věcem které se používají v jiném kódu, jako názvy souborů a funkcí (from jmeno_souboru import jmeno_funkce), počet argumentů funkce (jmeno_funkce(1, 2, 3)) se říká API (application programming interface). Když se API nějaké funkce změní (přejmenuju soubor, změním počet argumentů), kód který tu funkci používal přestane fungovat.

Poznámky o tom, že je něco nedodělané, by neměly být součástí API. Pak totiž vznikají věci jako:

from backend_WIP import get_tiles, get_coordinates, get_data

… které bude potřeba všechny opravit, až se backend „dodělá“. (Kdy to bude? Žádný kód není úplně hotový a perfektní, jsou v něm jen nedodělky s větší nebo menší prioritou.)

Poznámky "WIP" stačí mít mít v komentářích, dokumentaci, nebo issues.

Chybí obrázky políček

  • zeď
  • vlajka (1-8)
  • startovací políčka (1-8)
  • laser (začátek, paprsek)
    • jednoduchý
    • dvojitý
    • trojitý
  • posuvníky (pushers) (1/3/5 a 2/4)
  • díra
  • zem
  • pohyblivý pás
    • 1 rovný
    • 1 křižovatka
    • 1 zatáčka (doprava, doleva)
    • 2 rovný
    • 2 křižovatka
    • 2 zatáčka (doprava, doleva)
  • Otáčecí kolečko (doprava, doleva)
  • Opravovací políčko
    • Vylepšovací políčko

Budoucnost

  • Hru bude řídit server, ke kterému se budou přihlašovat klienti (speciální sraz)
  • Power Down (#232)
  • Vyřešit odpojování klientů (#384)
  • Z grafiky bude poznat, co se na herní ploše děje (#308)
  • Sepsat návod (#50)

Rozšíření:

  • Na přihlašovací obrazovce půjde vybrat robota a pojmenovat ho
  • Hra obsahuje návod přímo v sobě
  • Klient bude zabalený jako spustitelný soubor pro Windows (PyWorking, možná v červnu)
  • Nasadit server v cloudu

Nepředávat konstanty jako argumenty

Všemi velkými písmeny, např. WIDTH, se tradičně pojmenovávají konstanty – proměnné, které mají vždycky stejnou hodnotu.
Takové hodnoty není potřeba předávat funkcím jako argumenty. Použijte globální proměnnou (a jestli je nadefinovaná v jiném modulu, naimportujte si ji).

Dopsat README

Soubor README.md je vizitka projektu; GitHub ho ukazuje na hlavní stránce. Měly by tam být věci jako:

  • co ten program dělá
  • jak to nainstalovat (většinou předpokládám že čtenář má aktivované virt. prostředí, ale ten předpoklad tam zmíním),
  • jak to spustit
  • jak spustit testy
  • jak se zapojit (zatím asi nechcete aby se do toho zapojovali cizí lidi)

Přidat k mapě roboty

Aktuálně je stav hry jen mapa (slovník souřadnice → seznam políček). Bude k tomu potřeba přidat i seznam robotů, a případně pak nějaké zdi nebo jiné věci.

Udělejte si na stav hry dataclass, který bude obsahovat mapu a roboty. Roboti by se měli objevit na počátečních políčkách.

Použít třídu na efekt políčka

„Obrázky“ políčka jsou aktuálně reprezentovány jako dvojice (ID políčka, rotace). Dvojice není úplně ideální: když z ní chci jednotlivé prvky, musím dělat buď:

  • value[0] a value[1] (takže není poznat co dostávám), nebo
  • coordinate, rotation = value (což je super do té doby, než budu potřebovat další kousek informace, a bude potřeba všechno předělat na trojice).

Použijte na to místo dvojice třídu.

Mapy 4, 5, 6 nefunguji

Opravit mapy - nyni jejich nacitani kolabuje: na cestach k souborum, na spatnem tilesetu atd.

Odstranit Tile(0, 0)

Když je v JSON mapě prázdné políčko (id=0), je reprezentováno pomocí Tile(path=0, rotation=0):

roboprojekt/backend.py

Lines 58 to 66 in 29125f3

for data in layer['data']:
id = get_tile_id(data)
if id == 0:
tile = Tile(0, 0)
else:
rotation_index = get_tile_rotation(data)
rotation = rotation_dict[rotation_index]
tile = Tile(rotation, paths[id])
tilelist_layer.append(tile)

Ve frontendy je pak pro path=0 speciální logika:

roboprojekt/frontend.py

Lines 43 to 47 in 29125f3

for key, value in state[layer].items():
rotation = value.rotation
path = value.path
if path != 0:
img = pyglet.image.load(path)

Nebylo by lepší takovéhle „nepolíčko“ do seznamu tilelist_layer vůbec nedávat?


Na tomhle miniproblému nic dalšího nezávisí. Doporučuju někomu, kdo se v datovém modelu ještě úplně neorientuje (a má nějakou tu hodinku času). Jestli už teď víš jak to vyřešit, přenech to někomu jinému (nebo lépe, nabídni se jako kouč).

Jak vyřešit zeď?

Z UML diagramů zůstalo nedořešené téma, jak bude definovaná zeď v rámci efektu políčka.
Otevírám tedy tímto téma k zamyšlení a diskusi.
Souvisí s #22.

Zařídit, aby se robot při pohybu zarazil o zeď

Issues #84 (pohyb robota) a #82 (načítání efektů políček) vypadají že budou co nevidět vyřešené.
Myslím že je čas na první efekty políček!
Doporučuju se napřed zaměřit na zdi, než na ty ostatní.
Můžete přitom doladit, jak jsou efekty políček reprezentovány v kódu ­­– a zvášť jak reprezentujete zeď, #45.

Umírání

Když robot vyjede z mapy, tak spadne hra.

Vytvořit rozhraní hry

Napsat program, který vykreslí dvě statické části rozhraní - mapu a budoucí interaktivní část, viz obrázek.

Chybí mapa

Už je tu dost políček na jednoduchou testovací mapu: s jednou vrstvou, bez otočených políček. Nemusí být vůbec hratelná nebo složitá. Neměla by být symetrická, aby bylo poznat že se správně načte.

Pro sdílené mapy použijte Tiled 1.2 (jestli máš starší verzi a chceš dělat mapy, ozvi se na Slacku).

Naučit roboty střílet laserem

Přidat robotí metodu na střílení laserem. Laser robota neprochází zdí a zasáhne pouze prvního robota v cestě. Laser putuje přes hrací plochu dokud nenarazí na zeď nebo robota. Robot zasažený laserem získá jedno zranění. Roboti s PowerDown nestřílí, ale můžou být zasaženi.

Přidat dokumentační řetězce

Čím víc lidí (nebo kousků kódu) používá nějakou funkci, tím je k ní důležitější napsat dokumentaci – popis toho, co ta funkce dělá. Člověk si může číst samotný kód, ale tam není všechno.

Dobrá jména funkcí a argumentů už jsou dokumentace sama o sobě. Třeba:

def add(a, b):
    return a + b

… je OK pro funkci, kterou používám někde níž v tom samém souboru. Když si ale jen přečtu kód, není jasné např. jestli je tuhle funkci dobré zavolat na řetězce, add("Hello, ", "world!").

def add(a, b):
    """
    Add two numbers

    `a` and `b` should be numbers (int or float).
    Returns the sum.
    """
    return a + b

Velké projekty, kde je potřeba aby se s kódem mohl každý co nejrychleji seznámit a korektně ho měnit, to berou fakt vážně, a dokumentace je často delší než samotný kód – viz třeba tenhle kód z Javy.
Používají se i nástroje, které ověří že každá funkce a každý argument jsou zdokumentované. To už je docela extrém (u mladšího projektu se pak může stát, že se změní kód ale neaktualizuje dokumentace, a dokumentace co neodpovídá kódu je horší než žádná dokumentace). Ale je dobré se u každého argumentu aspoň zamyslet, jestli o něm jméno říká všechno co je potřeba.

Do dokumentačních řetězců (viz materiály, nebo do vyhledávače dej docstring) je dobré psát co funkce dělá, jaké bere argumenty, co vrací. U složitějších struktur (seznam dvojic slovníků souřadnic) je dobré uvést příklad, aby si to člověk líp uvědomil
Do normálních komentářů je dobré psát jak se to dělá, jak funkce postupuje – věci, které nezajímají toho, kdo pak bude funkci volat.
Například:

def get_coordinates(data):
    """
    Get a list of tile coordinates for a map

    `data` is a dict loaded from a Tiled 1.2 JSON file.
    Returns a list of all tile coordinates, for example:
       [(0, 11), (0, 10), (0, 9), ..., (0, 0), (1, 11), (1, 10), ..., (11, 1), (11, 0)]
    """

    # Get the size of the game board from JSON
    map_field_height = data['layers'][0]['height']
    map_field_width = data['layers'][0]['width']

    # Create map - list of x, y tuples 
    # Transformation with reversed is required as the JSON tiles
    # are in the opposite y direction
    coordinates = []
    for y in reversed(range(map_field_height)):
        for x in range(map_field_width):       
            coordinates.append((x, y))

    return coordinates

Co se „štábní kultury“ týče, je dobré mít jeden řádek s krátkým (jednořádkovým!) popisem, pak řádek vynechat, a pak rozepsat detaily. Všechno v „trojitých dvojitých“ uvozovkách, """.

Vytvořit třídu rotace

V backendu ve funkci move nahradí tento if:

if direction == 0:
    y += distance
elif direction == 90:
    x += distance
elif direction == 180:
    y -= distance
elif direction == 270:
    x -= distance

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.