Skip to content

Commit

Permalink
Various cleanups to lbdist, use Board::to_s to print the distance for…
Browse files Browse the repository at this point in the history
… that position.
  • Loading branch information
tewalds committed Feb 17, 2015
1 parent e8c541f commit aa13d2c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 68 deletions.
9 changes: 6 additions & 3 deletions havannah/board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,21 @@ std::string Board::Cell::to_s(int i) const {
", pattern: " + to_str((int)pattern);
}

std::string empty(Move m) { return "."; }

std::string Board::to_s(bool color) const {
return to_s(color, empty);
}
std::string Board::to_s(bool color, std::function<std::string(Move)> func) const {
using std::string;
string white = "O",
black = "@",
empty = ".",
coord = "",
reset = "";
if(color){
string esc = "\033";
reset = esc + "[0m";
coord = esc + "[1;37m";
empty = reset + ".";
white = esc + "[1;33m" + "@"; //yellow
black = esc + "[1;34m" + "@"; //blue
}
Expand All @@ -45,7 +48,7 @@ std::string Board::to_s(bool color) const {
s += (last == Move(x, y) ? coord + "[" :
last == Move(x-1, y) ? coord + "]" : " ");
Side p = get(x, y);
if( p == Side::NONE) s += empty;
if( p == Side::NONE) s += reset + func(Move(x, y));
else if(p == Side::P1) s += white;
else if(p == Side::P2) s += black;
else s += "?";
Expand Down
2 changes: 2 additions & 0 deletions havannah/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <algorithm>
#include <cassert>
#include <cstdio>
#include <functional>
#include <ostream>
#include <string>
#include <vector>
Expand Down Expand Up @@ -295,6 +296,7 @@ mutable uint8_t mark; //when doing a ring search, has this position been seen
int linelen(int y) const { return size_d - abs(sizem1 - y); }

std::string to_s(bool color) const;
std::string to_s(bool color, std::function<std::string(Move)> func) const;

friend std::ostream& operator<< (std::ostream &out, const Board & b) { return out << b.to_s(true); }

Expand Down
48 changes: 3 additions & 45 deletions havannah/gtpgeneral.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,53 +221,11 @@ GTPResponse GTP::gtp_dists(vecstr args){
}
}

string white = "O",
black = "@",
empty = ".",
coord = "",
reset = "";
if(colorboard){
string esc = "\033";
reset = esc + "[0m";
coord = esc + "[1;37m";
empty = reset + ".";
white = esc + "[1;33m" + "@"; //yellow
black = esc + "[1;34m" + "@"; //blue
if(args.size() >= 2) {
return GTPResponse(true, to_str(dists.get(Move(args[1]), side)));
}


int size = board.get_size();
int size_d = board.get_size_d();

string s = "\n";
s += string(size + 3, ' ');
for(int i = 0; i < size; i++)
s += " " + coord + to_str(i+1);
s += "\n";

for(int y = 0; y < size_d; y++){
s += string(abs(size-1 - y) + 2, ' ');
s += coord + char('A' + y);
for(int x = board.linestart(y); x < board.lineend(y); x++){
Side p = board.get(x, y);
s += ' ';
if(p == Side::NONE){
int d = (side == Side::NONE ? dists.get(Move(x, y)) : dists.get(Move(x, y), side));
if(d < 10)
s += reset + to_str(d);
else
s += empty;
}else if(p == Side::P1){
s += white;
}else if(p == Side::P2){
s += black;
}
}
if(y < size-1)
s += " " + coord + to_str(1 + size + y);
s += '\n';
}
return GTPResponse(true, s);
return GTPResponse(true, "\n" + board.to_s(colorboard, bind(&LBDists::get_s, &dists, _1, side)));
}

GTPResponse GTP::gtp_zobrist(vecstr args){
Expand Down
47 changes: 27 additions & 20 deletions havannah/lbdist.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,12 @@ namespace Havannah {

class LBDists {
struct MoveDist {
Move pos;
MoveValid pos;
int dist;
int dir;

MoveDist() { }
MoveDist(Move p, int d, int r) : pos(p), dist(d), dir(r) { }
MoveDist(int x, int y, int d, int r) : pos(Move(x,y)), dist(d), dir(r) { }
MoveDist(MoveValid p, int d, int r) : pos(p), dist(d), dir(r) { }
};

//a specialized priority queue
Expand Down Expand Up @@ -74,16 +73,18 @@ class LBDists {
IntPQueue Q;
const Board * board;

int & dist(int edge, Side player, int i) { return dists[edge][player.to_i() - 1][i]; }
int & dist(int edge, Side player, const Move & m) { return dist(edge, player, board->xy(m)); }
int & dist(int edge, Side player, int x, int y) { return dist(edge, player, board->xy(x, y)); }
int & dist(int edge, Side player, int i) { return dists[edge][player.to_i() - 1][i]; }
int & dist(int edge, Side player, const MoveValid & m) { return dist(edge, player, m.xy); }
int & dist(int edge, Side player, const Move & m) { return dist(edge, player, board->xy(m)); }
int & dist(int edge, Side player, int x, int y) { return dist(edge, player, board->xy(x, y)); }

void init(int x, int y, int edge, Side player, int dir){
Side val = board->get(x, y);
if(val != ~player){
bool empty = (val == Side::NONE);
Q.push(MoveDist(x, y, empty, dir));
dist(edge, player, x, y) = empty;
MoveValid move(x, y, board->xy(x, y));
Q.push(MoveDist(move, empty, dir));
dist(edge, player, move) = empty;
}
}

Expand All @@ -100,8 +101,8 @@ class LBDists {
for(int k = 0; k < board->vecsize(); k++)
dists[i][j][k] = maxdist; //far far away!

if(side == Side::P1 || side == Side::BOTH) init_player(crossvcs, Side::P1);
if(side == Side::P2 || side == Side::BOTH) init_player(crossvcs, Side::P2);
if((side & Side::P1) == Side::P1) init_player(crossvcs, Side::P1);
if((side & Side::P2) == Side::P2) init_player(crossvcs, Side::P2);
}

void init_player(bool crossvcs, Side player){
Expand Down Expand Up @@ -129,26 +130,25 @@ class LBDists {
while(Q.pop(cur)){
for(int i = 5; i <= 7; i++){
int nd = (cur.dir + i) % 6;
MoveDist next(cur.pos + neighbours[nd], cur.dist, nd);
MoveDist next(board->nb_begin(cur.pos)[nd], cur.dist, nd);

if(board->onboard(next.pos)){
int pos = board->xy(next.pos);
Side colour = board->get(pos);
Side colour = board->get(next.pos);

if(colour == otherplayer)
continue;

if(colour == Side::NONE){
if(!crossvcs && //forms a vc
board->get(cur.pos + neighbours[(nd - 1) % 6]) == otherplayer &&
board->get(cur.pos + neighbours[(nd + 1) % 6]) == otherplayer)
board->get(board->nb_begin(cur.pos)[(nd - 1) % 6]) == otherplayer &&
board->get(board->nb_begin(cur.pos)[(nd + 1) % 6]) == otherplayer)
continue;

next.dist++;
}

if( dist(edge, player, pos) > next.dist){
dist(edge, player, pos) = next.dist;
if( dist(edge, player, next.pos) > next.dist){
dist(edge, player, next.pos) = next.dist;
if(next.dist < board->get_size())
Q.push(next);
}
Expand All @@ -161,7 +161,7 @@ class LBDists {
Outcome outcome = Outcome::DRAW; // assume neither side can win
for(int y = 0; y < board->get_size_d(); y++){
for(int x = board->linestart(y); x < board->lineend(y); x++){
Move pos(x,y);
MoveValid pos(x, y, board->xy(x, y));

if(board->encirclable(pos, Side::P1) || get(pos, Side::P1) < maxdist-5)
outcome |= Outcome::P1; // P1 can win
Expand All @@ -175,8 +175,15 @@ class LBDists {
return -outcome; // this isn't certainty, so negate
}

int get(Move pos){ return std::min(get(pos, Side::P1), get(pos, Side::P2)); }
int get(Move pos, Side player){ return get(board->xy(pos), player); }
std::string get_s(Move pos, Side side) { // for use by Board::to_s
int dist = (side == Side::NONE ? get(pos) : get(pos, side));
return (dist < 10 ? to_str(dist) : ".");
}

int get(Move pos){ return get(MoveValid(pos, board->xy(pos))); }
int get(MoveValid pos){ return std::min(get(pos, Side::P1), get(pos, Side::P2)); }
int get(Move pos, Side player) { return get(board->xy(pos), player); }
int get(MoveValid pos, Side player) { return get(pos.xy, player); }
int get(int pos, Side player){
int list[6];
for(int i = 0; i < 6; i++)
Expand Down

0 comments on commit aa13d2c

Please sign in to comment.