-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathengine.py
More file actions
118 lines (97 loc) · 4.06 KB
/
engine.py
File metadata and controls
118 lines (97 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#!/usr/bin/env python3
import sys
import importlib.util
import random
import argparse
from typing import List, Dict, Any
class GameEngine:
def __init__(self):
self.round_number = 0
def load_bot(self, bot_path: str) -> Any:
spec = importlib.util.spec_from_file_location("bot", bot_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
return module
def run_game(self, bot_paths: List[str], num_rounds: int = 5) -> Dict[str, Any]:
if len(bot_paths) < 2:
raise ValueError("Need at least 2 bots to play")
bots = []
for i, path in enumerate(bot_paths):
try:
bot_module = self.load_bot(path)
bot_name = f"Bot_{i+1}_{path.split('/')[-1].replace('.py', '')}"
bots.append({
'name': bot_name,
'module': bot_module,
'path': path,
'score': 0
})
except Exception as e:
print(f"Failed to load bot from {path}: {e}")
return {'error': f'Failed to load bot from {path}'}
print(f"Starting Number Battle with {len(bots)} bots!")
print("=" * 50)
for bot in bots:
print(f"- {bot['name']} loaded from {bot['path']}")
print()
for round_num in range(1, num_rounds + 1):
print(f"Round {round_num}/{num_rounds}:")
print("-" * 20)
target = random.randint(1, 100)
round_results = []
for bot in bots:
try:
guess = bot['module'].make_guess()
distance = abs(target - guess)
round_results.append({
'bot': bot['name'],
'guess': guess,
'distance': distance
})
print(f"{bot['name']}: guessed {guess} (distance: {distance})")
except Exception as e:
print(f"{bot['name']}: ERROR - {e}")
round_results.append({
'bot': bot['name'],
'guess': 'ERROR',
'distance': 999
})
print(f"Target was: {target}")
winner = min(round_results, key=lambda x: x['distance'])
for bot in bots:
if bot['name'] == winner['bot']:
bot['score'] += 1
break
print(f"Round winner: {winner['bot']} (closest with distance {winner['distance']})")
print()
final_scores = sorted(bots, key=lambda x: x['score'], reverse=True)
print("FINAL RESULTS:")
print("=" * 50)
for i, bot in enumerate(final_scores):
place = [">G", ">H", ">I"][i] if i < 3 else f"{i+1}."
print(f"{place} {bot['name']}: {bot['score']} rounds won")
return {
'winner': final_scores[0]['name'],
'final_scores': [(bot['name'], bot['score']) for bot in final_scores],
'total_rounds': num_rounds
}
def main():
parser = argparse.ArgumentParser(description="Run the Number Battle game engine.")
parser.add_argument('bots', metavar='BOT', nargs='+', help='Bot Python files to compete')
parser.add_argument('-r', '--rounds', type=int, default=5, help='Number of rounds to play (default: 5)')
args = parser.parse_args()
if len(args.bots) < 2:
print("You must provide at least two bot files.")
sys.exit(1)
engine = GameEngine()
try:
result = engine.run_game(args.bots, num_rounds=args.rounds)
if 'error' not in result:
print(f"\nGame completed! Winner: {result['winner']}")
else:
print(f"Game failed: {result['error']}")
except Exception as e:
print(f"Engine error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()