-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrandbot.rs
85 lines (81 loc) · 2.5 KB
/
randbot.rs
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
use std;
import io::{reader,reader_util,writer_util};
import state::{state, outcome, cont, died, won, cmd, move, wait, shave};
import geom::{left, down, up, right};
import botshell::stuff;
import result::{result, ok, err};
fn get_map(-fh: reader) -> state {
let mut lines = ~[];
for fh.each_line |line| { lines += ~[copy line]; }
state::parse(lines)
}
const dfl_baglen : uint = 100;
pure fn opposed(c0: cmd, c1: cmd) -> bool {
alt (c0,c1) {
(move(left), move(right)) { true }
(move(right), move(left)) { true }
(move(up), move(down)) { true }
(move(down), move(up)) { true }
_ { false }
}
}
fn main(argv: ~[str]) {
let bagsize = if argv.len() > 1 {
option::get(uint::from_str(argv[1]))
} else {
dfl_baglen
};
let rng = if argv.len() > 2 {
rand::seeded_rng(str::bytes(argv[2]))
} else {
rand::rng()
};
let (shell, pos0) = botshell::start(get_map(io::stdin()));
let mut bag = ~[mut pos0];
let cmds = ~[move(left), move(right), move(up), move(down), wait, shave];
let weights = vec::to_mut(vec::from_elem(cmds.len(), 0));
loop {
let chosen = rng.gen_uint_range(0, bagsize);
let chosen = if chosen >= bag.len() { 0 } else { chosen };
let pos = bag[chosen];
assert(pos.outcome == cont);
let mut tl = 0;
for uint::range(0, cmds.len()) |i| {
let cmd = cmds[i];
let weight =
if !pos.state.useful(cmd) { 0 } else
if opposed(cmd, pos.head()) && !pos.state.collected { 1 } else
if cmd == wait { 5 } else
if cmd == shave { 85 } else
if cmd == pos.head() { 35 } else { 10 };
weights[i] = weight;
tl += weight;
}
if tl == 0 {
bag[chosen] = bag[0];
again
}
let mut impulse = rng.gen_uint_range(0, tl);
let mut ocmd = none;
for cmds.eachi |i,cmd| {
if impulse < weights[i] {
ocmd = some(cmd);
break;
} else {
impulse -= weights[i];
}
}
alt shell.step(pos, option::get(ocmd)) {
err(_) { break }
ok(npos) {
if npos.outcome == cont {
if bag.len() - 1 < bagsize {
bag += ~[npos];
} else {
bag[rng.gen_uint_range(1, bag.len())] = npos;
}
}
}
}
}
}