Skip to content

Commit d8356d7

Browse files
author
Anthony Burzillo
committed
Handle handicapped games
1 parent f096dca commit d8356d7

File tree

4 files changed

+91
-32
lines changed

4 files changed

+91
-32
lines changed

reformat.hs

Lines changed: 49 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,33 @@ parens = Token.parens lexer
2020
brackets = Token.brackets lexer
2121
semi = Token.semi lexer
2222
semiSep = Token.semiSep lexer
23+
whiteSpace = Token.whiteSpace lexer
2324

2425
type Position = (Int, Int)
25-
type DataPoint = (String, String)
26-
type HeaderInfo = (Double, Double)
27-
data Game = Game Double Double [Position]
26+
type DataPoint = (String, [String])
27+
type HeaderInfo = (Double, Double, [Position])
28+
data Game = Game Double Double [Position] [Position]
29+
30+
skipParentheses :: Parser ()
31+
skipParentheses = do
32+
many $ noneOf ['(', ')']
33+
(char ')' *> return ())
34+
<|> (char '(' *> skipParentheses *> skipParentheses)
35+
<|> skipParentheses
2836

2937
dataPoint :: Parser DataPoint
3038
dataPoint = do
3139
dataType <- identifier
32-
argument <- brackets . many $ noneOf [']']
40+
argument <- many1 . brackets . many $ (try $ char '\\' *> char ']') <|> noneOf [']']
3341
return $ (dataType, argument)
3442

43+
dataPoints :: Parser [DataPoint]
44+
dataPoints = many $ (try $ (many $ char '(' *> skipParentheses *> whiteSpace) *> dataPoint)
45+
<|> dataPoint
46+
3547
convertMove :: String -> Position
3648
convertMove (x : y : _) = (ord x - 97, ord y - 97)
49+
convertMove _ = (19, 19)
3750

3851
validateMove :: Position -> Parser Position
3952
validateMove (x, y) = if (x, y) >= (0, 0) && (x, y) <= (19, 19)
@@ -42,47 +55,57 @@ validateMove (x, y) = if (x, y) >= (0, 0) && (x, y) <= (19, 19)
4255

4356
move :: Parser Position
4457
move = do
45-
dataPoints <- many dataPoint
46-
validateMove $ foldr find (0, 0) dataPoints
47-
where find (f, a) r = if f == "W"
48-
then convertMove a
58+
dps <- dataPoints
59+
validateMove $ foldr find (0, 0) dps
60+
where find (f, as) r = if f == "W"
61+
then case as of (a : _) -> convertMove a
4962
else if f == "B"
50-
then convertMove a
63+
then case as of (a : _) -> convertMove a
5164
else r
5265

53-
convertScore :: String -> Maybe Double
54-
convertScore (c : _ : s) = if c == 'B'
66+
readScore :: String -> Maybe Double
67+
readScore (c : _ : s) = if c == 'B'
5568
then readMaybe s >>= \x -> Just $ -1.0 * x
5669
else readMaybe s
5770

71+
readHandicapPositions :: [String] -> Parser [Position]
72+
readHandicapPositions as = mapM (validateMove . convertMove) as
73+
5874
header :: Parser HeaderInfo
5975
header = do
6076
dataPoints <- many dataPoint
61-
let r = foldr find (Nothing, Nothing) dataPoints
77+
let r = foldr find (Nothing, Nothing, Nothing) dataPoints
6278
case r of
63-
(Nothing, _) -> fail "Couldn't read komi"
64-
(_, Nothing) -> fail "No final score"
65-
(Just k, Just s) -> return (k, s)
66-
where find (f, a) (k, s) = if f == "KM"
67-
then (readMaybe a, s)
79+
(Nothing, _, _) -> fail "Couldn't read komi"
80+
(_, Nothing, _) -> fail "Couldn't read final score"
81+
(Just k, Just s, Nothing) -> return (k, s, [])
82+
(Just k, Just s, Just as) -> do
83+
hp <- readHandicapPositions as
84+
return (k, s, hp)
85+
where find (f, as) (k, s, hp) = if f == "KM"
86+
then case as of (a : _) -> (readMaybe a, s, hp)
6887
else if f == "RE"
69-
then (k, convertScore a)
70-
else (k, s)
71-
88+
then case as of (a : _) -> (k, readScore a, hp)
89+
else if f == "AB"
90+
then (k, s, Just as)
91+
else (k, s, hp)
92+
7293
game :: Parser Game
7394
game = parens $ semi *> do
74-
(komi, score) <- header
95+
(komi, score, handicapPositions) <- header
7596
semi
7697
moves <- semiSep move
77-
return $ Game komi score moves
98+
many $ char '(' *> skipParentheses *> whiteSpace
99+
return $ Game komi score handicapPositions moves
78100

79101
parseFile :: FilePath -> IO (Either ParseError Game)
80-
parseFile f = parseFromFile (game <* eof) f
102+
parseFile f = parseFromFile game f
81103

82104
instance Show Game where
83-
show (Game komi score moves) =
84-
let h = show komi ++ " " ++ show score
85-
in h ++ foldr runMoves "" moves
105+
show (Game komi score handicaps moves) =
106+
let h = show komi ++ " " ++ show score ++ " " ++ show (length handicaps)
107+
in let h' = h ++ foldr runMoves "" handicaps
108+
in h' ++ foldr runMoves "" moves
86109
where runMoves (x, y) r = "\n" ++ show x ++ " " ++ show y ++ r
87110

88111
main = do

src/game.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,12 @@ float Game::getFinalScore(void) const
3636
return finalScore;
3737
}
3838

39-
void Game::addMove(const BoardLocation location)
39+
void Game::addHandicap(const BoardLocation& location)
40+
{
41+
handicap.push_back(location);
42+
}
43+
44+
void Game::addMove(const BoardLocation& location)
4045
{
4146
moves.push_back(location);
4247
}
@@ -45,11 +50,25 @@ Board Game::playGame(void) const
4550
{
4651
Board board(size, komi);
4752

48-
std::vector<BoardLocation>::const_iterator itt = moves.begin();
49-
5053
int i = 1;
5154

52-
for( ; itt != moves.end(); ++itt)
55+
if(handicap.size() > 0)
56+
{
57+
std::vector<BoardLocation>::const_iterator handicapItt = handicap.begin();
58+
std::vector<BoardLocation>::const_iterator handicapEnd = handicap.end();
59+
60+
for( ; handicapItt != handicapEnd; ++handicapItt)
61+
{
62+
board.playMove(handicapItt->x, handicapItt->y, BLACK);
63+
}
64+
65+
++i;
66+
}
67+
68+
std::vector<BoardLocation>::const_iterator itt = moves.begin();
69+
std::vector<BoardLocation>::const_iterator end = moves.end();
70+
71+
for( ; itt != end; ++itt)
5372
{
5473
SpaceState state = i % 2 == 1 ? BLACK : WHITE;
5574

src/game.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class Game
1414
int size;
1515
float komi;
1616
float finalScore;
17+
std::vector<BoardLocation> handicap;
1718
std::vector<BoardLocation> moves;
1819
std::map<Block*, float*> featureMap;
1920
public:
@@ -24,7 +25,8 @@ class Game
2425
float getKomi(void) const;
2526
float getFinalScore(void) const;
2627

27-
void addMove(const BoardLocation location);
28+
void addHandicap(const BoardLocation& location);
29+
void addMove(const BoardLocation& location);
2830

2931
Board playGame(void) const;
3032

src/parser.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ bool parseFile(Game* game, const char *filename, const int size)
1313

1414
float komi;
1515
float finalScore;
16+
int handicapStones;
1617

17-
if(fscanf(file, "%f %f", &komi, &finalScore) == EOF)
18+
if(fscanf(file, "%f %f %i", &komi, &finalScore, &handicapStones) == EOF)
1819
{
1920
fclose(file);
2021

@@ -26,6 +27,20 @@ bool parseFile(Game* game, const char *filename, const int size)
2627
int x;
2728
int y;
2829

30+
for(int i = 0; i < handicapStones; ++i)
31+
{
32+
if(fscanf(file, "%i %i", &x, &y) == EOF)
33+
{
34+
fclose(file);
35+
36+
return false;
37+
}
38+
39+
BoardLocation location(x, y);
40+
41+
result.addHandicap(location);
42+
}
43+
2944
while(fscanf(file, "%i %i", &x, &y) != EOF)
3045
{
3146
BoardLocation location(x, y);

0 commit comments

Comments
 (0)