• No results found

Efficient Single State Agents for Computer Go

N/A
N/A
Protected

Academic year: 2022

Share "Efficient Single State Agents for Computer Go"

Copied!
26
0
0

Loading.... (view fulltext now)

Full text

(1)

Efficient Single State Agents for Computer Go

David Flemström

davidfl@kth.se

April 29, 2014

Abstract

When it comes to Computer Go agents, the most common strategy is to traverse the game state tree to find as close to optimal solutions as possible. The goal is to sacrifice performance for a higher result accuracy.

Going in the other direction — sacrificing accuracy for performance — is a less explored approach to the problem.

In this report, a method combining the Copy-Move algorithm from the field of image forensics and computer vision with some pattern-based Computer Go digestion methods is tested against a large database of Go games. The partial soundness and fitness of the strategy is evaluated against a distinct subset of games by evaluating the predictability of human moves.

The result is that while pattern-based Go strategies are still clearly inferior to game-tree search algorithms, they sometimes yield promising results that can be used to adjust the pruning approaches typically employed in tree traversal algo- rithms.

(2)

Contents

1 Introduction 4

1.1 The game . . . 4

1.2 Previous work . . . 4

1.3 Problem . . . 5

2 Background 6 2.1 The Copy-Move algorithm . . . 6

2.1.1 General idea . . . 6

2.1.2 Source data . . . 7

2.1.3 Scalar classification . . . 7

2.1.4 Digestion . . . 7

2.1.5 Fingerprinting . . . 8

2.1.6 Clustering . . . 8

2.2 Efficient ordered observation storage . . . 8

3 Method 9 3.1 Source data . . . 9

3.1.1 Win conditions . . . 9

3.1.2 Ratings . . . 10

3.2 Normalization . . . 10

3.3 Fingerprinting . . . 11

3.4 Platform . . . 12

3.5 Technical implementation strategy . . . 12

3.6 SGF format . . . 13

3.7 Tree interpreter . . . 13

3.8 Scoring . . . 13

3.9 Vision index storage . . . 14

3.10 Querying vision index . . . 14

4 Result 15 4.1 Partial database ingestion . . . 15

4.2 Prediction speed . . . 15

4.3 Database integrity . . . 15

4.4 Prediction fitness . . . 15

(3)

5 Discussion 17

5.1 Difficulty of treating Go as a single-state game . . . 17

5.2 Hardware is still the bottleneck . . . 17

5.3 Optimization . . . 17

5.4 Hybrid algorithms . . . 17

A Source code 20 A.1 Normalized Fingerprinter . . . 20

A.2 SGF Parser . . . 20

A.3 SGF Tree Interpreter . . . 22

A.4 Index Storage . . . 24

A.5 Database ingestion system . . . 25

(4)

1 Introduction

Deep Blue’s victory over Kasparov in 1996 is both recognized as an important event in the history of computer science, and a turning point within the realm of artificial intelligence research. Shifting focus to games in general, the science community has recognized that there are interesting classes of problems within game theory beyond alpha-beta pruning search or similar methods, which were previously seen as one of the only approaches to game tree-based actor strategies.

In particular, the game of G has evoked significant interest in recent times[11].

Being not only a popular board game world-wide, but also one of the typical games that cannot be approached with a naive tree search strategy, G has lain the founda- tion for numerous research topics revolving around new approaches to game agent strategies.

1.1 The game

The game of G is played on a board consisting of a grid of lines, typically with19×19 intersections. Two players take turns placing respectively black and white stones onto the board, and simple rules govern when a move is legal or not, and whether a certain move will remove stones from the board. When both players agree that no more stones can be placed onto the board, the player with the greatest number of stones wins.

Because of the simplicity of the game, it is perhaps surprising that it should be the cause of such complexity in the realm of artificial intelligence, but the simplicity is also the source of its complexity.

1.2 Previous work

Some of the common approaches include using Monte-Carlo tree searching[6], using upper confidence trees[9, 13, 15], balancing simulations[10], parallel search[7], non- linear optimization and active learning[1], parallels to other games[14] or different heuristics[5].

Common to all of these approaches is that they generally boil down to performing searches on the game state tree. This idea seems to yield promising results, yet at the expense of the tremendous amount of computing power required for computing the traversed tree.

In general, research on game playing agents for computer G has typically revolved around finding optimal strategies for winning the game, in search of a generalized

“ideal strategy” that would beat any other agent. The purpose of such research is to fully understand the game and its complexities; as such, to gain insight into the mathematical structure behind the game. Beneficial side effects have also included advances in parallel and distributed computing to allow for the necessary and expen- sive computations to take place.

Despite the effort that has been invested into finding new strategies for G, it still remains a game where a human can typically beat a computer consistently no matter

(5)

what method is used by the agent. This is especially interesting considering the fact that the computer often has an order of magnitude more time and multiple orders of magnitude more resources (in terms of energy) at its disposal.

1.3 Problem

The realm of game tree searching algorithms is a well-explored topic at this point, and while there still are significant advances to be made in the field, there are other approaches which yet remain less explored.

Especially interesting is considering in more detail how humans perform compared to computers when playing Go. Experience suggests that humans will typically still beat computers even when both agents are under extreme time restrictions. The reason why this would be the case is not immediately obvious; limiting the available time does also in turn limit the strategical options available to either party to more trivial ones, which would theoretically bring both parties on an even footing. Is this really the case?

In particular, an investigation of how agents with extreme or even real-time per- formance requirements would perform compared to games played by human actors would yield insight into how similar the approaches taken by either party really are.

It would be desirable to investigate whether a reasonable strategy for predicting G

moves can be found simply by analyzing a single game state, but constructing that strategy solely based on associations that can be derived from that game state. The agent is allowed to possess a significant amount of pre-computed “experience,” but may not traverse a game state tree, try out an exhaustive set of options, or otherwise do expensive calculations. The agent must also “make a move” within a very limited time frame; on commodity hardware amounting to a few milliseconds.

(6)

2 Background

The initial approach taken in this report is to employ algorithms from image forensics and computer vision in order to classify, index and predict G game states.

2.1 The Copy-Move algorithm

Contrary to intuition, game state analysis shows some clear parallels to image foren- sics and computer vision data mining. In particular, the “Copy-Move” algorithm[2]

is proven to be useful when detecting patterns and links between structured data.

The purpose of the algorithm is to find common patterns within a large space of data points, where the data points are arranged in a finite set of matrices. The al- gorithm identifies partial segments in the matrices and the closeness and centrality between them. Thus a graph is built that represents the distance between subsets of data points, and implicitly the distance between the matrices. It uses a very general method that is widely applicable.

This particular algorithm was chosen for its characteristics of requiring a great deal of up-front computation, but allowing conclusions to be drawn about the data set in a very efficient way.

In this section, the parallels between the subjects of image forensics and game state analysis related to the “Copy-Move” algorithm will be explored. The trade-offs that were considered for the analysis in this article are outlined as well. The algorithm itself can be decomposed into multiple independent steps, which is reflected by the sectioning below.

2.1.1 General idea

The goal of “Copy-Move” is to identify patterns/similarities between a large set of N-ary matrices. The general strategy is roughly as follows:

1. Identify the source data that is to be employed. In other words: How can the data be seen as a matrix?

2. Transform the data in such a way that data points are classified as scalars. In other words: How can each cell in each matrix be assigned a number?

3. Digest the scalar representation to highlight the trait that is assumed to dis- play the pattern that is being identified. In other words: How can each cell be represented such that one can measure the amplitude of something that might exhibit a pattern?

4. Fingerprint the digested data so that cells are contextualized and can be lexico- graphically ordered. In other words: How can each cell’s digest be ordered in such a way that similar patterns are close to each other?

5. Cluster fingerprints, such that when a particular set of fingerprints are selected, they can be grouped in such a way that each group points to one or many of

(7)

the source matrices that were used to construct those fingerprints. In other words: Given some fingerprints, is there a way to determine whether a signifi- cant group of fingerprints exhibit the same pattern?

6. Efficiently store fingerprints, so that ordered look-ups of fingerprints is efficient.

In other words: Given one fingerprint, how is it possible to quickly find similar fingerprints?

2.1.2 Source data

The “Copy-Move” algorithm acts on any data that is structured in an N-ary matrix.

In particular, it is heavily explored as a tool for analyzing 2D matrices. The data must be formulated as a set of (sparse or dense) N-ary matrices. The matrices need not be the same size.

Typically, in the case of image forensics, an image consists of a 2D matrix of “pixels,”

and typically each image has only one such associated matrix. Thus each matrix can be grouped by the image that it belongs to.

In the case of G, each G game consists of a number of game states, representing the contents of the board after each move made by a player during the game. A game state is a matrix consisting of positions, each position being one of19× 19intersections on the board. Each position can either be occupied by a white, black, or no stone.

2.1.3 Scalar classification

Each datum in the matrix needs to be classified by a scalar, or some other attribute that produces an ordinal mapping for the particular datum. This is to allow one to absolutely order samples from the matrix.

Typically, in the case of images, one would convert the image to gray-scale in order to map each pixel in the image to a scalar.

In the case of G, some form of normalizing operator is needed to classify each board position with a scalar, since the game’s semantics do not yield an inherent ordinal for board positions. There are many ways of doing this, depending on the required information. The particular methods that were explored for this analysis are outlined further below.

2.1.4 Digestion

If the data that is analyzed exhibits a high variance or noise ratio, it may be necessary to digest the data using some well-known digestion algorithm, that brings the data into a representation that eliminates the noise and brings forward some characteristic to be analyzed.

For image data, usually a discrete cosine transform (DCT) is employed. Such a trans- form is useful because the parameters in the resulting tensor are structured in such a way that top/left-most cells describe the “coarse” structure of the initial data set, while the remaining cells describe “finer” details of the data set. This allows DCTs to

(8)

be ordered in such a way that coarse data differences dominate the ordering. A slid- ing window of a fixed size is used to fold the matrix into a four-dimensional tensor, mapping each former pixel to a DCT matrix.

An alternative to DCT is to use (fast) Fourier transforms. The disadvantage of using this method is that the resulting continuous histogram has no absolute ordering, and needs to be sampled to determine some canonical digestion.

The simplest digestion method is the identity digestion, which leaves the source ma- trix unchanged. Depending on the level of detail exhibited by the source data, this might be sufficient to allow one to draw some conclusions about the data. This is especially useful if the values in the source matrix are discrete, since such data does not lend itself well to being transformed by DCT or FFT.

2.1.5 Fingerprinting

The matrices are fingerprinted, meaning that every cell in the matrix is classified by its context in the matrix.

The simplest fingerprint is to classify each cell as itself. This yields results where the distance between matrices effectively is the magnitude of the vector between the his- tograms of the matrices.

For a DCT, it can simply be unwound from most significant cell to least significant cell. For other kinds of data, different fingerprinting methods can be used. One such alternative is to sample cells in a specific order. The fingerprints need to be strictly ordered, typically lexicographically.

2.1.6 Clustering

Ordering the fingerprints of the classified objects yields a strict distance estimation between the objects. They can then be clustered according to some criterium.

2.2 Efficient ordered observation storage

Storing a large amount of ordered data is not trivial, especially when the number of data points is in the billions.

By using an approach where storage is “sharded” on a granular level and strictly or- dered on a lower level yields predictable behavior. Fingerprints can be sorted into rough groups by using a prefix of their descriptors as a sharding hint. When query- ing the set, only fingerprints in the same sharding group need to be compared. With a sufficiently large set of fingerprints, it does not matter that the fingerprints are only ordered within each shard, since it is very likely that an arbitrarily chosen fingerprint will be in the middle of a shard rather than close to the edge of one.

This is already a solved problem, and a widely used solution such as Apache Cassandra is suitable for the storage model.

(9)

3 Method

The general approach to solving this problem can be summarized as follows:

1. A large database of Go games is acquired and curated.

2. The database is ingested and normalized to a context-free representation.

3. Each game state where an agent makes a move is characterized and a “finger- print” is computed that describes each board position.

4. The fingerprints are stored in a distributed data store.

5. The above process is massively parallellized using map-reduce concepts to build a knowledge index faster.

6. A query engine is constructed that evaluates a user-provided game state and uses computer vision to find the suggested next move.

3.1 Source data

In order to do any analysis of Go games, a large database of games needs to be ac- quired. In particular, games that have very constrained move times are ideal for this purpose. For this evaluation, the online service called “The KGS Go Server” seems to be the most suitable, because the games are typically short, with players from all skill levels, and the database is vast.

All games between 2001 and 2013 are used for this purpose, totaling 157284 games.

Of these, 67809 were won by black and 87457 were won by white, 6 games were invalid and 2 were draws.

3.1.1 Win conditions

Where games were decided, 89249 games were won by resignation, 28133 by time limits, 110 by one player forfeiting the game, and the rest by finishing the game until no more moves were possible.

Win condition Black White

Forfeit 18 92

Resign 39736 49513

Time 10422 17711

Score 17633 20141

The finishing scores were between0.50and8194.00, with the median being9.00, the mean being13.93, the first quartile being4.50and the third quartile being16.50. The standard deviation of the set of scores is104.3111.

(10)

3.1.2 Ratings

Players are generally highly rated. This minimizes the problem that new players win by the opponent making mistakes and not by skill. Players are counted once per game participated in, so this count is not for distinct players. The “d” stands for “dan”

(lit. Japanese: degree) and players are ranked from 1d (lowest advanced amateur rank) to 9d (highest advanced amateur rank). Traditionally, the “dan” ranking system only exhibits 8 levels, but a 9th level was used in this particular database, for reasons unknown.

Rating Number of players

9d 16524

8d 37639

7d 104982

6d 101221

5d 19279

4d 11673

Below 18409

3.2 Normalization

An algorithm that digests a game state into a desirable lesser description more suit- able for quick look-up has been designed. A pattern-based recognition algorithm has been constructed based on previous work in similar areas[12, 3], simplified to accommodate the approach of this article.

Each analyzed game consists of a set of states. A state consists of the current placed stones on the board along with their positions, and the position where the next player will place a stone.

During normalization, each position in a state is first classified according to some criteria. The criteria are listed below along with a set of states each criterium may use to classify a position.

1. The color that already occupies a position.

(Black, White, n/a)

2. The colors that can legally put a stone at a position without violating any of the NoGo rules, which means any position that does not lead to the suicide/cap- ture of one of the player’s groups[12].

This is determined by doing a simple BFS flood fill of the area around the po- sition. The rules of NoGo further state that Ko has to be respected as well, meaning that no previously seen game state may be repeated in any particular game, but since these game states originate from real games that were verified by a computer, the rule of Ko is never violated.

This criterium is of limited usefulness, since NoGo is semantically different from Go, and not just a reduced problem.

(Black, White, Black + White, n/a)

(11)

3. The territory that the unclaimed position belongs to. The territory of a posi- tion is determined by the color of the stone that is closest to the position. If there is a tie, the position will not belong to any territory.

(Black, White, n/a)[3].

4. The morphological group that the position belongs to.

LetB be all of the black positions on the board, andW be all of the white positions. The morphological groups of these sets are simplyX(B)andX(W ), the connected sets of the groups. “Outsideness” is determined by whether both nodes for an edge in a morphological group have the same color[12].

(Outside Black, Inside Black, Outside White, Inside White, n/a)

The necessity of all of these classifiers diminishes with the size of the fingerprint database. Indeed; with a database of a significant size, only classifier 1 is needed to get good results for queries.

In the most detailed case, each classifier having 3, 4, 3 and 5 possible states, respec- tively, it means that each position is mapped to one of 180 possible states. This is too much entropy for the “Copy-Move” algorithm, and without a DCT transform (which is impractical for discrete data as described above) or some similar digestion method, the data becomes too noisy to use. It is therefore more practical to use only a few of these classifiers at a time.

The game state is further transformed such that the colors of stones are separated into

“Ours” and “Theirs,” the former being the stones of the player who has the next move.

One final normalization step replicates the game state four times, each time rotating the game state by 90 degrees. Since G does not define semantics for orientation, any game state is isomorphic with its four rotations. Each game does thus map to 4 normalized states.

3.3 Fingerprinting

For a particular normalized game stateN, there is one fingerprint per position inN. Typically, this yields19× 19fingerprints per game state.

Each fingerprint is calculated with a very simple process. The process has to be simple in order to be performant, since this classification process represents the bottleneck of the analysis process.

For each position, a number of relative positions are “tapped” (meaning that the clas- sifier value — one of the up to 180 values as outlined above — is read for the cell at that relative position) in a certain order. This order is defined as:

taps=[(0, 0), (−1, 0), (0, −1), (1, 0), (0, 1), (−1, 1), (−2, 0), (−1, −1), (0, −2), (1,−1), (2, 0), (1, 1), (0, 2), (−1, 2), (−2, 1), (−3, 0), (−2, −1), (−1, −2), (0,−3), (1, −2), (2, −1), (3, 0), (2, 1), (1, 2), (0, 3), (−1, 3), (−2, 2)]

(1)

(12)

When drawn with pen and paper on an euclidean coordinate system, it becomes clear that this sequence of taps forms an arbitrary spiral of positions. The order of the taps is not significant, as long as the magnitudes of the coordinates are in semi-increasing order. The extra noise introduced by the arbitrary ordering (since the spiral is not a Fibonacci spiral or some similarly strictly growing spiral) helps improve query results by blurring the significance of each new element in the spiral.

For an example of how this strategy works, see listing A.1. For the sake of brevity, this only shows the most trivial fingerprinting strategy, where the classifiers being read adhere to classification rule (1) above.

3.4 Platform

The program code for the indexing system is written in Haskell. The declarative na- ture of this language makes creating massively parallel programs very easy. For opti- mal performance, a more low-level language could have been used, but seeing as this program will be IO-bound, it is not an important decision to make.

For search index storage, Apache Cassandra was used. This database engine supports massively parallel indexing and distributed storage. It is also optimal for doing fin- gerprint range queries.

The version of GHC is 7.6.3, and the version of Cassandra is 2.0.6.

3.5 Technical implementation strategy

There are a total of 157284 games in the database that is used to build the learning model. In these games, a total of 14253463 moves were made, which means that there are 14253463 game states to analyze. Each state contains 361 fingerprinted positions, which yields in total 5145500143 fingerprints to be built. Each fingerprint is also computed for 4 different orientations, and for two different players, but these scenarios play a lesser role, even though they impact the number of data points by another order of magnitude.

This is a hopelessly large number, and even if the program could run on very many computers with a significant amount of processing power, it would still take a very long time to process all of the game states.

Therefore, an adaptive model is used to incrementally improve the intelligence of the system. The system is functional with partial indexes of games, and indexing can occur at the same time as queries.

To build the vision database, a cluster of indexing nodes is used, each with a set of games to analyze. The Map-Reduce model[8] is used for indexing. Each node parses a game, breaks it down into game states (map), normalizes states and picks the ones that are deemed suitable for ingestion because they were part of a won game and did not violate any of the rule constraints (reduce). The node will then compute the fingerprints for a game state and order them (map) and store them in the fingerprint cluster for querying (reduce).

A single-process implementation of this can be seen in the simple database building system in listing A.5.

(13)

3.6 SGF format

The game database is in the SGF format. A combinator/coroutine-based parser as in listing A.2 for this format is used to stream partial game trees to the rest of the analyser pipeline. To maintain performance, the parser is suspendable and can yield partial results in real-time.

Typically, an SGF database is used to describe a set of game trees. The database of G games used in this case however does not describe game trees. Instead, each SGF file describes a single game, and there is one tree per game in the database.

Some simplifications have been made taking this into consideration. While the parser conforms to the BNF description of SGF[4], it is assumed that each node in the SGF tree will have only one child.

3.7 Tree interpreter

SGF game trees produced by the parser are interpreted so as to get a set of game states describing the game at hand, as can be seen in listing A.3. This is done by simulating a game board and performing the moves described in the game tree.

Metadata is also extracted during this process. Different metadata is used when scor- ing search results while doing queries.

3.8 Scoring

Each game state is assigned a score. This is done for the purpose of ordering clustered groups after “Copy-Move” clusters of game states have been identified. The scoring method works like this:

1. If the game ended in a draw, was aborted, was illegal or had an unknown out- come, all game states in the game get a score of 0.

2. If a winner could be determined, all of the game states where the winner made a move are awarded a positive score, and all of the game states where the loser made a move are awarded a negative score. The absolute value of the score is determined by:

Resignation The score value is 10, which is close to the mean score by exhaus- tion.

Time-out The score value is 5, which is half of the mean score by exhaustion.

Forfeit The score value is 2, with low impact.

Exhaustive game The score value is whatever score the remaining stones on the board dictated.

(14)

3.9 Vision index storage

The fingerprints are stored in a lexicographical ordering in a Cassandra database, us- ing the code in listing A.4. The storage is very straight-forward, but the data model and semantics are non-trivial. The data model being used can be described using the following Cassandra Thrift statements:

c r e a t e k e y s p a c e g o

w i t h p l a c e m e n t s t r a t e g y =

’ o r g . a p a c h e . c a s s a n d r a . l o c a t o r . S i m p l e S t r a t e g y ’ and s t r a t e g y o p t i o n s = {r e p l i c a t i o n f a c t o r : 1}; c r e a t e col umn f a m i l y g o

w i t h c o m p a r a t o r = UTF8Type

and k e y v a l i d a t i o n c l a s s =UTF8Type

and d e f a u l t v a l i d a t i o n c l a s s = B y t e s T y p e ;

A fingerprint is converted into a series of human-readable characters. The first two characters determine the shard that the fingerprint will be stored in. The whole fin- gerprint is stored in that shard in lexicographical order. Along with the fingerprint is some metadata describing whence the fingerprint came and what score it was as- signed.

3.10 Querying vision index

A query into the vision index is a game state. The objective of the query is to predict what the next game move of that state will be.

The query process follows similar steps as the ingestion process, and the relevant de- scription for each step can be seen above.

1. The game state is digested into fingerprints.

2. One query is made into the vision index for each fingerprint.

3. A range of similar fingerprints, which are thenfingerprints around the queried fingerprints, are selected. This yields19× 19 × nfingerprints.

4. Fingerprints are grouped by source game ID and implicitly by spatial proximity and scored by adding their game state scores.

5. The cluster of fingerprints with the highest collective score corresponds to a game state where the wanted move was performed. The other clusters are or- dered by decreasing compound score.

6. The relative location of the move compared to the cluster is computed.

7. The moves are reported in score order to the user.

(15)

4 Result

The database that was outlined above is partially ingested into a vision index. Queries have successfully been made against the index. It was possible to make significant observations on the data using these queries.

4.1 Partial database ingestion

It is important to note that it was not possible to ingest the entire game database into an index, due to time and hardware constraints. Out of the roughly 10–20 billion fingerprints that could theoretically be built from the database, only about 40 million were ingested. This means that the index only knew of about0.2% of the potential scenarios it could have known about.

4.2 Prediction speed

The index responds to lookups within an average of 15.09 microseconds on the same machine, and since19×19 = 361lookups are required to predict a move, about 5.41 milliseconds are needed for each prediction.

These statistics were taken from Cassandra’s internal metrics, using 40630902 read samples.

4.3 Database integrity

When querying for a state from a game that had been ingested verbatim into the search index, the result was exactly the next state from that game, or, if the state was from an early move, exact copies of that state from higher ranked games, in 19638 out of 20000 test cases. In the other states, a move was chosen which was clearly illegal. The error can probably be attributed to sometimes overwriting fingerprints in a race condition. During ingestion, no care was taken to prevent overwrites (such as requesting quorum consistency from Cassandra), and this leads to the eventual integrity of the index sometimes erasing fingerprints, overwriting a “highly scored”

fingerprint with a “lower scored” one.

4.4 Prediction fitness

When querying for game states from games that had not previously been indexed in the database, there is only one metric which can be tracked: Whether the predicted move corresponds to what the player did next in the actual game. Other fitness in- dicators seem to be too unreliable to be practical. This one metric was correlated to which generation the game state was sampled from.

A total of 20000 games were investigated. From these, the first 10 generations were queried.

(16)

Generation Prediction rate

1 5.26%

2 8.72%

3 12.93%

4 9.05%

5 3.43%

6 1.88%

7 0.60%

8 0.96%

9 0.34%

10 0.31%

This result is to be expected. The numbers have the following potential explanations:

1. The first move can hardly ever be predicted, as querying for the empty game state yielded the same hit every time (And every Go game does usually not start with the same move). The surprisingly high number of successful predictions can still be explained by the fact that many games in the database started with

“pre-placed” stones for a handicap (for example 5 black stones in a pattern), and the moves made in relation to those stones seemed to be predictable.

2. The following few moves are usually part of standard openings, so the high prediction rate reflects that. Even then, there are multiple variations so that the prediction was incorrect much of the time.

3. The remaining moves (6 and beyond) are generally unpredictable. The num- bers are still higher compared to random selection, which would yield a 0.2%

success rate.

One has to keep in mind that this metric is very unreliable, as the suggested move is compared to what an user actually did. The computer might have chosen a better move than the player; this metric does not reflect that.

(17)

5 Discussion

The method employed in this analysis had some known flaws from the start. How- ever, additional insights could also be inferred from the outcome of the experiment.

5.1 Difficulty of treating Go as a single-state game

Judging by the diminishing prediction fitness numbers as presented in the results section, a strategy which looks at a single game state in Go is not going to be successful against a strategy which does an in-depth game tree traversal.

This was something which was known from the start, but quantifying the success rate of the method gave some insight into exactly how unreliable it truly was.

5.2 Hardware is still the bottleneck

It was not practical to compute all of the fingerprints in the game database. Given that only about 0.2% of the database was ingested, it was surprising that the results were as positive as they turned out to be. With more nodes and more hardware, the predictions might have become significantly better.

5.3 Optimization

The approach offered here is a naive attempt, both in theory and in practice. The method is by no means fully refined or optimal in any way. Perhaps it will be possible to one day refine the method so that fingerprints can be coalesced, and predictions can take small game state trees into consideration.

5.4 Hybrid algorithms

Combining pattern search methods and game tree search methods might also yield interesting results. This approach of using computer vision to find interesting move candidates would in some sense replace some of the pruning models used in tree search algorithms.

(18)

References

[1] Anne Auger and Olivier Teytaud. Continuous lunches are free plus the design of optimal optimization algorithms. Algorithmica, 57(1):121–146, 2010.

[2] S. Bayram, H.T. Sencar, and N. Memon. An efficient and robust method for detecting copy-move forgery. In Acoustics, Speech and Signal Processing, 2009. ICASSP 2009. IEEE International Conference on, pages 1053–1056, April 2009.

[3] Bruno Bouzy and Tristan Cazenave. Computer Go: An AI oriented survey.

Artificial Intelligence, 132(1):39 – 103, 2001.

[4] Richard Cant, Julian Churchill, and David Al-dabass. Using hard and soft ar- tificial intelligence algorithms to simulate human Go playing techniques.

[5] Tristan Cazenave. A phantom-Go program. In H.Jaap Herik, Shun-Chin Hsu, Tsan-sheng Hsu, and H.H.L.M.( Jeroen) Donkers, editors, Advances in Com- puter Games, volume 4250 of Lecture Notes in Computer Science, pages 120–125.

Springer Berlin Heidelberg, 2006.

[6] G.M.J.B. Chaslot, H.J. van den Herik, B. Bouzy, M.H.M. Winands, and J.W.H.M. Uiterwijk. Progressive strategies for Monte-Carlo tree search, chap- ter 93, pages 655–661.

[7] GuillaumeM.J.-B. Chaslot, MarkH.M. Winands, and H.Jaap Herik. Paral- lel monte-carlo tree search. In H.Jaap Herik, Xinhe Xu, Zongmin Ma, and MarkH.M. Winands, editors, Computers and Games, volume 5131 of Lecture Notes in Computer Science, pages 60–71. Springer Berlin Heidelberg, 2008.

[8] Jeffrey Dean and Sanjay Ghemawat. Mapreduce: A flexible data processing tool. Commun. ACM, 53(1):72–77, January 2010.

[9] Sylvain Gelly and David Silver. Combining online and offline knowledge in UCT. In Proceedings of the 24th International Conference on Machine Learning, ICML ’07, pages 273–280, New York, NY, USA, 2007. ACM.

[10] Shih-Chieh Huang, Rémi Coulom, and Shun-Shii Lin. Monte-carlo simula- tion balancing in practice. In H.Jaap Herik, Hiroyuki Iida, and Aske Plaat, ed- itors, Computers and Games, volume 6515 of Lecture Notes in Computer Science, pages 81–92. Springer Berlin Heidelberg, 2011.

[11] C.-S. Lee, M. Müller, and O. Teytaud. Special issue on monte carlo techniques and computer Go. IEEE Transactions on Computational Intelligence and AI in Games, 2(4):225–228, 2010. cited By (since 1996)12.

[12] Chang-Shing Lee, Mei-Hui Wang, Yu-Jen Chen, Hani Hagras, Meng-Jhen Wu, and Olivier Teytaud. Genetic fuzzy markup language for game of nogo.

Knowledge-Based Systems, 34(0):64 – 80, 2012. A Special Issue on Artificial Intelligence in Computer Games: AICG.

[13] Shiven Sharma, Ziad Kobti, and Scott Goodwin. Knowledge generation for improving simulations in UCT for general game playing. In Wayne Wobcke

(19)

and Mengjie Zhang, editors, AI 2008: Advances in Artificial Intelligence, vol- ume 5360 of Lecture Notes in Computer Science, pages 49–55. Springer Berlin Heidelberg, 2008.

[14] István Szita, Guillaume Chaslot, and Pieter Spronck. Monte-carlo tree search in settlers of catan. In H.Jaap Herik and Pieter Spronck, editors, Advances in Computer Games, volume 6048 of Lecture Notes in Computer Science, pages 21–

32. Springer Berlin Heidelberg, 2010.

[15] Fabien Teytaud and Olivier Teytaud. Creating an upper-confidence-tree pro- gram for Havannah. In H.Jaap Herik and Pieter Spronck, editors, Advances in Computer Games, volume 6048 of Lecture Notes in Computer Science, pages 65–74. Springer Berlin Heidelberg, 2010.

(20)

A Source code

Here are some listings of essential parts of the source code for this project. Non- essential source code has been omitted to save space and paper.

A.1 Normalized Fingerprinter

module AI . Go . F i n g e r p r i n t . N o r m a l i z e d w h e r e i m p o r t AI . Go . F i n g e r p r i n t

i m p o r t AI . Go . N o r m a l i z e d i m p o r t C o n t r o l . D e e p S e q

i m p o r t C o n t r o l . Monad ( f o r e v e r , forM , when ) i m p o r t D a t a . M a t r i x

i m p o r t P i p e s

n o r m a l i z e d F i n g e r p r i n t : : Monad m

=> P i p e ( N o r m S t a t e N o r m P o s i t i o n ) F i n g e r p r i n t m ( ) n o r m a l i z e d F i n g e r p r i n t = f o r e v e r $ do

s t a t e < a w a i t

l e t b o a r d = n s B o a r d $ s t a t e

( ( l x , l y ) , ( hx , hy ) ) = ( ( 1 , 1 ) , ( n c o l s b o a r d , n r o w s b o a r d ) ) when ( n s N e x t T u r n s t a t e == S e l f ) $

f o r M [ ( x , y ) | x < [ l x . . hx ] , y < [ l y . . hy ] ] $ \ ( x , y ) −> do l e t p o s i t i o n s = f l i p map t a p s $ \ ( dx , dy ) −>

i f x + dx <= hx && x + dx >= l x &&

y + dy <= hy && y + dy >= l y

t h e n c a s e n s B o a r d s t a t e ! ( x + dx , y + dy ) o f C u r r e n t c −> S t o n e c

−> Empty e l s e O u t s i d e

y i e l d $ p o s i t i o n s ‘ d e e p s e q ‘ F i n g e r p r i n t ( F i n g e r p r i n t M e t a d a t a ( n s G a m e I d s t a t e )

x y ( n s S c o r e s t a t e ) ) p o s i t i o n s w h e r e

t a p s = [ ( 0 , 0 ) , (1 , 0 ) , ( 0 ,1 ) , ( 1 , 0 ) , ( 0 , 1 ) , (1 , 1 ) , (2 , 0 ) , (1 ,1 ) , ( 0 ,2 ) , ( 1 ,1 ) , ( 2 , 0 ) , ( 1 , 1 ) , ( 0 , 2 ) , (1 , 2 ) , (2 , 1 ) , (3 , 0 ) , (2 ,1 ) , (1 ,2) , ( 0 ,3 ) , ( 1 ,2 ) , ( 2 ,1 ) , ( 3 , 0 ) , ( 2 , 1 ) , ( 1 , 2 ) , ( 0 , 3 ) , (1 , 3 ) , (2 , 2 )

]

A.2 SGF Parser

(21)

{−# LANGUAGE O v e r l o a d e d S t r i n g s #−}

module AI . Go . SGF . P a r s e r w h e r e

i m p o r t P r e l u d e h i d i n g ( s e q u e n c e , t a k e W h i l e ) i m p o r t AI . Go . SGF h i d i n g ( s e q u e n c e )

i m p o r t C o n t r o l . A p p l i c a t i v e ( p u r e , (∗ >) , (<) , (<∗ >)) i m p o r t D a t a . A t t o p a r s e c . T e x t

i m p o r t q u a l i f i e d D a t a . HashMap . L a z y a s HashMap ( f r o m L i s t ) i m p o r t D a t a . F u n c t o r ((< $ >) )

i m p o r t D a t a . T e x t ( T e x t ) s g f S i n g l e F i l e : : P a r s e r SGF

s g f S i n g l e F i l e = s k i p S p a c e ∗> s g f S i n g l e < s k i p S p a c e s g f S i n g l e : : P a r s e r SGF

s g f S i n g l e = SGF . p u r e <$> g a m e T r e e s g f F i l e : : P a r s e r SGF

s g f F i l e = s k i p S p a c e ∗> s g f < s k i p S p a c e s g f : : P a r s e r SGF

s g f = SGF <$> g a m e T r e e ‘ s e p B y 1 ‘ s k i p S p a c e g a m e T r e e : : P a r s e r GameTree

g a m e T r e e = GameTree

<$> ( c h a r ’ ( ’ ∗> s k i p S p a c e ∗> s e q u e n c e < s k i p S p a c e )

<∗> ( ( g a m e T r e e ‘ s e p B y ‘ s k i p S p a c e ) < s k i p S p a c e < c h a r ’ ) ’ ) s e q u e n c e : : P a r s e r S e q u e n c e

s e q u e n c e = S e q u e n c e <$> n o d e ‘ s e p B y 1 ‘ s k i p S p a c e n o d e : : P a r s e r Node

n o d e =

Node . HashMap . f r o m L i s t

<$> ( c h a r ’ ; ’ ∗> s k i p S p a c e ∗> p r o p e r t y ‘ s e p B y 1 ‘ s k i p S p a c e ) p r o p e r t y : : P a r s e r ( Text , [ T e x t ] )

p r o p e r t y = ( , )

<$> p r o p I d e n t < s k i p S p a c e

<∗> p r o p V a l u e ‘ s e p B y 1 ‘ s k i p S p a c e p r o p I d e n t : : P a r s e r T e x t

p r o p I d e n t = t a k e W h i l e 1 $ i n C l a s s ” azAZ ” p r o p V a l u e : : P a r s e r T e x t

(22)

p r o p V a l u e = c h a r ’ [ ’ ∗> t a k e W h i l e ( / = ’ ] ’ ) < c h a r ’ ] ’

A.3 SGF Tree Interpreter

{−# LANGUAGE O v e r l o a d e d S t r i n g s #−}

{−# LANGUAGE R a n k N T y p e s #−}

module AI . Go . Game . SGF w h e r e i m p o r t P r e l u d e h i d i n g ( s e q u e n c e ) i m p o r t AI . Go . Game

i m p o r t AI . Go . SGF i m p o r t C o n t r o l . L e n s

i m p o r t C o n t r o l . Monad h i d i n g ( s e q u e n c e ) i m p o r t C o n t r o l . Monad . T r a n s . S t a t e . S t r i c t i m p o r t D a t a . M a t r i x

i m p o r t D a t a . Char ( o r d ) i m p o r t D a t a . D e f a u l t ( d e f ) i m p o r t D a t a . F u n c t o r ((< $ >) ) i m p o r t D a t a . T e x t ( T e x t )

i m p o r t q u a l i f i e d D a t a . T e x t a s T e x t i m p o r t P i p e s h i d i n g ( e a c h )

t y p e G a m e B u i l d e r m = S t a t e T Game m sgfToGame : : ( F u n c t o r m, Monad m)

=> P i p e SGF Game m ( )

sgfToGame = v o i d . f l i p e x e c S t a t e T 0 . f o r e v e r $ do s g f < l i f t a w a i t

c o n v e r t S G F s g f

c o n v e r t S G F : : ( F u n c t o r m, Monad m)

=> SGF −> S t a t e T I n t e g e r ( P r o x y x ’ x ( ) Game m) ( ) c o n v e r t S G F s g f = forMOf ( t r e e s . e a c h ) s g f $ \ t r e e −> do

g < g e t m o d i f y ( + 1 )

game < e x e c S t a t e T ( b u i l d F r o m T r e e g t r e e ) d e f l i f t $ y i e l d game

b u i l d F r o m T r e e : : ( F u n c t o r m, Monad m)

=> I n t e g e r −> GameTree −> G a m e B u i l d e r m ( ) b u i l d F r o m T r e e g t r e e = do

g i d . = g

forMOf ( s e q u e n c e . n o d e s . e a c h ) t r e e $ \ no d e −>

i f o r M ( v i e w p r o p e r t i e s n o d e ) b u i l d F r o m P r o p e r t y b u i l d F r o m P r o p e r t y : : ( F u n c t o r m, Monad m)

(23)

=> T e x t −> [ T e x t ] −> G a m e B u i l d e r m ( ) b u i l d F r o m P r o p e r t y ” SZ ” [ s z ] =

s i z e ?= ( r e a d . T e x t . u n p a c k $ s z ) b u i l d F r o m P r o p e r t y ”PW” [ pw ] =

whiteName ?= pw

b u i l d F r o m P r o p e r t y ” PB ” [ pb ] = b l a c k N a m e ?= pb

b u i l d F r o m P r o p e r t y ”WR” [ wr ] =

w h i t e R a t i n g ?= ( r e a d . i n i t . T e x t . u n p a c k $ wr ) b u i l d F r o m P r o p e r t y ” BR ” [ b r ] =

b l a c k R a t i n g ?= ( r e a d . i n i t . T e x t . u n p a c k $ b r ) b u i l d F r o m P r o p e r t y ” RE ” [ r ] =

w i n C o n d i t i o n ?= c a s e T e x t . u n p a c k r o f

” V o i d ” −> I n v a l i d

” 0 ” −> Draw

” ? ” −> Unknown

’ B ’ : ’ + ’ : s c o r e −> Winner B l a c k $ p a r s e S c o r e s c o r e

’W’ : ’ + ’ : s c o r e −> Winner White $ p a r s e S c o r e s c o r e o t h e r −> e r r o r $ ” R e s u l t n o t r e c o g n i z e d : ” ++ o t h e r w h e r e

p a r s e S c o r e ” R” = R e s i g n p a r s e S c o r e ” R e s i g n ” = R e s i g n p a r s e S c o r e ”T” = Time

p a r s e S c o r e ” Time ” = Time p a r s e S c o r e ” F ” = F o r f e i t

p a r s e S c o r e ” F o r f e i t ” = F o r f e i t p a r s e S c o r e num = S c o r e $ r e a d num b u i l d F r o m P r o p e r t y ”AW” m o v e s =

s t a r t M o v e s <>=

map ( Move White . p a r s e C o o r d . T e x t . u n p a c k ) m o v e s b u i l d F r o m P r o p e r t y ”AB” m o v e s =

s t a r t M o v e s <>=

map ( Move B l a c k . p a r s e C o o r d . T e x t . u n p a c k ) m o v e s b u i l d F r o m P r o p e r t y ”W” [ move ] =

p e r f o r m M o v e . Move White . p a r s e C o o r d . T e x t . u n p a c k $ move b u i l d F r o m P r o p e r t y ” B ” [ move ] =

p e r f o r m M o v e . Move B l a c k . p a r s e C o o r d . T e x t . u n p a c k $ move b u i l d F r o m P r o p e r t y = r e t u r n ( )

p e r f o r m M o v e : : ( F u n c t o r m, Monad m)

=> Move −> G a m e B u i l d e r m ( ) p e r f o r m M o v e ( Move bw c d ) = do

s t < u s e s t a t e s when ( n u l l s t ) $ do

s < maybe 19 i d <$> u s e s i z e s t a t e s . =

[ G a m e S t a t e B l a c k . m a t r i x s s $ c o n s t N o t h i n g ] ms < u s e s t a r t M o v e s

f o r M ms $ \ ( Move bw ’ cd ’ ) −> c a s e cd ’ o f Coord r c −>

(24)

s t a t e s . l a s t . b o a r d %=

f o r c e M a t r i x . s e t E l e m ( J u s t bw ’ ) ( r , c ) P a s s −> r e t u r n ( )

s < u s e $ s t a t e s . s i n g u l a r l a s t l e t n e w S t a t e = c a s e c d o f

Coord r c −>

s

& b o a r d %˜ s e t E l e m ( J u s t bw ) ( r , c )

& n e x t T u r n .˜ i n v e r t ( v i e w n e x t T u r n s ) P a s s −> s

i n v e r t B l a c k = White i n v e r t White = B l a c k

−− TODO : u s e b e t t e r d a t a s t r u c t u r e f o r a p p e n d s t a t e s <>= [ n e w S t a t e ]

p a r s e C o o r d : : S t r i n g −> Coord p a r s e C o o r d ” t t ” = P a s s

p a r s e C o o r d [ a , b ] =

Coord ( o r d a o r d ’ a ’ + 1 ) ( o r d b o r d ’ a ’ + 1 ) p a r s e C o o r d ” ” = P a s s

p a r s e C o o r d m = e r r o r $ ” U n r e c o g n i z e d move ” ++ m

A.4 Index Storage

module AI . Go . F i n g e r p r i n t . S t o r e w h e r e i m p o r t AI . Go . N o r m a l i z e d

i m p o r t AI . Go . F i n g e r p r i n t

i m p o r t C o n t r o l . Monad ( f o r e v e r ) i m p o r t D a t a . B i n a r y ( e n c o d e )

i m p o r t D a t a . B y t e S t r i n g . L a z y ( B y t e S t r i n g )

i m p o r t q u a l i f i e d D a t a . B y t e S t r i n g . L a z y a s B y t e S t r i n g i m p o r t D a t a b a s e . C a s s a n d r a . B a s i c

i m p o r t P i p e s

s t o r e C a s s a n d r a : : ( M o n a d C a s s a n d r a m)

=> Consumer F i n g e r p r i n t m ( ) s t o r e C a s s a n d r a = do

p o o l < l i f t g e t C a s s a n d r a P o o l f o r e v e r $ do

F i n g e r p r i n t m e t a p o s s < a w a i t l e t d e s c r i p t i o n = d e s c r i b e p o s s l i f t I O . r u n C a s p o o l $

i n s e r t ” g o ” ( B y t e S t r i n g . t a k e 2 d e s c r i p t i o n ) ONE [ p a c k C o l ( d e s c r i p t i o n , e n c o d e m e t a ) ]

(25)

d e s c r i b e : : [ F i n g e r p r i n t P o s i t i o n ] −> B y t e S t r i n g d e s c r i b e =

B y t e S t r i n g . p a c k . map c h a r a c t e r i z e w h e r e

c h a r a c t e r i z e ( S t o n e S e l f ) = 83 c h a r a c t e r i z e ( S t o n e O t h e r ) = 79 c h a r a c t e r i z e Empty = 32

c h a r a c t e r i z e O u t s i d e = 64

A.5 Database ingestion system

{−# LANGUAGE O v e r l o a d e d S t r i n g s #−}

module Main ( main ) w h e r e

i m p o r t AI . Go . F i n g e r p r i n t . N o r m a l i z e d ( n o r m a l i z e d F i n g e r p r i n t ) i m p o r t AI . Go . F i n g e r p r i n t . S t o r e ( s t o r e C a s s a n d r a )

i m p o r t AI . Go . Game . SGF ( sgfToGame )

i m p o r t AI . Go . SGF . P a r s e r ( s g f S i n g l e F i l e )

i m p o r t AI . Go . N o r m a l i z e d . Game ( g a m e T o N o r m a l i z e d ) i m p o r t C o n t r o l . Monad ( v o i d , forM , f o r e v e r ) i m p o r t C o n t r o l . Monad . T r a n s . S t a t e

i m p o r t C o n t r o l . C o n c u r r e n t . A s y n c

i m p o r t D a t a b a s e . C a s s a n d r a . B a s i c h i d i n g ( g e t ) i m p o r t P i p e s

i m p o r t P i p e s . A t t o p a r s e c i m p o r t P i p e s . C o n c u r r e n t i m p o r t P i p e s . T e x t . IO ( s t d i n ) main : : IO ( )

main = do

p o o l < c r e a t e C a s s a n d r a P o o l [ d e f S e r v e r ] 4 16 5 ” g o ” ( o u t p u t , i n p u t ) < s p a w n $ Bounded 65536

a s < forM [ 1 . . ( 4 1 6 ) : : I n t e g e r ] $ \ i −> a s y n c $ do p u t S t r L n $ ” S t a r t i n g C a s s a n d r a w o r k e r ” ++ show i r u n C a s p o o l . r u n E f f e c t $

f r o m I n p u t i n p u t >−> s t o r e C a s s a n d r a

p u t S t r L n $ ” S t o p p i n g C a s s a n d r a w o r k e r ” ++ show i performGC

a < a s y n c $ do

p u t S t r L n ” S t a r t i n g game s t a t e p r o d u c e r ”

r u n E f f e c t $ v o i d ( p a r s e d s g f S i n g l e F i l e s t d i n )

>−> sgfToGame

>−> g a m e T o N o r m a l i z e d

(26)

>−> pv

>−> n o r m a l i z e d F i n g e r p r i n t

>−> t o O u t p u t o u t p u t

p u t S t r L n ” S t o p p i n g game s t a t e p r o d u c e r ” performGC

mapM w a i t ( a : a s ) pv : : P i p e a a IO ( )

pv = v o i d . f l i p e x e c S t a t e T ( 0 : : I n t e g e r ) . f o r e v e r $ do a < l i f t a w a i t

i < g e t m o d i f y ( + 1 )

l i f t I O . p u t S t r L n $ ” P r o c e s s e d ” ++ show i l i f t $ y i e l d a

References

Related documents

To explore if Swedish upper secondary chemistry students perceive contextual settings interesting and relevant or not, this study emanates from previous studies

The theory conceptualizes group interaction grammars as rule regimes that structure and regulate social relationships and interaction patterns in any given group or organization: (1)

It discusses how gene transfer scientists attempt to gain public ac- ceptance by framing gene transfer as an ordinary kind of therapy, while simultaneously – in order to obtain

Deconsolidation theory suggests that countries are not completely resistant to democratic decline, and that just like democracy can become the only game in town when citizens

The purpose of this thesis is to deeper and with a different model, than above mentioned paper, examine the impact of EMU on the long-run covariance between the member countries

The important observation from our result is therefore the general correlation between heuristics and MCTS: If someone implements a heuristic that plays well against human players,

Thus, the game seems to be more helpful in the process of memorizing facts about Chinese currency to the game player as they remember better compared to reading group

Thus, the purpose of this study is to examine how to guide players through a horror game using level design, which aspects of level design affect.. players and how. The