Last active
July 22, 2019 12:53
-
-
Save vient/288b3a2516363d5b4fec0d223ced9883 to your computer and use it in GitHub Desktop.
cybrics game solution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2 | |
from pwn import * | |
import os | |
class Room: | |
def __init__(self, data=None): | |
self.dimX = None | |
self.dimY = None | |
self.player = None | |
self.flag = None | |
self.doors = [] | |
self.enemies = [] | |
self.fireballs = [] | |
if data is not None: | |
self.parse(data) | |
def parse(self, data): | |
self.dimX, data = u32(data[:4]), data[4:] | |
self.dimY, data = u32(data[:4]), data[4:] | |
doors, data = u32(data[:4]), data[4:] | |
for i in range(doors): | |
x, data = u32(data[:4]), data[4:] | |
y, data = u32(data[:4]), data[4:] | |
self.doors.append((x, y)) | |
x, data = u32(data[:4]), data[4:] | |
y, data = u32(data[:4]), data[4:] | |
self.player = (x, y) | |
enemies, data = u32(data[:4]), data[4:] | |
for i in range(enemies): | |
x, data = u32(data[:4]), data[4:] | |
y, data = u32(data[:4]), data[4:] | |
self.enemies.append((x, y)) | |
flags, data = u32(data[:4]), data[4:] | |
if flags: | |
x, data = u32(data[:4]), data[4:] | |
y, data = u32(data[:4]), data[4:] | |
self.flag = (x, y) | |
fireballs, data = u32(data[:4]), data[4:] | |
for i in range(fireballs): | |
x, data = u32(data[:4]), data[4:] | |
y, data = u32(data[:4]), data[4:] | |
self.fireballs.append((x, y)) | |
def __repr__(self): | |
return 'Room<dimX={}, dimY={}, player={}, flag={}, doors={}, enemies={}, fireballs={}>'.format( | |
self.dimX, | |
self.dimY, | |
self.player, | |
self.flag, | |
self.doors, | |
self.enemies, | |
self.fireballs | |
) | |
def __str__(self): | |
res = [[' ' for i in range(self.dimX + 2)] for j in range(self.dimY + 2)] | |
for i in range(self.dimX + 2): | |
res[0][i] = 'X' | |
res[self.dimY + 1][i] = 'X' | |
for i in range(self.dimY + 2): | |
res[i][0] = 'X' | |
res[i][self.dimX + 1] = 'X' | |
for x, y in self.doors: | |
if x == self.dimX - 1: | |
x += 2 | |
elif x: | |
x += 1 | |
if y == self.dimY - 1: | |
y += 2 | |
elif y: | |
y += 1 | |
res[y][x] = ' ' | |
for x, y in self.enemies: | |
res[y + 1][x + 1] = '#' | |
for x, y in self.fireballs: | |
res[y + 1][x + 1] = '*' | |
if self.player: | |
x, y = self.player | |
res[y + 1][x + 1] = 'P' | |
if self.flag: | |
x, y = self.flag | |
res[y + 1][x + 1] = 'F' | |
return '\n'.join(''.join(x) for x in res) | |
def readn(p, n): | |
res = '' | |
while len(res) < n: | |
t = p.recv(n - len(res), timeout=1) | |
if t is None: | |
log.error('readn') | |
res += t | |
return res | |
def main(): | |
with remote('95.179.148.72', 10003) as p: | |
need_goal = True | |
destx, desty = None, None | |
was = set() | |
last_id = None | |
node_exit = [] | |
queue = [] | |
is_return = None | |
last_level = '' | |
for LOOP in xrange(123456789): | |
room = readn(p, u32(readn(p, 4))) | |
if b'cybrics' in room: | |
print(room) | |
exit(0) | |
level = readn(p, u32(readn(p, 4))) | |
if b'cybrics' in level: | |
print(level) | |
exit(0) | |
os.system('clear') | |
r = Room(room) | |
print(repr(r)) | |
print(str(r)) | |
print('\n\n\n') | |
print(level) | |
if level != last_level: # next level | |
last_level = level | |
was = set() | |
need_goal = True | |
node_id = 0 | |
last_id = 0 | |
node_exit = [None] | |
queue = [] | |
is_return = False | |
if node_id == len(node_exit): # went to new room | |
node_exit.append(sorted( | |
[(abs(r.player[0] - door[0]) + abs(r.player[1] - door[1]), i) for i, door in enumerate(r.doors)] | |
)[0][1]) # nearest door | |
queue.append(last_id) # save id of previous room | |
need_goal = True | |
if node_id != last_id: # generic room switch | |
is_return = False | |
last_id = node_id | |
print 'Current node:', node_id | |
print 'Exits:', node_exit | |
print 'Queue:', queue | |
if need_goal: | |
need_goal = False | |
destx, desty = None, None | |
if r.flag is not None: | |
destx, desty = r.flag | |
else: | |
goal_door = None | |
for i in range(len(r.doors)): | |
if (node_id, i) in was: | |
continue | |
if i == node_exit[node_id]: | |
continue | |
goal_door = i | |
was.add((node_id, i)) | |
break | |
else: | |
goal_door = node_exit[node_id] | |
is_return = True | |
destx, desty = r.doors[goal_door] | |
action = None | |
if r.player == (destx, desty): # door | |
need_goal = True | |
if is_return: | |
node_id = queue.pop() | |
else: | |
node_id = len(node_exit) | |
if destx == 0: | |
action = 'a' | |
elif destx == r.dimX - 1: | |
action = 'd' | |
elif desty == 0: | |
action = 'w' | |
else: | |
action = 's' | |
else: | |
if destx < r.player[0]: | |
action = 'a' | |
if destx > r.player[0]: | |
action = 'd' | |
if desty < r.player[1]: | |
action = 'w' | |
if desty > r.player[1]: | |
action = 's' | |
kek = [] | |
if action == 'a': | |
kek += [enemy for enemy in r.enemies if enemy[0] < r.player[0]] | |
if action == 'd': | |
kek += [enemy for enemy in r.enemies if enemy[0] > r.player[0]] | |
if action == 'w': | |
kek += [enemy for enemy in r.enemies if enemy[1] < r.player[1]] | |
if action == 's': | |
kek += [enemy for enemy in r.enemies if enemy[1] > r.player[1]] | |
if kek and min(abs(r.player[0] - enemy[0]) + abs(r.player[1] - enemy[1]) for enemy in kek) < 3: | |
action = 'c' | |
print(destx, desty) | |
print('action', action) | |
if action == 'w': | |
action = 's' | |
elif action == 's': | |
action = 'w' | |
p.send(action) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment