VOID, WALL, SPIKES, MONSTER, TRAP, EXIT = 100, 101, 102, 107, 112, 117 GO_UP, GO_RIGHT, GO_DOWN, GO_LEFT, ATTACK, QUIT = 10, 11, 12, 13, 14, 15 NEW_GAME, TRAP_APPEARED, SPIKES_APPEARED = 20, 21, 22 VIDE, MUR, PICS, MONSTRE, PIEGE, SORTIE = VOID, WALL, SPIKES, MONSTER, TRAP, EXIT ALLER_HAUT, ALLER_DROITE, ALLER_BAS, ALLER_GAUCHE, ATTAQUER, QUITTER = GO_UP, GO_RIGHT, GO_DOWN, GO_LEFT, ATTACK, QUIT NOUVELLE_PARTIE, PIEGE_APPARU, PICS_APPARUS = NEW_GAME, TRAP_APPEARED, SPIKES_APPEARED def ri(rs,a,b): rs[0] = (rs[0] * 214013 + 2531011) % 4294967296 return ((rs[0] // 65536) & 0x7fff) % (b-a) + a ### Rendering def csi_tile(tile): s = tile==WALL and 140 or is_a(tile, SPIKES) and 134 or is_a(tile, MONSTER) and 165 or is_a(tile, TRAP) and 248 or is_a(tile, EXIT) and tile%2 and 93 or is_a(tile, EXIT) and 91 or tile < 4 and 182 or 32 if tile > WALL: tile = (tile - EXIT) % 5 return "\x1B[{};{}m".format((3, 1, 15, 2, 13, 7)[(tile==WALL or tile==VOID) and 5 or tile], 0) + chr(s) def render_game(board, players, old_players, updates): for y in range(8): s = "" for x in range(16): i = y*16+x s += csi_tile(not i in players and board[i] or players.index(i)) if y==7: s+= "\x1B[0m" print(s) ### API for submissions def is_a(obj, kind): return 0 <= obj - kind <= (kind != VOID and kind != WALL) * 4 def affects(obj, player): return (is_a(obj, SPIKES) or is_a(obj, MONSTER) or is_a(obj, TRAP)) and not obj-player in (SPIKES, MONSTER, TRAP) est_un, affecte = is_a, affects ### Board generator def ufr(uf,i): if uf[i] != i: uf[i] = ufr(uf, uf[i]) return uf[i] #def ufm(uf,i,j): # uf[ufr(uf,i)]=ufr(uf,j) def gb(rs): board = [WALL] * 128 pp = (17,30,97,110) pe = (47,80,95,32) for i in range(4): board[pp[i]] = VOID board[pe[i]] = EXIT+i uf = list(range(128)) while any([ufr(uf,pp[i]) != ufr(uf,pe[i]) for i in range(4)]): i = ri(rs,1,7)*16 + ri(rs,1,15) if board[i] == WALL and any(board[n] != VOID for n in (i-16,i+16,i-1,i+1)): board[i] = VOID for n in (i-16,i+16,i-1,i+1): if board[n] != WALL: uf[ufr(uf,i)]=ufr(uf,n) # ufm(uf,i,n) for i in range(128): if board[i] == VOID and ri(rs,0,16)<2: board[i]=(MONSTER, MONSTER, SPIKES, TRAP)[ri(rs,0,4)]+ri(rs,0,5) return board ### Game logic def play_board(rs, turn_function, blind): board = gb(rs) players = [17,30,97,110] old_players = [] ev = [(-1,-1,NEW_GAME,-1)] update = [-1] turns = 0 penalty = 0 while True: if not blind: render_game(board, players, old_players, update) action = turn_function(board, players, ev) ev = [] update = [] old_players = players[:] if action is None: continue if action == 15: return None turns += 1 traps_activated = 0 for p in range(4): coord = players[p] if coord < 0: continue if action == 14: for direction in range(4): i = coord + (direction == 1) - (direction == 3) + 16*((direction == 2) - (direction == 0)) dest = board[i] if is_a(dest, MONSTER): board[i] = VOID update.append(i) elif is_a(dest, TRAP) and affects(dest, p): traps_activated += 1 board[i] = VOID update.append(i) else: i = coord + (action == GO_RIGHT) - (action == GO_LEFT) + 16*((action == GO_DOWN) - (action == GO_UP)) dest = board[i] if dest == EXIT+p: players[p] = -1 continue if dest == WALL or is_a(dest, EXIT): continue players[p] = i if not affects(dest, p): continue if is_a(dest, SPIKES): penalty += 10 elif is_a(dest, MONSTER): penalty += 10 board[i] = VOID update.append(i) elif is_a(dest, TRAP): traps_activated += 1 board[i] = VOID update.append(i) while traps_activated: effect = ri(rs,0,3) if effect == 0: penalty += 10 x = ri(rs,1,15) y = ri(rs,1,7) i = y*16+x if board[i] == VOID and i not in players: board[i] = (TRAP if effect==1 else SPIKES) + ri(rs,0,4) ev.append((x, y, TRAP_APPEARED if effect==1 else SPIKES_APPEARED, p)) update.append(i) traps_activated -= 1 if all(p < 0 for p in players): score = 150 - penalty - turns print("Bravo! {}T {}D -> {}".format(turns, penalty, score)) return score def play_game(turn_function, blind=False, seed=0xc0ffee, maxgames=100): rs = [seed] games = 0 score = 0 while games != maxgames: print("#{}: ".format(games)+str(rs[0])) board_score = play_board(rs, turn_function, blind) if board_score is None: print("") print("Quit!") return score += max(board_score, 0) games += 1 print("Games solved:", games) print("Score:", score) return games, score