diff --git a/automafut_1.py b/automafut_1.py
new file mode 100644
index 0000000000000000000000000000000000000000..d84b8a1838805a10c37dd956b685891837448849
--- /dev/null
+++ b/automafut_1.py
@@ -0,0 +1,10 @@
+from online_game import OnlineGame
+
+def naive_ia(game):
+    return [1,1,1,1,1,1,1,1,1,1,1]
+
+game = OnlineGame('127.0.0.1',12345) # Server's address
+game.connect()
+game.set_ia(game.team,naive_ia)
+
+game.play()
\ No newline at end of file
diff --git a/automafut_2.py b/automafut_2.py
new file mode 100644
index 0000000000000000000000000000000000000000..d84b8a1838805a10c37dd956b685891837448849
--- /dev/null
+++ b/automafut_2.py
@@ -0,0 +1,10 @@
+from online_game import OnlineGame
+
+def naive_ia(game):
+    return [1,1,1,1,1,1,1,1,1,1,1]
+
+game = OnlineGame('127.0.0.1',12345) # Server's address
+game.connect()
+game.set_ia(game.team,naive_ia)
+
+game.play()
\ No newline at end of file
diff --git a/ball.py b/ball.py
new file mode 100644
index 0000000000000000000000000000000000000000..d9360df813764757f09c1347e4d874126ed69b49
--- /dev/null
+++ b/ball.py
@@ -0,0 +1,40 @@
+class Ball:
+    def __init__(self):
+        self.set_velocity(0,-1)
+
+    def set_position(self,pos_x, pos_y):
+        self.pos_x = pos_x
+        self.pos_y = pos_y
+    
+    def set_velocity(self,vel_x,vel_y):
+        self.vel_x = vel_x
+        self.vel_y = vel_y
+    
+    def run(self,delta_t):
+        self.pos_x += self.vel_x*delta_t
+        self.pos_y += self.vel_y*delta_t
+        self.verify_borders()
+
+    def verify_borders(self):
+        if self.pos_x < -100:
+            self.pos_x = -100
+            self.vel_x = - self.vel_x
+
+        if self.pos_x > 100:
+            self.pos_x = 100
+            self.vel_x = - self.vel_x
+
+        if self.pos_y < -50:
+            self.pos_y = -50
+            self.vel_y = - self.vel_y
+
+        if self.pos_y > 50:
+            self.pos_y = 50
+            self.vel_y = - self.vel_y
+            
+    def get_pos_x(self):
+        return self.pos_x
+
+    def get_pos_y(self):
+        return self.pos_y
+  
\ No newline at end of file
diff --git a/game.py b/game.py
new file mode 100644
index 0000000000000000000000000000000000000000..23593ffb3dafb5d5d876ec183cac62ffbdf6db80
--- /dev/null
+++ b/game.py
@@ -0,0 +1,51 @@
+from team import Team
+from ball import Ball
+class Game:
+    def __init__(self):
+        #self.automaplayer_1 = AutomaPlayer(True)
+        #self.automaplayer_2 = AutomaPlayer(True)
+        self.team_1 = Team()
+        self.team_2 = Team()
+        self.ball = Ball()
+        self.on = False
+
+    def start(self):
+        self.on = True
+
+    def ready(self):
+        return False
+
+    def run(self,delta_t):
+        self.ball.run(delta_t)
+        
+    def verify_colision(self):
+        pass
+  
+    def verify_borders(self):
+        self.team_1.verify_borders()
+        self.team_2.verify_borders()
+    
+    def set_ia(self,team,ia):
+        if team == 1:
+            self.team_1.set_ia(ia)
+        if team == 2:
+            self.team_2.set_ia(ia)
+
+    def output(self,team):
+        if team == 1:
+            return self.team_1.ia(self)
+        if team == 2:
+            return self.team_2.ia(self)
+
+    def input(self):
+        input = []
+        for i in range(5):
+            input.append(self.team_1.players[i].get_pos_x())
+            input.append(self.team_1.players[i].get_pos_y())
+        for i in range(5):
+            input.append(self.team_1.players[i].get_pos_x())
+            input.append(self.team_1.players[i].get_pos_y())
+        input.append(self.ball.get_pos_x())
+        input.append(self.ball.get_pos_y())
+        return input
+    
\ No newline at end of file
diff --git a/online_game.py b/online_game.py
new file mode 100644
index 0000000000000000000000000000000000000000..86d7463f58cebfb289d920c6d0626f287fa991b4
--- /dev/null
+++ b/online_game.py
@@ -0,0 +1,56 @@
+import socket # for socket 
+import sys  
+import json
+
+from game import Game
+
+class OnlineGame(Game):
+
+    def __init__(self,server_ip,port,*args):
+        super().__init__(*args)
+        self.server_ip = server_ip
+        self.port = port 
+        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
+        self.team = 1
+    
+    def send_message(self,d):
+        try:
+            b = json.dumps(d).encode('utf-8')
+            self.sock.sendall(b)
+            st = str(self.sock.recv(4096), 'utf-8')#.split(';')
+            #print(st)
+            return st
+        except socket.error as err: 
+            print ("socket creation failed with error",err) 
+            return None
+
+    def connect(self):
+        self.sock.connect((self.server_ip, self.port)) 
+        d = {'msg_type':'[GET] Connection Request'}
+        self.team = int(self.send_message(d))
+        print('Connected as team '+str(self.team))
+
+    def get_input(self):
+        d = {'msg_type':'[GET] Game State Request'}
+        r = self.send_message(d)
+        if (not r is None):
+            r = r.split(';')
+            input = [float(r[i]) for i in range(22)]
+            for i in range(5):
+                self.team_1.players[i].set_position(input[2*i],input[2*i+1])
+                self.team_2.players[i].set_position(input[10+2*i],input[10+2*i+1])
+            self.ball.set_position(input[20],input[21])
+
+    def send_output(self):
+        d = {'msg_type':'[POST] Refresh State','team':str(self.team),'output':str(self.output(self.team))}
+        self.send_message(d)
+    
+    def play(self):
+        while(True):
+            self.get_input()
+            self.send_output()
+
+
+        
+
+  
\ No newline at end of file
diff --git a/player.py b/player.py
new file mode 100644
index 0000000000000000000000000000000000000000..b912b53499e18e68c160b72ac52be2e6215bc18b
--- /dev/null
+++ b/player.py
@@ -0,0 +1,35 @@
+class Player:
+
+  def __init__(self,goal_keeper):
+    self.name = ""
+    self.goal_keeper = goal_keeper
+    self.angle = 0
+
+  def set_direction(self,angle):
+    self.angle = angle
+
+  def set_position(self,pos_x, pos_y):
+    self.pos_x = pos_x
+    self.pos_y = pos_y
+
+  def get_pos_x(self):
+    return self.pos_x
+
+  def get_pos_y(self):
+    return self.pos_y
+
+  def verify_borders(self):
+    if (self.pos_x < -100):
+      self.pos_x = -100
+
+    if (self.pos_x > 100):
+      self.pos_x = 100
+
+    if (self.pos_y < -50):
+      self.pos_y = -50
+
+    if (self.pos_y > 50):
+      self.pos_y = 50
+
+
+
diff --git a/stadium/automaplayer.pde b/stadium/automaplayer.pde
new file mode 100644
index 0000000000000000000000000000000000000000..0641a21ad8b565489adfeaa8f31a09f0f28eaf71
--- /dev/null
+++ b/stadium/automaplayer.pde
@@ -0,0 +1,27 @@
+class AutomaPlayer{
+  String name;
+  Client client;
+  boolean connected;
+  
+  AutomaPlayer() {
+    this.connected = false;
+  }
+  void set_client(Client c){
+     this.client = c; 
+  }
+  void set_name(String name){
+     this.name = name; 
+  }
+  void say_hello(){
+     client.write("Hello!");
+  }
+  boolean connected(){
+     return this.connected; 
+  }
+  void set_connected(boolean connected){
+     this.connected = connected; 
+  }
+  void run(){
+    
+  }
+}
diff --git a/stadium/ball.pde b/stadium/ball.pde
new file mode 100644
index 0000000000000000000000000000000000000000..54a698b74197468ec0f86206f07a5b3a0824e628
--- /dev/null
+++ b/stadium/ball.pde
@@ -0,0 +1,54 @@
+class Ball {
+  float pos_x;
+  float pos_y;
+  float vel_x;
+  float vel_y;
+  Ball() {
+    this.set_velocity(0,-10);
+  }
+  void set_position(float pos_x, float pos_y) {
+    this.pos_x = pos_x;
+    this.pos_y = pos_y;
+    this.vel_y = -1;
+  }
+  void set_velocity(float vel_x, float vel_y) {
+    this.vel_x = vel_x;
+    this.vel_y = vel_y;
+  }
+  void run(float delta_t) {
+    this.pos_x += this.vel_x*delta_t;
+    this.pos_y += this.vel_y*delta_t;
+    this.verify_borders();
+  }
+  void verify_borders() {
+    if (this.pos_x < -100) {
+      this.pos_x = -100;
+      this.vel_x = - this.vel_x;
+    }
+
+    if (this.pos_x > 100) {
+      this.pos_x = 100;
+      this.vel_x = - this.vel_x;
+    }
+
+    if (this.pos_y < -50) {
+      this.pos_y = -50;
+      this.vel_y = - this.vel_y;
+    }
+    if (this.pos_y > 50) {
+      this.pos_y = 50;
+      this.vel_y = - this.vel_y;
+    }
+  }
+  float get_pos_x() {
+    return this.pos_x;
+  }
+  float get_pos_y() {
+    return this.pos_y;
+  }
+  void show() {
+    noStroke();
+    fill(255, 161, 31, 122+122*sin(millis()/50.0));
+    ellipse(this.pos_x, this.pos_y, 3, 3);
+  }
+}
diff --git a/stadium/game.pde b/stadium/game.pde
new file mode 100644
index 0000000000000000000000000000000000000000..fa7b1060e4d3dd1ddecde833972ac54a57ed3b0f
--- /dev/null
+++ b/stadium/game.pde
@@ -0,0 +1,85 @@
+class Game {
+
+  Team team_1;
+  Team team_2;
+  Ball ball;
+  Game() {
+    this.team_1 = new Team();
+    this.team_2 = new Team();
+    this.ball = new Ball();
+  }
+  void keep_distance(Player player_1, boolean inverted_1, Player player_2, boolean inverted_2) {
+    int s1 = 1;
+    int s2 = 1;
+    if (inverted_1){
+       s1 = -1; 
+    }
+    if (inverted_2){
+       s2 = -1; 
+    }
+    float xm = s1*player_1.get_pos_x()/2.0 + s2*player_2.get_pos_x()/2.0;
+    float ym = player_1.get_pos_y()/2.0 + player_2.get_pos_y()/2.0;
+    float dx = s1*player_1.get_pos_x() - xm;
+    float dy = player_1.get_pos_y() - ym;
+    float  n = sqrt(pow(dx, 2)+pow(dy, 2));
+    
+    if (n < 6) {
+      dx *= 6/n;
+      dy *= 6/n;
+      player_1.set_position(s1*(xm+dx), ym+dy);
+      player_2.set_position(s2*(xm-dx), ym-dy);
+    }
+  }
+  void verify_colision() {
+    Player[] players = new Player[10]; 
+    for (int i=0; i<5; i++) {
+      players[i] = this.team_1.players[i];
+      players[5+i] = this.team_2.players[i];
+    }
+    for (int i=0; i<10; i++) {
+      for (int j=0; j<10; j++) {
+        if (i != j) {
+          keep_distance(players[i], i>=5, players[j],j>=5);
+        }
+      }
+    }
+  }
+
+  void verify_borders() {
+    this.team_1.verify_borders();
+    this.team_2.verify_borders();
+  }
+  void refresh_team(int team, float[] output) {
+    if (team == 1) {
+      this.team_1.refresh_team(output);
+    } else if (team == 2) {
+      this.team_2.refresh_team(output);
+    }
+  }
+  float[] input() {
+    float[] input = new float[22];
+    for (int i=0; i<5; i++) {
+      input[2*i] = this.team_1.players[i].get_pos_x();
+      input[2*i+1] = this.team_1.players[i].get_pos_y();
+      input[10+2*i] = this.team_1.players[i].get_pos_x();
+      input[10+2*i+1] = this.team_1.players[i].get_pos_y();
+    }
+    input[20] = this.ball.get_pos_x();
+    input[21] = this.ball.get_pos_y();
+    return input;
+  }
+  void run(float delta_t) {
+    this.ball.run(delta_t); 
+    this.team_1.run(delta_t);
+    this.team_2.run(delta_t);
+    this.verify_colision();
+  }
+  void show() {
+    this.team_1.show();
+    pushMatrix();
+    scale(-1, 1);
+    this.team_2.show();
+    popMatrix();
+    this.ball.show();
+  }
+}
diff --git a/stadium/player.pde b/stadium/player.pde
new file mode 100644
index 0000000000000000000000000000000000000000..571e6aefca78ee1a333f3c67aea47835c8fe9079
--- /dev/null
+++ b/stadium/player.pde
@@ -0,0 +1,73 @@
+class Player {
+  String name;
+  boolean goal_keeper;
+  color _color;
+  float pos_x;
+  float pos_y;
+  float vel;
+  float angle;
+  Player(boolean goal_keeper) {
+    this.name = "";
+    this.goal_keeper = goal_keeper;
+    this._color = color(0);
+    this.angle = 0;
+  }
+  void set_direction(float angle) {
+    this.angle = angle;
+  }
+  void set_velocity(float vel) {
+    this.vel = vel;
+  }
+  void set_color(color _color) {
+    this._color = _color;
+  }
+  int set_name(String name) {
+    this.name = name;
+    return 1;
+  }
+  void set_position(float pos_x, float pos_y) {
+    this.pos_x = pos_x;
+    this.pos_y = pos_y;
+  }
+  float get_pos_x() {
+    return this.pos_x;
+  }
+  float get_pos_y() {
+    return this.pos_y;
+  }
+  void verify_borders() {
+    if (this.pos_x < -93) {
+      this.pos_x = -93;
+    }
+    if (this.pos_x > 93) {
+      this.pos_x = 93;
+    }
+    if (this.pos_y < -43) {
+      this.pos_y = -43;
+    }
+    if (this.pos_y > 43) {
+      this.pos_y = 43;
+    }
+  }
+  void run(float delta_t) {
+    this.pos_x += this.vel*cos(angle)*delta_t;
+    this.pos_y += this.vel*sin(angle)*delta_t;
+    this.verify_borders();
+  }
+  void showPos(){
+    textSize(2);
+    fill(255,0,0);
+    text(str(this.pos_x)+","+str(this.pos_y),0,0);
+  }
+  void show() {
+    noStroke();
+    fill(this._color);
+    pushMatrix();
+    translate(this.pos_x, this.pos_y);
+    arc(0, 0, 12, 12, this.angle+PI/16, this.angle+2*PI-PI/16);
+    fill(0);
+    ellipse(0, 0, 10, 10);  
+    //this.showPos();
+    popMatrix();
+  }
+}
diff --git a/stadium/socket.pde b/stadium/socket.pde
new file mode 100644
index 0000000000000000000000000000000000000000..f23305f592bae432360a020525c91e8284315e85
--- /dev/null
+++ b/stadium/socket.pde
@@ -0,0 +1,66 @@
+Server s;
+Client c;
+String input;
+int data[];
+
+class Socket {
+  Socket() {
+  }
+  int listen_client() {
+    c = s.available();
+    if (c != null) {
+      input = c.readString();
+      JSONObject json = parseJSONObject(input);
+      if (json == null) {
+        println("JSONObject could not be parsed");
+      } else {
+        String msg_type = json.getString("msg_type");
+        if (msg_type.equals("[GET] Connection Request")) {
+          println("\'[GET] Connection Request\' received from "+c.ip()) ;
+          this.connect(c);
+          //float x = float(json.getString("x"));
+        }
+        else if (msg_type.equals("[GET] Game State Request")) {
+          println("\'[GET] Game State Request\' received from "+c.ip()) ;
+          this.send_input(c);
+        }
+        else if (msg_type.equals("[POST] Refresh State")) {
+          println("\'[POST] Refresh State\' received from "+c.ip()) ;
+          this.refresh_team(int(json.getString("team")), json.getString("output"));
+          c.write("Received!");
+        }
+        else{
+          println("\'unrecognized message\' received from "+c.ip()) ;
+          println(input);
+        }
+      }
+    }
+    return 1;
+  }
+  void refresh_team(int team, String input) {
+    String[] list = split(input.substring(1,input.length()-1), ',');
+    if (list.length != 11) {
+      println("Problem with refresh team ");
+      println(list);
+    } else {
+      float[] output = new float[11];
+      for (int i =0; i<11; i++) {
+        output[i] = float(list[i]);
+      }
+      game.refresh_team(team,output);
+    }
+  }
+
+  void connect(Client c) {
+    int r = stadium.connect(c, "no_name");
+    c.write(str(r));
+  }
+  void send_input(Client c) {
+    String s = "";
+    float[] input = game.input();
+    for (int i = 0; i<22; i++) {
+      s += str(input[i])+";";
+    }
+    c.write(s);
+  }
+}
diff --git a/stadium/stadium.pde b/stadium/stadium.pde
new file mode 100644
index 0000000000000000000000000000000000000000..74e219ad41d06d6d0b49b1e13083f17e44051df6
--- /dev/null
+++ b/stadium/stadium.pde
@@ -0,0 +1,110 @@
+import processing.net.*;
+
+Game game = new Game();
+Stadium stadium = new Stadium(game, width, height);
+Socket socket = new Socket();
+
+class Stadium {
+
+  AutomaPlayer automaplayer_1;
+  AutomaPlayer automaplayer_2;
+  int size_x;
+  int size_y;
+  Game game;
+
+  Stadium(Game game, int size_x, int size_y) {
+    this.automaplayer_1 = new AutomaPlayer();
+    this.automaplayer_2 = new AutomaPlayer();
+    this.size_x = size_x;
+    this.size_y = size_y;
+    this.game = game;
+  }
+  int connect(Client c, String name) {
+    if (this.automaplayer_1.connected()) {
+      if (this.automaplayer_2.connected()) {
+        return 0;
+      } else {
+        this.automaplayer_2.set_client(c);
+        this.automaplayer_2.set_name(name);
+        this.automaplayer_2.set_connected(true);
+        return 2;
+      }
+    } else {
+      this.automaplayer_1.set_client(c);
+      this.automaplayer_1.set_name(name);
+      this.automaplayer_1.set_connected(true);
+      return 1;
+    }
+  }
+  void say_hello() {
+     this.automaplayer_1.say_hello();
+     this.automaplayer_2.say_hello();
+  }
+  void draw_borders() {
+    noStroke();
+    fill(255, 161, 31);
+    rect(3, 3, 5, this.size_y-6); //laterals
+    rect(this.size_x-8, 3, 5, this.size_y-6);
+    rect(3, 3, this.size_x-6, 5);//up
+    rect(3, this.size_y-8, this.size_x-6, 5);//down
+    fill(0);
+    rect(3, this.size_y*(2.0/8.0), 5, this.size_y*(4/8.0));//goal
+    rect(this.size_x-8, this.size_y*(2.0/8.0), 5, this.size_y*(4/8.0));
+    noFill();
+    stroke(255, 161, 31);
+    strokeWeight(5);
+    arc(5, this.size_y/2, this.size_x/3, this.size_x/3, -PI/2, +PI/2);//goal
+    arc(this.size_x-6, this.size_y/2, this.size_x/3, this.size_x/3, +PI/2, 2*PI-PI/2);
+    triangle(this.size_x/2-3, 8, this.size_x/2+3, 8, this.size_x/2, 12);
+    triangle(this.size_x/2-3, this.size_y-8, this.size_x/2+3, this.size_y-8, this.size_x/2, this.size_y-12);
+  }
+  void draw_layout() {
+    fill(255, 161, 31);
+    textSize(26);
+    text("Automafut v1.0", 5, 27);
+    text(str(this.game.team_1.get_score())+"x"+str(this.game.team_1.get_score()), this.size_x/2-30, 27);
+    strokeWeight(2);
+    noFill();
+    if (this.automaplayer_1.connected()) {
+      stroke(0, 255, 0);
+    } else {
+      stroke(255, 0, 0);
+    }
+    ellipse(this.size_x-50, 15, 26, 26); 
+    if (this.automaplayer_2.connected()) {
+      stroke(0, 255, 0);
+    } else {
+      stroke(255, 0, 0);
+    }
+    ellipse(this.size_x-20, 15, 26, 26);
+  }
+  void show() {
+    background(0);
+    this.draw_layout();
+    translate(0, 30);
+    this.draw_borders();
+    pushMatrix();
+    scale(this.size_x/200.0, this.size_y/100.0);
+    translate(100, 50);
+    this.game.show();
+    popMatrix();
+  }
+  void run() {
+    if (this.automaplayer_1.connected() && this.automaplayer_2.connected()) {
+      this.game.run(0.1);
+      //this.say_hello(); // server only answers
+    }
+    
+  }
+}
+void setup() {
+  size(800, 430);
+  stadium.size_x = width;
+  stadium.size_y = height-30;
+  s = new Server(this,12345); // Start a simple server on a port
+}
+void draw() {
+  socket.listen_client();
+  stadium.show();
+  stadium.run();
+}
diff --git a/stadium/team.pde b/stadium/team.pde
new file mode 100644
index 0000000000000000000000000000000000000000..5d4ed7140f81fb69985b2a11790679c5d11e8f0f
--- /dev/null
+++ b/stadium/team.pde
@@ -0,0 +1,59 @@
+class Team {
+
+  Player[] players = new Player[5];
+  int score = 0;
+
+  Team() {
+    this.players[0] = new Player(true);
+    for (int i = 1; i<5; i++) {
+      this.players[i] = new Player(false);
+    }
+    this.initial_position();
+    this.set_color(color(random(255), random(255), random(255)));
+  }
+  void refresh_team(float[] output) {
+    for (int i = 0; i<5; i++) {
+      this.players[i].set_velocity(output[i*2]);
+      this.players[i].set_direction(output[i*2+1]);
+    }
+  }
+  void initial_position() {
+    this.players[0].set_position(-80, 0);
+    this.players[1].set_position(-50, -30);
+    this.players[2].set_position(-50, 30);
+    this.players[3].set_position(-20, -20);
+    this.players[4].set_position(-20, 20);
+  }
+  int insert_names(String[] names) {
+    for (int i = 0; i<5; i++) {
+      this.players[i].set_name(names[i]);
+    }
+    return 1;
+  }
+  int get_score() {
+    return this.score;
+  }
+  void add_score() {
+    this.score +=1;
+  }
+  void verify_borders() {
+    for (int i = 0; i<5; i++) {
+      this.players[i].verify_borders();
+    }
+  }
+  void set_color(color _color) {
+    for (int i = 0; i<5; i++) {
+      this.players[i].set_color(_color);
+    }
+  }
+  void run(float delta_t) {
+    for (int i = 0; i<5; i++) {
+      this.players[i].run(delta_t);
+    }
+  }
+  void show() {
+    for (int i = 0; i<5; i++) {
+      this.players[i].show();
+    }
+  }
+}
diff --git a/team.py b/team.py
new file mode 100644
index 0000000000000000000000000000000000000000..d6e795cfa49a9d6603bed9ef818db4323585269c
--- /dev/null
+++ b/team.py
@@ -0,0 +1,30 @@
+from player import Player
+class Team:
+
+    def __init__(self):
+        self.players = []
+        self.ia = lambda x: None
+        self.players.append(Player(True))
+        for i in range(1,5):
+            self.players.append(Player(False))
+        self.initial_position()
+        self.score = 0
+    
+    def set_ia(self,ia):
+        self.ia = ia
+    def get_score(self):
+        return self.score
+    
+    def add_score(self):
+        self.score += 1
+
+    def initial_position(self):
+        self.players[0].set_position(-80,0)
+        self.players[1].set_position(-50,-30)
+        self.players[2].set_position(-50,30)
+        self.players[3].set_position(-20,-20)
+        self.players[4].set_position(-20,20)
+
+    def verify_borders(self):
+        for i in range(5):
+            self.players[i].verify_borders()