ソースを参照

troops selection: add troops to country list

Bastien Sevajol 6 年 前
コミット
ecc3cc2997
共有7 個のファイルを変更した157 個の追加17 個の削除を含む
  1. 13 1
      opencombat/strategy/manager.py
  2. 93 10
      opencombat/strategy/selection/gui.py
  3. 28 1
      opencombat/strategy/team/stash.py
  4. 18 1
      opencombat/strategy/teams.xml
  5. 2 1
      opencombat/strategy/troops.py
  6. 1 1
      select_troops.py
  7. 2 2
      tests/fixtures/teams.xml

+ 13 - 1
opencombat/strategy/manager.py ファイルの表示

@@ -2,7 +2,9 @@
2 2
 from synergine2.config import Config
3 3
 from synergine2.log import get_logger
4 4
 
5
+from opencombat.strategy.team.stash import TeamStash
5 6
 from opencombat.strategy.troops import TroopClassBuilder
7
+from opencombat.strategy.unit.stash import UnitStash
6 8
 
7 9
 
8 10
 class TroopManager(object):
@@ -16,8 +18,18 @@ class TroopManager(object):
16 18
         self._logger = get_logger('TroopManager', config)
17 19
 
18 20
         builder = TroopClassBuilder(config)
19
-        self._unit_stash = builder.get_unit_stash(units_file_path)
21
+        self._unit_stash = builder.get_unit_stash(
22
+            units_file_path,
23
+        )
20 24
         self._team_stash = builder.get_team_stash(
21 25
             units_file_path,
22 26
             teams_file_path,
23 27
         )
28
+
29
+    @property
30
+    def team_stash(self) -> TeamStash:
31
+        return self._team_stash
32
+
33
+    @property
34
+    def unit_stash(self) -> UnitStash:
35
+        return self._unit_stash

+ 93 - 10
opencombat/strategy/selection/gui.py ファイルの表示

@@ -1,14 +1,18 @@
1 1
 # coding: utf-8
2 2
 import typing
3 3
 from tkinter import Tk
4
+from tkinter import Button
5
+from tkinter import YES
4 6
 from tkinter import StringVar
5 7
 from tkinter import OptionMenu
6 8
 from tkinter import W
9
+from tkinter.ttk import Combobox
10
+from tkinter.ttk import Treeview
7 11
 
8 12
 from synergine2.config import Config
9 13
 
10 14
 from opencombat.gui import Gui
11
-from opencombat.strategy.manager import TroopManager
15
+from opencombat.strategy.team.stash import TeamStash
12 16
 
13 17
 
14 18
 class SelectTroopsGui(Gui):
@@ -16,26 +20,105 @@ class SelectTroopsGui(Gui):
16 20
         self,
17 21
         config: Config,
18 22
         master: Tk,
19
-        troop_manager: TroopManager,
23
+        team_stash: TeamStash,
20 24
         countries: typing.List[str],
21 25
     ) -> None:
22 26
         super().__init__(config, master)
23 27
         self._master.title('Troops selection')
28
+        self._team_stash = team_stash
29
+        self._countries_troops = {}  # type: typing.Dict[str, typing.List[TeamModel]]  # nopep8
24 30
 
25 31
         # Widgets
26
-        self.selected_country_var = StringVar(self._master)
27
-        self.selected_country_var.set(countries[0])
28
-        self.selected_country_var.trace('w', self.change_country)
29
-        self.select_country_menu = OptionMenu(
32
+        self._selected_country_var = StringVar(self._master)
33
+        self._selected_country_var.set(countries[0])
34
+        self._selected_country_var.trace('w', self._country_changed)
35
+        self._select_country_menu = OptionMenu(
30 36
             self._master,
31
-            self.selected_country_var,
37
+            self._selected_country_var,
32 38
             *countries,
33 39
         )
34 40
 
41
+        self._teams_var = StringVar(self._master)
42
+        self._teams_list = Combobox(
43
+            self._master,
44
+            height=10,
45
+            state='readonly',
46
+            textvariable=self._teams_var,
47
+        )
48
+
49
+        self._add_troop_var = StringVar(self._master)
50
+        self._add_troop_button = Button(
51
+            self._master,
52
+            textvariable=self._add_troop_var,
53
+            command=self._add_troop,
54
+        )
55
+        self._add_troop_var.set('Add troop')
56
+
57
+        self._troops_view = Treeview(
58
+            self._master,
59
+            columns=('Soldiers',),
60
+            height=10,
61
+        )
62
+        self._troops_view.heading('#0', text='Team')
63
+        self._troops_view.heading('#1', text='Soldiers')
64
+        self._troops_view.column('#0', stretch=YES)
65
+        self._troops_view.column('#1', stretch=YES)
66
+
35 67
         # Layout
36
-        self.select_country_menu.grid(row=0, column=0, sticky=W)
68
+        self._select_country_menu.grid(row=0, column=0, sticky=W)
69
+        self._teams_list.grid(row=1, column=0, sticky=W)
70
+        self._add_troop_button.grid(row=2, column=0, sticky=W)
71
+        self._troops_view.grid(row=3, column=0, sticky=W)
72
+
73
+        # Default behaviours
74
+        self._selected_country_var.set(countries[0])
75
+        self._country_changed()
76
+
77
+    def _country_changed(self, *args, **kwargs) -> None:
78
+        country = self._selected_country_var.get()
37 79
 
38
-    def change_country(self, *args, **kwargs) -> None:
39 80
         self._logger.info('Change country to "{}"'.format(
40
-            self.selected_country_var.get(),
81
+            country,
41 82
         ))
83
+        country_team_names = [
84
+            t.name for
85
+            t in self._team_stash.get_team_by_country(
86
+                self._selected_country_var.get(),
87
+            )
88
+        ]
89
+
90
+        self._logger.debug('Change teams for: "{}"'.format(country_team_names))
91
+        self._teams_list['values'] = country_team_names
92
+        self._teams_var.set(country_team_names[0])
93
+        self._update_troops_view(country)
94
+
95
+    def _add_troop(self, *args, **kwargs) -> None:
96
+        if self._teams_var.get():
97
+            country = self._selected_country_var.get()
98
+            team_name = self._teams_var.get()
99
+
100
+            self._logger.info('Add troop "{}" to country "{}" troops'.format(
101
+                team_name,
102
+                team_name,
103
+            ))
104
+
105
+            team_model = self._team_stash.get_team_by_name(
106
+                team_name=team_name,
107
+                team_country=country,
108
+            )
109
+            self._countries_troops.setdefault(country, []).append(
110
+                team_model,
111
+            )
112
+            self._update_troops_view(country)
113
+
114
+    def _update_troops_view(self, country: str) -> None:
115
+        teams = self._countries_troops.get(country, [])
116
+
117
+        self._troops_view.delete(*self._troops_view.get_children())
118
+        for team in teams:
119
+            self._troops_view.insert(
120
+                '',
121
+                'end',
122
+                text=team.name,
123
+                values=('o' * len(team.units,))
124
+            )

+ 28 - 1
opencombat/strategy/team/stash.py ファイルの表示

@@ -21,6 +21,7 @@ class TeamStash(object):
21 21
         self._config = config
22 22
         self._teams = None  # type: typing.List[TeamModel]
23 23
         self._unit_stash = unit_stash
24
+        self._teams_file_path = teams_file_path
24 25
 
25 26
         self.schema_file_path = self._config.get(
26 27
             'global.teams_schema',
@@ -31,7 +32,7 @@ class TeamStash(object):
31 32
             self.schema_file_path,
32 33
         )
33 34
         self._root_element = self._xml_validator.validate_and_return(
34
-            teams_file_path,
35
+            self._teams_file_path,
35 36
         )
36 37
 
37 38
     def _get_computed_teams(self) -> typing.List[TeamModel]:
@@ -85,3 +86,29 @@ class TeamStash(object):
85 86
                 self.schema_file_path,
86 87
             )
87 88
         )
89
+
90
+    def get_team_by_name(
91
+        self,
92
+        team_name: str,
93
+        team_country: str,
94
+    ) -> TeamModel:
95
+        for team in self.teams:
96
+            if team.name == team_name and team.country == team_country:
97
+                return team
98
+
99
+        raise NotFoundException(
100
+            'No team matching with name "{}" and country "{}" in "{}"'.format(
101
+                team_name,
102
+                team_country,
103
+                self.schema_file_path,
104
+            )
105
+        )
106
+
107
+    def get_team_by_country(self, country: str) -> typing.List[TeamModel]:
108
+        teams = []  # type: typing.List[TeamModel]
109
+
110
+        for team in self.teams:
111
+            if team.country == country:
112
+                teams.append(team)
113
+
114
+        return teams

+ 18 - 1
opencombat/strategy/teams.xml ファイルの表示

@@ -1,7 +1,24 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <teams>
3 3
     <team id="std_team" country="URSS">
4
-        <name>Standard team</name>
4
+        <name>Standard URSS team</name>
5
+        <units>
6
+            <unit>
7
+                <id>std_soldier</id>
8
+            </unit>
9
+            <unit>
10
+                <id>std_soldier</id>
11
+            </unit>
12
+            <unit>
13
+                <id>std_soldier</id>
14
+            </unit>
15
+            <unit>
16
+                <id>std_soldier</id>
17
+            </unit>
18
+        </units>
19
+    </team>
20
+    <team id="std_team" country="DE">
21
+        <name>Standard DE team</name>
5 22
         <units>
6 23
             <unit>
7 24
                 <id>std_soldier</id>

+ 2 - 1
opencombat/strategy/troops.py ファイルの表示

@@ -2,6 +2,7 @@
2 2
 from synergine2.config import Config
3 3
 from synergine2.log import get_logger
4 4
 
5
+from opencombat.strategy.team.stash import TeamStash
5 6
 from opencombat.strategy.unit.stash import UnitStash
6 7
 from opencombat.util import get_class_from_string_path
7 8
 
@@ -35,7 +36,7 @@ class TroopClassBuilder(object):
35 36
         self,
36 37
         units_file_path: str,
37 38
         teams_file_path: str,
38
-    ) -> UnitStash:
39
+    ) -> TeamStash:
39 40
         class_address = self._config.resolve(
40 41
             'global.team_stash',
41 42
             'opencombat.strategy.team.stash.TeamStash',

+ 1 - 1
select_troops.py ファイルの表示

@@ -27,7 +27,7 @@ def main(
27 27
     gui = SelectTroopsGui(
28 28
         config,
29 29
         master=master,
30
-        troop_manager=troop_manager,
30
+        team_stash=troop_manager.team_stash,
31 31
         countries=countries,
32 32
     )
33 33
     master.mainloop()

+ 2 - 2
tests/fixtures/teams.xml ファイルの表示

@@ -1,7 +1,7 @@
1 1
 <?xml version="1.0" encoding="UTF-8"?>
2 2
 <teams>
3 3
     <team id="std_team" country="URSS">
4
-        <name>Standard team</name>
4
+        <name>Standard URSS team</name>
5 5
         <units>
6 6
             <unit>
7 7
                 <id>std_soldier</id>
@@ -18,7 +18,7 @@
18 18
         </units>
19 19
     </team>
20 20
     <team id="std_team" country="DE">
21
-        <name>Standard team</name>
21
+        <name>Standard DE team</name>
22 22
         <units>
23 23
             <unit>
24 24
                 <id>std_soldier</id>