-
Notifications
You must be signed in to change notification settings - Fork 0
/
evobot.rs
114 lines (110 loc) · 3.94 KB
/
evobot.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
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
use std;
import io::{reader,reader_util,writer_util};
import state::{state, outcome, cont, died, won, cmd, move, wait, shave};
import mine::{lambda, razor, horock, target, geom};
import geom::{left, down, up, right, geom};
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;
const linkmax : uint = 5;
const chainmax : uint = 3;
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 + 1);
let chosen = if chosen >= bag.len() { 0 } else { chosen };
let mut pos = bag[chosen];
for rng.gen_uint_range(1, chainmax + 1).times {
let mut replicate = 1;
for rng.gen_uint_range(1, linkmax + 1).times {
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 };
let weight = alt cmd {
move(dir) {
alt pos.state.mine.get(pos.state.rloc.step(dir)) {
lambda | razor { weight * 9 }
_ { weight }
}
}
_ { weight }
};
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];
}
}
pos = alt shell.step(pos, option::get(ocmd)) {
err(_) { ret }
ok(npos) {
if npos.outcome != cont { replicate = 0; break }
if npos.state.lgot == npos.state.c.lamb { replicate += 1 }
if ocmd == some(shave) { replicate += 3; }
alt pos.state.mine.get(npos.state.rloc) {
lambda | razor { replicate += 1 }
horock { replicate += 2 }
target(_) { replicate += 5 }
_ { }
}
npos
}
}
}
if replicate == 0 { break }
for replicate.times {
if bag.len() - 1 < bagsize {
bag += ~[pos];
} else {
bag[rng.gen_uint_range(1, bag.len())] = pos;
}
}
}
}
}