Skip to content

Instantly share code, notes, and snippets.

@vient
Last active July 22, 2019 12:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vient/288b3a2516363d5b4fec0d223ced9883 to your computer and use it in GitHub Desktop.
Save vient/288b3a2516363d5b4fec0d223ced9883 to your computer and use it in GitHub Desktop.
cybrics game solution
#!/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