forked from ja3537/A-Magical-Code
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mission.py
128 lines (108 loc) · 4.33 KB
/
mission.py
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
119
120
121
122
import numpy as np
import cards
import constants
from importlib import import_module
from agents.default import Agent as default_agent
class Mission:
def __init__(self, args):
self.seed = args.seed
self.verbose = args.verbose
if(self.seed != 0):
self.rng = np.random.default_rng(self.seed)
else:
self.rng = np.random.default_rng()
if args.agent[0] in constants.possible_agents:
if args.agent[0] == 'd':
self.agent = default_agent()
else:
agent_name = "agent{}".format(args.agent[0])
agent_module = import_module(f".{agent_name}", "agents")
self.agent = agent_module.Agent()
else:
print("error loading agent ", args.agent[0])
exit()
self.n = int(args.n)
self.rand_n = args.rand_n
self.null_rate = float(args.null_rate)
self.output = args.output
self.messages = []
with open(args.messages, 'r') as f:
text_lines = f.read().splitlines()
i = 0
while i < len(text_lines):
if(text_lines[i] == ''):
i += 1
continue
null_roll = self.rng.random()
if null_roll > (1-self.null_rate):
self.messages.append("NULL")
else:
self.messages.append(text_lines[i])
i += 1
self.encoded_decks = []
self.shuffled_decks = []
self.n_values = []
self.decoded = [None]*len(self.messages)
self.scores = [None]*len(self.messages)
self.total_score = 0
self.messages_index = list(range(len(self.messages))) #indexes of messages not yet used in mission
self.rng.shuffle(self.messages_index) #determines random order for messages during decoding
def execute_mission(self):
for m in self.messages: #encode stage
if m != "NULL":
d = self.agent.encode(m)
if(not cards.valid_deck(d)):
print("invalid deck")
else:
d = cards.generate_deck(self.rng, random = True)
self.encoded_decks.append(d)
for i in range(len(self.encoded_decks)): #shuffling stage
d = self.encoded_decks[i]
if cards.valid_deck(d):
if(self.rand_n):
n = self.rng.integers(1, self.n + 1, 1)[0]
else:
n = self.n
self.n_values.append(n)
self.shuffled_decks.append(self.s(n, d))
for i in self.messages_index:
s_deck = self.shuffled_decks[i]
if cards.valid_deck(s_deck):
decoded_m = self.agent.decode(s_deck)
score = self.score_message(self.messages[i], decoded_m)
self.decoded[i] = decoded_m
else:
score = 0
self.decoded[i] = "invalid deck: {}".format(e_deck)
self.scores[i] = score
self.total_score += score
self.make_output_file()
def score_partial(self, m, decoded_m):
#print(decoded_m.removeprefix("PARTIAL: "))
return 0
def score_message(self, m, decoded_m):
if decoded_m.startswith("PARTIAL: "):
return self.score_partial(m, decoded_m)
if m == decoded_m:
return 1
else:
return 0
def s(self, n, deck):
shuffles = self.rng.integers(0, 52, n)
for pos in shuffles:
top_card = deck[0]
deck = deck[1:]
deck = deck[:pos] + [top_card] + deck[pos:]
return deck
def make_output_file(self):
with open(self.output, 'w+') as f:
for i in range(len(self.messages)):
f.write(self.messages[i] + '\n')
if(self.verbose):
f.write('encoded deck: ' + str(self.encoded_decks[i]) + '\n')
f.write('n value: ' + str(self.n_values[i]) + '\n')
f.write('shuffled deck: ' + str(self.shuffled_decks[i]) + '\n')
f.write(self.decoded[i] + '\n')
f.write(str(self.scores[i]) + '\n')
f.write('\n')
f.write('total score for agent: {}/{}'.format(self.total_score, len(self.messages)))