Repository navigation
Expand file tree
/
Copy pathclever.cs
More file actions
92 lines (78 loc) · 3.35 KB
/
Copy pathclever.cs
File metadata and controls
92 lines (78 loc) · 3.35 KB
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
using System.Collections.Generic;
using static System.Console;
class Clever : Player {
bool match(Game game, int within, int x, int y, int player) {
for (int x1 = x - within; x1 <= x + within ; ++x1)
if (x1 >= 0 && x1 < Game.Size && game.squares[x1, y] == player)
return true;
return false;
}
public Move chooseMove(Game game) {
List<Move> possibleMoves = game.possibleMoves();
if (game.moves < 2) { // my first move
int count = possibleMoves.Count;
int index = game.seed >= 0 ? game.seed % count : game.random.next(count);
return possibleMoves[index];
}
int me = game.turn, opp = 3 - me, dir = game.dir();
int adjY(int y) => dir > 0 ? y : Game.Size - 1 - y;
List<Move> best = new List<Move>();
int bestVal = int.MinValue;
int forwardY = dir > 0 ? int.MinValue : int.MaxValue;
int forwardOppY = dir > 0 ? int.MaxValue : int.MinValue;
for (int x = 0 ; x < Game.Size ; ++x)
for (int y = 0 ; y < Game.Size ; ++y) {
if (game.squares[x, y] == me && (dir > 0 ? y > forwardY : y < forwardY))
forwardY = y;
if (game.squares[x, y] == opp && (dir > 0 ? y < forwardOppY : y > forwardOppY))
forwardOppY = y;
}
foreach (Move m in possibleMoves) {
int val;
int gain = 0, lose = 0;
if (m.to.y == 0 || m.to.y == Game.Size - 1)
val = 100;
else {
int attack = 0, defend = 0;
for (int dx = -1; dx <= 1 ; dx += 2) {
int x1 = m.to.x + dx;
if (x1 >= 0 && x1 < Game.Size) {
if (game.squares[x1, m.to.y + dir] == opp)
attack += 1;
if (x1 != m.from.x &&
game.squares[x1, m.from.y] == me)
defend += 1;
}
}
if (attack <= defend)
lose = gain = attack;
else {
lose = defend + 1;
gain = defend;
}
bool capture = game.squares[m.to.x, m.to.y] > 0;
int toY = adjY(m.to.y);
val = gain * 10 - lose * 10 + toY;
if (capture)
val += toY == 1 ? 30 : 15;
if (match(game, 1, m.to.x, forwardY, me))
val += 3;
if (adjY(m.from.y) < adjY(forwardOppY) &&
match(game, 1, m.from.x, forwardOppY, opp))
val -= 2;
else if (adjY(m.to.y) < adjY(forwardOppY) &&
match(game, 1, m.to.x, forwardOppY, opp))
val += 2;
if (m.to.x == 0 || m.to.x == Game.Size - 1)
val += 1;
}
if (val > bestVal) {
best = new List<Move>();
best.Add(m);
bestVal = val;
} else if (val == bestVal)
best.Add(m);
}
return best[game.random.next(best.Count)];
}
}