pyscreeps-arena 0.5.6.6__tar.gz → 0.5.7a0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/PKG-INFO +1 -1
  2. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/compiler.py +187 -10
  3. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/const.py +1 -1
  4. pyscreeps_arena-0.5.7a0/pyscreeps_arena/project.7z +0 -0
  5. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena.egg-info/PKG-INFO +1 -1
  6. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/setup.py +1 -1
  7. pyscreeps_arena-0.5.6.6/pyscreeps_arena/project.7z +0 -0
  8. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/__init__.py +0 -0
  9. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/build.py +0 -0
  10. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/__init__.py +0 -0
  11. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/basic.py +0 -0
  12. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/config.py +0 -0
  13. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/core.py +0 -0
  14. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/main.py +0 -0
  15. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/core/utils.py +0 -0
  16. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/localization.py +0 -0
  17. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/ui/P2PY.py +0 -0
  18. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/ui/__init__.py +0 -0
  19. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/ui/project_ui.py +0 -0
  20. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena/ui/rs_icon.py +0 -0
  21. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena.egg-info/SOURCES.txt +0 -0
  22. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena.egg-info/dependency_links.txt +0 -0
  23. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena.egg-info/entry_points.txt +0 -0
  24. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena.egg-info/requires.txt +0 -0
  25. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/pyscreeps_arena.egg-info/top_level.txt +0 -0
  26. {pyscreeps_arena-0.5.6.6 → pyscreeps_arena-0.5.7a0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscreeps-arena
3
- Version: 0.5.6.6
3
+ Version: 0.5.7a0
4
4
  Summary: Python api|interface to play game: Screeps: Arena.
5
5
  Author-email: 2229066748@qq.com
6
6
  Maintainer: Eagle'sBaby
@@ -9,6 +9,7 @@ import chardet
9
9
  import subprocess
10
10
  import pyperclip
11
11
  from colorama import Fore
12
+ from typing import List, Optional, Tuple, Union
12
13
 
13
14
  WAIT = Fore.YELLOW + ">>>" + Fore.RESET
14
15
  GREEN = Fore.GREEN + "{}" + Fore.RESET
@@ -92,18 +93,18 @@ export var loop = function () {
92
93
  timeLine = get.cpu_us();
93
94
  know.handle();
94
95
  knowCost = get.cpu_us() - timeLine;
95
- if (know.now === 1) {
96
- std.show_welcome();
97
- init (know);
98
-
99
- }
100
-
96
+
101
97
  timeLine = get.cpu_us();
102
98
  monitor.handle();
103
99
  monitorCost = get.cpu_us() - timeLine;
104
100
  for (const creep of know.creeps){
105
101
  creep.handle();
106
102
  }
103
+ if (know.now === 1) {
104
+ std.show_welcome();
105
+ init (know);
106
+
107
+ }
107
108
  step (know);
108
109
  timeLine = get.cpu_us();
109
110
  if (get._SCH_FLAG) sch.handle();
@@ -685,6 +686,167 @@ class Compiler_Utils(Compiler_Const):
685
686
  code = re.sub(r"'''[^']*'''", '', code)
686
687
  return code
687
688
 
689
+ @classmethod
690
+ def _collect_logical_line(cls, lines: List[str], start_idx: int) -> Tuple[str, int]:
691
+ """收集从start_idx开始的逻辑行(处理多行语句,直到遇到:结尾)"""
692
+ if start_idx >= len(lines):
693
+ return "", start_idx
694
+
695
+ parts = [lines[start_idx].rstrip()]
696
+ i = start_idx
697
+
698
+ # 持续收集直到找到以:结尾的行
699
+ while i < len(lines) and not parts[-1].endswith(':'):
700
+ i += 1
701
+ if i < len(lines):
702
+ parts.append(lines[i].rstrip())
703
+
704
+ return " ".join(parts), i
705
+
706
+ @classmethod
707
+ def _convert_block(cls, lines: List[str], match_counter: Optional[List[int]] = None) -> List[str]:
708
+ if match_counter is None:
709
+ match_counter = [0]
710
+
711
+ result = []
712
+ i = 0
713
+
714
+ while i < len(lines):
715
+ line = lines[i].rstrip()
716
+
717
+ # 检测match语句(支持多行)
718
+ if re.match(r'^\s*match\s+', line):
719
+ full_match, end_idx = cls._collect_logical_line(lines, i)
720
+
721
+ match_stmt = re.match(r'^(\s*)match\s+(.+?)\s*:', full_match)
722
+ if not match_stmt:
723
+ result.append(line)
724
+ i += 1
725
+ continue
726
+
727
+ indent = match_stmt.group(1)
728
+ subject = match_stmt.group(2).strip()
729
+ i = end_idx + 1 # 跳过match语句
730
+
731
+ # 生成临时变量
732
+ var_name = f"__MATCH_{match_counter[0]}__"
733
+ match_counter[0] += 1
734
+ result.append(f"{indent}{var_name} = {subject}")
735
+
736
+ # 解析case语句
737
+ cases: List[Tuple[str, List[str]]] = []
738
+ case_indent = None
739
+
740
+ while i < len(lines):
741
+ case_line = lines[i].rstrip()
742
+
743
+ # 缩进检查 - case必须比match缩进更多
744
+ if not case_line.startswith(indent + ' ') and case_line.strip():
745
+ if re.match(r'^\s*case\s+', case_line):
746
+ raise MatchCaseError(f"第 {i + 1} 行: case 缩进必须大于 match")
747
+ break
748
+
749
+ # 检测case语句(不再使用_collect_logical_line,而是单独处理每一行)
750
+ case_match = re.match(r'^(\s+)case\s+(.+?)\s*:', case_line)
751
+ if case_match:
752
+ curr_case_indent = case_match.group(1)
753
+ case_val = case_match.group(2).strip()
754
+
755
+ # 验证缩进 - 允许不同的case缩进(用于嵌套)
756
+ if len(curr_case_indent) <= len(indent):
757
+ raise MatchCaseError(f"第 {i + 1} 行: case 缩进必须大于 match")
758
+
759
+ # 不再强制要求所有case缩进一致,允许嵌套情况下的不同缩进
760
+ if case_indent is None:
761
+ case_indent = curr_case_indent
762
+
763
+ # 提取内联代码(如果有)
764
+ inline_code = ""
765
+ if ':' in case_line:
766
+ after_colon = case_line.split(':', 1)[1].strip()
767
+ if after_colon:
768
+ inline_code = after_colon
769
+
770
+ i += 1
771
+
772
+ # 收集case块
773
+ block_lines = []
774
+ if inline_code:
775
+ block_lines.append(f"{curr_case_indent} {inline_code}")
776
+
777
+ while i < len(lines):
778
+ block_line = lines[i].rstrip()
779
+ if not block_line.strip():
780
+ block_lines.append(block_line)
781
+ i += 1
782
+ continue
783
+
784
+ # 检查是否是下一个case或者缩进回到当前match级别
785
+ if re.match(r'^\s*case\s+', block_line):
786
+ # 检查这个case是否属于当前match还是父级match
787
+ next_case_indent = re.match(r'^\s*', block_line).group(0)
788
+ if len(next_case_indent) <= len(indent):
789
+ # 属于父级match,退出当前match的处理
790
+ break
791
+ # 仍然属于当前match,继续收集
792
+ if block_line.startswith(curr_case_indent + ' '):
793
+ block_lines.append(block_line)
794
+ i += 1
795
+ continue
796
+ else:
797
+ break
798
+
799
+ if block_line.startswith(indent) and not block_line.startswith(curr_case_indent):
800
+ break
801
+
802
+ if block_line.startswith(curr_case_indent + ' '):
803
+ block_lines.append(block_line)
804
+ i += 1
805
+ continue
806
+
807
+ break
808
+
809
+ cases.append((case_val, block_lines))
810
+ else:
811
+ break
812
+
813
+ # 验证case
814
+ seen = set()
815
+ for idx, (val, _) in enumerate(cases):
816
+ if val == '_':
817
+ if idx != len(cases) - 1:
818
+ raise MatchCaseError(f"第 {i + 1} 行附近: case _ 必须在最后")
819
+ else:
820
+ if val in seen:
821
+ raise MatchCaseError(f"第 {i + 1} 行附近: 重复的 case 值 '{val}'")
822
+ seen.add(val)
823
+
824
+ # 生成if/elif/else
825
+ for idx, (case_val, blk_lines) in enumerate(cases):
826
+ keyword = "else" if case_val == '_' else ("if" if idx == 0 else "elif")
827
+ if keyword == "else":
828
+ result.append(f"{indent}else:")
829
+ else:
830
+ result.append(f"{indent}{keyword} {var_name} == {case_val}:")
831
+
832
+ if blk_lines:
833
+ # 递归处理block_lines,以支持嵌套match
834
+ converted_blk_lines = cls._convert_block(blk_lines, match_counter)
835
+ result.extend(converted_blk_lines)
836
+
837
+ continue
838
+
839
+ result.append(line)
840
+ i += 1
841
+
842
+ return result
843
+
844
+ @classmethod
845
+ def convert_match_to_if(cls, code: str) -> str:
846
+ lines = code.split('\n')
847
+ converted_lines = cls._convert_block(lines, [0])
848
+ return '\n'.join(converted_lines)
849
+
688
850
 
689
851
  class CompilerBase(Compiler_Utils):
690
852
 
@@ -827,10 +989,11 @@ class Compiler(CompilerBase):
827
989
  else:
828
990
  _pre_sort_[fname] = 65535
829
991
 
830
- # ------------------------------------ 自定义:调用process_mate_code ------------------------------------ #
992
+ # ------------------------------------ 自定义:mate & match ------------------------------------ #
831
993
  for fpath in py_fpath:
832
994
  content = self.auto_read(fpath)
833
995
  content = self.process_mate_code(content) # 调用process_mate_code
996
+ content = self.convert_match_to_if(content) # 调用convert_match_to_if
834
997
  with open(fpath, 'w', encoding='utf-8') as f:
835
998
  f.write(content)
836
999
 
@@ -1216,6 +1379,20 @@ class Compiler(CompilerBase):
1216
1379
 
1217
1380
 
1218
1381
  if __name__ == '__main__':
1219
- compiler = Compiler('src', 'library', 'build')
1220
- compiler.compile()
1221
- compiler.clean()
1382
+ # compiler = Compiler('src', 'library', 'build')
1383
+ # compiler.compile()
1384
+ # compiler.clean()
1385
+ test = """
1386
+
1387
+ def patrolling(self, c: Creep):
1388
+ e = self.center.nearest(k.civilian.enemies, 5)
1389
+ if e:
1390
+ match c.test(e,
1391
+ int(c.hpPer <= 0.9) * 2,
1392
+ int(c.info.melee) * -3
1393
+ ):
1394
+ case True: c.move(e, SWAMP_MOTION)
1395
+ case False: c.move(self.bpos, SWAMP_MOTION)
1396
+
1397
+ """
1398
+ print(f"res=\n{Compiler.convert_match_to_if(test)}")
@@ -9,7 +9,7 @@
9
9
  #
10
10
  import re
11
11
 
12
- VERSION = "0.5.6.6"
12
+ VERSION = "0.5.7a0"
13
13
  AUTHOR = "●ω<🤍♪"
14
14
  STEAM_ID = "1029562896"
15
15
  GITHUB_NAME = "EagleBaby"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyscreeps-arena
3
- Version: 0.5.6.6
3
+ Version: 0.5.7a0
4
4
  Summary: Python api|interface to play game: Screeps: Arena.
5
5
  Author-email: 2229066748@qq.com
6
6
  Maintainer: Eagle'sBaby
@@ -7,7 +7,7 @@ with open(r"T:\New_PC\Import_Project\uploads\pyscreeps-arena_upload\pyscreeps-ar
7
7
  long_description = f.read()
8
8
  setup(
9
9
  name='pyscreeps-arena',
10
- version='0.5.6.6',
10
+ version='0.5.7a0',
11
11
  description='Python api|interface to play game: Screeps: Arena.',
12
12
  long_description=long_description,
13
13
  long_description_content_type='text/markdown',