11from scipy .spatial import Delaunay
22from pyrusgeom .geom_2d import *
3- from enum import Enum
43from pyrusgeom .soccer_math import min_max
54import logging
6- from abc import ABC , abstractmethod
7- import json
8-
9-
10- class FormationType (Enum ):
11- Static = 's'
12- DelaunayTriangulation2 = 'D'
13-
14- class FormationIndexData :
15- def __init__ (self , ball , players ):
16- self ._ball : list [float ] = ball
17- self ._players : list [list [float ]] = players
18-
19- def ball (self ) -> list [float ]:
20- return self ._ball
21-
22- def players (self ) -> list [list [float ]]:
23- return self ._players
24-
25- class PlayerRole :
26- def __init__ (self , name , type , side , pair ):
27- self ._name = name
28- self ._type = type
29- self ._side = side
30- self ._pair = pair
31-
32- class IFormationFileReader (ABC ):
33- @abstractmethod
34- def read_file (self , path ) -> list [FormationIndexData ]:
35- pass
36-
37- class OldStaticFormationFileReader (IFormationFileReader ):
38- def read_file (self , lines ):
39- players = {}
40- roles = {}
41- for i in range (len (lines )):
42- if i == 0 or lines [i ].startswith ('#' ):
43- continue
44- player = lines [i ].split ()
45- players [int (player [0 ])] = ([float (player [2 ]), float (player [3 ])])
46- roles [int (player [0 ])] = PlayerRole (player [1 ], None , None , None )
47-
48- return [FormationIndexData (None , players )], roles
49-
50- class OldDelaunayFormationFileReader (IFormationFileReader ):
51- def read_file (self , lines ):
52- roles = {}
53- begin_roles = False
54- for i in range (len (lines )):
55- if lines [i ].startswith ('Begin Roles' ):
56- begin_roles = True
57- continue
58- if lines [i ].startswith ('End Roles' ):
59- break
60- if begin_roles :
61- player = lines [i ].split ()
62- roles [int (player [0 ])] = PlayerRole (player [1 ], None , None , int (player [2 ]))
63- indexes = []
64- for i in range (len (lines )):
65- if lines [i ].find ('Ball' ) >= 0 :
66- indexes .append (self .read_index (i , lines ))
67- i += 11
68- return indexes , roles
69-
70- def read_index (self , i , lines ):
71- ball = lines [i ].split (' ' )
72- ball_x = float (ball [1 ])
73- ball_y = float (ball [2 ])
74- ball = [ball_x , ball_y ]
75- players = {}
76- for j in range (1 , 12 ):
77- player = lines [i + j ].split (' ' )
78- player_x = float (player [1 ])
79- player_y = float (player [2 ])
80- players [j ] = ([player_x , player_y ])
81- return FormationIndexData (ball , players )
82-
83- class JsonFormationFileReader (IFormationFileReader ):
84- def read_file (self , lines ) -> list [FormationIndexData ]:
85- text = '' .join (lines )
86- data = json .loads (text )
87- roles = {}
88- for role in data ['role' ]:
89- roles [role ['number' ]] = PlayerRole (role ['name' ], role ['type' ], role ['side' ], role ['pair' ])
90- indexes = []
91- for index in data ['data' ]:
92- ball = [index ['ball' ]['x' ], index ['ball' ]['y' ]]
93- players = {}
94- for i in range (1 , 12 ):
95- players [i ] = [index [str (i )]['x' ], index [str (i )]['y' ]]
96- indexes .append (FormationIndexData (ball , players ))
97- return indexes , roles
98-
99- @staticmethod
100- def is_json (lines ):
101- return lines [0 ].find ('{' ) >= 0
102-
103- @staticmethod
104- def get_method (lines ):
105- text = '' .join (lines )
106- data = json .loads (text )
107- if data ['method' ] == 'Static' :
108- return FormationType .Static
109- return FormationType .DelaunayTriangulation2
110-
111-
112- class FormationFileReaderFactory :
113- def get_reader (self , lines ) -> list [IFormationFileReader , FormationType ]:
114- if JsonFormationFileReader .is_json (lines ):
115- return JsonFormationFileReader (), JsonFormationFileReader .get_method (lines )
116- if lines [0 ].find ('Static' ) >= 0 :
117- return OldStaticFormationFileReader (), FormationType .Static
118- return OldDelaunayFormationFileReader (), FormationType .DelaunayTriangulation2
119-
120- def read_file (self , path ) -> list [FormationIndexData ]:
121- file = open (path , 'r' )
122- lines = file .readlines ()
123- reader , formation_type = self .get_reader (lines )
124- indexes , roles = reader .read_file (lines )
125- return indexes , roles , formation_type
5+ from src .strategy .formation_file_reader import FormationFileReaderFactory , FormationType
6+ from src .strategy .player_role import PlayerRole
1267
1278class FormationFile :
1289 def __init__ (self , path , logger : logging .Logger ):
@@ -133,11 +14,12 @@ def __init__(self, path, logger: logging.Logger):
13314 self ._formation_type = FormationType .Static
13415 self ._target_players = {}
13516 self ._path = path
17+ self ._roles : dict [int , PlayerRole ] = {}
13618 self .read_file (path )
13719 self .calculate ()
13820
13921 def read_file (self , path ):
140- indexes , roles , self ._formation_type = FormationFileReaderFactory ().read_file (path )
22+ indexes , self . _roles , self ._formation_type = FormationFileReaderFactory ().read_file (path )
14123
14224 if self ._formation_type == FormationType .Static :
14325 data = indexes [0 ]
@@ -202,6 +84,9 @@ def get_pos(self, unum):
20284
20385 def get_poses (self ):
20486 return self ._target_players
87+
88+ def get_role (self , unum ) -> PlayerRole :
89+ return self ._roles [unum ]
20590
20691 def __repr__ (self ):
20792 return self ._path
0 commit comments