Skip to content

Commit

Permalink
Merge branch 'main' of github.com:opendilab/GoBigger
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangming committed Jan 17, 2022
2 parents 18a91d3 + 889a7fe commit f2a7dc1
Show file tree
Hide file tree
Showing 43 changed files with 1,257 additions and 55 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

## Ongoing

* 2022.1.17 We updated our C++ based game engine implementation which is ten times faster than python version. Please check [cpp](https://github.com/opendilab/GoBigger/tree/cpp) branch to get more details.
* 2021.11.13 We are holding a [competition](https://github.com/opendilab/GoBigger-Challenge-2021) —— Go-Bigger: Multi-Agent Decision Intelligence Environment. Come and make your agents in the game!

GoBigger is a simple and efficient *agar-like* game engine and provides various interfaces for game AI development. The game is similar to [Agar](https://agar.io/), which is a massively multiplayer online action game created by Brazilian developer Matheus Valadares. In GoBigger, players control one or more circular balls in a map. The goal is to gain as much size as possible by eating food balls and other balls smaller than the player's balls while avoiding larger ones which can eat the player's balls. Each player starts with one ball, but players can split a ball into two when it reaches a sufficient size, allowing them to control multiple balls.
Expand Down
86 changes: 86 additions & 0 deletions docs/en/source/advanced/hyper.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
Derived Environments and Action Spaces
################

Overview
=======================

On the basis of the GoBigger environment, considering the complexity of large-scale environment training and
algorithm verification for specific tasks, we provide some small environments under specific conditions,
as well as advanced serialization actions to facilitate training and algorithm design.


small environment
=======================

We provide the initialization method of the small environment by providing config.


* The clone fits the ball, the clone holds the ball (2f2s)

There are only two teams in this small environment, and there are two players in each team.
There will also be food summed thorn balls in the same scale in the map. In this map, the blue A ball
only needs to split to the right, while the blue B ball needs to eat the small ball split by the blue A ball
and move down, and eat the yellow A by splitting (or moving). ball.

.. only:: html

.. figure:: images/2f2s.png
:width: 300
:align: center


* Measured increase (2f2s_v2)

This small environment is the v2 version of 2f2s. In this map, the blue A ball only needs to split
to the right, while the blue B ball remains stationary to eat the yellow A ball.

.. only:: html

.. figure:: images/2f2s_v2.png
:width: 300
:align: center


* Measured increase (2f2s_v3)

This small environment is the v3 version of 2f2s. In this map, the blue A ball needs to split between
the yellow ball and the blue B ball and spore the center, while the blue B ball moves down to eat the yellow A ball.

.. only:: html

.. figure:: images/2f2s_v3.png
:width: 300
:align: center


Advanced Serialization Actions
=======================

Please check ``gobigger/hyper/tests`` to get more details on serialization actions.


* Straight line

.. only:: html

.. figure:: images/straight_merge.gif
:width: 362
:align: center


* Four point ball

.. only:: html

.. figure:: images/quarter_merge.gif
:width: 362
:align: center


* Eights

.. only:: html

.. figure:: images/eighth_merge.gif
:width: 338
:align: center
Binary file added docs/en/source/advanced/images/2f2s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/en/source/advanced/images/2f2s_v2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/en/source/advanced/images/2f2s_v3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/en/source/advanced/images/eighth_merge.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/en/source/advanced/images/quarter_merge.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/en/source/advanced/images/straight_merge.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/en/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Indices and tables
advanced/cfg_intro
advanced/custom_init
advanced/collision
advanced/hyper

.. toctree::
:maxdepth: 2
Expand Down
2 changes: 1 addition & 1 deletion docs/en/source/tutorial/quick_start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ After installation, you can launch your game environment easily according the fo
server = Server()
render = EnvRender(server.map_width, server.map_height)
server.set_render(render)
server.start()
server.reset()
player_names = server.get_player_names_with_team()
# get [[team1_player1, team1_player2], [team2_player1, team2_player2], ...]
for i in range(10000):
Expand Down
82 changes: 82 additions & 0 deletions docs/zh_CN/source/advanced/hyper.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
衍生环境和动作空间
################

总览
======================

在 GoBigger 环境的基础上,考虑到大环境训练的复杂度以及针对特定任务的算法验证,我们提供了部分特定条件下的小环境,以及高级序列化动作来方便
大家进行训练和算法设计。


小环境
======================

我们通过提供config的方式来提供小环境的初始化方式。


* 分身合球,分身持球(2f2s)

这个小环境中只有两只队伍,每支队伍中有两个玩家。地图中同时还会存在相同比例的食物求和荆棘球。在本地图中,蓝色A球
只需要向右边进行分裂,同时蓝色B球需要吃掉蓝色A球分裂出来的小球并向下移动,通过分裂(或移动)的方式吃掉黄色A球。

.. only:: html

.. figure:: images/2f2s.png
:width: 300
:align: center


* 测涨(2f2s_v2)

这个小环境是2f2s的v2版本。在本地图中,蓝色A球只需要向右边进行分裂,同时蓝色B球保持不动即可吃掉黄色A球。

.. only:: html

.. figure:: images/2f2s_v2.png
:width: 300
:align: center


* 测涨(2f2s_v3)

这个小环境是2f2s的v3版本。在本地图中,蓝色A球需要向黄色球和蓝色B球之间进行分裂并向中心吐孢子,同时蓝色B球
向下移动即可吃掉黄色A球。

.. only:: html

.. figure:: images/2f2s_v3.png
:width: 300
:align: center


高级序列化动作
======================

请查看 ``gobigger/hyper/tests`` 目录下的测试文件来使用高级序列化动作。


* 直线合球

.. only:: html

.. figure:: images/straight_merge.gif
:width: 362
:align: center


* 四分合球

.. only:: html

.. figure:: images/quarter_merge.gif
:width: 362
:align: center


* 八分合球

.. only:: html

.. figure:: images/eighth_merge.gif
:width: 338
:align: center
Binary file added docs/zh_CN/source/advanced/images/2f2s.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/zh_CN/source/advanced/images/2f2s_v2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/zh_CN/source/advanced/images/2f2s_v3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions docs/zh_CN/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ GoBigger 提供了多种接口供用户方便快捷地与游戏环境进行交
advanced/cfg_intro
advanced/custom_init
advanced/collision
advanced/hyper

.. toctree::
:maxdepth: 2
Expand Down
2 changes: 1 addition & 1 deletion docs/zh_CN/source/tutorial/quick_start.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
server = Server()
render = EnvRender(server.map_width, server.map_height)
server.set_render(render)
server.start()
server.reset()
player_names = server.get_player_names_with_team()
# get [[team1_player1, team1_player2], [team2_player1, team2_player2], ...]
for i in range(10000):
Expand Down
2 changes: 1 addition & 1 deletion docs/zh_CN/source/tutorial/space.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
}
}
``player_state`` 中的 ``overlap`` 代表的是当前玩家视野中出现的球的结构化信息。``overlap`` 是一个简单的字典,每个键值对代表了视野中的一种球的信息。``overlap`` 中包含了食物球,荆棘球,孢子球,分身球的结构化信息(位置和半径,如果是分身球则包含所属玩家名称和队伍名称)。具体来说,例如我们发现 ``food`` 字段的内容为 ``[[3.0, 4.0, 2], ..]``(简单起见这里只展示了列表中的第一个元素),那么其中的含义是玩家的视野中,坐标 ``(3.0, 4.0)`` 位置存在一个半径为 ``2`` 的食物球。
``player_state`` 中的 ``overlap`` 代表的是当前玩家视野中出现的球的结构化信息。``overlap`` 是一个简单的字典,每个键值对代表了视野中的一种球的信息。``overlap`` 中包含了食物球,荆棘球,孢子球,分身球的结构化信息(位置和半径,如果是分身球则包含所属玩家名称和队伍名称)。具体来说,例如我们发现 ``food`` 字段的内容为 ``[[3.0, 4.0, 2], ..]`` (简单起见这里只展示了列表中的第一个元素),那么其中的含义是玩家的视野中,坐标 ``(3.0, 4.0)`` 位置存在一个半径为 ``2`` 的食物球。
请注意,每一种球的信息列表的长度是不确定的。例如,在当前帧视野中一共有20个食物球,那么当前 ``food`` 对应的列表长度为20。在下一帧,视野内的食物球如果变为25,则对应的列表长度将会变成25。 此外,如果某个球只有一部分出现在玩家视野中,GoBigger也会在 ``overlap`` 中给出该球的圆心和半径信息。
Expand Down
1 change: 0 additions & 1 deletion gobigger/agents/base_agent.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import random
import logging


Expand Down
7 changes: 3 additions & 4 deletions gobigger/balls/clone_ball.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import logging
import uuid
import copy
import random
from easydict import EasyDict
from pygame.math import Vector2

Expand Down Expand Up @@ -92,7 +91,7 @@ def __init__(self, team_name, name, position, border, size=None, vel=None, acc=N
if (self.vel + self.vel_last).length() != 0:
self.direction = copy.deepcopy((self.vel + self.vel_last).normalize())
else:
self.direction = Vector2(random.random(), random.random()).normalize()
self.direction = Vector2(0.000001, 0.000001).normalize()

self.check_border()
self.stop_flag = stop_flag
Expand Down Expand Up @@ -160,7 +159,7 @@ def move(self, given_acc=None, given_acc_center=None, duration=0.05):
if (self.vel + self.vel_last).length() != 0:
self.direction = copy.deepcopy((self.vel + self.vel_last).normalize())
else:
self.direction = Vector2(random.random(), random.random()).normalize()
self.direction = Vector2(0.000001, 0.000001).normalize()
self.check_border()

def eat(self, ball, clone_num=None):
Expand Down Expand Up @@ -315,7 +314,7 @@ def stop(self, direction=None):
self.stop_time = 0
self.acc_stop = - 1 / self.stop_zero_time * (self.vel + self.vel_last)
self.acc = Vector2(0, 0)
self.direction = direction if direction is not None else Vector2(random.random(), random.random())
self.direction = direction if direction is not None else Vector2(0.000001, 0.000001)
self.last_given_acc = Vector2(0, 0)
return True

Expand Down
1 change: 0 additions & 1 deletion gobigger/bin/demo_bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import uuid
from pygame.math import Vector2
import time
import random
import numpy as np
import cv2
import pygame
Expand Down
1 change: 0 additions & 1 deletion gobigger/bin/play.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import uuid
from pygame.math import Vector2
import pygame
import random
import numpy as np
import cv2
import argparse
Expand Down
110 changes: 110 additions & 0 deletions gobigger/bin/play_hyper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import logging
import pytest
import uuid
from pygame.math import Vector2
import pygame
import numpy as np
import cv2
import argparse
import time
import importlib

from gobigger.utils import Border
from gobigger.server import Server
from gobigger.render import RealtimeRender, RealtimePartialRender, EnvRender
from gobigger.agents import BotAgent

logging.basicConfig(level=logging.DEBUG)


def play_by_config(config_name):
config_module = importlib.import_module('gobigger.hyper.configs.config_{}'.format(config_name))
config = config_module.server_default_config
server = Server(config)
server.reset()
render = RealtimeRender(server.map_width, server.map_height)
server.set_render(render)
human_team_name = '0'
human_team_player_name = []
bot_agents = []
for player in server.player_manager.get_players():
if player.team_name != human_team_name:
bot_agents.append(BotAgent(player.name))
else:
human_team_player_name.append(player.name)
fps_real = 0
t1 = time.time()
clock = pygame.time.Clock()
fps_set = server.state_tick_per_second
for i in range(100000):
obs = server.obs()
# actions_bot = {bot_agent.name: bot_agent.step(obs[1][bot_agent.name]) for bot_agent in bot_agents}
actions_bot = {bot_agent.name: [None, None, -1] for bot_agent in bot_agents}
actions = {player_name: [None, None, -1] for player_name in human_team_player_name}
x, y = None, None
action_type = -1
# ================ control by keyboard ===============
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
x1, y1, x2, y2 = None, None, None, None
action_type1 = -1
action_type2 = -1
if event.key == pygame.K_UP:
x1, y1 = 0, -1
if event.key == pygame.K_DOWN:
x1, y1 = 0, 1
if event.key == pygame.K_LEFT:
x1, y1 = -1, 0
if event.key == pygame.K_RIGHT:
x1, y1 = 1, 0
if event.key == pygame.K_LEFTBRACKET: # Spores
action_type1 = 0
if event.key == pygame.K_RIGHTBRACKET: # Splite
action_type1 = 1
if event.key == pygame.K_BACKSLASH: # Stop moving
action_type1 = 2
if event.key == pygame.K_w:
x2, y2 = 0, -1
if event.key == pygame.K_s:
x2, y2 = 0, 1
if event.key == pygame.K_a:
x2, y2 = -1, 0
if event.key == pygame.K_d:
x2, y2 = 1, 0
if event.key == pygame.K_1: # Spores
action_type2 = 0
if event.key == pygame.K_2: # Splite
action_type2 = 1
if event.key == pygame.K_3: # Stop moving
action_type2 = 2
actions = {
human_team_player_name[0]: [x1, y1, action_type1],
human_team_player_name[1]: [x2, y2, action_type2],
}
if server.last_time < server.match_time:
actions.update(actions_bot)
print(actions)
server.step_state_tick(actions=actions)
if actions is not None and x is not None and y is not None:
render.fill(server, direction=Vector2(x, y), fps=fps_real, last_time=server.last_time)
else:
render.fill(server, direction=None, fps=fps_real, last_time=server.last_time)
render.show()
if i % server.state_tick_per_second == 0:
t2 = time.time()
fps_real = server.state_tick_per_second/(t2-t1)
t1 = time.time()
else:
logging.debug('Game Over')
break
clock.tick(fps_set)
render.close()


if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', type=str, default='2f2s')
args = parser.parse_args()

play_by_config(args.config)

1 change: 1 addition & 0 deletions gobigger/hyper/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .actions import StraightMergeHyperAction, QuarterMergeHyperAction, EighthMergeHyperAction
Loading

0 comments on commit f2a7dc1

Please sign in to comment.